Dify AI 应用平台零基础入门教程
📘 本教程版本:基于 Dify v1.x 系列编写 🕐 预计学习时间:8-12 小时 🎯 适合人群:零基础开发者、AI 爱好者、产品经理、企业技术决策者
目录
- 第一章 Dify 简介
- 第二章 快速开始
- 第三章 应用类型详解
- 第四章 知识库管理
- 第五章 Prompt 工程在 Dify 中的应用
- 第六章 工作流编排
- 第七章 Agent 模式开发
- 第八章 API 集成开发
- 第九章 高级功能
- 第十章 部署与运维
- 第十一章 实战项目:构建企业级智能文档问答系统
第一章 Dify 简介
1.1 什么是 Dify
Dify 是一个开源的大语言模型(LLM)应用开发平台,致力于让每个人都能轻松构建和运营生成式 AI 原生应用。它的名字来源于 "Define" 和 "Simplify" 的组合,寓意"定义并简化 AI 应用开发"。
Dify 提供了从 Agent 构建到 AI workflow 编排、RAG 检索、模型管理等全方位能力,使开发者和非技术用户都能通过可视化界面快速搭建生产级的 AI 应用。与传统的 AI 开发方式相比,Dify 将原本需要数周甚至数月的开发周期压缩到数小时或数天。
Dify 的核心理念
Dify 的设计理念可以概括为以下几个方面:
- 可视化优先:所有操作都通过直观的图形界面完成,无需编写大量代码
- 模型无关:支持接入数十种主流大模型,包括 OpenAI、Anthropic、Google、百度文心、阿里通义等
- 生产就绪:内置 API 服务、监控、日志等企业级功能
- 开源开放:基于 Apache 2.0 协议开源,社区活跃
1.2 Dify 的核心功能
Dify 提供了一系列强大的核心功能模块:
1. 可视化 Prompt 编排
Dify 提供了直观的 Prompt 编辑器,支持变量绑定、上下文引用、模板管理等功能。用户可以通过拖拽和配置的方式,轻松设计复杂的提示词逻辑。编辑器支持实时预览,方便调试和优化。
2. 多模型支持
平台内置了对主流大语言模型的统一接入层,包括:
| 模型提供商 | 代表模型 | 特点 |
|---|---|---|
| OpenAI | GPT-4o、GPT-4、GPT-3.5-Turbo | 综合能力最强 |
| Anthropic | Claude 3.5 Sonnet、Claude 3 Opus | 长文本处理优秀 |
| Gemini Pro、Gemini 1.5 Pro | 多模态能力强 | |
| 百度 | 文心一言 4.0 | 中文理解突出 |
| 阿里 | 通义千问 Max | 性价比高 |
| 月之暗面 | Kimi (Moonshot) | 长上下文窗口 |
| 深度求索 | DeepSeek V3 | 开源高性能 |
| 智谱 | GLM-4 | 中文对话自然 |
3. RAG(检索增强生成)引擎
Dify 内置了完整的 RAG 管道,包括:
- 文档导入与自动解析(支持 PDF、Word、Markdown、CSV 等格式)
- 智能文本分段(自动/自定义分段策略)
- 向量化索引构建(支持高质量和经济两种模式)
- 多路召回与重排序
- 引用溯源
4. Agent 智能体
支持构建具有自主推理和工具调用能力的 AI Agent,内置多种推理策略:
- ReAct(推理-行动-观察循环)
- Function Calling(函数调用)
- 支持自定义工具扩展
5. 工作流编排
提供可视化的 DAG(有向无环图)工作流编辑器,支持:
- LLM 节点、条件分支、代码执行、HTTP 请求等多种节点类型
- 变量在节点间的传递与转换
- 循环与错误处理机制
- 工作流的导入与导出
6. 后端即服务(BaaS)
每个创建的应用都自动暴露标准的 RESTful API,支持:
- 对话型 API(含会话管理)
- 补全型 API
- 流式输出(SSE)
- 文件上传
1.3 Dify 与其他 AI 平台对比
在选择 AI 应用开发平台时,了解不同平台的特点至关重要。以下是 Dify 与两个主流竞品的详细对比:
Dify vs Coze(扣子)
| 对比维度 | Dify | Coze(扣子) |
|---|---|---|
| 开源性 | 完全开源(Apache 2.0) | 闭源 |
| 部署方式 | 支持本地/私有化部署 | 仅云端 |
| 模型选择 | 支持数十种模型自由切换 | 主要依赖字节系模型 |
| 数据隐私 | 数据可完全私有化 | 数据存储在字节服务器 |
| 工作流 | 功能强大,节点类型丰富 | 工作流能力较新,仍在完善 |
| 生态系统 | 开源社区活跃,插件丰富 | 依托字节跳动生态 |
| 适用场景 | 企业级应用、私有化部署 | 个人用户、轻量级应用 |
| 学习曲线 | 中等,文档齐全 | 较低,上手快 |
| 定价 | 开源免费,云版按用量 | 免费额度 + 付费 |
总结:如果你需要数据隐私、私有化部署或灵活的模型选择,Dify 是更好的选择。如果你是个人用户,想要快速搭建简单的聊天机器人且不介意数据存储在第三方,Coze 也是一个不错的选项。
Dify vs FastGPT
| 对比维度 | Dify | FastGPT |
|---|---|---|
| 开源性 | 完全开源 | 开源(部分高级功能闭源) |
| 核心优势 | 全栈 AI 应用开发平台 | 专注知识库问答 |
| RAG 能力 | 完善,支持多种索引策略 | 非常强,知识库管理更精细 |
| 工作流 | 强大,节点类型多样 | 支持,但相对简单 |
| Agent | 内置多种推理策略 | 支持,但功能较基础 |
| 模型支持 | 广泛 | 广泛 |
| 社区规模 | 更大(GitHub 60k+ Stars) | 较大(GitHub 20k+ Stars) |
| 适用场景 | 通用 AI 应用开发 | 知识库问答为主 |
| 企业级功能 | 完善 | 基础 |
总结:如果你的核心需求是知识库问答,FastGPT 在这方面有独到的优势。如果你需要构建多样化的 AI 应用(Agent、工作流、文本生成等),Dify 的功能更全面。
1.4 Dify 的适用场景
Dify 适用于以下典型场景:
1. 企业知识库问答
- 内部文档搜索与问答
- 客户服务智能助手
- 产品手册查询系统
2. 内容创作与处理
- 文案生成、翻译、摘要
- SEO 内容批量生产
- 报告自动生成
3. 智能客服
- 多轮对话管理
- 工单自动分类与路由
- 常见问题自动应答
4. 数据分析助手
- 自然语言查询数据库
- 数据可视化描述生成
- 业务指标分析解读
5. 工作流自动化
- 文档审核流程
- 邮件自动分类与回复
- 多步骤业务流程编排
6. AI Agent 应用
- 自动化研究助手
- 多工具协调的任务执行
- 信息聚合与分析
1.5 Dify 的技术架构概览
Dify 采用前后端分离的架构设计:
┌─────────────────────────────────────────────┐
│ 前端 (Next.js) │
│ 可视化编辑器 / 应用管理 / 数据分析面板 │
├─────────────────────────────────────────────┤
│ API 网关层 │
│ 认证 / 限流 / 路由 / 日志 │
├─────────────────────────────────────────────┤
│ 核心服务层 (Python/Flask) │
│ 应用编排 / RAG 引擎 / Agent / 模型调度 │
├─────────────────────────────────────────────┤
│ 基础设施层 │
│ PostgreSQL / Redis / Weaviate / Qdrant │
│ Celery (异步任务) / Nginx (反向代理) │
└─────────────────────────────────────────────┘
核心技术栈:
- 后端:Python 3.10+、Flask、Celery、SQLAlchemy
- 前端:Next.js 14、React 18、TailwindCSS
- 数据库:PostgreSQL(主数据库)、Redis(缓存与消息队列)
- 向量数据库:Weaviate(默认)、Qdrant、Milvus、Pgvector 等
- 搜索引擎:Elasticsearch(可选)
第二章 快速开始
2.1 云端注册与使用
对于零基础用户,最简单的方式是使用 Dify 的云端服务。
步骤一:访问 Dify 官网
打开浏览器,访问 Dify 官方网站 https://dify.ai。在首页可以了解 Dify 的主要功能和特性。点击页面右上角的"开始使用"或"Get Started"按钮。
步骤二:注册账号
Dify 云端支持以下注册方式:
- 邮箱注册:输入邮箱地址,设置密码,完成邮箱验证
- GitHub 登录:使用 GitHub 账号快速注册
- Google 登录:使用 Google 账号快速注册
推荐使用 GitHub 登录,方便后续关联代码仓库。
步骤三:创建首个应用
注册完成后,系统会自动跳转到控制台首页。你会看到一个简洁的仪表板,展示当前的应用列表和使用统计。点击"创建应用"按钮,选择应用类型(如聊天助手),输入应用名称和描述,即可开始配置。
步骤四:配置模型
首次使用需要配置模型供应商的 API Key:
- 进入"设置" → "模型供应商"
- 选择你要使用的模型提供商(如 OpenAI)
- 输入 API Key
- 点击"保存"并验证连通性
提示:云端版本提供了免费的试用额度,无需立即配置自己的 API Key 即可体验基础功能。
2.2 本地部署(Docker Compose)
对于需要数据隐私或自定义配置的用户,推荐使用 Docker Compose 进行本地部署。
2.2.1 环境要求
在开始部署之前,请确保你的机器满足以下最低配置要求:
| 资源 | 最低要求 | 推荐配置 |
|---|---|---|
| CPU | 2 核 | 4 核及以上 |
| 内存 | 4 GB | 8 GB 及以上 |
| 磁盘 | 20 GB | 50 GB SSD |
| 操作系统 | Linux (Ubuntu 20.04+) | Ubuntu 22.04 LTS |
| Docker | 20.10+ | 最新稳定版 |
| Docker Compose | 2.0+ | 最新稳定版 |
2.2.2 安装 Docker 和 Docker Compose
如果你的机器还没有安装 Docker,可以按照以下步骤安装:
Ubuntu/Debian 系统:
# 更新包索引
sudo apt-get update
# 安装必要的系统工具
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
# 添加 Docker 官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 添加 Docker 软件源
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装 Docker Engine
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 将当前用户添加到 docker 组(避免每次使用 sudo)
sudo usermod -aG docker $USER
# 验证安装
docker --version
docker compose version
macOS 系统:
推荐直接下载安装 Docker Desktop for Mac,它包含了 Docker Engine 和 Docker Compose。访问 Docker 官网下载对应芯片(Intel/Apple Silicon)的安装包。
2.2.3 克隆 Dify 仓库
# 克隆 Dify 代码仓库
git clone https://github.com/langgenius/dify.git
# 进入 Docker 部署目录
cd dify/docker
2.2.4 配置环境变量
# 复制环境变量模板文件
cp .env.example .env
使用你喜欢的编辑器打开 .env 文件,修改以下关键配置:
# 应用密钥(用于加密,请修改为随机字符串)
SECRET_KEY=your-random-secret-key-here
# 数据库密码
POSTGRES_PASSWORD=your-database-password
# Redis 密码
REDIS_PASSWORD=your-redis-password
# 应用访问端口
EXPOSE_NGINX_PORT=80
EXPOSE_NGINX_SSL_PORT=443
# 向量数据库类型(默认使用 weaviate)
VECTOR_STORE=weaviate
# 存储类型(local 表示本地文件存储)
STORAGE_TYPE=local
安全提示:
SECRET_KEY和数据库密码必须修改为强随机字符串,不能使用默认值。可以使用openssl rand -base64 42命令生成随机密钥。
2.2.5 启动服务
# 拉取最新镜像并启动所有服务
docker compose up -d
首次启动需要下载镜像,根据网络情况可能需要 5-15 分钟。启动过程中可以使用以下命令查看日志:
# 查看所有服务的运行状态
docker compose ps
# 查看实时日志
docker compose logs -f
# 查看特定服务的日志
docker compose logs -f api
docker compose logs -f web
正常启动后,你应该看到类似以下的输出:
NAME STATUS PORTS
dify-api Up (healthy) 0.0.0.0:5001->5001/tcp
dify-web Up (healthy) 0.0.0.0:3000->3000/tcp
dify-worker Up (healthy)
dify-db Up (healthy) 0.0.0.0:5432->5432/tcp
dify-redis Up (healthy) 0.0.0.0:6379->6379/tcp
dify-weaviate Up (healthy) 0.0.0.0:8080->8080/tcp
dify-nginx Up (healthy) 0.0.0.0:80->80/tcp
2.2.6 访问 Dify 控制台
打开浏览器,访问 http://localhost(如果修改了端口,使用 http://localhost:你设置的端口)。
首次访问会跳转到初始化页面:
- 设置管理员邮箱和密码
- 填写基本的站点信息
- 点击"初始化"完成安装
初始化完成后即可登录控制台开始使用。
2.2.7 常见部署问题排查
问题1:端口被占用
# 查看占用 80 端口的进程
sudo lsof -i :80
# 解决方案:修改 .env 中的 EXPOSE_NGINX_PORT 为其他端口
# 例如:EXPOSE_NGINX_PORT=8080
问题2:内存不足导致服务启动失败
# 检查可用内存
free -h
# 解决方案:增加 swap 空间
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
问题3:向量数据库连接失败
# 检查 Weaviate 服务状态
docker compose logs weaviate
# 如果持续失败,可以切换到 pgvector(使用内置 PostgreSQL)
# 修改 .env:VECTOR_STORE=pgvector
2.3 界面导览
登录 Dify 控制台后,你会看到一个功能丰富的管理界面。以下是主要区域的介绍:
2.3.1 顶部导航栏
顶部导航栏包含以下元素:
- Logo 与名称:左上角显示 Dify 的 Logo 和当前工作空间名称
- 工作空间切换:如果你属于多个工作空间,可以在此切换
- 通知中心:显示系统通知和告警信息
- 用户菜单:个人设置、API 密钥管理、团队管理、退出登录
2.3.2 左侧导航面板
左侧导航面板是主要的功能入口:
- 🏠 首页(仪表板):展示应用统计、最近活动、快速入门指引
- 📦 应用:应用列表,包含创建、编辑、删除等管理操作
- 📚 知识库:知识库管理,包含文档上传、分段管理、检索测试
- 🔧 工具:内置工具和自定义工具的管理
- ⚙️ 设置:模型配置、成员管理、系统设置
2.3.3 应用编辑器
当你打开一个应用时,会进入应用编辑器界面。这是 Dify 最核心的操作界面:
左侧面板:
- Prompt 编排区域
- 变量配置
- 上下文引用设置
- 对话开场白配置
中间区域:
- 编辑器主体(根据应用类型不同而变化)
- 聊天测试面板(可以在此实时测试应用效果)
右侧面板:
- 模型选择与参数调节
- 功能开关(如引用标记、内容审核等)
- 发布设置
2.3.4 知识库界面
知识库界面分为以下几个部分:
- 文档列表:显示已上传的文档,支持搜索和筛选
- 分段预览:查看文档被自动分段后的结果
- 检索测试:输入测试查询,查看检索效果
- 设置面板:配置索引方式、分段策略等参数
2.3.5 工作流编辑器
工作流编辑器是一个可视化的画布区域:
- 节点面板:左侧展示可拖拽的节点类型
- 画布区域:中间的可视化编辑区域,支持缩放和拖拽
- 节点配置:右侧展示选中节点的详细配置
- 调试面板:底部展示运行日志和变量状态
2.4 快速创建第一个应用
让我们通过一个简单的例子来快速体验 Dify 的功能。
目标:创建一个 "英语学习助手" 聊天应用
第一步:创建应用
- 在控制台首页,点击"创建应用"
- 选择"聊天助手"类型
- 输入应用名称:
英语学习助手 - 输入应用描述:
帮助用户学习英语,纠正语法错误,提供例句和翻译 - 点击"创建"
第二步:编写 Prompt
在 Prompt 编辑区域,输入以下提示词:
你是一位专业的英语学习助手,具有以下能力:
1. **语法纠错**:当用户输入英语句子时,指出语法错误并给出正确写法
2. **词汇解释**:解释用户不理解的英语单词或短语,包含词性、释义和例句
3. **口语练习**:与用户进行英语对话练习,适时纠正表达
4. **翻译辅助**:帮助用户进行中英文互译,注意语境和地道表达
请始终使用简洁清晰的语言回复。在给出英语内容时,同时提供中文解释。
如果用户的英语有错误,先肯定正确的部分,再指出需要改进的地方。
第三步:选择模型
在右侧面板中:
- 选择模型提供商(如 OpenAI)
- 选择模型(如 GPT-4o)
- 保持默认参数或根据需要调整 Temperature(建议设置为 0.7)
第四步:测试应用
在右侧的预览面板中,输入测试内容:
I goes to school yesterday and goed to the library.
观察 AI 的回复是否正确识别了语法错误(went 而非 goed,go 而非 goes),并给出了详细的解释。
第五步:发布应用
确认效果满意后:
- 点击右上角的"发布"按钮
- 选择发布渠道(Web 应用 / API)
- 获取访问链接或 API 密钥
恭喜!你已经成功创建了第一个 Dify 应用。
第三章 应用类型详解
Dify 支持四种主要的应用类型,每种类型都有其独特的特点和适用场景。理解这些类型的区别,是高效使用 Dify 的基础。
3.1 聊天助手(Chat)
特点
聊天助手是 Dify 中最常用的应用类型,具有以下特点:
- 多轮对话:支持上下文连续的多轮对话,AI 能够记住之前的对话内容
- 对话记忆:可配置对话窗口大小(即 AI 能记住多少轮之前的对话)
- 交互式界面:提供友好的聊天界面,支持 Markdown 渲染、代码高亮等
- 开场白:可以设置对话开始时 AI 的主动发言内容
- 建议问题:在对话过程中可以显示建议的后续问题
配置要点
在聊天助手的配置中,以下几个参数特别重要:
1. 对话窗口大小(Dialogue Turns)
这个参数决定了 AI 能"记住"多少轮历史对话。设置范围通常为 5-100 轮。
- 设置过小:AI 会"失忆",忘记之前的对话内容
- 设置过大:会消耗更多的 Token,增加成本和响应时间
建议值:
- 简单问答场景:5-10 轮
- 复杂咨询场景:20-30 轮
- 深度对话场景:50 轮以上
2. 对话开场白(Opening Statement)
开场白是 AI 在对话开始时主动发送的第一条消息,可以引导用户正确使用应用。
示例:
👋 你好!我是你的英语学习助手。
我可以帮你:
• 🔍 纠正英语语法错误
• 📖 解释英语单词和短语
• 💬 进行英语口语练习
• 🌐 中英文翻译
请输入任何你想学习的英语内容,或者直接用英语和我聊天!
3. 建议问题(Suggested Questions)
在开场白之后显示的建议问题按钮,帮助用户快速开始对话。
示例设置:
- "帮我检查一段英语作文"
- "Explain the difference between 'affect' and 'effect'"
- "我们来练习英语对话吧"
适用场景
- 客户服务机器人
- 教育辅导助手
- 咨询顾问系统
- 日常问答助手
- 语言学习伙伴
3.2 文本生成(Completion)
特点
文本生成类型适用于单次输入、单次输出的场景:
- 单轮交互:每次调用独立,不保留对话历史
- 模板化输入:通过变量模板接收用户输入
- 结构化输出:适合生成格式化的内容
- 批量处理:易于进行批量文本处理
与聊天助手的区别
| 特性 | 聊天助手 | 文本生成 |
|---|---|---|
| 对话模式 | 多轮对话 | 单轮输入输出 |
| 上下文 | 保留历史 | 每次独立 |
| 输入方式 | 自由文本 | 变量模板 |
| 输出界面 | 聊天气泡 | 文本展示区 |
| 适用场景 | 对话交互 | 内容生成 |
变量模板示例
文本生成类型支持使用 {{变量名}} 来定义输入模板:
请将以下 {{source_language}} 文本翻译为 {{target_language}}:
原文:
{{text}}
翻译要求:
- 保持原文的语气和风格
- 使用地道的表达方式
- 如有专业术语,请在翻译后附上解释
用户在使用时,会看到对应的输入框,分别填写源语言、目标语言和要翻译的文本。
适用场景
- 文案生成(广告、营销文案)
- 文本翻译
- 内容摘要
- 数据格式转换
- 代码生成
- 批量文本处理
3.3 Agent(智能体)
特点
Agent 是 Dify 中最智能的应用类型,具有自主推理和工具使用能力:
- 自主推理:AI 能够分析问题并制定解决方案
- 工具调用:可以调用各种外部工具(搜索引擎、计算器、API 等)
- 多步执行:能够自动分解复杂任务为多个步骤依次执行
- 自我纠错:当工具调用失败时,能够调整策略重试
推理策略
Dify 提供两种主要的 Agent 推理策略:
1. ReAct 策略(推理-行动-观察)
ReAct 是一种经典的 Agent 推理模式,其执行循环如下:
思考(Thought)→ 行动(Action)→ 观察(Observation)→ 思考 → ...
示例流程:
用户问题:"今天北京的天气怎么样?适合户外运动吗?"
思考:用户想知道北京今天的天气,并询问是否适合户外运动。
我需要先查询北京今天的天气信息。
行动:调用天气查询工具,查询北京天气
观察:北京今天晴,气温 28°C,空气质量良好,风力 2 级
思考:根据天气信息,今天北京天气不错,温度适中,适合户外运动。
但需要注意防晒。
回答:北京今天天气晴朗,气温 28°C,空气质量良好,风力 2 级。
非常适合户外运动!建议做好防晒措施,多补充水分。
2. Function Calling 策略
Function Calling 是 OpenAI 等模型提供商原生支持的工具调用方式:
- 模型直接输出结构化的函数调用请求
- 平台执行函数并返回结果
- 模型基于结果生成最终回答
相比 ReAct,Function Calling 的优势在于:
- 调用更精准,减少幻觉
- 响应速度更快
- 支持并行调用多个工具
内置工具
Dify 提供了丰富的内置工具:
| 工具名称 | 功能 | 来源 |
|---|---|---|
| 网页抓取 | 读取指定网页内容 | 内置 |
| 维基百科 | 搜索维基百科 | 内置 |
| 数学计算 | 执行数学表达式计算 | 内置 |
| 代码执行器 | 运行 Python 代码 | 内置 |
| 搜索引擎 | 联网搜索 | 需配置 |
| DALL-E | AI 图片生成 | 需配置 API |
| Stable Diffusion | AI 图片生成 | 需配置 |
| 天气查询 | 查询天气信息 | 需配置 API |
适用场景
- 智能研究助手(搜索 + 分析 + 总结)
- 数据查询与分析
- 自动化任务执行
- 多步骤问题求解
- 信息聚合与报告生成
3.4 工作流(Workflow)
特点
工作流是 Dify 中最灵活的应用类型,适合构建复杂的自动化流程:
- 可视化编排:拖拽式节点编辑器
- DAG 架构:有向无环图结构,支持分支和并行
- 变量系统:支持在节点间传递和转换数据
- 两种子类型:工作流和对话流
工作流 vs 对话流
| 特性 | 工作流(Workflow) | 对话流(Chatflow) |
|---|---|---|
| 交互模式 | 单次运行 | 多轮对话 |
| 输入 | 一次性输入 | 持续交互 |
| 输出 | 一次性结果 | 多轮回复 |
| 适用场景 | 数据处理、报告生成 | 智能客服、引导式对话 |
节点类型总览
工作流支持以下主要节点类型:
- 开始节点:定义输入变量
- LLM 节点:调用大语言模型
- 知识库检索节点:从知识库中检索信息
- 条件分支节点:根据条件进行路由
- 代码执行节点:运行自定义 Python/JavaScript 代码
- HTTP 请求节点:调用外部 API
- 变量聚合节点:合并多路变量
- 模板转换节点:Jinja2 模板渲染
- 迭代节点:循环处理列表数据
- 参数提取节点:从文本中提取结构化参数
- 结束节点:定义输出结果
适用场景
- 复杂的多步骤业务流程
- 数据处理与转换管道
- 条件化的内容生成
- API 编排与集成
- 自动化报告生成
- 多模型协作流程
3.5 如何选择合适的应用类型
面对四种应用类型,可以参考以下决策流程:
你需要多轮对话吗?
├── 是 → 你需要使用外部工具吗?
│ ├── 是 → 选择 Agent
│ └── 否 → 选择 聊天助手
└── 否 → 你需要复杂的工作流程吗?
├── 是 → 选择 工作流
└── 否 → 选择 文本生成
简单决策规则:
- 只是想和 AI 对话?→ 聊天助手
- 需要 AI 搜索网页、计算数据?→ Agent
- 需要批量生成内容、格式化处理?→ 文本生成
- 需要多步骤、有条件分支的复杂流程?→ 工作流
第四章 知识库管理
4.1 知识库概述
知识库是 Dify 中 RAG(检索增强生成)功能的核心组件。它允许你将私有文档导入 Dify,在用户提问时自动检索相关文档片段,将其作为上下文提供给大模型,从而使 AI 能够基于你的专属知识回答问题。
知识库的工作原理
用户提问 → 文本向量化 → 向量相似度搜索 → 检索相关文档片段
↓
LLM 基于检索结果生成回答
核心流程分为三个阶段:
- 索引阶段(离线):文档导入 → 文本分段 → 向量化 → 存储到向量数据库
- 检索阶段(在线):用户提问 → 问题向量化 → 相似度搜索 → 返回 Top-K 结果
- 生成阶段(在线):将检索结果作为上下文,连同用户问题一起发送给 LLM 生成回答
4.2 创建知识库
步骤一:新建知识库
- 在左侧导航栏中点击"知识库"
- 点击"创建知识库"按钮
- 输入知识库名称(例如:
产品文档) - 输入知识库描述(例如:
包含所有产品的使用手册和 FAQ) - 点击"创建"
步骤二:上传文档
Dify 支持以下文档格式:
| 格式 | 扩展名 | 说明 |
|---|---|---|
| 文本文件 | .txt, .markdown, .md | 纯文本,最易处理 |
| 自动提取文本内容 | ||
| Word | .docx, .doc | 自动提取文本内容 |
| Excel | .xlsx, .xls | 按行/列解析 |
| CSV | .csv | 按行列解析 |
| HTML | .html, .htm | 提取正文内容 |
| JSON | .json | 按结构解析 |
| 代码文件 | .py, .js, .java 等 | 保留代码格式 |
上传步骤:
- 在知识库页面中,点击"添加文档"
- 选择"上传文件"或"从网页导入"
- 拖拽文件到上传区域,或点击选择文件
- 等待文件上传完成(支持批量上传)
文件大小限制:单个文件建议不超过 15MB,单次上传总大小不超过 50MB。如果文件过大,建议先进行拆分。
步骤三:配置分段策略
上传文件后,需要配置文本分段策略。这一步对检索效果至关重要。
4.3 文本分段策略
文本分段是将长文档切分为适合检索的小段落的过程。合理的分段策略能显著提升检索效果。
自动分段(推荐新手使用)
Dify 提供了智能自动分段功能,会根据文档结构自动选择最佳的分段方式:
- 分段标识符:默认使用
\n\n(双换行符)作为段落分隔 - 最大分段长度:默认 500 tokens
- 分段重叠:默认 50 tokens
自定义分段
对于需要更精细控制的场景,可以自定义分段参数:
分段标识符(Chunk Separator)
常用的分段标识符:
\n\n:按段落分隔(最常用)\n:按行分隔。:按句号分隔(中文文档).:按句号分隔(英文文档)##:按二级标题分隔(Markdown 文档)###:按三级标题分隔
可以组合使用,如 \n\n## 表示优先按二级标题分隔,其次按段落分隔。
最大分段长度(Max Tokens)
每个分段包含的最大 Token 数量:
- 过小(<200):语义不完整,影响检索质量
- 适中(300-800):大多数场景的最佳范围
- 过大(>1000):包含过多噪音信息,降低精确度
建议设置: | 文档类型 | 建议分段长度 | 原因 | |---------|------------|------| | FAQ 文档 | 200-400 | 一问一答通常较短 | | 技术文档 | 400-600 | 需要包含足够的技术细节 | | 长篇文章 | 500-800 | 需要足够的上下文 | | 代码文档 | 300-500 | 代码块不宜过长 |
分段重叠(Chunk Overlap)
相邻分段之间的重叠 Token 数。重叠可以避免重要信息被切断在两个分段之间。
- 建议设置为分段长度的 10%-20%
- 例如:分段长度 500 → 重叠 50-100
分段预览与调整
配置完成后,Dify 会展示分段预览。你应该仔细检查:
- 每个分段是否语义完整
- 重要信息是否被切断
- 分段长度是否合理
- 是否有过多的空白或噪音内容
如果发现分段效果不理想,可以返回调整参数后重新分段。
4.4 索引方式
分段完成后,需要选择索引方式将文本转换为向量表示。Dify 提供两种索引模式:
高质量模式(High Quality)
- 原理:使用 Embedding 模型将文本转换为高维向量
- 特点:
- 语义理解能力强,支持同义词匹配
- 检索精度高
- 需要调用 Embedding 模型 API
- 索引时间较长
- 会消耗模型 Token 额度
- 推荐场景:对检索质量要求高的正式应用
配置步骤:
- 选择"高质量"索引模式
- 选择 Embedding 模型(如 text-embedding-3-small、text-embedding-ada-002 等)
- 点击"开始索引"
经济模式(Economical)
- 原理:使用关键词匹配(基于 TF-IDF 或 BM25 算法)
- 特点:
- 不需要调用 Embedding 模型
- 索引速度快
- 不消耗模型 Token
- 不支持语义理解,只支持关键词匹配
- 推荐场景:预算有限、文档量大、对语义理解要求不高的场景
索引方式选择建议
| 场景 | 推荐模式 | 理由 |
|---|---|---|
| 正式产品应用 | 高质量 | 检索效果更好 |
| 快速原型验证 | 经济 | 成本低、速度快 |
| 技术文档查询 | 高质量 | 术语匹配需要语义理解 |
| FAQ 常见问题 | 经济/高质量 | 关键词匹配已足够 |
| 大量文档(1000+) | 经济 | 节省成本 |
4.5 检索测试
索引完成后,务必进行检索测试以验证效果。
测试步骤
- 在知识库页面中,点击"检索测试"
- 在输入框中输入测试问题
- 查看返回的文档片段和相似度分数
评估检索质量
好的检索结果应该满足:
- 相关性:返回的文档片段与问题高度相关
- 完整性:包含回答问题所需的完整信息
- 排序合理:最相关的排在最前面
- 数量适中:通常 Top 3-5 个结果足够
检索测试示例
假设你的知识库包含产品使用手册,测试如下:
测试问题:如何重置密码?
期望结果:返回的文档片段应该包含密码重置的具体步骤
如果结果不理想:
- 如果返回了不相关的内容 → 检查分段是否合理,考虑重新分段
- 如果没有返回相关内容 → 检查文档是否成功索引
- 如果相关内容排名靠后 → 考虑切换到高质量索引模式
4.6 知识库优化技巧
1. 文档预处理
上传前对文档进行预处理,可以显著提升效果:
- 去除噪音:删除页眉页脚、页码、水印等无关内容
- 统一格式:确保文档结构清晰,标题层级明确
- 补充上下文:在段落前添加适当的标题或摘要
2. 分层索引
对于大型文档库,可以建立多层索引结构:
- 父文档:包含完整的章节内容
- 子文档:章节下的细分段落
这种方法被称为"Parent-Child Chunking",检索时先命中子文档,然后返回父文档的完整上下文。
3. 元数据标注
为文档添加元数据标签,可以提高检索的精确度:
文档类型:FAQ
产品名称:产品A
更新日期:2024-01-15
分类:账户管理
在检索时可以使用元数据进行过滤,缩小搜索范围。
4. 混合检索
Dify 支持同时使用向量检索和关键词检索,然后融合结果:
- 向量检索:擅长语义匹配
- 关键词检索:擅长精确匹配
- 混合模式:结合两者优势
5. 定期更新
知识库需要定期维护和更新:
- 及时上传最新的文档版本
- 删除过时的文档
- 重新索引修改过的文档
- 定期进行检索测试,确保效果
4.7 在应用中使用知识库
创建好知识库后,需要将其关联到应用中:
- 打开应用编辑页面
- 在"上下文"区域,点击"添加"
- 选择要关联的知识库
- 配置检索参数:
- Top-K:返回最相关的 K 个分段(建议 3-5)
- Score 阈值:只返回相似度高于此阈值的结果(建议 0.5-0.7)
- 保存配置
在 Prompt 中引用知识库的上下文:
请根据以下参考资料回答用户的问题。如果参考资料中没有相关信息,请如实告知用户。
参考资料:
{{#context#}}
用户问题:
{{#question#}}
{{#context#}} 变量会自动填充检索到的文档片段。
第五章 Prompt 工程在 Dify 中的应用
5.1 Prompt 工程基础
Prompt 工程是与大语言模型交互的核心技术。一个好的 Prompt 能够显著提升 AI 的输出质量。在 Dify 中,Prompt 的设计尤为重要,因为它直接决定了你的应用表现。
Prompt 的基本结构
一个完整的 Prompt 通常包含以下要素:
1. 角色设定(System Role)
└─ 定义 AI 的身份、能力范围和行为准则
2. 任务描述(Task Description)
└─ 明确说明 AI 需要完成的任务
3. 输入格式(Input Format)
└─ 定义用户输入的预期格式
4. 输出格式(Output Format)
└─ 定义 AI 输出的期望格式
5. 约束条件(Constraints)
└─ 设定 AI 行为的限制和边界
6. 示例(Examples)
└─ 提供输入输出的参考示例
Dify 中的 Prompt 编辑器
Dify 提供了一个功能丰富的 Prompt 编辑器:
界面布局:
- 系统提示词区域:编写 System Prompt,定义 AI 的角色和行为
- 变量列表:显示当前定义的所有变量
- 预览面板:实时查看组装后的完整 Prompt
- 测试面板:输入测试内容查看效果
5.2 变量绑定
变量是 Dify Prompt 系统的核心特性,允许你创建动态的、可复用的 Prompt 模板。
变量类型
Dify 支持以下变量类型:
| 变量类型 | 说明 | 使用场景 |
|---|---|---|
| 文本(Text) | 单行文本输入 | 简短的问题、名称等 |
| 段落(Paragraph) | 多行文本输入 | 长文本、文档内容等 |
| 下拉选择(Select) | 预设选项列表 | 选择输出风格、语言等 |
| 数字(Number) | 数字输入 | 设置数量、长度等 |
变量定义与使用
步骤一:定义变量
在应用编辑页面,找到"变量"配置区域:
- 点击"添加变量"
- 设置变量名称(如
user_name) - 选择变量类型(如 Text)
- 设置是否必填
- 填写默认值(可选)
- 添加变量描述/标签
步骤二:在 Prompt 中引用变量
使用双花括号 {{变量名}} 来引用变量:
你好,{{user_name}}!
我将用{{language}}为你解释以下概念:
概念:{{concept}}
请用简洁易懂的语言解释,适合{{level}}水平的学习者理解。
步骤三:测试变量
在预览面板中,你会看到变量被替换为输入框。填写不同的值来测试 Prompt 的效果。
变量的高级用法
1. 条件逻辑
在某些场景下,可以根据变量值调整 Prompt 内容。虽然 Dify 的标准 Prompt 编辑器不直接支持条件语法,但你可以通过巧妙的 Prompt 设计来实现:
请根据用户选择的输出格式生成内容:
- 如果格式为"详细":请提供全面深入的解释,包含多个示例
- 如果格式为"简洁":请用 2-3 句话概括核心要点
- 如果格式为"列表":请使用编号列表的形式组织回答
用户选择的格式:{{output_format}}
2. 变量组合
多个变量可以组合使用来构建复杂的 Prompt:
为{{target_audience}}写一篇关于{{topic}}的{{content_type}}。
要求:
- 字数:{{word_count}}字左右
- 语气:{{tone}}
- 语言:{{language}}
- 包含关键词:{{keywords}}
5.3 上下文引用
上下文引用允许你将知识库检索结果、对话历史等信息注入到 Prompt 中。
知识库上下文
当应用关联了知识库后,可以使用 {{#context#}} 变量引用检索结果:
你是一个专业的技术支持助手。请根据以下技术文档回答用户的问题。
重要规则:
1. 只基于提供的文档内容回答,不要编造信息
2. 如果文档中没有相关信息,明确告知用户
3. 回答时引用相关的文档来源
技术文档:
{{#context#}}
用户问题:{{query}}
对话历史
在聊天助手类型的应用中,对话历史会自动注入。你可以在 System Prompt 中引导 AI 如何利用历史对话:
你是一个智能客服助手。请注意以下事项:
1. 仔细阅读对话历史,了解用户之前的问题和已经提供的信息
2. 如果用户引用了之前的对话内容,请正确理解上下文
3. 如果发现用户的需求发生了变化,主动确认
4. 避免重复提供已经说过的信息
5.4 提示词模板
Dify 提供了内置的提示词模板库,帮助用户快速构建高质量的 Prompt。
使用内置模板
- 在 Prompt 编辑器中,点击"模板"按钮
- 浏览模板分类(对话、内容生成、数据分析等)
- 选择合适的模板
- 根据需要进行修改和调整
创建自定义模板
你也可以将自己编写的优质 Prompt 保存为模板:
- 完成 Prompt 编写和测试
- 点击"保存为模板"
- 填写模板名称、描述、分类
- 模板会保存到你的个人模板库
常用 Prompt 模式
1. CO-STAR 框架
C - Context(背景):提供任务的背景信息
O - Objective(目标):明确 AI 需要达成的目标
S - Style(风格):指定输出的写作风格
T - Tone(语气):设定输出的情感基调
A - Audience(受众):说明目标读者群体
R - Response(格式):定义输出的格式要求
2. 链式思考(Chain of Thought)
引导 AI 逐步推理:
请按照以下步骤分析这个问题:
1. 首先,理解问题的核心需求
2. 然后,列出相关的已知信息
3. 接着,分析可能的解决方案
4. 最后,给出你的结论和建议
请在回答中展示你的思考过程。
3. 少样本学习(Few-Shot Learning)
通过提供示例来引导 AI 的输出:
请根据以下示例的格式生成产品描述:
示例 1:
产品:无线蓝牙耳机
描述:采用最新蓝牙 5.3 技术,支持主动降噪,续航长达 30 小时。
轻量设计仅重 5.2g,长时间佩戴无压力。IPX5 防水等级,
适合运动使用。
示例 2:
产品:便携式充电宝
描述:20000mAh 超大容量,支持 65W 快充,可同时为 3 台设备充电。
机身仅重 350g,轻松放入口袋。LED 电量显示,随时掌握电量。
现在请为以下产品生成描述:
产品:{{product_name}}
5.5 对话开场白设计
好的对话开场白能够提升用户体验,引导用户正确使用应用。
开场白设计原则
- 简洁明了:不要过于冗长,3-5 行即可
- 说明能力:让用户知道 AI 能做什么
- 引导使用:提供使用示例或建议问题
- 友好亲切:使用恰当的问候和表情符号
开场白示例
技术支持助手:
你好!👋 我是技术支持助手。
我可以帮你解决产品使用中的各种问题,包括:
• 🔧 故障排查与解决
• 📖 功能使用指南
• ❓ 常见问题解答
请描述你遇到的问题,我会尽力帮助你!
写作助手:
嗨!我是你的写作助手 ✍️
我能帮你:
• 📝 撰写各类文章和文案
• ✏️ 润色和改写现有文本
• 🌐 多语言翻译
• 💡 提供写作灵感和大纲
告诉我你想写什么,我们开始吧!
建议问题的设置
在开场白下方,可以设置 3-4 个建议问题,帮助用户快速开始:
建议问题:
1. "如何重置账号密码?"
2. "产品支持哪些文件格式?"
3. "怎么联系人工客服?"
4. "最新版本更新了什么功能?"
5.6 Prompt 优化技巧
1. 明确具体
❌ 模糊的 Prompt:帮我写一篇文章
✅ 明确的 Prompt:为 25-35 岁的职场女性写一篇 800 字左右的健康饮食建议文章,使用轻松活泼的语气,包含 3 个实用的食谱建议
2. 设定边界
重要限制:
- 不要编造不存在的数据或引用
- 如果不确定,请明确说明
- 不要提供医疗、法律方面的专业建议
- 涉及敏感话题时保持中立
3. 输出格式化
请使用以下 JSON 格式输出分析结果:
{
"summary": "一句话总结",
"key_points": ["要点1", "要点2", "要点3"],
"sentiment": "正面/负面/中性",
"confidence": 0.85
}
4. 迭代优化
Prompt 的优化是一个持续的过程:
- 编写初始版本
- 使用不同的输入测试
- 分析输出的质量和一致性
- 调整 Prompt 中的指令和约束
- 重复测试和优化
第六章 工作流编排
6.1 工作流基础
工作流是 Dify 中最灵活的应用构建方式。通过可视化编排不同的功能节点,你可以构建出复杂的 AI 应用流程。
创建工作流应用
- 在控制台点击"创建应用"
- 选择"工作流"类型
- 输入应用名称和描述
- 进入工作流编辑器
编辑器界面
工作流编辑器主要包含以下区域:
- 节点面板(左侧):展示所有可用的节点类型,拖拽到画布即可添加
- 画布区域(中间):可视化的工作流编辑区域,支持缩放、拖拽、框选
- 节点配置(右侧):选中节点后,右侧显示该节点的详细配置面板
- 工具栏(顶部):包含保存、运行、调试、撤销/重做等操作按钮
基本操作
添加节点:
- 从左侧节点面板拖拽节点到画布
- 或者点击画布上的
+按钮快速添加
连接节点:
- 从一个节点的输出端口拖拽连线到另一个节点的输入端口
- 连线会自动吸附和弯曲
配置节点:
- 点击选中节点
- 在右侧配置面板中设置参数
删除节点:
- 选中节点后按 Delete 键
- 或右键选择删除
6.2 节点类型详解
6.2.1 开始节点
开始节点是工作流的入口,每个工作流有且只有一个开始节点。
配置内容:
- 输入变量:定义工作流接收的输入参数
- 每个变量需要设置名称、类型(文本/段落/数字/文件)、是否必填
示例配置:
变量1:query(文本,必填)- 用户的查询问题
变量2:language(下拉选择,默认"中文")- 输出语言
变量3:file(文件,选填)- 上传的附件
6.2.2 LLM 节点
LLM 节点是工作流中最核心的节点,用于调用大语言模型。
配置项:
- 模型选择:选择要使用的 LLM 模型
- System Prompt:系统提示词
- User Prompt:用户消息(支持变量引用)
- Temperature:控制输出的随机性(0-1)
- Max Tokens:最大输出长度
- 输出变量:定义该节点的输出变量名
System Prompt 示例:
你是一个专业的文档分析师。请根据提供的文档内容,提取关键信息并生成结构化的摘要。
输出格式要求:
1. 主题概括(一句话)
2. 关键要点(3-5 个要点)
3. 重要数据/指标(如有)
User Prompt 示例:
请分析以下文档内容:
{{start_node.file_content}}
用户的关注点:{{start_node.query}}
6.2.3 知识库检索节点
知识库检索节点用于从指定知识库中检索相关文档。
配置项:
- 知识库选择:选择要检索的知识库(可选择多个)
- 检索变量:指定用哪个变量作为查询文本
- Top-K:返回最相关的 K 个结果
- Score 阈值:相似度阈值过滤
- 检索模式:向量检索 / 全文检索 / 混合检索
输出变量:
result:检索到的文档片段列表result[0].content:第一个结果的内容result[0].title:第一个结果的标题result[0].score:第一个结果的相似度分数
6.2.4 条件分支节点(IF/ELSE)
条件分支节点根据条件判断来决定工作流的执行路径。
配置项:
- 条件表达式:定义判断条件
- 分支路径:满足条件和不满足条件的两条路径
支持的条件操作:
- 等于 / 不等于
- 大于 / 小于
- 包含 / 不包含
- 为空 / 不为空
- 开头是 / 结尾是
- 正则匹配
示例:
条件:{{llm_node.category}} == "技术问题"
├── 是 → 连接到"技术支持"LLM 节点
└── 否 → 连接到"通用客服"LLM 节点
6.2.5 代码执行节点
代码执行节点允许你在工作流中运行自定义代码,支持 Python 和 JavaScript。
使用场景:
- 数据格式转换
- 复杂的逻辑计算
- 字符串处理
- JSON 解析与生成
- 外部库调用
Python 示例 - JSON 解析:
import json
def main(text: str) -> dict:
try:
data = json.loads(text)
return {
"result": data.get("key", "未找到"),
"success": True
}
except json.JSONDecodeError:
return {
"result": "JSON 解析失败",
"success": False
}
Python 示例 - 文本处理:
def main(text: str, max_length: int) -> dict:
# 去除多余空白
cleaned = " ".join(text.split())
# 截断到指定长度
if len(cleaned) > max_length:
cleaned = cleaned[:max_length] + "..."
# 统计字数
word_count = len(cleaned)
return {
"cleaned_text": cleaned,
"word_count": word_count,
"is_truncated": len(text) > max_length
}
6.2.6 HTTP 请求节点
HTTP 请求节点用于调用外部 API,实现与第三方服务的集成。
配置项:
- 请求方法:GET / POST / PUT / DELETE / PATCH
- URL:请求地址(支持变量)
- Headers:请求头
- Body:请求体(POST/PUT 时使用)
- 超时时间:请求超时设置
- 输出变量:响应状态码、响应体等
POST 请求示例:
方法:POST
URL:https://api.example.com/analyze
Headers:
Content-Type: application/json
Authorization: Bearer {{api_key}}
Body:
{
"text": "{{llm_node.output}}",
"language": "zh"
}
使用场景:
- 发送通知(邮件、Slack、企业微信)
- 调用第三方 AI 服务
- 数据存储到外部数据库
- 触发 Webhook
6.2.7 变量聚合节点
当工作流有多条分支路径时,变量聚合节点用于将不同分支的输出合并为统一的变量。
使用场景:
条件分支
├── 分支 A → 输出 result_a
├── 分支 B → 输出 result_b
└── 分支 C → 输出 result_c
↓
变量聚合节点
将 result_a / result_b / result_c 统一为 result
↓
后续节点使用 {{aggregate.result}}
6.2.8 模板转换节点
模板转换节点使用 Jinja2 模板语法来格式化和组合变量。
示例模板:
## 分析报告
**查询问题**:{{query}}
**分析结果**:
{{analysis_result}}
**参考来源**:
{% for source in sources %}
{{loop.index}}. {{source.title}} (相关度: {{source.score}})
{% endfor %}
---
生成时间:{{current_time}}
6.2.9 迭代节点
迭代节点用于对列表数据进行循环处理。
配置:
- 输入列表:指定要迭代的变量(必须是数组类型)
- 迭代体:内部包含的子工作流
- 输出:每次迭代的结果组成的数组
使用场景:
- 批量处理多篇文档
- 对多个搜索结果逐一分析
- 批量调用 API
- 逐条处理数据库记录
6.2.10 参数提取节点
参数提取节点使用 LLM 从非结构化文本中提取结构化参数。
配置:
- 输入文本:要提取参数的文本
- 参数定义:定义要提取的参数列表(名称、类型、描述、是否必填)
- 模型:用于提取的 LLM 模型
示例:
输入文本:"我想订一张明天从北京到上海的机票,经济舱,下午的航班"
参数定义:
- 出发城市(文本):出发地城市名称
- 到达城市(文本):目的地城市名称
- 出发日期(文本):出发日期
- 舱位等级(选择):经济舱/商务舱/头等舱
- 时间偏好(选择):上午/下午/晚上
提取结果:
{
"出发城市": "北京",
"到达城市": "上海",
"出发日期": "明天",
"舱位等级": "经济舱",
"时间偏好": "下午"
}
6.2.11 结束节点
结束节点定义工作流的最终输出。
配置:
- 输出变量:选择要作为最终输出的变量
- 可以输出多个变量
6.3 变量传递
变量在工作流节点间的传递是工作流的核心机制。
引用其他节点的变量
使用 {{节点名.变量名}} 的格式引用其他节点的输出:
{{start.query}} → 开始节点的 query 变量
{{llm_1.text}} → LLM 节点 llm_1 的输出
{{kb_search.result}} → 知识库检索节点的结果
{{code_1.output}} → 代码节点的输出
{{http_1.body}} → HTTP 请求的响应体
变量类型转换
不同节点输出的变量类型可能不同,需要注意类型匹配:
- LLM 节点输出:字符串类型
- 代码节点输出:可以是任意类型(取决于代码的返回值)
- HTTP 节点输出:字符串(JSON)类型
- 条件分支输出:根据分支不同可能不同
6.4 错误处理
在工作流执行过程中,可能会遇到各种错误。Dify 提供了完善的错误处理机制。
常见错误类型
- LLM 调用失败:API 限流、模型不可用、Token 超限
- 知识库检索失败:向量数据库连接问题
- HTTP 请求失败:网络超时、接口返回错误
- 代码执行错误:代码异常、类型错误
- 变量缺失:引用了不存在的变量
错误处理策略
1. 节点级重试
对于 LLM 和 HTTP 节点,可以配置自动重试策略:
- 最大重试次数:建议设置为 2-3 次
- 重试间隔:建议使用指数退避(如 1s, 2s, 4s)
2. 异常分支
在可能失败的节点后添加条件分支,处理异常情况:
HTTP 请求节点
├── 成功 → 继续正常流程
└── 失败 → 连接到"错误处理"LLM 节点
└── 生成友好的错误提示返回给用户
3. 默认值设置
为可能为空的变量设置默认值:
{{http_node.response | default("服务暂时不可用,请稍后再试")}}
6.5 工作流最佳实践
1. 模块化设计
将复杂的工作流拆分为多个子模块:
- 主工作流:负责整体流程控制
- 子工作流:处理特定的功能模块
2. 清晰的命名
为每个节点使用有意义的名称:
❌ 好的命名:LLM 节点 1、LLM 节点 2
✅ 好的命名:分析用户意图、生成回答、内容审核
3. 充分的测试
在发布前,使用多种输入测试工作流:
- 正常输入
- 边界情况
- 异常输入(空值、超长文本等)
- 特殊字符
4. 日志记录
在关键节点添加日志输出,方便调试和监控。
5. 性能优化
- 减少不必要的 LLM 调用
- 合理使用并行分支
- 设置合理的超时时间
- 控制变量传递的数据量
第七章 Agent 模式开发
7.1 Agent 概述
Agent 是 Dify 中最智能化的应用类型。与普通的聊天助手不同,Agent 具备自主推理、工具调用和多步执行的能力,能够处理更加复杂的任务。
Agent 与普通聊天助手的区别
| 特性 | 聊天助手 | Agent |
|---|---|---|
| 推理能力 | 被动回答 | 主动推理和规划 |
| 工具使用 | 无 | 支持多种工具调用 |
| 任务复杂度 | 单步回答 | 多步骤执行 |
| 外部交互 | 无 | 可以访问外部数据和服务 |
| 执行模式 | 即时响应 | 思考-行动-观察循环 |
7.2 创建 Agent 应用
步骤一:创建应用
- 点击"创建应用"
- 选择"Agent"类型
- 填写应用名称和描述
- 进入 Agent 配置界面
步骤二:编写系统提示词
Agent 的系统提示词需要明确定义其角色、能力和行为准则:
你是一个专业的研究助手 Agent。你的任务是帮助用户进行信息收集、分析和总结。
## 你的能力
- 搜索互联网获取最新信息
- 阅读和分析网页内容
- 进行数学和逻辑计算
- 执行代码进行数据处理
## 工作原则
1. 对于需要最新信息的问题,主动搜索互联网
2. 对于需要计算的问题,使用计算工具而非心算
3. 综合多个来源的信息,给出全面的回答
4. 始终引用信息来源
5. 如果无法找到可靠信息,如实告知用户
## 输出格式
- 先简要说明你的分析思路
- 然后给出详细的回答
- 最后列出参考来源
步骤三:选择推理策略
在 Agent 配置中,选择合适的推理策略:
ReAct 策略:
- 适合大多数场景
- 思维链清晰可见
- 执行过程透明
Function Calling 策略:
- 速度更快
- 调用更精准
- 需要模型支持(如 GPT-4、Claude 3 等)
7.3 工具配置
7.3.1 使用内置工具
Dify 提供了丰富的内置工具,可以直接在 Agent 中使用:
网页抓取工具:
- 功能:读取指定 URL 的网页内容
- 适用场景:获取网页信息、阅读文章
- 使用示例:用户问"帮我看看这个网页的内容",Agent 会调用网页抓取工具
维基百科搜索:
- 功能:搜索维基百科获取信息
- 适用场景:查询百科知识
- 使用示例:用户问"什么是量子计算",Agent 会搜索维基百科
数学计算器:
- 功能:执行数学表达式计算
- 适用场景:数学计算、数据分析
- 使用示例:用户问"计算 15% 的年化收益",Agent 会使用计算器
代码执行器:
- 功能:运行 Python 代码
- 适用场景:数据处理、图表生成、复杂计算
- 使用示例:用户问"帮我生成一个柱状图",Agent 会编写并执行 Python 代码
7.3.2 添加内置工具
在 Agent 配置界面:
- 找到"工具"配置区域
- 点击"添加工具"
- 从工具列表中选择需要的工具
- 按照提示完成配置(如 API Key 等)
- 保存配置
7.3.3 创建自定义工具
当内置工具无法满足需求时,你可以创建自定义工具:
方式一:通过 API Schema 创建
- 在"工具"页面,点击"创建自定义工具"
- 输入工具名称和描述
- 导入 API Schema(支持 OpenAPI/Swagger 格式)
- 配置认证方式(如 API Key、Bearer Token 等)
- 测试工具调用
OpenAPI Schema 示例:
{
"openapi": "3.0.0",
"info": {
"title": "天气查询 API",
"version": "1.0.0"
},
"paths": {
"/weather": {
"get": {
"summary": "查询天气信息",
"description": "根据城市名称查询当前天气",
"parameters": [
{
"name": "city",
"in": "query",
"required": true,
"schema": {
"type": "string"
},
"description": "城市名称"
}
],
"responses": {
"200": {
"description": "天气信息",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"temperature": {"type": "number"},
"condition": {"type": "string"},
"humidity": {"type": "number"}
}
}
}
}
}
}
}
}
}
}
方式二:通过可视化界面创建
- 点击"创建自定义工具"
- 选择"可视化创建"
- 配置请求方法、URL、参数、认证等
- 测试并保存
7.4 推理策略详解
7.4.1 ReAct 策略
ReAct(Reasoning + Acting)策略的核心思想是让 AI 在"思考"和"行动"之间交替进行。
执行流程:
用户输入
↓
[思考] 分析问题,确定需要哪些信息/工具
↓
[行动] 调用工具获取信息
↓
[观察] 分析工具返回的结果
↓
[判断] 信息是否足够?
├── 否 → 返回 [思考] 继续
└── 是 → 生成最终回答
ReAct 的优势:
- 思维链清晰可见,用户可以看到 AI 的推理过程
- 每一步都有明确的思考和行动
- 容易调试和优化
ReAct 的限制:
- 执行速度相对较慢
- 每次只调用一个工具
- 可能需要多轮循环才能完成任务
7.4.2 Function Calling 策略
Function Calling 是模型提供商(如 OpenAI、Anthropic)提供的原生工具调用机制。
执行流程:
用户输入 + 工具列表
↓
模型分析并输出函数调用请求(JSON 格式)
↓
平台执行函数
↓
返回结果给模型
↓
模型生成最终回答(可能再次调用函数)
Function Calling 的优势:
- 调用更精准,减少误调用
- 支持并行调用多个工具
- 响应速度更快
- 与模型深度集成
Function Calling 的限制:
- 需要模型本身支持此功能
- 不同模型的实现可能有差异
- 调试相对困难
7.4.3 如何选择推理策略
| 场景 | 推荐策略 | 原因 |
|---|---|---|
| 需要透明的推理过程 | ReAct | 思维链清晰 |
| 追求响应速度 | Function Calling | 更快 |
| 需要调用多个工具 | Function Calling | 支持并行 |
| 使用较旧的模型 | ReAct | 兼容性更好 |
| 复杂的多步骤任务 | ReAct | 流程更可控 |
| 简单的工具调用 | Function Calling | 更高效 |
7.5 多工具协作
在实际应用中,Agent 往往需要协调使用多个工具来完成复杂任务。
示例:智能研究助手
假设用户问:"帮我研究一下 2024 年中国新能源汽车市场的发展趋势"
Agent 的执行过程可能是:
步骤 1 - 思考:
用户需要关于中国新能源汽车市场的最新信息。
我需要搜索互联网获取最新数据。
步骤 1 - 行动:
调用搜索引擎,查询"2024年中国新能源汽车市场发展趋势"
步骤 2 - 观察:
搜索返回了多条相关结果,包含市场数据和分析报告
步骤 2 - 思考:
我需要获取更详细的数据。让我抓取排名第一的网页内容。
步骤 2 - 行动:
调用网页抓取工具,读取详细报告页面
步骤 3 - 观察:
获取到了详细的市场数据,包括销量、增长率、主要厂商等
步骤 3 - 思考:
用户可能还需要一些数据计算。让我计算增长率等指标。
步骤 3 - 行动:
调用计算器工具,计算相关数据指标
步骤 4 - 思考:
我已经收集了足够的信息,可以给用户一个全面的回答了。
最终回答:
综合多个来源的信息,2024年中国新能源汽车市场呈现以下趋势...
7.6 Agent 调试与优化
7.6.1 调试技巧
1. 查看执行日志
Agent 的每次执行都会记录详细的日志:
- 思考过程
- 工具调用的输入输出
- 执行时间
- Token 消耗
2. 测试不同的输入
使用各种类型的输入测试 Agent:
- 简单问题(不需要工具)
- 中等问题(需要一个工具)
- 复杂问题(需要多个工具协作)
- 边界情况(工具无法获取信息)
3. 分析失败案例
当 Agent 执行失败或结果不理想时:
- 检查推理链是否合理
- 确认工具调用是否正确
- 分析返回结果是否被正确利用
7.6.2 优化策略
1. 优化系统提示词
- 明确 Agent 的能力边界
- 提供清晰的工具使用指引
- 设定回答质量标准
2. 工具描述优化
为每个工具提供详细准确的描述,帮助模型正确选择工具:
❌ 模糊的描述:搜索信息
✅ 清晰的描述:使用 Google 搜索引擎搜索互联网上的最新信息。适用于需要获取最新新闻、实时数据、产品信息等场景。输入应该是简洁的搜索关键词。
3. 限制执行步骤
设置最大执行步骤数,避免 Agent 陷入无限循环:
- 建议设置 5-10 步
- 对于特别复杂的任务,可以适当增加
4. 优化模型选择
选择对工具调用支持更好的模型:
- GPT-4o / GPT-4:Function Calling 支持最好
- Claude 3.5 Sonnet:推理能力强
- 本地模型:可能需要使用 ReAct 策略
第八章 API 集成开发
8.1 API 概述
Dify 的一个重要特性是为每个应用自动生成标准的 RESTful API。这意味着你可以将 Dify 构建的 AI 能力无缝集成到任何现有的应用系统中。
API 的核心特性
- 标准 RESTful 风格:遵循 REST 架构规范
- 认证机制:基于 API Key 的 Bearer Token 认证
- 流式输出:支持 Server-Sent Events (SSE) 实现流式响应
- 会话管理:支持多轮对话的会话 ID 管理
- 文件上传:支持在对话中上传文件
8.2 API 密钥管理
获取 API 密钥
- 打开你的应用
- 点击左侧菜单中的"访问 API"
- 在 API 密钥管理页面,点击"创建新密钥"
- 为密钥添加描述(如"生产环境-前端应用")
- 复制并安全保存生成的 API 密钥
安全提示:API 密钥只在创建时显示一次,请务必妥善保存。如果遗失,需要重新创建新的密钥。
API 密钥安全最佳实践
- 不要在前端代码中硬编码密钥:应通过后端服务代理 API 调用
- 定期轮换密钥:建议每 3-6 个月更换一次
- 不同环境使用不同密钥:开发、测试、生产环境分别使用独立密钥
- 监控密钥使用情况:定期检查 API 调用日志
API 基础信息
Dify API 的基础 URL 格式:
- 云端版:
https://api.dify.ai/v1 - 本地部署:
http://your-server-ip/v1
8.3 HTTP 调用示例
8.3.1 对话型 API(Chat API)
发送消息:
curl -X POST 'http://your-server/v1/chat-messages' \
-H 'Authorization: Bearer {api_key}' \
-H 'Content-Type: application/json' \
-d '{
"inputs": {},
"query": "你好,请介绍一下你自己",
"response_mode": "blocking",
"user": "user-123"
}'
请求参数说明:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| inputs | object | 是 | 输入变量(键值对) |
| query | string | 是 | 用户的输入内容 |
| response_mode | string | 是 | "blocking"(阻塞)或"streaming"(流式) |
| conversation_id | string | 否 | 会话 ID(多轮对话时使用) |
| user | string | 是 | 用户唯一标识 |
| files | array | 否 | 上传的文件列表 |
阻塞模式响应示例:
{
"event": "message",
"message_id": "msg-abc123",
"conversation_id": "conv-xyz789",
"answer": "你好!我是一个AI助手,很高兴为你服务...",
"created_at": 1700000000,
"metadata": {
"usage": {
"prompt_tokens": 150,
"completion_tokens": 200,
"total_tokens": 350
}
}
}
8.3.2 流式输出(SSE)
流式输出可以让用户在 AI 生成回答的过程中实时看到内容,提升用户体验。
请求示例:
curl -X POST 'http://your-server/v1/chat-messages' \
-H 'Authorization: Bearer {api_key}' \
-H 'Content-Type: application/json' \
-d '{
"inputs": {},
"query": "请详细解释量子计算的原理",
"response_mode": "streaming",
"user": "user-123"
}'
流式响应示例:
data: {"event": "message", "answer": "量子", "message_id": "msg-abc123"}
data: {"event": "message", "answer": "计算", "message_id": "msg-abc123"}
data: {"event": "message", "answer": "是一种", "message_id": "msg-abc123"}
data: {"event": "message", "answer": "利用量子力学原理", "message_id": "msg-abc123"}
...
data: {"event": "message_end", "message_id": "msg-abc123", "metadata": {"usage": {"prompt_tokens": 150, "completion_tokens": 500, "total_tokens": 650}}}
8.3.3 补全型 API(Completion API)
对于文本生成类型的应用,使用补全型 API:
curl -X POST 'http://your-server/v1/completion-messages' \
-H 'Authorization: Bearer {api_key}' \
-H 'Content-Type: application/json' \
-d '{
"inputs": {
"query": "人工智能",
"language": "中文",
"style": "学术"
},
"response_mode": "blocking",
"user": "user-123"
}'
8.3.4 文件上传
上传文件并在对话中使用:
curl -X POST 'http://your-server/v1/files/upload' \
-H 'Authorization: Bearer {api_key}' \
-F 'file=@/path/to/document.pdf' \
-F 'user=user-123'
上传成功后,在发送消息时引用文件:
curl -X POST 'http://your-server/v1/chat-messages' \
-H 'Authorization: Bearer {api_key}' \
-H 'Content-Type: application/json' \
-d '{
"inputs": {},
"query": "请总结这个文档的主要内容",
"response_mode": "blocking",
"user": "user-123",
"files": [
{
"type": "document",
"transfer_method": "local_file",
"upload_file_id": "file-id-from-upload-response"
}
]
}'
8.4 Python SDK 使用
Dify 官方提供了 Python SDK,简化了 API 的调用过程。
安装 SDK
pip install dify-client
基本使用
from dify_client import DifyClient
# 初始化客户端
client = DifyClient(api_key="your-api-key")
# 发送消息(阻塞模式)
response = client.create_chat_message(
inputs={},
query="你好,请介绍一下机器学习的基本概念",
user="user-123",
response_mode="blocking"
)
# 获取回答
result = response.json()
print(result["answer"])
print(f"Token 使用量: {result['metadata']['usage']['total_tokens']}")
流式输出处理
from dify_client import DifyClient
client = DifyClient(api_key="your-api-key")
# 发送消息(流式模式)
response = client.create_chat_message(
inputs={},
query="请详细解释深度学习的原理",
user="user-123",
response_mode="streaming"
)
# 处理流式响应
for line in response.iter_lines():
if line:
line = line.decode("utf-8")
if line.startswith("data: "):
data = line[6:]
import json
event = json.loads(data)
if event.get("event") == "message":
print(event["answer"], end="", flush=True)
elif event.get("event") == "message_end":
print("\n--- 回答结束 ---")
多轮对话
from dify_client import DifyClient
client = DifyClient(api_key="your-api-key")
conversation_id = None # 首次对话不设置
def chat(query):
global conversation_id
response = client.create_chat_message(
inputs={},
query=query,
user="user-123",
conversation_id=conversation_id,
response_mode="blocking"
)
result = response.json()
conversation_id = result["conversation_id"] # 保存会话 ID
return result["answer"]
# 多轮对话
print(chat("你好,我想学习Python"))
print(chat("我应该从哪里开始?"))
print(chat("推荐一些学习资源"))
错误处理
from dify_client import DifyClient
import requests
client = DifyClient(api_key="your-api-key")
try:
response = client.create_chat_message(
inputs={},
query="测试消息",
user="user-123",
response_mode="blocking"
)
if response.status_code == 200:
result = response.json()
print(result["answer"])
elif response.status_code == 401:
print("错误:API 密钥无效")
elif response.status_code == 429:
print("错误:请求过于频繁,请稍后重试")
else:
print(f"错误:{response.status_code} - {response.text}")
except requests.exceptions.ConnectionError:
print("错误:无法连接到 Dify 服务器")
except requests.exceptions.Timeout:
print("错误:请求超时")
except Exception as e:
print(f"未知错误:{str(e)}")
8.5 JavaScript SDK 使用
安装
npm install dify-client
# 或
yarn add dify-client
基本使用
import { DifyClient } from 'dify-client';
// 初始化客户端
const client = new DifyClient('your-api-key');
// 发送消息
async function chat(query) {
try {
const response = await client.createChatMessage({
inputs: {},
query: query,
user: 'user-123',
response_mode: 'blocking'
});
const result = response.data;
console.log(result.answer);
return result;
} catch (error) {
console.error('请求失败:', error.message);
}
}
chat('你好,请介绍一下自然语言处理');
流式输出处理
import { DifyClient } from 'dify-client';
const client = new DifyClient('your-api-key');
async function chatStream(query) {
try {
const response = await client.createChatMessage({
inputs: {},
query: query,
user: 'user-123',
response_mode: 'streaming'
});
const reader = response.data.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value);
const lines = text.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = JSON.parse(line.slice(6));
if (data.event === 'message') {
process.stdout.write(data.answer);
} else if (data.event === 'message_end') {
console.log('\n--- 回答结束 ---');
}
}
}
}
} catch (error) {
console.error('流式请求失败:', error.message);
}
}
chatStream('请详细解释机器学习的工作原理');
在前端应用中集成
<!DOCTYPE html>
<html>
<head>
<title>Dify 聊天应用</title>
<style>
#chat-container {
max-width: 600px;
margin: 20px auto;
font-family: Arial, sans-serif;
}
#messages {
height: 400px;
overflow-y: auto;
border: 1px solid #ddd;
padding: 10px;
margin-bottom: 10px;
}
.message {
margin: 5px 0;
padding: 8px 12px;
border-radius: 8px;
}
.user { background: #007bff; color: white; text-align: right; }
.ai { background: #f1f1f1; }
#input-area { display: flex; gap: 10px; }
#input { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px; }
button { padding: 10px 20px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; }
</style>
</head>
<body>
<div id="chat-container">
<h2>Dify AI 聊天</h2>
<div id="messages"></div>
<div id="input-area">
<input type="text" id="input" placeholder="输入消息..." onkeypress="if(event.key==='Enter')sendMessage()">
<button onclick="sendMessage()">发送</button>
</div>
</div>
<script>
const API_KEY = 'your-api-key';
const API_URL = 'http://your-server/v1/chat-messages';
let conversationId = null;
async function sendMessage() {
const input = document.getElementById('input');
const query = input.value.trim();
if (!query) return;
// 显示用户消息
addMessage(query, 'user');
input.value = '';
// 创建 AI 消息占位
const aiMsg = addMessage('', 'ai');
try {
const body = {
inputs: {},
query: query,
user: 'web-user',
response_mode: 'streaming'
};
if (conversationId) body.conversation_id = conversationId;
const response = await fetch(API_URL, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value);
const lines = text.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
try {
const data = JSON.parse(line.slice(6));
if (data.event === 'message') {
aiMsg.textContent += data.answer;
}
if (data.conversation_id) {
conversationId = data.conversation_id;
}
} catch (e) {}
}
}
}
} catch (error) {
aiMsg.textContent = '请求失败: ' + error.message;
}
}
function addMessage(text, type) {
const messages = document.getElementById('messages');
const div = document.createElement('div');
div.className = `message ${type}`;
div.textContent = text;
messages.appendChild(div);
messages.scrollTop = messages.scrollHeight;
return div;
}
</script>
</body>
</html>
8.6 API 高级功能
8.6.1 会话管理
获取会话列表:
GET /v1/conversations?user=user-123&limit=20&sort_by=-updated_at
获取会话消息历史:
GET /v1/messages?user=user-123&conversation_id=conv-xyz789
删除会话:
DELETE /v1/conversations/{conversation_id}?user=user-123
8.6.2 消息反馈
用户可以对 AI 的回答进行评价:
POST /v1/messages/{message_id}/feedbacks
{
"rating": "like", // "like" 或 "dislike"
"user": "user-123",
"content": "回答非常准确"
}
8.6.3 获取应用参数
获取应用的输入参数配置和工具信息:
GET /v1/parameters?user=user-123
响应示例:
{
"opening_statement": "你好!我是AI助手...",
"suggested_questions": ["问题1", "问题2", "问题3"],
"suggested_questions_after_answer": {
"enabled": true
},
"speech_to_text": {
"enabled": false
},
"retriever_resource": {
"enabled": true
},
"annotation_reply": {
"enabled": false
},
"user_input_form": [
{
"text-input": {
"variable": "query",
"label": "查询内容",
"required": true,
"default": ""
}
}
]
}
第九章 高级功能
9.1 多模型切换
Dify 支持在一个应用中灵活切换不同的模型,这使得你可以根据需求选择最合适的模型。
模型配置
- 进入"设置" → "模型供应商"
- 添加不同的模型提供商和 API Key
- 在应用编辑中,点击模型选择器切换模型
模型选择策略
| 场景 | 推荐模型 | 原因 |
|---|---|---|
| 复杂推理任务 | GPT-4o / Claude 3.5 Sonnet | 推理能力强 |
| 简单问答 | GPT-3.5-Turbo / DeepSeek V3 | 速度快、成本低 |
| 长文本处理 | Claude 3 Opus / Kimi | 上下文窗口大 |
| 代码生成 | GPT-4o / DeepSeek Coder | 代码能力突出 |
| 中文对话 | 通义千问 / 文心一言 | 中文优化 |
模型参数调优
Temperature(温度):
- 范围:0-1
- 低温度(0-0.3):输出更确定、更保守,适合事实性问答
- 中温度(0.4-0.7):平衡创意和准确性,适合大多数场景
- 高温度(0.8-1):输出更随机、更有创意,适合创作类任务
Top-P(核采样):
- 范围:0-1
- 与 Temperature 配合使用
- 建议只调整其中一个参数
Max Tokens(最大 Token 数):
- 控制 AI 的最大输出长度
- 根据预期回答长度设置
- 过小可能截断回答,过大浪费资源
Frequency Penalty(频率惩罚):
- 范围:-2 到 2
- 正值减少重复内容
- 适合需要多样性的场景
Presence Penalty(存在惩罚):
- 范围:-2 到 2
- 正值鼓励谈论新话题
- 适合对话和创意写作
9.2 内容审核
Dify 支持内容审核功能,确保 AI 的输出安全合规。
配置内容审核
- 在应用编辑页面,找到"功能"设置
- 开启"内容审核"功能
- 选择审核方式:
- 内置审核:使用 Dify 内置的敏感词库
- 自定义审核 API:接入第三方内容审核服务
自定义审核 API
你可以接入自己的内容审核服务:
{
"type": "moderation",
"config": {
"provider": "api",
"api_url": "https://your-moderation-api.com/check",
"api_key": "your-key"
}
}
审核 API 需要返回以下格式的响应:
{
"flagged": true,
"categories": {
"hate": false,
"violence": true,
"sexual": false
}
}
9.3 对话记忆管理
对话记忆是聊天类应用的核心功能。Dify 提供了灵活的记忆管理机制。
记忆窗口大小
- 定义 AI 能"记住"多少轮对话
- 设置方法:在应用配置中找到"对话轮数"参数
- 建议值:10-30 轮
记忆压缩
对于长对话,Dify 支持记忆压缩功能:
- 自动摘要:将较早的对话内容自动压缩为摘要
- 保留关键信息:确保重要的上下文不丢失
- 节省 Token:减少每次请求的 Token 消耗
记忆清理
用户可以通过以下方式清理对话记忆:
- 开始新的对话(创建新的 conversation_id)
- 通过 API 删除特定会话
9.4 标注与反馈
Dify 的标注功能允许你对 AI 的回答进行人工审核和优化。
开启标注功能
- 在应用编辑页面,找到"标注"功能
- 开启标注回复功能
- 配置标注参数
标注流程
- 用户与 AI 对话
- 在对话记录中,对不满意的回答进行标注
- 添加期望的正确回答
- 当相似问题再次出现时,AI 会优先使用标注的回答
反馈收集
- 用户反馈:用户可以对 AI 回答点赞/踩
- 反馈分析:在应用分析页面查看反馈统计
- 持续优化:根据反馈数据优化 Prompt 和知识库
9.5 分析与监控
Dify 提供了丰富的数据分析功能,帮助你了解应用的使用情况。
核心指标
- 总对话数:应用的累计对话次数
- 活跃用户数:使用应用的独立用户数量
- 平均对话轮数:每个会话的平均消息数
- Token 消耗:模型调用的 Token 使用量
- 用户满意度:基于用户反馈的评分
日志查看
在应用的"日志"页面,可以查看:
- 每条对话的详细记录
- 模型的输入输出
- Token 使用量
- 响应时间
- 用户反馈
导出数据
支持导出对话日志和分析数据:
- CSV 格式导出
- JSON 格式导出
- 自定义时间范围
第十章 部署与运维
10.1 Docker 生产环境部署
生产环境的部署需要考虑安全性、可靠性和性能。
10.1.1 生产环境配置
服务器推荐配置:
| 组件 | 推荐配置 |
|---|---|
| 应用服务器 | 4 核 CPU, 8GB RAM, 100GB SSD |
| 数据库服务器 | 4 核 CPU, 16GB RAM, 200GB SSD |
| 向量数据库 | 4 核 CPU, 16GB RAM, 200GB SSD |
对于小型团队或低并发场景,所有组件可以部署在同一台服务器上。
生产环境 .env 配置:
# ==================== 安全配置 ====================
# 应用密钥(必须修改)
SECRET_KEY=<使用 openssl rand -base64 42 生成>
# ==================== 数据库配置 ====================
# PostgreSQL
POSTGRES_USER=dify
POSTGRES_PASSWORD=<强密码>
POSTGRES_DB=dify
# Redis
REDIS_PASSWORD=<强密码>
# ==================== 网络配置 ====================
EXPOSE_NGINX_PORT=443
EXPOSE_NGINX_SSL_PORT=443
# ==================== 存储配置 ====================
STORAGE_TYPE=s3 # 生产环境推荐使用 S3 兼容存储
S3_ENDPOINT=https://your-s3-endpoint
S3_BUCKET_NAME=dify-storage
S3_ACCESS_KEY=your-access-key
S3_SECRET_KEY=your-secret-key
# ==================== 日志配置 ====================
LOG_LEVEL=WARNING
LOG_FILE=/var/log/dify/app.log
# ==================== 性能配置 ====================
# Worker 数量
API_WORKER_AMOUNT=4
CELERY_WORKER_AMOUNT=2
# 数据库连接池
DB_POOL_SIZE=20
DB_MAX_OVERFLOW=10
10.1.2 HTTPS 配置
生产环境必须使用 HTTPS:
方案一:使用 Nginx 反向代理 + Let's Encrypt
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
location / {
proxy_pass http://localhost:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# WebSocket 支持
location /v1/chat-messages {
proxy_pass http://localhost:80;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
方案二:使用云服务商的负载均衡器
大多数云服务商(如阿里云、腾讯云、AWS)都提供支持 HTTPS 的负载均衡器,可以直接在负载均衡器上配置 SSL 证书。
10.1.3 数据库优化
PostgreSQL 优化:
-- 连接数配置
ALTER SYSTEM SET max_connections = 200;
-- 内存配置
ALTER SYSTEM SET shared_buffers = '4GB';
ALTER SYSTEM SET effective_cache_size = '12GB';
ALTER SYSTEM SET work_mem = '256MB';
-- WAL 配置
ALTER SYSTEM SET wal_buffers = '64MB';
ALTER SYSTEM SET checkpoint_completion_target = 0.9;
-- 重启 PostgreSQL 使配置生效
SELECT pg_reload_conf();
Redis 优化:
# redis.conf 配置优化
maxmemory 2gb
maxmemory-policy allkeys-lru
save 900 1
save 300 10
save 60 10000
10.2 环境变量完整配置
以下是 Dify 的主要环境变量及其说明:
核心配置
# 应用密钥
SECRET_KEY=your-secret-key
# 控制台管理员邮箱(首次初始化时使用)
INIT_PASSWORD=your-admin-password
# 应用 Web 前端 URL
CONSOLE_WEB_URL=https://dify.your-domain.com
APP_WEB_URL=https://app.your-domain.com
# API 服务 URL
API_URL=https://api.your-domain.com
模型配置
# OpenAI
OPENAI_API_KEY=your-openai-key
OPENAI_API_BASE=https://api.openai.com/v1
# Anthropic
ANTHROPIC_API_KEY=your-anthropic-key
# 通义千问
DASHSCOPE_API_KEY=your-dashscope-key
存储配置
# 本地存储
STORAGE_TYPE=local
STORAGE_LOCAL_PATH=storage
# S3 存储
STORAGE_TYPE=s3
S3_ENDPOINT=https://s3.amazonaws.com
S3_BUCKET_NAME=dify
S3_ACCESS_KEY=your-key
S3_SECRET_KEY=your-secret
S3_REGION=us-east-1
# Azure Blob 存储
STORAGE_TYPE=azure-blob
AZURE_BLOB_ACCOUNT_NAME=your-account
AZURE_BLOB_ACCOUNT_KEY=your-key
AZURE_BLOB_CONTAINER_NAME=dify
向量数据库配置
# Weaviate(默认)
VECTOR_STORE=weaviate
WEAVIATE_ENDPOINT=http://weaviate:8080
# Qdrant
VECTOR_STORE=qdrant
QDRANT_URL=http://qdrant:6333
QDRANT_API_KEY=your-key
# Milvus
VECTOR_STORE=milvus
MILVUS_URI=http://milvus:19530
# Pgvector(使用内置 PostgreSQL)
VECTOR_STORE=pgvector
10.3 数据备份
10.3.1 数据库备份
PostgreSQL 备份脚本:
#!/bin/bash
# dify-backup.sh
BACKUP_DIR="/backup/dify"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/dify_db_$DATE.sql"
# 创建备份目录
mkdir -p $BACKUP_DIR
# 执行数据库备份
docker exec dify-db pg_dump -U dify dify > $BACKUP_FILE
# 压缩备份文件
gzip $BACKUP_FILE
# 删除 30 天前的备份
find $BACKUP_DIR -name "*.gz" -mtime +30 -delete
echo "备份完成: ${BACKUP_FILE}.gz"
设置定时备份:
# 编辑 crontab
crontab -e
# 添加每天凌晨 2 点执行备份
0 2 * * * /path/to/dify-backup.sh >> /var/log/dify-backup.log 2>&1
10.3.2 文件存储备份
如果使用本地存储,需要备份上传的文件:
#!/bin/bash
# 文件存储备份
BACKUP_DIR="/backup/dify/files"
DATE=$(date +%Y%m%d_%H%M%S)
SOURCE_DIR="/path/to/dify/docker/volumes/app/storage"
mkdir -p $BACKUP_DIR
# 使用 rsync 增量备份
rsync -av --delete $SOURCE_DIR/ $BACKUP_DIR/current/
# 创建压缩快照
tar -czf $BACKUP_DIR/files_$DATE.tar.gz -C $BACKUP_DIR current/
# 删除 30 天前的快照
find $BACKUP_DIR -name "files_*.tar.gz" -mtime +30 -delete
10.3.3 数据恢复
PostgreSQL 恢复:
# 解压备份文件
gunzip dify_db_20240101_020000.sql.gz
# 停止 Dify 服务
docker compose stop api worker
# 恢复数据库
cat dify_db_20240101_020000.sql | docker exec -i dify-db psql -U dify dify
# 重启服务
docker compose start api worker
10.4 监控告警
10.4.1 服务健康检查
检查脚本:
#!/bin/bash
# dify-healthcheck.sh
# 检查 API 服务
API_STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:80/v1/health)
if [ "$API_STATUS" != "200" ]; then
echo "ERROR: API 服务异常 (HTTP $API_STATUS)"
# 发送告警通知
fi
# 检查数据库
DB_STATUS=$(docker exec dify-db pg_isready -U dify)
if [ $? -ne 0 ]; then
echo "ERROR: 数据库连接异常"
fi
# 检查 Redis
REDIS_STATUS=$(docker exec dify-redis redis-cli -a $REDIS_PASSWORD ping)
if [ "$REDIS_STATUS" != "PONG" ]; then
echo "ERROR: Redis 连接异常"
fi
# 检查磁盘空间
DISK_USAGE=$(df -h / | tail -1 | awk '{print $5}' | sed 's/%//')
if [ "$DISK_USAGE" -gt 85 ]; then
echo "WARNING: 磁盘使用率过高 ($DISK_USAGE%)"
fi
# 检查内存使用
MEM_USAGE=$(free | grep Mem | awk '{print $3/$2 * 100.0}')
if (( $(echo "$MEM_USAGE > 90" | bc -l) )); then
echo "WARNING: 内存使用率过高 ($MEM_USAGE%)"
fi
10.4.2 使用 Prometheus + Grafana 监控
Dify 的 API 服务暴露了 Prometheus 指标端点:
Prometheus 配置:
# prometheus.yml
scrape_configs:
- job_name: 'dify-api'
static_configs:
- targets: ['dify-api:5001']
metrics_path: '/metrics'
Grafana Dashboard:
推荐监控以下指标:
- API 请求量(QPS)
- API 响应时间(P50/P95/P99)
- 错误率
- 活跃连接数
- Token 使用量
- 模型调用延迟
10.5 性能优化
10.5.1 应用层优化
1. Prompt 优化
- 精简不必要的 Prompt 内容
- 合理设置 Max Tokens
- 使用较低的 Temperature 减少生成时间
2. 知识库优化
- 合理设置 Top-K(通常 3-5 足够)
- 使用 Score 阈值过滤低质量结果
- 定期清理过时文档
3. 缓存策略
- 启用 Redis 缓存
- 对频繁查询的结果设置缓存
- 合理设置缓存过期时间
10.5.2 基础设施优化
1. 水平扩展
# docker-compose.yml - 扩展 API Worker
services:
api:
deploy:
replicas: 4 # 根据负载调整
worker:
deploy:
replicas: 2
2. 数据库优化
- 定期执行 VACUUM 和 ANALYZE
- 优化慢查询
- 添加适当的索引
3. 负载均衡
使用 Nginx 或云负载均衡器分发请求:
upstream dify_api {
server api-1:5001;
server api-2:5001;
server api-3:5001;
server api-4:5001;
}
server {
listen 80;
location /v1/ {
proxy_pass http://dify_api;
}
}
10.5.3 成本优化
1. 模型选择策略
- 简单任务使用低成本模型
- 复杂任务使用高能力模型
- 建立模型路由规则
2. Token 优化
- 精简 System Prompt
- 控制对话历史长度
- 合理设置 Max Tokens
3. 缓存利用
- 对相同或相似的查询使用缓存结果
- 减少重复的模型调用
4. 预算管理
- 设置 API 调用预算告警
- 监控每日 Token 消耗
- 分析高消耗应用并优化
第十一章 实战项目:构建企业级智能文档问答系统
11.1 项目概述
在本章中,我们将从零开始构建一个完整的企业级智能文档问答系统。这个系统将综合运用前面学到的所有知识点,包括知识库管理、Prompt 工程、工作流编排、API 集成等。
系统功能
- 支持多种格式的企业文档导入(PDF、Word、Markdown)
- 智能问答,基于文档内容生成准确回答
- 引用溯源,标注回答的文档来源
- 多轮对话,支持追问和上下文理解
- API 接口,可集成到企业内部系统
- 反馈机制,持续优化回答质量
技术架构
┌──────────────────────────────────────────────┐
│ 前端界面 │
│ (Web Chat / 企业内部系统) │
├──────────────────────────────────────────────┤
│ API 层 │
│ (Dify RESTful API + 流式输出) │
├──────────────────────────────────────────────┤
│ 工作流引擎 │
│ 查询分类 → 知识库检索 → 回答生成 → 质量检查 │
├──────────────────────────────────────────────┤
│ 知识库引擎 │
│ 文档解析 → 分段 → 向量化 → 存储 → 检索 │
├──────────────────────────────────────────────┤
│ 基础设施 │
│ PostgreSQL / Redis / Weaviate / Nginx │
└──────────────────────────────────────────────┘
11.2 准备工作
11.2.1 环境准备
确保你已经完成了以下准备工作:
- Dify 已成功部署并可以访问
- 至少配置了一个模型供应商的 API Key(推荐 OpenAI GPT-4o)
- 准备好需要导入的企业文档
11.2.2 文档准备
准备以下类型的测试文档:
- 产品手册:产品功能说明、操作指南
- FAQ 文档:常见问题与解答
- 政策文件:公司制度、流程规范
- 技术文档:系统架构、API 文档
建议先用 5-10 个文档进行测试,验证效果后再批量导入。
11.3 创建知识库
步骤一:创建产品知识库
- 进入"知识库"页面
- 点击"创建知识库"
- 名称:
企业文档知识库 - 描述:
包含产品手册、FAQ、政策文件等企业内部文档
步骤二:上传文档
将准备好的文档逐一上传:
- 点击"添加文档"
- 选择"上传文件"
- 拖拽或选择文件
- 等待上传完成
步骤三:配置分段策略
对于不同类型的企业文档,建议使用不同的分段策略:
产品手册(Markdown/Word):
- 分段标识符:
\n\n##(按二级标题分段) - 最大分段长度:600 tokens
- 分段重叠:100 tokens
FAQ 文档:
- 分段标识符:
\n\n(按段落分段) - 最大分段长度:400 tokens
- 分段重叠:50 tokens
政策文件(PDF):
- 分段标识符:
\n\n(按段落分段) - 最大分段长度:500 tokens
- 分段重叠:80 tokens
步骤四:选择索引方式
选择"高质量"索引模式:
- Embedding 模型:text-embedding-3-small(性价比最高)
- 等待索引完成(根据文档量大小,可能需要几分钟到几十分钟)
步骤五:检索测试
进行多轮检索测试:
测试 1:产品有哪些功能?
→ 期望返回产品功能相关文档
测试 2:如何重置密码?
→ 期望返回密码重置相关的 FAQ
测试 3:请假流程是什么?
→ 期望返回人事政策相关文档
测试 4:API 的认证方式是什么?
→ 期望返回 API 技术文档
根据测试结果调整分段策略和索引参数。
11.4 创建问答应用
步骤一:选择应用类型
创建一个新的"聊天助手"类型应用:
- 名称:
企业智能文档问答系统 - 描述:
基于企业文档的智能问答助手
步骤二:设计 System Prompt
编写高质量的 System Prompt:
你是一个专业的"企业智能文档问答系统"。你的任务是基于企业内部文档,为员工提供准确、专业的回答。
## 你的角色
- 你是公司的智能知识助手
- 你对企业的产品、政策、流程非常熟悉
- 你始终基于提供的文档内容回答问题
## 回答原则
1. **准确性优先**:只基于提供的参考资料回答,绝不编造信息
2. **引用来源**:回答时明确标注参考的文档来源
3. **简洁明了**:使用清晰简洁的语言,避免冗长
4. **结构化输出**:适当使用标题、列表、表格等格式组织回答
5. **主动引导**:如果文档中没有直接答案,建议用户联系相关部门
## 回答格式
回答时请遵循以下格式:
### 回答
(基于文档内容的详细回答)
### 参考来源
- (文档名称 / 章节)
### 相关建议
- (如有需要,提供进一步的建议或联系方式)
## 特殊情况处理
- 如果文档中没有相关信息:明确告知用户"根据现有文档,未找到相关信息",并建议联系对应部门
- 如果信息可能已过时:提醒用户确认信息的时效性
- 如果问题涉及机密信息:礼貌拒绝并说明原因
## 禁止行为
- 不要编造文档中不存在的信息
- 不要猜测或推测
- 不要透露系统的技术实现细节
- 不要回答与企业文档无关的问题
步骤三:关联知识库
- 在"上下文"配置区域,点击"添加"
- 选择刚创建的"企业文档知识库"
- 配置检索参数:
- Top-K:5
- Score 阈值:0.5
- 检索模式:混合检索
步骤四:配置变量
添加以下变量:
| 变量名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| department | 下拉选择 | 否 | 用户所在部门(用于筛选更相关的结果) |
下拉选项:技术部、产品部、市场部、人事部、财务部、其他
步骤五:设置对话开场白
👋 你好!我是企业智能文档问答助手。
我可以帮你查询:
• 📦 产品功能和使用方法
• ❓ 常见问题解答
• 📋 公司政策和流程
• 🔧 技术文档和 API 接口
你可以直接输入问题,或者尝试以下问题:
建议问题:
- "产品有哪些主要功能?"
- "如何申请年假?"
- "API 的认证方式是什么?"
步骤六:优化 Prompt 中的上下文引用
在 System Prompt 中添加上下文引用:
## 参考资料
以下是与用户问题相关的企业文档内容。请基于这些资料回答问题:
{{#context#}}
步骤七:选择模型并调优
- 选择模型:GPT-4o(推荐,效果最好)
- Temperature:0.3(事实性问答,需要较低的随机性)
- Max Tokens:2000(足够生成详细的回答)
11.5 构建高级工作流(可选)
如果你需要更复杂的处理逻辑,可以创建一个工作流版本:
工作流设计
开始节点(接收用户查询)
↓
知识库检索节点(检索相关文档)
↓
条件分支节点(判断是否有检索结果)
├── 有结果 → LLM 节点(基于文档生成回答)
│ ↓
│ 代码节点(格式化输出,添加引用)
└── 无结果 → LLM 节点(生成无结果提示)
↓
结束节点(输出回答)
详细配置
1. 开始节点
输入变量:
- query:文本,必填,用户的查询问题
- department:文本,选填,用户所在部门
2. 知识库检索节点
知识库:企业文档知识库
检索变量:{{start.query}}
Top-K:5
Score 阈值:0.5
检索模式:混合检索
3. 条件分支节点
条件:{{kb_search.result}} 不为空
├── 是 → 连接到"基于文档回答"LLM 节点
└── 否 → 连接到"无结果提示"LLM 节点
4. "基于文档回答" LLM 节点
System Prompt:
你是一个企业文档问答助手。请根据以下参考资料,准确回答用户的问题。
回答要求:
1. 只基于参考资料回答,不要编造信息
2. 回答要结构化,使用标题和列表
3. 在回答末尾列出参考来源
参考资料:
{{kb_search.result}}
User Prompt:
用户问题:{{start.query}}
5. "无结果提示" LLM 节点
System Prompt:
用户的问题在企业文档中没有找到相关内容。请礼貌地告知用户,并建议他们:
1. 换一种方式提问
2. 联系对应的部门获取帮助
请根据问题内容推荐可能负责的部门。
6. 代码节点(格式化输出)
def main(llm_output: str, search_results: list) -> dict:
# 添加引用信息
references = []
for i, result in enumerate(search_results[:3], 1):
references.append(f"{i}. {result.get('title', '未知文档')}")
formatted_output = llm_output
if references:
formatted_output += "\n\n### 参考来源\n" + "\n".join(references)
return {
"answer": formatted_output,
"has_references": len(references) > 0
}
7. 结束节点
输出:{{format_node.answer}}
11.6 API 集成
将问答系统集成到企业内部系统中。
创建 API 密钥
- 进入应用的"访问 API"页面
- 创建新密钥,命名为"内部系统集成"
- 复制并保存密钥
后端集成代码
"""
企业文档问答系统 - 后端集成示例
"""
import requests
import json
from flask import Flask, request, jsonify, Response
app = Flask(__name__)
DIFY_API_URL = "http://your-dify-server/v1"
DIFY_API_KEY = "your-api-key"
@app.route("/api/ask", methods=["POST"])
def ask():
"""接收前端请求,转发到 Dify API"""
data = request.json
query = data.get("query", "")
user_id = data.get("user_id", "anonymous")
conversation_id = data.get("conversation_id")
# 构建请求体
body = {
"inputs": {},
"query": query,
"user": user_id,
"response_mode": "streaming" # 使用流式输出
}
if conversation_id:
body["conversation_id"] = conversation_id
# 调用 Dify API
headers = {
"Authorization": f"Bearer {DIFY_API_KEY}",
"Content-Type": "application/json"
}
def generate():
"""流式输出生成器"""
with requests.post(
f"{DIFY_API_URL}/chat-messages",
headers=headers,
json=body,
stream=True
) as response:
for line in response.iter_lines():
if line:
yield line.decode("utf-8") + "\n"
return Response(generate(), mimetype="text/event-stream")
@app.route("/api/feedback", methods=["POST"])
def feedback():
"""提交用户反馈"""
data = request.json
message_id = data.get("message_id")
rating = data.get("rating") # "like" 或 "dislike"
headers = {
"Authorization": f"Bearer {DIFY_API_KEY}",
"Content-Type": "application/json"
}
response = requests.post(
f"{DIFY_API_URL}/messages/{message_id}/feedbacks",
headers=headers,
json={
"rating": rating,
"user": data.get("user_id", "anonymous")
}
)
return jsonify(response.json())
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
前端集成示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>企业智能文档问答</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: #f5f5f5; }
.container { max-width: 800px; margin: 0 auto; padding: 20px; }
h1 { text-align: center; color: #333; margin-bottom: 20px; }
.chat-box { background: white; border-radius: 12px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); overflow: hidden; }
.messages { height: 500px; overflow-y: auto; padding: 20px; }
.msg { margin-bottom: 16px; display: flex; }
.msg.user { justify-content: flex-end; }
.msg .bubble { max-width: 70%; padding: 12px 16px; border-radius: 12px; line-height: 1.6; }
.msg.user .bubble { background: #007bff; color: white; border-bottom-right-radius: 4px; }
.msg.ai .bubble { background: #f0f0f0; color: #333; border-bottom-left-radius: 4px; }
.msg .feedback { margin-top: 8px; font-size: 12px; }
.msg .feedback button { background: none; border: none; cursor: pointer; font-size: 16px; padding: 2px 6px; }
.input-area { display: flex; padding: 16px; border-top: 1px solid #eee; gap: 10px; }
.input-area input { flex: 1; padding: 12px; border: 1px solid #ddd; border-radius: 8px; font-size: 14px; }
.input-area button { padding: 12px 24px; background: #007bff; color: white; border: none; border-radius: 8px; cursor: pointer; font-size: 14px; }
.input-area button:disabled { background: #ccc; }
.sources { margin-top: 8px; font-size: 12px; color: #666; }
</style>
</head>
<body>
<div class="container">
<h1>📚 企业智能文档问答</h1>
<div class="chat-box">
<div class="messages" id="messages">
<div class="msg ai">
<div class="bubble">
👋 你好!我是企业智能文档问答助手。<br><br>
我可以帮你查询产品文档、公司政策、常见问题等。<br>
请输入你的问题吧!
</div>
</div>
</div>
<div class="input-area">
<input type="text" id="queryInput" placeholder="输入你的问题..."
onkeypress="if(event.key==='Enter')askQuestion()">
<button id="sendBtn" onclick="askQuestion()">发送</button>
</div>
</div>
</div>
<script>
const API_URL = '/api/ask';
let conversationId = null;
async function askQuestion() {
const input = document.getElementById('queryInput');
const query = input.value.trim();
if (!query) return;
// 显示用户消息
addMessage(query, 'user');
input.value = '';
document.getElementById('sendBtn').disabled = true;
// 创建 AI 消息占位
const aiBubble = addMessage('', 'ai');
const sourcesDiv = document.createElement('div');
sourcesDiv.className = 'sources';
try {
const body = { query, user_id: 'web-user' };
if (conversationId) body.conversation_id = conversationId;
const response = await fetch(API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value);
const lines = text.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
try {
const data = JSON.parse(line.slice(6));
if (data.event === 'message') {
aiBubble.innerHTML += data.answer;
}
if (data.conversation_id) {
conversationId = data.conversation_id;
}
if (data.event === 'message_end' && data.metadata?.retriever_resources) {
const refs = data.metadata.retriever_resources;
if (refs.length > 0) {
sourcesDiv.innerHTML = '📖 参考来源:' +
refs.map(r => r.dataset_name).join('、');
aiBubble.parentNode.appendChild(sourcesDiv);
}
}
} catch (e) {}
}
}
}
} catch (error) {
aiBubble.textContent = '请求失败,请稍后重试。';
}
document.getElementById('sendBtn').disabled = false;
document.getElementById('messages').scrollTop = document.getElementById('messages').scrollHeight;
}
function addMessage(text, type) {
const messages = document.getElementById('messages');
const div = document.createElement('div');
div.className = `msg ${type}`;
const bubble = document.createElement('div');
bubble.className = 'bubble';
bubble.innerHTML = text || '...';
div.appendChild(bubble);
messages.appendChild(div);
messages.scrollTop = messages.scrollHeight;
return bubble;
}
</script>
</body>
</html>
11.7 测试与优化
11.7.1 功能测试
进行全面的功能测试:
基本问答测试:
测试 1:产品支持哪些操作系统?
→ 验证是否正确回答并引用文档来源
测试 2:如何申请年假?
→ 验证是否返回正确的流程说明
测试 3:API 的限流策略是什么?
→ 验证技术文档的检索和回答质量
多轮对话测试:
第 1 轮:产品有哪些功能?
第 2 轮:其中 XX 功能如何使用?
第 3 轮:这个功能有什么限制?
→ 验证对话历史是否正确维护
边界测试:
测试 1:输入空字符串
测试 2:输入超长文本
测试 3:输入与文档无关的问题
测试 4:输入特殊字符和表情
11.7.2 效果优化
根据测试结果进行优化:
检索效果不佳:
- 调整分段策略
- 增加文档覆盖范围
- 优化 Embedding 模型选择
- 尝试混合检索模式
回答质量不高:
- 优化 System Prompt
- 调整 Temperature 参数
- 增加示例和约束
- 优化上下文引用格式
响应速度慢:
- 减少 Top-K 值
- 优化 Prompt 长度
- 使用更快的模型
- 启用缓存
11.7.3 持续优化机制
建立持续优化的闭环:
- 收集用户反馈:通过 API 的反馈功能收集用户评价
- 分析日志:定期查看对话日志,发现共性问题
- 更新知识库:及时添加新文档,删除过时内容
- 优化 Prompt:根据反馈不断调优提示词
- 监控指标:跟踪满意度、准确率等核心指标
11.8 部署上线
11.8.1 上线检查清单
在正式上线前,完成以下检查:
- 所有文档已正确导入和索引
- 检索测试结果满意
- Prompt 优化完成
- API 接口测试通过
- 前端界面功能正常
- 错误处理机制完善
- 安全配置检查(HTTPS、API Key 保护)
- 性能测试通过(并发、响应时间)
- 备份策略已配置
- 监控告警已设置
11.8.2 灰度发布
建议采用灰度发布策略:
- 先在小范围(如技术团队)内试用
- 收集反馈并优化
- 逐步扩大使用范围
- 全面上线
11.8.3 运维监控
上线后需要持续监控:
- 使用统计:每日活跃用户、对话量、问题类型分布
- 质量指标:用户满意度、回答准确率
- 性能指标:响应时间、错误率
- 成本指标:Token 消耗、模型调用费用
11.9 扩展功能
系统上线后,可以考虑以下扩展:
1. 多语言支持
在 Prompt 中添加多语言处理指令,支持中英文混合的文档和问答。
2. 图片理解
集成多模态模型,支持对文档中图片内容的理解和回答。
3. 自动摘要
添加文档自动摘要功能,在回答时提供简要概述。
4. 知识图谱
构建企业知识图谱,实现更深层次的知识关联和推理。
5. 多 Agent 协作
针对不同领域(技术、人事、财务等)创建专门的 Agent,通过路由分发实现专业回答。
总结
恭喜你完成了 Dify AI 应用平台零基础入门教程的全部学习!
让我们回顾一下你学到的关键知识点:
- Dify 基础:了解了 Dify 的核心功能、技术架构和适用场景
- 快速上手:掌握了云端注册和本地部署的方法
- 应用类型:理解了聊天助手、文本生成、Agent、工作流四种类型的区别和适用场景
- 知识库管理:学会了文档上传、分段策略、索引方式和检索优化
- Prompt 工程:掌握了变量绑定、上下文引用、模板设计等技巧
- 工作流编排:学会了使用各种节点类型构建复杂的工作流程
- Agent 开发:掌握了工具配置、推理策略和多工具协作
- API 集成:学会了通过 API 将 Dify 能力集成到外部系统
- 高级功能:了解了多模型切换、内容审核、标注反馈等高级特性
- 部署运维:掌握了生产环境部署、数据备份、监控告警的方法
- 实战项目:完成了一个完整的企业级智能文档问答系统的构建
下一步学习建议
- 深入学习:阅读 Dify 官方文档,了解更多高级功能
- 动手实践:尝试构建更多类型的 AI 应用
- 社区参与:加入 Dify 社区,与其他开发者交流经验
- 持续关注:Dify 正在快速迭代,关注最新的功能更新
学习资源
- Dify 官方文档:
https://docs.dify.ai - Dify GitHub 仓库:
https://github.com/langgenius/dify - Dify 社区论坛:
https://community.dify.ai - Dify 官方博客:
https://dify.ai/blog
📝 版权声明:本教程由 AI 辅助创作,所有内容原创,不涉及任何版权内容。你可以自由使用、修改和分享本教程。
🕐 最后更新:2025 年 5 月