深入解析Dify:从架构到应用的全面探索
文章目录
- 引言
- 一、Dify基础架构
- 1.1 架构概述
- 1.2 前端界面
- 1.3 后端服务
- 1.4 数据库设计
- 二、Dify核心概念
- 2.1 节点(Node)
- 2.2 变量(Variable)
- 2.3 工作流类型
- 三、代码示例
- 3.1 蓝图注册
- 3.2 节点运行逻辑
- 3.3 工作流运行逻辑
- 四、应用场景
- 4.1 对话机器人开发
- 4.2 自动化数据处理
- 4.3 智能知识库问答
- 五、开发与部署注意事项
- 5.1 环境依赖配置
- 5.2 数据库迁移与版本控制
- 5.3 性能优化策略
- 六、总结
引言
在开源技术蓬勃发展的浪潮中,Dify作为一款开源AI对话平台,凭借强大的功能与灵活的扩展性脱颖而出,吸引了众多开发者与企业的目光。它不仅支持多模态对话,还具备出色的工作流编排能力,能够满足从简单问答到复杂业务流程自动化的多样化需求。然而,若想充分挖掘Dify的潜力,仅使用其API或界面远远不够。深入解析Dify的源码,有助于我们理解其内部运行机制,更为二次开发与优化奠定坚实基础。本文将从Dify的基础架构、核心概念出发,结合代码示例展开解析,助力读者快速掌握并深入理解Dify。
一、Dify基础架构
1.1 架构概述
Dify整体架构遵循现代微服务架构原则,将系统拆解为多个独立模块,每个模块各司其职。这种设计大幅提升了系统的可维护性与可扩展性,开发者可根据需求灵活选择、组合模块。Dify主要由以下核心模块构成:
- 前端界面:提供用户交互入口,支持工作流编排、知识库管理等功能。
- 后端服务:包含API服务与Worker服务,分别负责处理前端请求与任务调度。
- 数据库:用于存储工作流定义、知识库数据、用户信息等内容。
- 消息队列:实现异步任务处理,提升系统性能。
- 存储服务:存储上传文件与知识库数据。
1.2 前端界面
前端界面是用户与Dify交互的主要窗口,其直观可视化设计支持以下核心功能:
- 工作流编排:用户通过拖拽操作,轻松构建复杂工作流,定义节点与边。
- 知识库管理:支持文档上传、文本预处理及知识库构建。
- Agent配置:用户可灵活配置Agent能力,选择所需工具与功能。
前端代码位于/frontend
目录,基于React框架开发,主要组件结构如下:
/frontend
├── src
│ ├── components
│ │ ├── WorkflowEditor
│ │ ├── KnowledgeBaseManager
│ │ └── AgentConfigurator
│ ├── pages
│ │ ├── Home
│ │ ├── Workflow
│ │ └── KnowledgeBase
│ ├── store
│ │ └── workflow.js
│ └── App.js
1.3 后端服务
后端服务是Dify的核心,承担着处理前端请求、任务调度与数据存储的重任,主要分为API服务与Worker服务。
- API服务:提供RESTful接口处理前端请求,涵盖工作流管理、知识库管理、Agent配置等功能。其核心代码位于
/backend/api
目录,基于Flask框架开发,主要路由结构如下:
# /backend/api/__init__.py
from flask import Flask
from.routes import workflow, knowledge_base, agentapp = Flask(__name__)app.register_blueprint(workflow.bp)
app.register_blueprint(knowledge_base.bp)
app.register_blueprint(agent.bp)
# /backend/api/routes/workflow.py
from flask import Blueprint, request, jsonify
from.services import workflow_servicebp = Blueprint('workflow', __name__)@bp.route('/workflows', methods=['POST'])
def create_workflow():data = request.jsonworkflow = workflow_service.create_workflow(data)return jsonify(workflow)@bp.route('/workflows/<int:id>', methods=['GET'])
def get_workflow(id):workflow = workflow_service.get_workflow(id)return jsonify(workflow)@bp.route('/workflows/<int:id>', methods=['PUT'])
def update_workflow(id):data = request.jsonworkflow = workflow_service.update_workflow(id, data)return jsonify(workflow)@bp.route('/workflows/<int:id>', methods=['DELETE'])
def delete_workflow(id):workflow_service.delete_workflow(id)return jsonify({'message': 'Workflow deleted'})
- Worker服务:负责处理异步任务,如知识库构建、工作流执行等。它通过消息队列接收任务并在后台运行,核心代码位于
/backend/worker
目录,基于Celery框架开发,主要任务结构如下:
# /backend/worker/__init__.py
from celery import Celery
app = Celery('dify_worker', broker='redis://localhost:6379/0')@app.task
def build_knowledge_base(file_id):# 构建知识库的逻辑pass@app.task
def execute_workflow(workflow_id):# 执行工作流的逻辑pass
1.4 数据库设计
Dify采用关系型数据库(如MySQL)存储系统数据,主要表结构如下:
- 工作流表(workflows):包含工作流ID、名称、定义(JSON格式)、创建时间与更新时间。
- 知识库表(knowledge_bases):记录知识库ID、名称、关联文件ID、创建时间与更新时间。
- 用户表(users):存储用户ID、用户名、加密密码、创建时间与更新时间。
数据库初始化与迁移代码位于/backend/database
目录,基于SQLAlchemy框架开发,初始化代码示例如下:
# /backend/database/__init__.py
from sqlalchemy import create_engine, Column, Integer, String, JSON, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from datetime import datetimeBase = declarative_base()class Workflow(Base):__tablename__ = 'workflows'id = Column(Integer, primary_key=True)name = Column(String(255))definition = Column(JSON)created_at = Column(DateTime, default=datetime.utcnow)updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)class KnowledgeBase(Base):__tablename__ = 'knowledge_bases'id = Column(Integer, primary_key=True)name = Column(String(255))file_id = Column(Integer)created_at = Column(DateTime, default=datetime.utcnow)updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)class User(Base):__tablename__ = 'users'id = Column(Integer, primary_key=True)username = Column(String(255), unique=True)password = Column(String(255))created_at = Column(DateTime, default=datetime.utcnow)updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)engine = create_engine('mysql+pymysql://user:password@localhost/dify')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
二、Dify核心概念
2.1 节点(Node)
节点是Dify工作流的基本单元,每个节点代表一项具体任务或操作。Dify支持多种节点类型:
- 开始节点(Start Node):工作流的起始点。
- 结束节点(End Node):工作流的终止点。
- 回复节点(Reply Node):用于生成回复内容。
- 条件节点(Condition Node):判断条件并执行分支逻辑。
- 工具调用节点(Tool Node):调用外部工具或API。
节点定义与运行逻辑代码示例如下:
# /backend/core/node.py
class Node:def __init__(self, id, type, data):self.id = idself.type = typeself.data = datadef run(self, context):if self.type =='start':return self.run_start(context)elif self.type == 'end':return self.run_end(context)elif self.type =='reply':return self.run_reply(context)elif self.type == 'condition':return self.run_condition(context)elif self.type == 'tool':return self.run_tool(context)def run_start(self, context):# 开始节点的逻辑return contextdef run_end(self, context):# 结束节点的逻辑return contextdef run_reply(self, context):# 回复节点的逻辑reply = self.data['reply']context['reply'] = replyreturn contextdef run_condition(self, context):# 条件节点的逻辑condition = self.data['condition']if condition:return contextelse:raise Exception('Condition not met')def run_tool(self, context):# 工具调用节点的逻辑tool_name = self.data['tool_name']tool_input = self.data['tool_input']result = call_tool(tool_name, tool_input)context['tool_result'] = resultreturn contextdef call_tool(tool_name, tool_input):# 调用外部工具的逻辑pass
2.2 变量(Variable)
变量是Dify存储与传递数据的关键机制,主要包含以下类型:
- 系统变量(System Variables):由系统自动维护,如
workflow_id
、node_id
等。 - 环境变量(Environment Variables):用户在系统配置中自定义,如API密钥。
- 会话变量(Session Variables):存储用户会话数据,如用户输入、工具调用结果。
变量定义与使用示例如下:
# /backend/core/variable.py
class Variable:def __init__(self, name, value):self.name = nameself.value = valuedef get_value(self):return self.valuedef set_value(self, value):self.value = value# 示例:使用变量
context = {'system_variables': {'workflow_id': 1, 'node_id': 2},'environment_variables': {'api_key': 'your_api_key'},'session_variables': {'user_input': 'Hello, world!'}
}# 获取变量值
workflow_id = context['system_variables']['workflow_id']
api_key = context['environment_variables']['api_key']
user_input = context['session_variables']['user_input']
2.3 工作流类型
Dify支持多种工作流类型,适配不同应用场景:
- Chatflow:适用于对话类任务,处理用户与系统的交互。
- Workflow:用于自动化批处理任务,处理复杂工作流逻辑。
工作流类型定义与运行逻辑代码示例如下:
# /backend/core/workflow.py
class Workflow:def __init__(self, id, definition):self.id = idself.definition = definitiondef run(self, context):nodes = self.definition['nodes']edges = self.definition['edges']current_node = nodes[0] # 从开始节点开始while True:context = current_node.run(context)next_node_id = self.get_next_node_id(current_node.id, edges)if next_node_id is None:break # 到达结束节点current_node = nodes[next_node_id]def get_next_node_id(self, current_node_id, edges):for edge in edges:if edge['from'] == current_node_id:return edge['to']return None# 示例:运行工作流
workflow_definition = {'nodes': [{'id': 0, 'type':'start', 'data': {}},{'id': 1, 'type':'reply', 'data': {'reply': 'Hello, world!'}},{'id': 2, 'type': 'end', 'data': {}}],'edges': [{'from': 0, 'to': 1},{'from': 1, 'to': 2}]
}workflow = Workflow(1, workflow_definition)
context = {}
workflow.run(context)
三、代码示例
3.1 蓝图注册
在Dify的API服务中,蓝图(Blueprint)用于组织管理路由,示例代码如下:
# /backend/api/__init__.py
from flask import Flask
from.routes import workflow, knowledge_base, agentapp = Flask(__name__)app.register_blueprint(workflow.bp)
app.register_blueprint(knowledge_base.bp)
app.register_blueprint(agent.bp)
# /backend/api/routes/workflow.py
from flask import Blueprint, request, jsonify
from.services import workflow_servicebp = Blueprint('workflow', __name__)@bp.route('/workflows', methods=['POST'])
def create_workflow():data = request.jsonworkflow = workflow_service.create_workflow(data)return jsonify(workflow)@bp.route('/workflows/<int:id>', methods=['GET'])
def get_workflow(id):workflow = workflow_service.get_workflow(id)return jsonify(workflow)@bp.route('/workflows/<int:id>', methods=['PUT'])
def update_workflow(id):data = request.jsonworkflow = workflow_service.update_workflow(id, data)return jsonify(workflow)@bp.route('/workflows/<int:id>', methods=['DELETE'])
def delete_workflow(id):workflow_service.delete_workflow(id)return jsonify({'message': 'Workflow deleted'})
3.2 节点运行逻辑
节点作为工作流基础,其运行逻辑示例如下:
# /backend/core/node.py
class Node:def __init__(self, id, type, data):self.id = idself.type = typeself.data = datadef run(self, context):if self.type =='start':return self.run_start(context)elif self.type == 'end':return self.run_end(context)elif self.type =='reply':return self.run_reply(context)elif self.type == 'condition':return self.run_condition(context)elif self.type == 'tool':return self.run_tool(context)def run_start(self, context):# 开始节点的逻辑return contextdef run_end(self, context):# 结束节点的逻辑return contextdef run_reply(self, context):# 回复节点的逻辑reply = self.data['reply']context['reply'] = replyreturn contextdef run_condition(self, context):# 条件节点的逻辑condition = self.data['condition']if condition:return contextelse:raise Exception('Condition not met')def run_tool(self, context):# 工具调用节点的逻辑tool_name = self.data['tool_name']tool_input = self.data['tool_input']result = call_tool(tool_name, tool_input)context['tool_result'] = resultreturn contextdef call_tool(tool_name, tool_input):# 调用外部工具的逻辑pass
3.3 工作流运行逻辑
工作流运行逻辑是Dify核心功能,示例如下:
# /backend/core/workflow.py
class Workflow:def __init__(self, id, definition):self.id = idself.definition = definitiondef run(self, context):nodes = self.definition['nodes']edges = self.definition['edges']current_node = nodes[0] # 从开始节点开始while True:context = current_node.run(context)next_node_id = self.get_next_node_id(current_node.id, edges)if next_node_id is None:break # 到达结束节点current_node = nodes[next_node_id]def get_next_node_id(self, current_node_id, edges):for edge in edges:if edge['from'] == current_node_id:return edge['to']return None# 示例:运行工作流
workflow_definition = {'nodes': [{'id': 0, 'type':'start', 'data': {}},{'id': 1, 'type':'reply', 'data': {'reply': 'Hello, world!'}},{'id': 2, 'type': 'end', 'data': {}}],'edges': [{'from': 0, 'to': 1},{'from': 1, 'to': 2}]
}workflow = Workflow(1, workflow_definition)
context = {}
workflow.run(context)
四、应用场景
4.1 对话机器人开发
利用Dify的Chatflow工作流,开发者可轻松构建对话机器人。以简单客服机器人为例,工作流定义如下:
{"nodes": [{"id": 0, "type": "start", "data": {}},{"id": 1, "type": "reply", "data": {"reply": "欢迎咨询,请问有什么可以帮您?"}}],"edges": [{"from": 0, "to": 1}]
4.2 自动化数据处理
Dify 的 Workflow 工作流 适用于批量数据处理场景。例如,构建一个「数据清洗-分析-报告生成」的自动化流程:
{ "nodes": [ {"id": 0, "type": "start", "data": {}}, {"id": 1, "type": "tool", "data": {"tool_name": "data_cleaner", "tool_input": {"file_path": "/data/raw_data.csv"}}}, {"id": 2, "type": "tool", "data": {"tool_name": "data_analyzer", "tool_input": {"cleaned_file": "{{session_variables.cleaned_data_path}}"}}}, {"id": 3, "type": "reply", "data": {"reply": "数据分析完成,结果已保存至:{{session_variables.report_path}}"}}, {"id": 4, "type": "end", "data": {}} ], "edges": [ {"from": 0, "to": 1}, {"from": 1, "to": 2}, {"from": 2, "to": 3}, {"from": 3, "to": 4} ]
}
关键逻辑:
- 通过工具节点调用数据清洗工具(如 Pandas 脚本)处理原始数据;
- 利用会话变量(
session_variables
)传递文件路径,实现节点间数据共享; - 最终通过回复节点返回处理结果,触发下游系统(如邮件通知)。
4.3 智能知识库问答
结合 Dify 的 知识库管理 与 语义检索 能力,可快速搭建企业内部问答系统:
- 数据预处理:上传 PDF/Word 格式的产品手册、技术文档,Dify 自动解析文本并构建向量索引;
- 工作流设计:使用
Chatflow
类型工作流,通过语义检索节点
匹配用户问题与知识库内容,再通过回复节点
生成答案; - 多轮对话:利用
对话历史(Memory)
节点保留上下文,支持追问场景下的连续语义理解。
示例对话流程:
graph LR
A[用户提问:如何更换打印机墨盒?] --> B[语义检索节点:匹配知识库中「打印机维护」章节]
B --> C[回复节点:生成步骤说明,并询问是否需要视频教程]
C --> D[用户追问:请发送视频链接]
D --> E[工具调用节点:从 CMS 系统获取对应视频 URL]
E --> F[回复节点:发送视频链接与操作指南]
五、开发与部署注意事项
5.1 环境依赖配置
Dify 运行需以下环境支持:
组件 | 版本要求 | 说明 |
---|---|---|
Python | 3.8+ | 后端服务运行环境 |
Node.js | 16+ | 前端界面编译工具 |
MySQL | 5.7+/8.0 | 关系型数据库 |
Redis | 6.0+ | 消息队列与缓存 |
FFmpeg | 4.0+ | 多媒体文件处理(可选) |
部署建议:
- 使用 Docker 容器化部署,通过
docker-compose
管理服务依赖; - 生产环境建议分离前端静态资源服务器(如 Nginx)与后端 API 服务。
5.2 数据库迁移与版本控制
Dify 基于 Alembic 实现数据库迁移,流程如下:
- 安装工具:
pip install alembic
- 初始化迁移配置:
alembic init migrations
- 生成迁移脚本:
alembic revision --autogenerate -m "add_new_columns"
- 应用迁移:
alembic upgrade head
最佳实践:
- 每次模型变更后立即生成迁移脚本,避免版本差异导致的数据丢失;
- 通过 Git 管理迁移脚本,确保团队协作时数据库 schema 一致。
5.3 性能优化策略
优化方向 | 具体措施 |
---|---|
异步任务 | 增加 Celery Worker 实例数,配合 Redis Cluster 提升消息队列处理能力 |
数据库性能 | 为高频查询字段添加索引(如 workflow_id 、user_id ),启用连接池复用 |
缓存机制 | 使用 Redis 缓存知识库向量索引、用户会话数据,减少数据库查询压力 |
前端优化 | 启用 Webpack 代码分割(Code Splitting),压缩静态资源文件大小 |
六、总结
Dify 作为开源 AI 对话平台的代表,通过 低代码工作流编排、多模型集成能力 和 灵活的数据管理,降低了 AI 应用开发门槛,同时保持了高度的扩展性。其微服务架构设计使其适用于从个人开发者原型开发到企业级复杂业务场景的全生命周期需求。
对于技术团队,Dify 提供了可定制的源码底座——通过修改前端界面(React)、扩展后端工具节点(Python)或集成私有模型,可快速构建垂直领域解决方案(如医疗问诊、法律文书生成);对于非技术人员,通过可视化工作流与预制模板,也能轻松实现业务流程自动化。
未来,随着大语言模型与多模态技术的发展,Dify 有望在 智能体(Agent)开发、实时协作工作流 等场景中进一步释放潜力,成为连接业务需求与 AI 技术的核心枢纽。
相关文章:
深入解析Dify:从架构到应用的全面探索
文章目录 引言一、Dify基础架构1.1 架构概述1.2 前端界面1.3 后端服务1.4 数据库设计 二、Dify核心概念2.1 节点(Node)2.2 变量(Variable)2.3 工作流类型 三、代码示例3.1 蓝图注册3.2 节点运行逻辑3.3 工作流运行逻辑 四、应用场…...
电子电路:怎么理解放大电路中集电极电流Ic漂移?
如果放大电路中集电极电阻RC因为温度或老化而阻值变化,Vce Vcc - IcRc - IcRc,这会改变工作点,导致集电极的电流漂移。 IC漂移的定义:集电极电流随时间、温度等变化。影响IC的因素:β、IB、VBE、温度、电源电压、元件…...
【疑难杂症】Mysql 无报错 修改配置文件后服务启动不起来 已解决|设置远程连接
我修改配置后,服务无法启动可以试试用记事本打开后另存为,格式选择ANSI,然后重新启动mysql试试 设置运行远程、 1、配置my.ini文件 在[mysqld]下 添加bind-address0.0.0.0 2、设置root权限 使用MySql命令行执行, CREATE USER…...
Java基础 5.21
1.多态注意事项和细节讨论 多态的前提是:两个对象(类)存在继承关系 多态的向上转型 本质:父类的引用指向了子类的对象语法:父类类型 引用名 new 子类类型();特点:编译类型看左边,运行类型看…...
探索Puter:一个基于Web的轻量级“云操作系统”
在云计算与Web技术高度融合的今天,开发者们不断尝试将传统桌面体验迁移到浏览器中。近期,GitHub上一个名为Puter的开源项目吸引了社区的关注。本文将带你深入解析Puter的设计理念、技术架构与使用场景,探索它如何通过现代Web技术重构用户的“云端桌面”。 一、项目概览 Put…...
Java SpringBoot 项目中 Redis 存储 Session 具体实现步骤
目录 一、添加依赖二、配置 Redis三、配置 RedisTemplate四、创建控制器演示 Session 使用五、启动应用并测试六、总结 Java 在 Spring Boot 项目中使用 Redis 来存储 Session,能够实现 Session 的共享和高可用,特别适用于分布式系统环境。以下是具体的实…...
电商项目-商品微服务-规格参数管理,分类与品牌管理需求分析
本文章介绍:规格参数管理与分类与品牌管理的需求分析和表结构的设计。 一、规格参数管理 规格参数模板是用于管理规格参数的单元。规格是例如颜色、手机运行内存等信息,参数是例如系统:安卓(Android)后置摄像头像素&…...
Java 定时任务中Cron 表达式与固定频率调度的区别及使用场景
Java 定时任务:Cron 表达式与固定频率调度的区别及使用场景 一、核心概念对比 1. Cron 表达式调度 定义:基于日历时间点的调度,通过 秒 分 时 日 月 周 年 的格式定义复杂时间规则。时间基准:绝对时间点(如每天 12:…...
2025年- H39-Lc147 --394.字符串解码(双栈,递归)--Java版
1.题目描述 2.思路 可以用递归也可以用双栈,这边用栈。 首先先创建一个双栈,一个栈存数字(interger),另一个栈存字符(character)。设置数字临时变量num,设置字母临时变量curString在…...
学编程对数学成绩没帮助?
今天听到某机构直播说“学编程对数学成绩没帮助,如果想提高数学成绩那就单独去学数学”,实在忍不住要和各位家长聊聊我的思考,也欢迎各位家长评论。 恰在此时我看见了一道小学6年级的数学题如下,虽然题不难,但立刻让我…...
现代计算机图形学Games101入门笔记(十九)
光场 在近处画上图像,VR的效果。 任何时间任何位置看到的图像都不一样,是不是就是一个世界了。 光场就是任何一个位置往任何一个方向去的光的强度 知道光场就能知道这个物体长什么样子。 光线可以用一个点和一个方向确定。 也可以用2个点确定一条光线。 …...
STM32单片机GUI系统1 GUI基本内容
目录 一、GUI简介 1、emWin 2、LVGL (Light and Versatile Graphics Library) 3、TouchGFX 4、Qt for Embedded 5、特性对比总结 二、LVGL移植要求 三、优化LVGL运行效果方法 四、LVGL系统文件 一、GUI简介 在嵌入式系统中,emWin、LVGL、TouchGFX 和 Qt 是…...
Prometheus+Grafana实现对服务的监控
PrometheusGrafana实现对服务的监控 前言:PrometheusGrafana实现监控会更加全面,监控的组件更多 Prometheus官网 https://prometheus.io/docs/prometheus/latest/getting_started/ Grafana官网 https://grafana.com/docs/ 一、安装PrometheusGrafana 这…...
hook原理和篡改猴编写hook脚本
hook原理: hook是常用于js反编译的技术;翻译就是钩子,他的原理就是劫持js的函数然后进行篡改 一段简单的js代码 :这个代码是顺序执行的 function test01(){console.log(test01)test02() } function test02(){console.log(02)tes…...
Sign签证绕过
Sign的简介 Sign是指一种类似于token的东西 他的出现主要是保证数据的完整性,防篡改 就是一般的逻辑是 sign的加密的值和你输入的数据是相连的(比如sign的加密是使用输入的数据的前2位数字配合SHA1 等这样的) 绕过 :碰运气可以…...
【Vue篇】重剑无锋:面经PC项目工程化实战面经全解
目录 引言 一、项目功能演示 1. 目标 2. 项目收获 二、项目创建目录初始化 vue-cli 建项目 三、ESlint代码规范及手动修复 1. JavaScript Standard Style 规范说明 2. 代码规范错误 3. 手动修正 四、通过eslint插件来实现自动修正 五、调整初始化目录结构 1. 删除…...
JVM参数详解与实战案例指南(AI)
JVM参数详解与实战案例指南 一、JVM参数概述与分类 JVM参数是控制Java虚拟机运行时行为的关键配置项,合理设置这些参数可以显著提升应用性能。根据功能和稳定性,JVM参数主要分为三类: 标准参数:所有JVM实现都必须支持ÿ…...
C++通过空间配置器实现简易String类
C实现简易String类 在C中,使用空间配置器(allocator)实现自定义string类需要管理内存分配、释放及对象构造/析构。 #include <memory> #include <algorithm> #include <cstring> #include <stdexcept> #include &l…...
MyBatis:简化数据库操作的持久层框架
1、什么是Mybatis? MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由 apachesoftwarefoundation 迁移到了google code,由谷歌托管,并且改名为MyBatis 。 2013年11月迁移到Github。 iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框…...
Spring Boot集成Spring AI与Milvus实现智能问答系统
在Spring Boot中集成Spring AI与Milvus实现智能问答系统 引言 随着人工智能技术的快速发展,越来越多的企业开始探索如何将AI能力集成到现有系统中。本文将介绍如何在Spring Boot项目中集成Spring AI和向量数据库Milvus,构建一个高效的智能问答系统。 …...
软件工程(六):一致性哈希算法
哈希算法 定义 哈希算法是一种将任意长度的输入(如字符串、文件等)转换为固定长度输出的算法,这个输出称为“哈希值”或“摘要”。 常见的哈希算法 哈希算法哈希位数特点MD5128位快速,但已不安全SHA-1160位安全性提高…...
Linux内存分页管理详解
Linux内存分页管理详解:原理、实现与实际应用 目录 Linux内存分页管理详解:原理、实现与实际应用 一、引言 二、内存分页机制概述 1. 虚拟地址与物理地址的划分 2. 分页的基本原理 三、虚拟地址到物理地址的转换 1. 地址转换流程 2. 多级页表的遍历 四、多级页表的…...
work-platform阅读
Redis存储的是字节数据,所以任何对象想要存进redis,都要转化成字节。对象转化为字节流的过程,叫序列化,反之,叫反序列化 Redis 序列化详解及高性能实践-CSDN博客https://blog.csdn.net/zhangkunls/article/details/14…...
在 Excel xll 自动注册操作 中使用东方仙盟软件————仙盟创梦IDE
windows 命令 "C:\Program Files\Microsoft Office\root\Office16\EXCEL.EXE" /X "C:\Path\To\仙盟.xll" excel 注册 Application.RegisterXLL "XLMAPI.XLL" 重点代码解析 excel 命令模式 [ExcelCommand(Description "使用参数")] …...
微调后的模型保存与加载
在Hugging Face Transformers库中,微调后的模型保存与加载方式因微调方法(如常规微调或参数高效微调)而异。 一、常规微调模型的保存与加载 1、 保存完整模型 使用 save_pretrained() 方法可将整个模型(包含权重、配置、分词器…...
PostgreSQL 日常维护
目录 一、基本使用 1、登录数据库 2、数据库操作 (1)列出库 (2)创建库 (3)删除库 (4)切换库 (5)查看库大小 3、数据表操作 (1ÿ…...
Ntfs!ATTRIBUTE_RECORD_HEADER结构$INDEX_ROOT=0x90的一个例子
Ntfs!ATTRIBUTE_RECORD_HEADER结构$INDEX_ROOT0x90的一个例子 1: kd> dx -id 0,0,899a2278 -r1 ((Ntfs!_FILE_RECORD_SEGMENT_HEADER *)0xc431a400) ((Ntfs!_FILE_RECORD_SEGMENT_HEADER *)0xc431a400) : 0xc431a400 [Type: _FILE_RECORD_SEGMENT_HEADER …...
leetcode hot100刷题日记——7.最大子数组和
class Solution { public:int maxSubArray(vector<int>& nums) {//方法一:动态规划//dp[i]表示以i下标结尾的数组的最大子数组和//那么在i0时,dp[0]nums[0]//之后要考虑的就是我们要不要把下一个数加进来,如果下一个数加进来会使结…...
LlamaIndex
1、大语言模型开发框架的价值是什么? SDK:Software Development Kit,它是一组软件工具和资源的集合,旨在帮助开发者创建、测试、部署和维护应用程序或软件。 所有开发框架(SDK)的核心价值,都是降低开发、维护成本。 大语言模型开发框架的价值,是让开发者可以更方便地…...
下一代电子电气架构(EEA)的关键技术
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…...
CSDN gitcode代码推送
当我使用用户名密码时一直无法推送,报下面这个错误 找了半天才知道, 他这个git不能用账号密码推送代码,idea弹出来的用户名,就是你头像旁边这个,没有符号 密码需要你创建一个令牌 这个令牌才是你要填写的密码&#x…...
中级统计师-统计学基础知识-第五章 相关分析
第一节 相关关系 1. 函数关系 vs 相关关系 函数关系 定义:变量间存在严格确定性的对应关系(如 y f ( x ) y f(x) yf(x))例子:本金 x x x 与利息收入 y x 0.027 x y x 0.027x yx0.027x特点:一一对应ÿ…...
OpenCV CUDA模块图像过滤------用于创建一个最大值盒式滤波器(Max Box Filter)函数createBoxMaxFilter()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 createBoxMaxFilter()函数创建的是一个 最大值滤波器(Maximum Filter),它对图像中每个像素邻域内的像素值取最…...
OpenCv高阶(十五)——EigenFace人脸识别
文章目录 前言一、EigenFace人脸识别原理二、EigenFace人脸识别代码1、导入OpenCV和NumPy库2、数据加载与预处理部分3、创建与训练EigenFace模型部分4、预测与结果输出部分5、可视化部分:在测试图像上叠加识别结果 总结 前言 人脸识别作为生物特征识别技术的重要分…...
Linux系统下nslookup命令的基本使用
Linux系统下 nslookup命令的基本使用 引言一、nslookup介绍二、使用帮助三、 基本使用方法1. 查询域名对应的IP地址2. 查询特定的DNS记录类型3. 使用特定的DNS服务器进行查询4. 交互模式 四、注意事项五、总结 引言 在网络管理中,DNS(域名系统ÿ…...
【笔记】PyCharm 中创建Poetry解释器
#工作记录 在使用 PyCharm 进行 Python 项目开发时,为项目配置合适的 Python 解释器至关重要。Poetry 作为一款强大的依赖管理和打包工具,能帮助我们更便捷地管理项目的依赖项与虚拟环境。下面将详细记录在 PyCharm 中创建 Poetry 解释器的步骤。 前提条…...
Qwen 3技术报告详细解读
近日,Qwen 3系列大模型正式发布,涵盖从0.6B到235B参数的多个规模版本,包括6个Dense模型和2个混合专家(MoE)模型。本文将从模型架构、预训练策略、后训练优化等方面进行全面解读,帮助读者深入理解Qwen 3的技…...
leetcode 螺旋矩阵 java
官方还得是官方! class Solution {public List<Integer> spiralOrder(int[][] matrix) {int l 0, r matrix[0].length - 1;int t 0, b matrix.length - 1;int x 0;List<Integer> res new ArrayList<>();while (true) {for (int i l; i …...
Spring Boot 项目中 Redis 存储 Session 对象序列化处理
目录 一、为什么需要序列化处理二、Spring Boot 集成 Redis 存储 Session2.1 添加依赖2.2 配置 Redis 三、自定义序列化和反序列化3.1 创建序列化配置类3.2 测试序列化和反序列化 四、其他序列化方式4.1 使用 JdkSerializationRedisSerializer4.2 使用 StringRedisSerializer 五…...
军工与航空航天特种PCB精密制造:猎板如何定义行业技术新标准?
一、军工与航空航天PCB的极限挑战 在低轨卫星载荷、战机航电系统等场景中,特种PCB需同时满足三大核心指标: 极端环境耐受性:工作温度横跨-55℃至200℃,承受20G机械振动与100krad辐射剂量,盐雾腐蚀测试超过50…...
springboot+vue实现鲜花商城系统源码(带用户协同过滤个性化推荐算法)
今天教大家如何设计一个 鲜花商城 , 基于目前主流的技术:前端vue3,后端springboot。学习完这个项目,你将来找工作开发实际项目都会又很大帮助。文章最后部分还带来的项目的部署教程。 系统有着基于用户的协同过滤推荐算法,还有保证…...
MyBatis 关联映射与多表查询实战教程
一、关联查询基础 1. 连接类型与选择 LEFT JOIN(左连接)SELECT u.*, r.role_name FROM User u LEFT JOIN user_role ur ON u.id = ur.uid LEFT JOIN Role r ON ur.rid = r.id;- **规则**:以左表为主,保留左表所有记录,右表无匹配时填充`NULL`。 - **场景**:查询主体…...
【AI流程应用】智能知识库搭建与实战应用
JeecgBoot 平台的 AIGC 功能模块,是一套类似 Dify 的 AIGC应用开发平台 知识库问答 子系统,是一款基于 LLM 大语言模型 AI 应用平台和 RAG 的知识库问答系统。 其直观的界面结合了 AI 流程编排、RAG 管道、知识库管理、模型管理、对接向量库、实时运行可…...
微店平台店铺商品接口开发指南
微店API获取店铺所有商品实现方案 以下是使用微店开放平台API获取店铺所有商品的完整实现代码,包含请求封装、分页处理和错误处理机制。 点击获取key和secret from weidian_api import WeidianAPI # 配置你的微店应用凭证 APP_KEY "your_app_key" APP_…...
springboot3+vue3融合项目实战-大事件文章管理系统-更新文章分类和增加文章分类优化-分组校验
因为我们之前在category实体类里面增加了notnull注解,而之前新增文章分类模块新增文章是不需要id的,而id是由数据库自动分配的,这就导致不能新增文章了,所以我们要进行分组校验 思路如下: 我们更改category代码&…...
Vue.js教学第九章:Vue动态与异步组件,高效开发全攻略
Vue 组件的动态与异步:探索高效开发路径 在 Vue.js 开发领域中,组件的动态与异步加载机制是构建复杂且高性能前端应用的关键策略。本研究深入探究 Vue 中动态组件与异步组件的原理、用法及性能优化实践,旨在为开发者提供全面且深入的技术指引,助力其在实际项目中高效运用。…...
CVE-2018-1270源码分析与漏洞复现(spring-messaging 表达式注入)
漏洞概述 CVE-2018-1270 是 Spring 框架中的一个高危远程代码执行(RCE)漏洞,影响版本为 Spring Framework 5.0–5.0.4 和 4.3–4.3.14。攻击者通过构造包含恶意 SpEL(Spring Expression Language)表达式的 STOMP&…...
DevOps学习回顾03-ops三部曲之配置管理(CM)
快速回顾 Ops 中配置管理的一些常见的方式,以及一些配置文件常见的组织形式 参考来源 极客时间-全栈工程师修炼指南-OPS三部曲之配置管理 什么是配置管理?–IBM 五大最流行的配置管理工具 为啥需要配置管理? CM 的主要目标是控制复杂系统…...
二进制编码、定点数与浮点数
1. 二进制编码 1.1. 字符串的表示,从编码到数字 不仅数值可以用二进制表示,字符乃至更多的信息都能用二进制表示。最典型的例子就是字符串(Character String)。最早计算机只需要使用英文字符,加上数字和一些特殊符号…...
CentOS:搭建国内软件repository,以实现自动yum网络安装
centosgit仓库_寂寞沙冷州的技术博客_51CTO博客 yum 很慢 centos yum安装慢_mob64ca1417b0c6的技术博客_51CTO博客 yum配置,文件,命令详解-CSDN博客 yum仓库简介_yum库是什么-CSDN博客 rootwww:/etc/yum.repos.d# pwd /etc/yum.repos.d ###创建下面这个.…...