第五章:工作流编排

5.1 工作流概述

5.1.1 什么是工作流

工作流(Workflow)是 Dify 平台中用于处理复杂任务的核心功能。它通过将复杂的任务分解为较小的步骤(节点),降低系统复杂度,减少对提示词技术和模型推理能力的依赖。

工作流的核心优势:

  • 提高性能:面向复杂任务的性能提升
  • 可解释性:每个步骤清晰可见
  • 稳定性:减少模型不确定性的影响
  • 容错性:支持错误处理和重试

5.1.2 工作流类型

Dify 工作流分为两种类型:

Chatflow(对话流):

  • 面向对话类情景
  • 支持多轮对话
  • 包含对话历史(Memory)
  • 适用场景:客户服务、语义搜索、多步逻辑对话

Workflow(工作流):

  • 面向自动化和批处理
  • 单次执行完成
  • 无对话历史
  • 适用场景:翻译、数据分析、内容生成、邮件自动化

5.1.3 Chatflow vs Workflow 对比

特性 Chatflow Workflow
交互方式 多轮对话 单次执行
触发方式 用户消息 API/定时/Webhook
对话历史 支持 不支持
开始节点 开始 开始
输出节点 Answer 结束
适用场景 聊天、问答 批处理、自动化

5.1.4 常见应用案例

客户服务: 通过 LLM 理解客户查询的上下文和意图,实时生成准确回答,减轻支持团队工作负担。

内容生成: 根据大纲或主题,利用 LLM 广泛的知识库生成博客文章、产品描述、营销材料等内容。

任务自动化: 与 Trello、Slack、飞书等系统集成,通过自然语言创建任务、更新状态、分配优先级。

数据分析和报告: 分析大型知识库,识别趋势和模式,生成分析报告和摘要。

邮件自动化: 根据关键要点起草邮件、社交媒体更新等,确保内容清晰专业。

5.2 创建工作流

5.2.1 创建步骤

步骤一:进入工作室 登录 Dify,点击”创建空白应用”。

步骤二:选择工作流类型

  • 选择 “Chatflow” 或 “Workflow”
  • 填写应用名称和描述

步骤三:进入编排界面 创建后自动进入画布编辑界面。

5.2.2 画布界面介绍

画布区域:

  • 节点拖放和连接区域
  • 支持缩放和平移
  • 网格对齐辅助

左侧节点面板:

  • 所有可用节点类型
  • 拖拽添加到画布

右侧配置面板:

  • 选中节点的配置项
  • 参数设置和变量绑定

顶部工具栏:

  • 保存、发布、运行
  • 撤销、重做
  • 视图控制

5.2.3 基本操作

添加节点:

  1. 从左侧面板拖拽节点到画布
  2. 或点击节点间的 “+” 按钮

连接节点:

  1. 从源节点的输出端点拖拽
  2. 连接到目标节点的输入端点

配置节点:

  1. 点击选中节点
  2. 在右侧面板进行配置

删除节点:

  1. 选中节点
  2. 按 Delete 键或右键删除

5.3 核心节点类型

5.3.1 开始节点(Start)

开始节点是工作流的入口点,用于定义输入参数。

配置项:

输入变量:
  - 名称: user_input
    类型: 字符串
    必填: 是
    描述: 用户输入的内容
    
  - 名称: language
    类型: 选择器
    选项:
      - 中文
      - 英文
    默认值: 中文

Chatflow 特有: 在 Chatflow 中,开始节点自动包含系统变量:

  • sys.query:用户当前输入
  • sys.conversation_id:会话 ID
  • sys.user_id:用户 ID

5.3.2 LLM 节点

LLM 节点是工作流的核心,用于调用大语言模型处理文本。

配置项:

模型: gpt-4
上下文:
  - 系统提示词: |
      你是一个专业的翻译助手,请将用户输入的内容翻译成目标语言。
  - 用户消息: |
      请将以下内容翻译成{{language}}:
      {{user_input}}

参数:
  temperature: 0.3
  max_tokens: 2000

输出:

  • text:模型生成的文本
  • usage:Token 消耗信息

高级配置:

  • 记忆功能:在 Chatflow 中保存对话历史
  • 视觉能力:支持图像输入(多模态模型)
  • 结构化输出:指定 JSON Schema 格式

5.3.3 知识检索节点

用于从知识库检索相关内容。

配置项:

知识库: 
  - 产品文档知识库
  - FAQ 知识库
查询内容: {{user_input}}
检索参数:
  Top K: 5
  Score 阈值: 0.6
  重排序: 启用

输出:

  • result:检索到的文档分段列表
  • 每个分段包含:content、score、source

5.3.4 条件分支节点(IF/ELSE)

根据条件执行不同的分支路径。

配置示例:

条件:
  - IF: {{sentiment}} == "positive"
    THEN: 分支 A
  - ELIF: {{sentiment}} == "negative"
    THEN: 分支 B
  - ELSE:
    THEN: 分支 C

支持的操作符:

  • 相等:==
  • 不相等:!=
  • 包含:contains
  • 不包含:not contains
  • 开头是:starts with
  • 结尾是:ends with
  • 为空:is empty
  • 不为空:is not empty
  • 数值比较:>, <, >=, <=

5.3.5 代码执行节点

运行 Python 或 JavaScript 代码进行数据处理。

Python 示例:

def main(inputs: dict) -> dict:
    text = inputs["text"]
    
    # 处理文本
    words = text.split()
    word_count = len(words)
    
    return {
        "word_count": word_count,
        "processed_text": text.upper()
    }

JavaScript 示例:

function main(inputs) {
    const text = inputs.text;
    
    const wordCount = text.split(' ').length;
    
    return {
        word_count: wordCount,
        processed_text: text.toUpperCase()
    };
}

限制:

  • 执行时间限制
  • 内存限制
  • 不能访问网络
  • 不能访问文件系统

5.3.6 HTTP 请求节点

调用外部 API 服务。

配置示例:

请求方法: POST
URL: https://api.example.com/analyze
请求头:
  Content-Type: application/json
  Authorization: Bearer {{api_key}}
请求体:
  {
    "text": "{{user_input}}",
    "language": "{{language}}"
  }
超时: 30 秒

输出:

  • status_code:HTTP 状态码
  • body:响应体内容
  • headers:响应头

5.3.7 模板转换节点

使用 Jinja2 模板语法格式化文本。

模板示例:

# 分析报告

## 基本信息
- 输入内容:{{ input_text }}
- 分析时间:{{ current_time }}

## 分析结果
{% for item in results %}
- {{ item.title }}: {{ item.value }}
{% endfor %}

## 总结
{{ summary }}

5.3.8 变量聚合节点

合并多个分支的变量。

使用场景:

  • 并行处理后合并结果
  • 多个条件分支后统一输出

配置:

输入变量:
  - 分支A.result
  - 分支B.result
输出变量: merged_result
聚合方式: 数组

5.3.9 迭代节点

对数组进行循环处理。

配置示例:

输入数组: {{document_list}}
迭代变量: current_doc
并行执行: 是
最大并行数: 5

迭代内部: 可以添加任意节点处理每个元素。

输出:

  • 所有迭代结果组成的数组

5.3.10 问题分类节点

基于 LLM 对用户问题进行分类。

配置示例:

分类定义:
  - 名称: 产品咨询
    描述: 关于产品功能、价格、规格的问题
    关键词: 功能, 价格, 怎么用
    
  - 名称: 技术支持
    描述: 使用过程中遇到的问题
    关键词: 报错, 无法使用, 故障
    
  - 名称: 投诉建议
    描述: 对产品或服务的投诉和建议
    关键词: 投诉, 建议, 不满意

输出:

  • class_name:分类名称
  • 可连接到对应的处理分支

5.3.11 参数提取节点

从文本中提取结构化信息。

配置示例:

提取参数:
  - 名称: customer_name
    类型: 字符串
    描述: 客户姓名
    必填: 是
    
  - 名称: phone_number
    类型: 字符串
    描述: 联系电话
    必填: 否
    
  - 名称: order_id
    类型: 字符串
    描述: 订单号
    必填: 否

5.3.12 Answer 节点(Chatflow)

在 Chatflow 中用于输出回答。

配置:

回答内容: |
  {{ llm_response }}
  
  ---
  来源:{{ sources }}

特点:

  • 支持流式输出
  • 可在工作流中多次使用
  • 每次执行都会输出内容

5.3.13 结束节点(Workflow)

在 Workflow 中标记流程结束并定义输出。

配置:

输出变量:
  - 名称: result
    类型: 字符串
    值: {{final_output}}
    
  - 名称: metadata
    类型: 对象
    值:
      word_count: {{word_count}}
      processing_time: {{time}}

5.4 高级功能

5.4.1 变量系统

变量类型:

  • 字符串(String)
  • 数字(Number)
  • 布尔值(Boolean)
  • 数组(Array)
  • 对象(Object)
  • 文件(File)

系统变量:

sys.query: 用户当前输入
sys.conversation_id: 会话 ID
sys.user_id: 用户 ID
sys.files: 上传的文件列表

环境变量:

  • 在应用设置中定义
  • 工作流中通过 {{env.变量名}} 引用

5.4.2 对话记忆(Memory)

在 Chatflow 中使用对话记忆:

配置:

记忆窗口:
  类型: 消息数量
  数量: 10
  
# 或
  类型: Token 数量
  数量: 2000

使用方式: 在 LLM 节点中启用”使用对话历史”选项。

5.4.3 错误处理

默认错误处理:

  • 节点失败时整个工作流停止
  • 返回错误信息

自定义错误处理:

错误处理:
  策略: 重试
  重试次数: 3
  重试间隔: 5 秒
  
# 或
  策略: 失败分支
  失败分支: error_handler

5.4.4 并行执行

通过添加多个分支实现并行处理:

        ┌── 节点 A ──┐
开始 ──┼── 节点 B ──┼── 变量聚合 ── 结束
        └── 节点 C ──┘

优势:

  • 减少总执行时间
  • 提高处理效率

5.4.5 触发器

Workflow 触发方式:

触发类型 说明 配置
API 调用 通过 API 触发 发布后获取 API 端点
定时触发 按计划执行 Cron 表达式
Webhook HTTP 回调触发 配置 Webhook URL
插件触发 通过插件触发 安装触发器插件

定时触发配置示例:

触发器: 定时
Cron 表达式: 0 9 * * 1  # 每周一早上 9 点
时区: Asia/Shanghai

5.5 调试与预览

5.5.1 单步调试

调试步骤:

  1. 点击节点右上角的运行按钮
  2. 输入测试数据
  3. 查看节点输出

调试面板信息:

  • 输入变量
  • 输出结果
  • 执行耗时
  • Token 消耗

5.5.2 全流程预览

预览步骤:

  1. 点击”预览”按钮
  2. 填写开始节点的输入
  3. 运行整个工作流
  4. 查看每个节点的执行情况

5.5.3 运行日志

日志信息:

  • 执行时间线
  • 每个节点的输入输出
  • 错误信息和堆栈
  • Token 消耗统计

5.5.4 常见调试问题

问题一:变量引用错误

错误:变量 {{user_input}} 未定义
解决:检查变量名拼写,确认上游节点已输出该变量

问题二:条件判断不生效

错误:条件分支总是走同一路径
解决:检查条件表达式,注意变量类型匹配

问题三:循环超时

错误:迭代执行超时
解决:减少迭代次数,或优化单次迭代的处理逻辑

5.6 发布与调用

5.6.1 发布工作流

发布步骤:

  1. 完成调试验证
  2. 点击”发布”按钮
  3. 填写版本说明
  4. 确认发布

5.6.2 API 调用

Workflow API 示例:

curl -X POST 'https://api.dify.ai/v1/workflows/run' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "inputs": {
      "user_input": "需要处理的文本",
      "language": "中文"
    },
    "user": "user-123"
  }'

响应示例:

{
  "workflow_run_id": "xxx",
  "task_id": "xxx",
  "data": {
    "outputs": {
      "result": "处理后的结果"
    },
    "status": "succeeded"
  }
}

5.6.3 流式输出

对于 Chatflow,支持流式输出:

curl -X POST 'https://api.dify.ai/v1/chat-messages' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "inputs": {},
    "query": "用户问题",
    "response_mode": "streaming",
    "user": "user-123"
  }'

5.7 实战案例

5.7.1 智能客服工作流

需求:根据用户问题类型,路由到不同的处理流程。

工作流设计:

开始
  ↓
问题分类
  ├── 产品咨询 → 知识检索 → LLM 回答
  ├── 技术支持 → 知识检索 → LLM 回答 → 创建工单
  └── 其他 → LLM 通用回答
  ↓
Answer

5.7.2 文档翻译工作流

需求:翻译长文档,保持格式。

工作流设计:

开始(文档输入)
  ↓
文档解析(代码节点)
  ↓
分段处理(迭代节点)
  ↓
  └── LLM 翻译
  ↓
结果合并(代码节点)
  ↓
结束(输出翻译文档)

5.7.3 数据分析报告工作流

需求:分析数据并生成报告。

工作流设计:

开始(数据输入)
  ↓
数据处理(代码节点)
  ↓
┌─────────┬─────────┐
趋势分析   异常检测   统计汇总
└─────────┴─────────┘
  ↓
变量聚合
  ↓
LLM 生成报告
  ↓
结束(输出报告)

5.8 最佳实践

5.8.1 设计原则

模块化设计:

  • 每个节点职责单一
  • 便于复用和维护

错误处理:

  • 添加必要的错误处理分支
  • 提供有意义的错误信息

性能优化:

  • 尽可能并行执行
  • 避免不必要的 LLM 调用

5.8.2 命名规范

节点命名:
  - 使用描述性名称
  - 包含节点类型前缀
  - 示例: "LLM_翻译处理", "条件_语言判断"

变量命名:
  - 使用小写下划线命名法
  - 示例: user_input, translation_result

5.8.3 文档和注释

  • 为复杂节点添加描述
  • 记录工作流的整体逻辑
  • 标注关键配置的原因

5.9 本章小结

通过本章的学习,你应该掌握:

  1. 工作流概念:理解 Chatflow 和 Workflow 的区别
  2. 节点类型:熟悉各类核心节点的功能和配置
  3. 流程编排:掌握工作流的设计和实现方法
  4. 调试技巧:学会调试和优化工作流
  5. 实战应用:能够设计和实现实际业务场景的工作流

5.10 思考与练习

  1. 实践练习:
    • 创建一个多语言翻译工作流
    • 实现一个智能客服分流系统
    • 设计一个数据处理管道
  2. 思考题:
    • 什么场景适合使用 Chatflow?什么场景适合 Workflow?
    • 如何设计高效的错误处理机制?
    • 并行执行和串行执行各有什么优缺点?

下一章预告:第六章将深入介绍 Agent 智能助手的开发,包括推理模式、工具配置和高级技巧。