1. dify简介
Dify是一个开源的LLM应用开发平台。其直观的界面结合了AI工作流、RAG管道、Agent、模型管理、可观测性功能等,让您可以快速从原型到生产。
2. dify核心功能:
2.1. 强大的AI工作流构建与测试
- 用户可以直观地设计和构建 AI 工作流,根据不同的业务需求和场景进行定制化操作。
- 能够对构建的工作流进行全面测试,确保其在实际应用中的稳定性和准确性。
2.2. 全面的模型支持
- 无缝集成了数百种来自数十个推理提供商和自托管解决方案的专有 / 开源大型语言模型(LLM)。
- 涵盖了多种不同类型的模型,为用户提供了丰富的选择,以满足不同的任务需求。
2.3. 便捷的提示 IDE
- 提供了一个集成开发环境(IDE),方便用户编写和优化提示(prompt)。
- 帮助用户更好地与语言模型进行交互,提高提示的质量和效果。
2.4. 强大的 RAG(检索增强生成)管道
- 具备高效的检索增强生成功能,能够从大量的文本数据中检索相关信息,并结合语言模型生成更加准确和丰富的内容。
- 提升了语言模型的输出质量和实用性。
2.5. 灵活的代理能力
- 允许用户设置代理,以满足不同的网络环境和访问需求。
- 增强了系统的灵活性和可扩展性。
2.6. 有效的LLMOps
- 提供了一系列针对语言模型的操作和管理工具,包括模型部署、监控、优化等。
- 帮助用户更好地管理和维护语言模型的运行,提高工作效率。
2.7. 后端即服务
- 可以作为后端服务提供给其他应用程序使用,方便集成和扩展。
- 为开发者提供了便捷的接口和工具,降低了开发成本和难度。
与LangChain、Flowise、OpenAI Assistant API对比:
功能 | Dify.AI | LangChain | Flowise | OpenAI Assistant API |
---|---|---|---|---|
编程方法 | API + 应用程序导向 | Python 代码 | 应用程序导向 | API 导向 |
支持的 LLMs | 丰富多样 | 丰富多样 | 丰富多样 | 仅限 OpenAI |
RAG引擎 | ✅ | ✅ | ✅ | ✅ |
Agent | ✅ | ✅ | ❌ | ✅ |
工作流 | ✅ | ❌ | ✅ | ❌ |
可观测性 | ✅ | ✅ | ❌ | ❌ |
企业功能(SSO/访问控制) | ✅ | ❌ | ❌ | ❌ |
本地部署 | ✅ | ✅ | ✅ | ❌ |
3. 源码部署
通过源码部署,方便后续代码调试,了解具体实现原理
- 克隆dify源码
git clone https://github.com/langgenius/dify.git
- docker-compose部署外部依赖PostgresSQL/Redis/Weaviate等
cd dify/docker
cp middleware.env.example middleware.env
docker compose -f docker-compose.middleware.yaml up -d
- 准备dify虚拟环境
conda create --name dify python=3.10
conda activate dify
pip install poetry
- 启动dify-api/dify-worker服务
# 进入api目录
cd api/
# 拷贝环境变量文件
cp .env.example .env
# 生成随机密钥
openssl rand -base64 42
# 替换环境变量文件中的密钥
sed -i 's/SECRET_KEY=.*/SECRET_KEY=<your_value>/' .env
# 使用poetry安装依赖
poetry install
# 执行数据库迁移到最新版本
flask db upgrade
# 启动dify-api服务
flask run --host 0.0.0.0 --port=5001 --debug
# 启动dify-worker服务
celery -A app.celery worker -P gevent -c 1 --loglevel INFO -Q dataset,generation,mail,ops_trace
- 启动dify-web服务
cd web
# 安装依赖
npm install
# 拷贝环境变量文件
cp .env.example .env.local
# 编译
npm run build
# 启动前端服务
npm run start
附上一个vscode launch.json文件:
{
"version": "0.2.0",
"configurations": [
{
"name": "dify-api",
"type": "debugpy",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "app.py",
"FLASK_ENV": "development",
"GEVENT_SUPPORT": "true",
},
"args": [
"run",
"--host=0.0.0.0",
"--port=5001",
"--debug"
],
"cwd": "${workspaceFolder}/api",
"justMyCode": false
},
{
"name": "dify-worker",
"type": "debugpy",
"request": "launch",
"program": "/opt/anaconda3/envs/dify/bin/celery",
"env": {
"GEVENT_SUPPORT": "true",
},
"args": [
"-A",
"app.celery",
"worker",
"-P",
"gevent",
"-c",
"1",
"--loglevel=INFO",
"-Q",
"dataset,generation,mail,ops_trace"
],
"cwd": "${workspaceFolder}/api",
"justMyCode": false,
"console": "integratedTerminal"
},
{
"name": "dify-web",
"type": "node",
"request": "launch",
"runtimeExecutable": "/opt/homebrew/bin/pnpm",
"runtimeArgs": [
"start"
],
"cwd": "${workspaceFolder}/web",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
}
]
}
如果源码编译dify-web失败的话,可以使用docker容器启动dify-web
docker run -it -d -p 3000:3000 -e CONSOLE_URL=http://127.0.0.1:5001 -e APP_URL=http://127.0.0.1:5001 langgenius/dify-web:latest
源码分析
dify-api
api基于flask框架实现
app = create_app()
def create_app() -> Flask:
"""
创建并配置Flask应用实例。
该函数负责初始化一个Flask应用,设置其密钥,配置日志处理,以及注册各种扩展、蓝本和命令。
Returns:
Flask: 配置好的Flask应用实例。
"""
# 初始化Flask应用并应用配置
app = create_flask_app_with_configs()
# 设置Flask应用的secret_key,这对于会话管理是必要的
app.secret_key = app.config["SECRET_KEY"]
# 默认情况下没有日志处理器
log_handlers = None
# 从配置中获取日志文件路径
log_file = app.config.get("LOG_FILE")
if log_file:
# 确保日志文件的目录存在,如果不存在则创建
log_dir = os.path.dirname(log_file)
os.makedirs(log_dir, exist_ok=True)
# 配置日志处理器,包括文件日志和控制台日志
log_handlers = [
RotatingFileHandler(
filename=log_file,
maxBytes=1024 * 1024 * 1024, # 1GB
backupCount=5, # 保留5个备份文件
),
logging.StreamHandler(sys.stdout), # 将日志输出到控制台
]
# 配置基本的日志记录设置
logging.basicConfig(
level=app.config.get("LOG_LEVEL"), # 日志级别
format=app.config.get("LOG_FORMAT"), # 日志格式
datefmt=app.config.get("LOG_DATEFORMAT"), # 日期格式
handlers=log_handlers, # 使用之前配置的日志处理器
force=True, # 强制重新配置日志设置,以确保上述配置生效
)
# 如果配置中指定了日志时区,则进行时区配置
log_tz = app.config.get("LOG_TZ")
if log_tz:
from datetime import datetime
import pytz
# 创建时区对象
timezone = pytz.timezone(log_tz)
# 定义将UTC时间转换为指定时区时间的函数
def time_converter(seconds):
return datetime.utcfromtimestamp(seconds).astimezone(timezone).timetuple()
# 将所有根记录器的处理器的格式化器的时间转换函数设置为上面定义的函数
for handler in logging.root.handlers:
handler.formatter.converter = time_converter
# 初始化应用所需的扩展
initialize_extensions(app)
# 注册蓝本,蓝本是Flask中组织路由的一种方式
register_blueprints(app)
# 注册命令行命令
register_commands(app)
# 返回配置好的应用实例
return app
if __name__ == "__main__":
# 当作为主程序运行时,启动Flask应用程序
# 通过指定host为"0.0.0.0",允许网络中的其他设备访问该服务
# 端口号设置为5001,与其他设备通信时使用此端口
app.run(host="0.0.0.0", port=5001)
dify-worker
如何添加一个内置工具
- 代码参考实现:https://github.com/langgenius/dify/pull/7991
- 官方指引:https://docs.dify.ai/guides/tools/quick-tool-integration
如何添加一个对象存储实现
代码参考实现:https://github.com/langgenius/dify/pull/8164
如何添加一个向量数据库
代码参考实现:https://github.com/langgenius/dify/pull/9287
如何添加一个LLM Model Provider
- 代码参考实现:https://github.com/langgenius/dify/pull/8428
- 官方指引:https://docs.dify.ai/guides/model-configuration/new-provider
如何添加一个Embedding Model Provider
- 代码参考实现:https://github.com/langgenius/dify/pull/8728
- 官方指引:https://docs.dify.ai/guides/model-configuration/predefined-model
参考链接
「真诚赞赏,手留余香」
真诚赞赏,手留余香
使用微信扫描二维码完成支付