Dify AI应用开发平台完全教程

教程简介

零基础Dify AI应用开发平台完全教程,涵盖Dify架构原理、Chatflow对话流设计、Workflow工作流构建、知识库管理、Agent集成、API二次开发、插件开发等核心技能,配有企业级智能客服系统实战项目,适合AI应用开发者系统学习。

Dify AI应用开发平台完全教程

前言

在AI应用开发领域,如何快速将大语言模型的能力转化为可用的商业产品,一直是开发者面临的核心挑战。传统的AI应用开发需要深厚的机器学习知识、复杂的工程架构和大量的基础设施投入。而Dify的出现,彻底改变了这一局面。

Dify是一个开源的AI应用开发平台,它提供了可视化的编排界面、强大的工作流引擎和完善的API接口,让开发者无需深入底层技术细节,就能快速构建生产级的AI应用。

本教程将从零开始,系统性地讲解Dify平台的架构原理、核心功能、开发技巧,并通过一个完整的企业级智能客服系统实战项目,帮助你掌握Dify开发的全流程。


第一章:Dify平台概述与架构

1.1 什么是Dify

Dify(发音为"Define")是一个开源的LLM应用开发平台,其核心理念是通过可视化编排降低AI应用的开发门槛。它提供了以下核心能力:

  • 可视化应用编排:通过拖拽式界面构建AI应用,无需编写代码
  • 多模型支持:集成OpenAI、Anthropic、本地模型等多种LLM
  • 知识库管理:支持文档上传、智能分段、向量检索
  • 工作流引擎:支持复杂的业务逻辑编排
  • API驱动:所有功能都可以通过API调用
  • 插件生态:可扩展的插件系统

1.2 平台架构

Dify采用经典的分层架构设计:

┌─────────────────────────────────────────────────────────────┐
│                    前端层(Frontend)                          │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐       │
│  │ 应用编排  │ │ 知识库   │ │ 模型管理  │ │ 数据分析 │       │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘       │
└─────────────────────────┬───────────────────────────────────┘
                          │ HTTP/WebSocket
┌─────────────────────────┴───────────────────────────────────┐
│                    API层(API Server)                        │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐       │
│  │ 应用API  │ │ 知识库API│ │ 模型API  │ │ 插件API  │       │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘       │
└─────────────────────────┬───────────────────────────────────┘
                          │
┌─────────────────────────┴───────────────────────────────────┐
│                  服务层(Service Layer)                       │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐       │
│  │ 编排引擎 │ │ RAG引擎  │ │ 模型调度  │ │ 插件引擎 │       │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘       │
└─────────────────────────┬───────────────────────────────────┘
                          │
┌─────────────────────────┴───────────────────────────────────┐
│                   基础设施层(Infrastructure)                  │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐       │
│  │ PostgreSQL│ │  Redis   │ │ 向量数据库│ │ 文件存储 │       │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘       │
└─────────────────────────────────────────────────────────────┘

1.3 核心概念

在使用Dify之前,需要理解以下核心概念:

应用(Application) Dify中的基本单元。每个应用对应一个具体的AI功能,如聊天机器人、文本生成器、工作流等。

应用类型

  • Chatflow(对话流):多轮对话应用,支持上下文记忆
  • Workflow(工作流):单次执行的自动化流程
  • Agent(智能体):具备工具调用和自主推理能力的应用
  • 文本生成:单次文本生成应用

节点(Node) 工作流中的基本单元,每个节点执行一个特定的功能,如LLM调用、条件判断、工具调用等。

变量(Variable) 在工作流中传递数据的载体。包括环境变量、会话变量、节点输出变量等。

知识库(Knowledge Base) 存储和管理文档数据的模块,支持向量检索和全文检索。


第二章:Dify安装部署

2.1 环境要求

在安装Dify之前,确保你的系统满足以下要求:

  • 操作系统:Linux(推荐Ubuntu 20.04+)、macOS、Windows(WSL2)
  • Docker:20.10+
  • Docker Compose:2.0+
  • 内存:最低4GB,推荐8GB+
  • 磁盘:最低20GB可用空间
  • 网络:能够访问Docker Hub和模型API

2.2 Docker Compose本地部署

Dify官方推荐使用Docker Compose进行部署,这是最简单的方式。

第一步:克隆代码

# 克隆Dify仓库
git clone https://github.com/langgenius/dify.git
cd dify/docker

第二步:配置环境变量

# 复制环境变量模板
cp .env.example .env

# 编辑环境变量
vim .env

关键环境变量说明:

# 应用密钥(必须修改)
SECRET_KEY=your-random-secret-key-here

# 数据库配置
DB_USERNAME=postgres
DB_PASSWORD=your-db-password
DB_HOST=db
DB_PORT=5432
DB_DATABASE=dify

# Redis配置
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=your-redis-password

# 向量数据库(默认使用Weaviate)
VECTOR_STORE=weaviate

# 文件存储类型
STORAGE_TYPE=local

# 日志级别
LOG_LEVEL=INFO

第三步:启动服务

# 启动所有服务
docker compose up -d

# 查看服务状态
docker compose ps

# 查看日志
docker compose logs -f api

第四步:访问Dify

服务启动后,通过浏览器访问 http://localhost(默认端口80)。

首次访问需要设置管理员账号:

  1. 输入邮箱和密码
  2. 完成初始化配置
  3. 进入Dify控制台

2.3 使用Dify云服务

如果不想自行部署,可以直接使用Dify提供的云服务:

  1. 访问 https://cloud.dify.ai
  2. 注册账号
  3. 直接开始使用

云服务的优势:

  • 无需维护基础设施
  • 自动更新到最新版本
  • 提供技术支持
  • 按使用量付费

2.4 配置模型提供商

安装完成后,需要配置至少一个模型提供商:

  1. 进入 设置模型供应商
  2. 添加模型提供商(如OpenAI、Anthropic等)
  3. 输入API Key
  4. 测试连接是否成功
# 如果使用OpenAI
export OPENAI_API_KEY=sk-your-api-key

# 如果使用自定义API端点
export OPENAI_API_BASE=https://your-custom-endpoint.com/v1

第三章:Chatflow对话流设计

3.1 什么是Chatflow

Chatflow是Dify中最常用的应用类型,用于构建多轮对话应用。它的核心特点:

  • 支持上下文记忆
  • 可视化节点编排
  • 支持变量传递
  • 支持条件分支
  • 支持工具调用

3.2 创建Chatflow应用

  1. 在Dify控制台,点击 创建应用
  2. 选择 Chatflow 类型
  3. 输入应用名称和描述
  4. 进入可视化编辑器

3.3 核心节点详解

开始节点

每个Chatflow都从"开始"节点开始。在这里可以定义:

  • 系统提示词(System Prompt):定义AI的角色和行为准则
  • 变量:定义用户输入的变量
系统提示词示例:
你是一个专业的客户服务代表。请用友好、专业的语气回答用户的问题。
如果遇到无法回答的问题,请引导用户联系人工客服。

用户输入变量:
- user_query: 用户的问题(字符串类型)
- user_id: 用户ID(字符串类型,可选)

LLM节点

LLM节点是Chatflow的核心,用于调用大语言模型:

配置项:
- 模型:选择使用的模型(如gpt-4、gpt-3.5-turbo)
- 提示词:可以引用变量,如 {{user_query}}
- 温度:控制输出的随机性(0-1)
- 最大Token数:限制输出长度
- 上下文:选择是否包含对话历史

变量引用语法:

在提示词中引用变量使用双花括号:{{variable_name}}

示例提示词:
用户的问题是:{{user_query}}

请根据以下知识库内容回答:
{{#context#}}

如果知识库中没有相关信息,请告知用户你不确定。

条件分支节点

用于根据条件执行不同的逻辑:

条件配置示例:
- IF {{user_query}} 包含 "退款" → 进入退款处理分支
- ELSE IF {{user_query}} 包含 "投诉" → 进入投诉处理分支  
- ELSE → 进入通用问答分支

知识检索节点

用于从知识库中检索相关信息:

配置项:
- 知识库:选择要检索的知识库
- 检索模式:
  - 向量检索:基于语义相似度
  - 全文检索:基于关键词匹配
  - 混合检索:结合两者
- TopK:返回最相关的K条结果
- 相似度阈值:过滤低相关性的结果

代码节点

用于执行自定义代码逻辑:

# 代码节点示例:数据处理
def main(query: str, context: list) -> dict:
    # 处理检索到的上下文
    processed_context = []
    for item in context:
        if item.get("score", 0) > 0.7:  # 只保留高相关性的结果
            processed_context.append(item["content"])
    
    return {
        "processed_context": "\n".join(processed_context),
        "has_results": len(processed_context) > 0
    }

HTTP请求节点

用于调用外部API:

配置项:
- 方法:GET/POST/PUT/DELETE
- URL:API地址,支持变量插值
- Headers:请求头
- Body:请求体
- 超时:请求超时时间

结束节点

定义Chatflow的输出格式:

输出变量:
- answer: AI的回答
- sources: 引用的知识库来源(可选)

3.4 变量传递机制

变量是Chatflow中数据流转的核心。理解变量的作用域和传递规则非常重要:

节点输出变量

每个节点执行后都会产生输出变量,可以在后续节点中引用:

LLM节点输出:
- text: 生成的文本
- usage: Token使用量

知识检索节点输出:
- result: 检索结果列表
  - 每个结果包含:content, score, metadata

代码节点输出:
- 由代码中的return语句定义

会话变量

会话变量在整个对话过程中持续存在:

# 设置会话变量
conversation_id = get_conversation_id()
set_variable("conversation_turn", get_variable("conversation_turn", 0) + 1)

# 使用会话变量实现上下文记忆
turn_count = get_variable("conversation_turn", 0)
if turn_count > 5:
    # 超过5轮对话,建议转人工
    suggest_human_agent()

3.5 实战:构建客服对话流

下面是一个完整的客服Chatflow设计:

[开始] → [意图识别LLM] → [条件分支]
                              ├─ "订单问题" → [订单知识库检索] → [订单回复LLM] → [结束]
                              ├─ "退款问题" → [退款政策检索] → [退款回复LLM] → [结束]
                              ├─ "投诉" → [记录投诉HTTP] → [安抚回复LLM] → [结束]
                              └─ "其他" → [通用回复LLM] → [结束]

意图识别节点的提示词:

请分析用户的意图,并返回以下类别之一:
- order: 订单相关问题(查询、修改、取消订单)
- refund: 退款相关问题(退款流程、退款状态)
- complaint: 投诉(服务不满意、产品质量问题)
- other: 其他问题

用户输入:{{user_query}}

请只返回类别名称,不要添加其他内容。

第四章:Workflow工作流构建

4.1 Chatflow vs Workflow

特性 Chatflow Workflow
交互方式 多轮对话 单次执行
上下文 保持对话历史 无上下文
适用场景 客服、聊天 数据处理、自动化
输入 用户消息 结构化参数
输出 AI回复 执行结果

4.2 Workflow典型应用场景

  1. 数据处理流水线:批量处理文档、数据清洗
  2. 内容生成:自动生成文章、报告
  3. 信息提取:从非结构化文本中提取结构化数据
  4. 自动化决策:基于规则的自动审批、分类
  5. API编排:串联多个API实现复杂业务逻辑

4.3 构建数据处理Workflow

下面以"批量文章摘要生成"为例,展示Workflow的构建过程:

第一步:定义输入

输入变量:
- articles: 文章列表(数组类型)
  - 每个元素包含:title, content, url
- language: 输出语言(字符串,默认"中文")
- max_length: 摘要最大长度(数字,默认200)

第二步:迭代处理节点

Dify的Workflow支持迭代节点,可以对数组中的每个元素执行相同的操作:

迭代节点配置:
- 输入数组:{{articles}}
- 迭代变量:current_article

子流程:
1. [LLM节点] 生成摘要
   提示词:
   请为以下文章生成摘要,语言为{{language}},长度不超过{{max_length}}字。
   
   标题:{{current_article.title}}
   内容:{{current_article.content}}
   
2. [代码节点] 格式化输出
   代码:
   def main(title: str, summary: str, url: str) -> dict:
       return {
           "formatted": f"## {title}\n\n{summary}\n\n来源:{url}\n"
       }

第三步:聚合结果

代码节点:聚合所有摘要
def main(summaries: list) -> dict:
    combined = "\n---\n".join(summaries)
    return {
        "final_output": f"# 文章摘要汇总\n\n共处理 {len(summaries)} 篇文章\n\n{combined}",
        "count": len(summaries)
    }

4.4 条件路由与错误处理

Workflow中需要考虑异常情况:

# 代码节点:错误处理
def main(article: dict) -> dict:
    if not article.get("content"):
        return {
            "error": True,
            "message": f"文章 '{article.get('title', '未知')}' 内容为空"
        }
    
    if len(article["content"]) < 100:
        return {
            "error": True,
            "message": f"文章 '{article['title']}' 内容太短,跳过处理"
        }
    
    return {"error": False, "article": article}

4.5 Workflow调试技巧

  1. 逐步执行:Dify支持单步调试,可以查看每个节点的输入输出
  2. 日志查看:在运行日志中查看详细的执行过程
  3. 变量检查:在每个节点后检查变量值是否正确
  4. 错误追踪:当执行失败时,查看错误堆栈信息

第五章:知识库管理

5.1 知识库概述

知识库是RAG(检索增强生成)的核心组件。它允许AI基于你提供的文档来回答问题,而不是仅依赖模型的预训练知识。

Dify的知识库功能包括:

  • 支持多种文档格式(PDF、Word、TXT、Markdown等)
  • 智能文档分段
  • 向量检索和全文检索
  • 检索结果排序和过滤

5.2 创建知识库

  1. 在Dify控制台,点击 知识库
  2. 点击 创建知识库
  3. 输入知识库名称和描述
  4. 上传文档

5.3 文档分段策略

文档分段是知识库质量的关键。Dify提供多种分段策略:

自动分段

Dify会根据文档结构自动进行分段,适合大多数场景。

自定义分段

可以手动设置分段参数:

  • 分段标识符:指定用什么字符来分割文档
  • 最大分段长度:每个分段的最大字符数
  • 分段重叠:相邻分段之间的重叠字符数
分段配置示例:
- 分段标识符:\n\n(按段落分割)
- 最大长度:500字符
- 重叠:50字符

这样可以确保:
1. 每个分段是一个完整的语义单元
2. 不会切断句子或段落
3. 重叠部分保持上下文连贯性

5.4 索引方法

Dify支持多种索引方法:

高质量索引

  • 使用Embedding模型将文本转换为向量
  • 支持语义检索
  • 需要配置Embedding模型
  • 检索效果更好

经济索引

  • 使用关键词匹配
  • 不需要Embedding模型
  • 检索速度更快
  • 成本更低

混合索引

  • 结合向量检索和关键词检索
  • 综合两者的优势
  • 推荐在生产环境中使用

5.5 检索配置优化

# 推荐的检索配置
检索模式: 混合检索
向量检索权重: 0.7
关键词检索权重: 0.3
TopK: 5
相似度阈值: 0.5
Rerank模型: 启用
Rerank TopK: 3

5.6 知识库维护

更新文档

当源文档更新时,需要重新上传并建立索引:

  1. 选择要更新的文档
  2. 点击"重新上传"
  3. 等待索引重建完成

监控检索质量

定期检查检索结果的质量:

  1. 使用测试查询检查返回结果的相关性
  2. 如果结果不理想,调整分段策略或检索参数
  3. 考虑添加更多高质量的文档

第六章:Agent集成

6.1 Dify中的Agent

Dify的Agent应用类型允许创建具备自主推理和工具调用能力的AI应用。与Chatflow不同,Agent可以:

  • 自主决定是否调用工具
  • 多轮推理完成复杂任务
  • 动态选择合适的工具

6.2 创建Agent应用

  1. 创建新应用,选择 Agent 类型
  2. 配置系统提示词
  3. 添加工具
  4. 设置推理模式

6.3 工具配置

Dify提供三类工具:

内置工具

Dify内置了多种常用工具:

  • 网络搜索(Google、Bing等)
  • 数学计算
  • 代码执行
  • 图片生成
  • 更多...

自定义工具

可以通过OpenAPI Schema自定义工具:

{
  "openapi": "3.0.0",
  "info": {
    "title": "订单查询API",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.example.com"
    }
  ],
  "paths": {
    "/orders/{order_id}": {
      "get": {
        "summary": "查询订单详情",
        "operationId": "getOrder",
        "parameters": [
          {
            "name": "order_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "订单ID"
          }
        ],
        "responses": {
          "200": {
            "description": "订单详情",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "order_id": {"type": "string"},
                    "status": {"type": "string"},
                    "total": {"type": "number"}
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

工作流工具

可以将Workflow封装为Agent可调用的工具。

6.4 推理模式

Dify的Agent支持多种推理模式:

Function Calling

利用模型原生的Function Calling能力,是推荐的模式。

ReAct

经典的推理-行动循环模式,兼容性更好。

6.5 Agent提示词设计

# 系统提示词示例

## 角色
你是一个专业的客户服务Agent,能够帮助用户查询订单、处理退款、解答问题。

## 能力
- 查询订单状态和详情
- 处理退款申请
- 解答产品相关问题
- 记录用户反馈

## 规则
1. 始终保持友好专业的语气
2. 需要用户提供订单号时,主动询问
3. 涉及金额操作时,需要用户确认
4. 无法处理的问题,引导联系人工客服

## 工具使用指南
- 使用 order_query 查询订单信息
- 使用 refund_apply 提交退款申请
- 使用 knowledge_search 搜索产品知识库

第七章:API集成与二次开发

7.1 Dify API概述

Dify提供完整的RESTful API,所有在界面上能做的操作都可以通过API完成。

API基础信息:

  • 基础URL:http://your-dify-host/v1
  • 认证方式:Bearer Token
  • 数据格式:JSON

7.2 对话型应用API

发送对话消息

curl -X POST 'http://your-dify-host/v1/chat-messages' \
  -H 'Authorization: Bearer {api_key}' \
  -H 'Content-Type: application/json' \
  -d '{
    "inputs": {},
    "query": "我想查询我的订单状态",
    "response_mode": "streaming",
    "conversation_id": "",
    "user": "user-123"
  }'

Python SDK使用

import requests
import json

class DifyClient:
    """Dify API客户端"""
    
    def __init__(self, api_key: str, base_url: str = "http://localhost/v1"):
        self.api_key = api_key
        self.base_url = base_url
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
    
    def chat(self, query: str, conversation_id: str = "", user: str = "default") -> dict:
        """发送对话消息"""
        url = f"{self.base_url}/chat-messages"
        data = {
            "inputs": {},
            "query": query,
            "response_mode": "blocking",
            "conversation_id": conversation_id,
            "user": user
        }
        
        response = requests.post(url, headers=self.headers, json=data)
        return response.json()
    
    def chat_stream(self, query: str, conversation_id: str = "", user: str = "default"):
        """流式对话"""
        url = f"{self.base_url}/chat-messages"
        data = {
            "inputs": {},
            "query": query,
            "response_mode": "streaming",
            "conversation_id": conversation_id,
            "user": user
        }
        
        response = requests.post(url, headers=self.headers, json=data, stream=True)
        
        for line in response.iter_lines():
            if line:
                line = line.decode('utf-8')
                if line.startswith('data: '):
                    event_data = json.loads(line[6:])
                    if event_data.get('event') == 'message':
                        yield event_data.get('answer', '')
    
    def get_conversations(self, user: str = "default", limit: int = 20) -> dict:
        """获取对话列表"""
        url = f"{self.base_url}/conversations"
        params = {"user": user, "limit": limit}
        response = requests.get(url, headers=self.headers, params=params)
        return response.json()
    
    def get_messages(self, conversation_id: str, user: str = "default") -> dict:
        """获取对话消息"""
        url = f"{self.base_url}/messages"
        params = {"conversation_id": conversation_id, "user": user}
        response = requests.get(url, headers=self.headers, params=params)
        return response.json()
    
    def upload_file(self, file_path: str, user: str = "default") -> dict:
        """上传文件"""
        url = f"{self.base_url}/files/upload"
        with open(file_path, 'rb') as f:
            files = {'file': f}
            data = {'user': user}
            headers = {"Authorization": f"Bearer {self.api_key}"}
            response = requests.post(url, headers=headers, files=files, data=data)
        return response.json()


# 使用示例
client = DifyClient(api_key="app-your-api-key")

# 单轮对话
result = client.chat("你好,请问你们的营业时间是?")
print(result["answer"])

# 多轮对话
conv_id = ""
while True:
    user_input = input("你: ")
    if user_input.lower() in ['quit', 'exit']:
        break
    
    result = client.chat(user_input, conversation_id=conv_id)
    conv_id = result.get("conversation_id", conv_id)
    print(f"AI: {result['answer']}")

7.3 工作流API

执行工作流

class DifyWorkflowClient:
    """Dify工作流API客户端"""
    
    def __init__(self, api_key: str, base_url: str = "http://localhost/v1"):
        self.api_key = api_key
        self.base_url = base_url
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
    
    def run_workflow(self, inputs: dict, user: str = "default", 
                     response_mode: str = "blocking") -> dict:
        """执行工作流"""
        url = f"{self.base_url}/workflows/run"
        data = {
            "inputs": inputs,
            "response_mode": response_mode,
            "user": user
        }
        response = requests.post(url, headers=self.headers, json=data)
        return response.json()
    
    def get_workflow_run(self, workflow_run_id: str) -> dict:
        """获取工作流运行状态"""
        url = f"{self.base_url}/workflows/run/{workflow_run_id}"
        response = requests.get(url, headers=self.headers)
        return response.json()


# 使用示例
workflow_client = DifyWorkflowClient(api_key="app-your-workflow-api-key")

# 执行批量摘要工作流
result = workflow_client.run_workflow(
    inputs={
        "articles": [
            {"title": "AI发展趋势", "content": "...", "url": "https://..."},
            {"title": "LLM应用案例", "content": "...", "url": "https://..."}
        ],
        "language": "中文",
        "max_length": 200
    }
)

print(result["data"]["outputs"]["final_output"])

7.4 知识库API

class DifyKnowledgeClient:
    """Dify知识库API客户端"""
    
    def __init__(self, api_key: str, base_url: str = "http://localhost/v1"):
        self.api_key = api_key
        self.base_url = base_url
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
    
    def create_dataset(self, name: str, description: str = "") -> dict:
        """创建知识库"""
        url = f"{self.base_url}/datasets"
        data = {"name": name, "description": description}
        response = requests.post(url, headers=self.headers, json=data)
        return response.json()
    
    def upload_document(self, dataset_id: str, file_path: str, 
                        indexing_technique: str = "high_quality") -> dict:
        """上传文档到知识库"""
        url = f"{self.base_url}/datasets/{dataset_id}/document/create-by-file"
        
        with open(file_path, 'rb') as f:
            files = {'file': f}
            data = {
                'data': json.dumps({
                    "indexing_technique": indexing_technique,
                    "process_rule": {
                        "mode": "automatic"
                    }
                }),
                'type': 'text'
            }
            headers = {"Authorization": f"Bearer {self.api_key}"}
            response = requests.post(url, headers=headers, files=files, data=data)
        
        return response.json()
    
    def search(self, dataset_id: str, query: str, top_k: int = 5) -> dict:
        """在知识库中搜索"""
        url = f"{self.base_url}/datasets/{dataset_id}/retrieve"
        data = {
            "query": query,
            "retrieval_model": {
                "search_method": "hybrid_search",
                "reranking_enable": True,
                "top_k": top_k
            }
        }
        response = requests.post(url, headers=self.headers, json=data)
        return response.json()

第八章:插件开发与生态扩展

8.1 Dify插件系统概述

Dify的插件系统允许开发者扩展平台的功能。插件可以:

  • 添加新的工具(Tool)
  • 添加新的模型提供商(Model Provider)
  • 添加新的数据源(Datasource)

8.2 插件开发基础

插件结构

my-plugin/
├── manifest.yaml          # 插件清单
├── provider/
│   └── my_provider.yaml   # 提供商定义
├── tools/
│   └── my_tool.yaml       # 工具定义
└── src/
    └── main.py            # 插件代码

manifest.yaml示例

name: my-custom-plugin
version: 0.1.0
description: 自定义插件示例
author: Your Name
plugins:
  tools:
    - tools/my_tool.yaml

工具定义示例

# tools/my_tool.yaml
name: my_custom_tool
description: 自定义工具描述
parameters:
  - name: input_text
    type: string
    required: true
    description: 输入文本
  - name: format
    type: string
    required: false
    description: 输出格式
    default: text

插件代码示例

# src/main.py
from typing import Any, Dict

class MyCustomTool:
    """自定义工具实现"""
    
    def execute(self, input_text: str, format: str = "text") -> Dict[str, Any]:
        """执行工具逻辑"""
        # 处理逻辑
        result = self._process(input_text)
        
        # 格式化输出
        if format == "json":
            return {"result": {"processed": result}}
        else:
            return {"result": result}
    
    def _process(self, text: str) -> str:
        """实际处理逻辑"""
        # 这里实现你的业务逻辑
        return f"处理结果: {text}"

8.3 模型提供商插件

# provider/my_model_provider.yaml
name: my-model-provider
description: 自定义模型提供商
models:
  - name: my-custom-model
    model_type: llm
    model_properties:
      context_size: 8192
      mode: chat
    parameter_definitions:
      temperature:
        type: float
        default: 0.7
        min: 0
        max: 2
      max_tokens:
        type: int
        default: 2048
        min: 1
        max: 8192

8.4 插件发布与分享

开发完成后,可以通过以下方式分享插件:

  1. GitHub仓库:将插件代码发布到GitHub
  2. Dify插件市场:提交到官方插件市场(即将推出)
  3. 私有部署:在团队内部分享

第九章:实战项目——构建企业级智能客服系统

9.1 项目概述

我们将使用Dify构建一个完整的企业级智能客服系统,具备以下功能:

  1. 多轮对话:支持上下文记忆的多轮对话
  2. 意图识别:自动识别用户意图并路由到相应处理流程
  3. 知识库问答:基于企业知识库回答常见问题
  4. 订单查询:查询订单状态和详情
  5. 工单创建:自动创建客服工单
  6. 人工转接:无法处理时转接人工客服

9.2 系统架构

用户请求
    │
    ▼
[入口Chatflow]
    │
    ├─→ [意图识别节点]
    │       │
    │       ├─ "订单问题" → [订单处理Agent]
    │       │                    ├─ 查询订单
    │       │                    └─ 订单状态说明
    │       │
    │       ├─ "产品问题" → [知识库检索] → [产品回复LLM]
    │       │
    │       ├─ "退款问题" → [退款处理流程]
    │       │                    ├─ 退款政策说明
    │       │                    └─ 提交退款申请
    │       │
    │       ├─ "投诉" → [投诉处理流程]
    │       │               ├─ 安抚话术
    │       │               └─ 创建工单
    │       │
    │       └─ "其他" → [通用问答LLM]
    │
    └─→ [输出格式化] → [结束]

9.3 详细实现步骤

步骤1:创建知识库

首先,创建产品知识库,上传产品手册、FAQ等文档:

# 产品FAQ示例

## Q: 你们的产品有哪些?
A: 我们主要提供以下产品:
- 智能手表系列:X1、X2、X3
- 无线耳机系列:S1、S2
- 智能音箱系列:H1、H2

## Q: 产品保修政策是什么?
A: 所有产品享受1年质保服务。在保修期内,非人为损坏的产品可以免费维修或更换。

## Q: 如何联系客服?
A: 您可以通过以下方式联系我们:
- 在线客服:7×24小时
- 电话:400-xxx-xxxx(工作日9:00-18:00)
- 邮箱:support@example.com

## Q: 配送范围和时间?
A: 我们支持全国配送。
- 一般地区:3-5个工作日
- 偏远地区:5-7个工作日
- 支持顺丰、京东物流

步骤2:创建入口Chatflow

系统提示词:

# 角色
你是小智,一个专业、友好的客户服务代表。

# 职责
1. 识别用户意图
2. 根据意图提供相应的帮助
3. 保持友好、专业的语气
4. 记录重要信息

# 意图分类规则
请将用户的问题分类为以下类别之一:
- order: 订单相关(查询、修改、取消订单)
- product: 产品相关(功能、规格、使用方法)
- refund: 退款相关(退款流程、退款状态)
- complaint: 投诉(服务质量、产品质量)
- general: 其他问题

# 输出格式
请以JSON格式输出:
{"intent": "类别", "summary": "问题摘要", "key_info": "关键信息"}

# 注意事项
- 如果用户情绪激动,先安抚再处理
- 如果无法确定意图,归类为general
- 用中文回复

意图识别节点配置:

节点类型:LLM
模型:gpt-3.5-turbo(意图识别不需要太强的模型)
温度:0.1(保持稳定的分类结果)
提示词:{{intent_prompt}}
输出变量:intent_result

步骤3:条件分支路由

# 代码节点:解析意图
def main(intent_result: str) -> dict:
    import json
    
    try:
        result = json.loads(intent_result)
        intent = result.get("intent", "general")
    except:
        intent = "general"
    
    return {
        "intent": intent,
        "summary": result.get("summary", ""),
        "key_info": result.get("key_info", "")
    }

条件分支配置:

条件1:{{intent}} == "order" → 订单处理分支
条件2:{{intent}} == "product" → 产品咨询分支
条件3:{{intent}} == "refund" → 退款处理分支
条件4:{{intent}} == "complaint" → 投诉处理分支
默认:→ 通用问答分支

步骤4:订单查询功能

创建订单查询Agent:

# 订单查询Agent系统提示词

你是一个订单查询助手。你的任务是帮助用户查询订单信息。

## 工作流程
1. 如果用户没有提供订单号,请友好地询问
2. 使用订单查询工具获取订单信息
3. 用清晰易懂的方式向用户说明订单状态

## 订单状态说明
- pending: 待支付
- paid: 已支付,待发货
- shipping: 运输中
- delivered: 已送达
- cancelled: 已取消
- refunded: 已退款

## 注意事项
- 保护用户隐私,不要透露完整手机号和地址
- 如果订单异常,建议用户联系人工客服

订单查询工具定义:

{
  "openapi": "3.0.0",
  "info": {"title": "订单系统API", "version": "1.0.0"},
  "servers": [{"url": "https://api.example.com"}],
  "paths": {
    "/orders/{order_id}": {
      "get": {
        "summary": "查询订单详情",
        "operationId": "getOrder",
        "parameters": [{
          "name": "order_id",
          "in": "path",
          "required": true,
          "schema": {"type": "string"},
          "description": "订单号"
        }],
        "responses": {
          "200": {
            "description": "订单信息",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "order_id": {"type": "string"},
                    "status": {"type": "string"},
                    "items": {"type": "array", "items": {"type": "object"}},
                    "total_amount": {"type": "number"},
                    "created_at": {"type": "string"},
                    "tracking_number": {"type": "string"}
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

步骤5:退款处理流程

# 退款处理节点提示词

根据用户的问题和订单信息,处理退款相关请求:

## 退款政策
1. 订单状态为"已支付"或"运输中"可以申请退款
2. 已送达的订单需要在7天内申请退款
3. 退款将在3-5个工作日内到账

## 处理规则
1. 先确认订单是否符合退款条件
2. 向用户说明退款政策
3. 如果用户确认退款,使用退款申请工具提交申请
4. 告知用户退款预计到账时间

## 订单信息
{{order_info}}

步骤6:投诉处理与工单创建

# 工单创建HTTP请求配置
POST https://api.example.com/tickets
Authorization: Bearer {{api_token}}
Content-Type: application/json

{
  "customer_id": "{{user_id}}",
  "type": "complaint",
  "priority": "high",
  "subject": "{{complaint_summary}}",
  "description": "{{user_query}}",
  "source": "ai_chatbot",
  "metadata": {
    "conversation_id": "{{conversation_id}}",
    "detected_intent": "complaint"
  }
}

投诉处理提示词:

# 投诉处理提示词

用户正在投诉。请按照以下流程处理:

## 处理步骤
1. **表达理解**:首先表示理解用户的感受
2. **收集信息**:了解具体问题和期望的解决方案
3. **记录投诉**:创建工单记录投诉内容
4. **承诺跟进**:告知用户会尽快处理

## 话术参考
- "非常抱歉给您带来了不好的体验..."
- "我完全理解您的心情..."
- "我会立即为您记录这个问题..."
- "我们的专业团队会在24小时内联系您..."

## 注意事项
- 不要推卸责任
- 不要承诺无法兑现的解决方案
- 保持冷静和专业

步骤7:对话记忆管理

在Chatflow中实现上下文记忆:

# 记忆管理节点

## 对话历史
{{#conversation_history#}}

## 用户信息
- 用户ID:{{user_id}}
- 会员等级:{{member_level}}

## 当前会话摘要
{{session_summary}}

## 指令
1. 参考对话历史,保持上下文连贯
2. 根据用户等级提供差异化服务
3. 如果用户之前提过的问题,不要重复询问

9.4 部署与上线

环境变量配置:

# .env
DIFY_API_KEY=app-your-api-key
DIFY_BASE_URL=https://your-dify-instance.com/v1
ORDER_API_KEY=your-order-api-key
TICKET_API_KEY=your-ticket-api-key

接入渠道集成:

# 接入微信公众号
from flask import Flask, request
import xml.etree.ElementTree as ET

app = Flask(__name__)
dify_client = DifyClient(api_key="your-api-key")

@app.route('/wechat', methods=['POST'])
def wechat():
    xml_data = request.data
    root = ET.fromstring(xml_data)
    
    user_id = root.find('FromUserName').text
    content = root.find('Content').text
    
    # 调用Dify API
    result = dify_client.chat(content, user=user_id)
    reply = result.get('answer', '抱歉,暂时无法处理您的请求。')
    
    # 返回微信消息格式
    return f"""
    <xml>
        <ToUserName><![CDATA[{user_id}]]></ToUserName>
        <FromUserName><![CDATA[gh_xxx]]></FromUserName>
        <CreateTime>{int(time.time())}</CreateTime>
        <MsgType><![CDATA[text]]></MsgType>
        <Content><![CDATA[{reply}]]></Content>
    </xml>
    """

9.5 测试与优化

测试用例:

test_cases = [
    {
        "name": "订单查询",
        "input": "我的订单 ORD-20240115-001 到哪了?",
        "expected_intent": "order",
        "should_contain": "物流"
    },
    {
        "name": "退款申请",
        "input": "我想退款,订单号是 ORD-20240110-002",
        "expected_intent": "refund",
        "should_contain": "退款"
    },
    {
        "name": "产品咨询",
        "input": "X3手表的电池能用多久?",
        "expected_intent": "product",
        "should_contain": "电池"
    },
    {
        "name": "投诉",
        "input": "你们的客服态度太差了,我要投诉!",
        "expected_intent": "complaint",
        "should_contain": "抱歉"
    }
]

for test in test_cases:
    result = dify_client.chat(test["input"])
    print(f"测试: {test['name']}")
    print(f"  输入: {test['input']}")
    print(f"  输出: {result['answer'][:100]}...")
    print(f"  通过: {test['should_contain'] in result['answer']}")
    print()

性能优化建议:

  1. 模型选择优化

    • 意图识别使用轻量模型(gpt-3.5-turbo)
    • 复杂问答使用强力模型(gpt-4)
    • 根据实际效果调整
  2. 知识库优化

    • 定期更新知识库内容
    • 优化分段策略提高检索精度
    • 添加更多高质量的FAQ
  3. 缓存策略

    • 对常见问题的回答进行缓存
    • 缓存订单查询结果(短期)
  4. 监控指标

    • 意图识别准确率
    • 用户满意度评分
    • 转人工率
    • 平均响应时间

第十章:高级技巧与最佳实践

10.1 提示词工程

系统提示词模板:

# 角色定义
你是[角色名称],[角色描述]。

# 能力范围
1. [能力1]
2. [能力2]
3. [能力3]

# 行为规则
- [规则1]
- [规则2]
- [规则3]

# 输出格式
[定义期望的输出格式]

# 示例
用户: [示例输入]
助手: [示例输出]

10.2 工作流设计原则

  1. 单一职责:每个节点只做一件事
  2. 错误处理:每个关键节点都要有错误处理
  3. 日志记录:在关键节点记录日志
  4. 幂等设计:相同输入应产生相同输出
  5. 超时控制:为外部调用设置合理的超时时间

10.3 性能优化

# 并行执行多个知识库检索
from concurrent.futures import ThreadPoolExecutor

def search_multiple_knowledge_bases(query: str, kb_ids: list) -> list:
    """并行搜索多个知识库"""
    with ThreadPoolExecutor(max_workers=3) as executor:
        futures = [
            executor.submit(search_knowledge_base, kb_id, query)
            for kb_id in kb_ids
        ]
        results = []
        for future in futures:
            results.extend(future.result())
    
    # 去重和排序
    results = deduplicate_results(results)
    results.sort(key=lambda x: x["score"], reverse=True)
    
    return results[:5]  # 返回Top5

10.4 安全最佳实践

  1. 输入验证:对所有用户输入进行验证和清理
  2. 权限控制:不同用户组设置不同的访问权限
  3. API密钥管理:定期轮换API密钥
  4. 日志脱敏:敏感信息在日志中脱敏处理
  5. 速率限制:防止API被滥用

10.5 监控与告警

# 监控指标收集
class DifyMonitor:
    """Dify应用监控"""
    
    def __init__(self):
        self.metrics = {
            "request_count": 0,
            "error_count": 0,
            "avg_response_time": 0,
            "intent_distribution": {},
            "satisfaction_rate": 0
        }
    
    def record_request(self, intent: str, response_time: float, 
                       success: bool, satisfaction: float = None):
        """记录请求指标"""
        self.metrics["request_count"] += 1
        
        if not success:
            self.metrics["error_count"] += 1
        
        # 更新平均响应时间
        n = self.metrics["request_count"]
        self.metrics["avg_response_time"] = (
            (self.metrics["avg_response_time"] * (n-1) + response_time) / n
        )
        
        # 更新意图分布
        self.metrics["intent_distribution"][intent] = \
            self.metrics["intent_distribution"].get(intent, 0) + 1
        
        # 检查告警条件
        self._check_alerts()
    
    def _check_alerts(self):
        """检查是否需要告警"""
        error_rate = self.metrics["error_count"] / self.metrics["request_count"]
        
        if error_rate > 0.1:  # 错误率超过10%
            self._send_alert(f"警告:错误率过高 ({error_rate:.1%})")
        
        if self.metrics["avg_response_time"] > 5:  # 响应时间超过5秒
            self._send_alert(f"警告:响应时间过长 ({self.metrics['avg_response_time']:.1f}秒)")
    
    def _send_alert(self, message: str):
        """发送告警"""
        print(f"🚨 告警: {message}")
        # 实际实现中可以发送到钉钉、飞书等

总结

本教程系统性地讲解了Dify AI应用开发平台的核心功能和开发技巧:

  1. 平台架构:理解Dify的分层架构和核心概念
  2. 安装部署:Docker Compose部署和云服务使用
  3. Chatflow设计:可视化对话流编排和变量传递
  4. Workflow构建:复杂业务逻辑的自动化编排
  5. 知识库管理:文档分段、索引和检索优化
  6. Agent集成:工具配置和推理模式选择
  7. API集成:RESTful API和SDK的使用
  8. 插件开发:平台功能扩展
  9. 实战项目:企业级智能客服系统的完整实现

Dify极大地降低了AI应用的开发门槛,让开发者可以专注于业务逻辑,而不是底层技术细节。随着Dify生态的不断壮大,它将成为AI应用开发的重要平台。

建议读者在学习本教程后,选择一个具体的业务场景,动手构建一个完整的AI应用,在实践中加深理解。


本教程内容为原创撰写,如有疑问欢迎交流讨论。

内容声明

本文内容为AI技术学习教程,仅供学习参考。如涉及技术问题,欢迎通过 xurj005@163.com 与我们交流。

目录