Dify 工作流编排
基于 Dify 平台构建的 AI 工作流,将意图识别、参数提取、工具调用和结果拼接串联成可控的 AI 应用链路。
我的理解
Dify 工作流的价值是让 AI 问数从一次性 Demo 变成可控的业务链路。通过意图识别、参数提取、指标标准化、权限校验、数据服务调用和结果协议拼接,把模型能力放进企业级工程框架里。核心是把业务判断从提示词里抽出来,放进工程系统。
很多人用 Dify 只用到“聊天+知识库”这一层,以为接了 RAG 就算做完 AI 应用。但企业级 AI 问数不能靠 RAG 兜底——RAG 只能回答“文档里写了什么”,回答不了“上个月某项目收缴率是多少”。后者要走意图识别→参数提取→指标标准化→权限校验→数据服务→结果拼接的完整工作流,每一步都是工程节点,不是提示词能覆盖的。
工作流的六个节点
我把 Dify 工作流拆成六个工程节点,每个节点解决一个不确定性来源。节点之间通过结构化数据传递,不是把上一步的自然语言输出直接塞给下一步。
- 意图识别:判断用户想问什么(查数、对比、趋势、明细)
- 参数提取:从自然语言里抽出指标、时间、组织、对象
- 指标标准化:把口语化指标名映射到语义层的 targetId
- 权限校验:检查用户是否有权查询该组织范围的数据
- 数据服务调用:走服务层查询,不直连数据库
- 结果协议拼接:把结构化结果转成可解释的自然语言回答
为什么把业务判断从提示词里抽出来
提示词里写业务规则是最脆弱的方案——改一个字就可能让模型行为全变,而且无法回归测试。把业务判断抽成工程节点后,每个节点都能单独测试、单独监控、单独回滚。模型只负责语言理解,业务规则由工程系统保证。
6工作流节点
0提示词业务规则
1统一权限入口
100%节点可单独测试
- 用户问“上个月某项目收缴率多少”,进入意图识别节点。
- 意图识别判定为“查数”类,进入参数提取节点。
- 参数提取抽出指标=收缴率、时间=上月、对象=某项目,进入指标标准化节点。
- 指标标准化把“收缴率”映射到 targetId=metric_payment_rate,进入权限校验节点。
- 权限校验检查用户是否有权看该项目数据,通过后进入数据服务调用节点。
- 数据服务返回结构化结果,结果协议拼接节点转成“上月某项目收缴率为 92.7%”回答用户。
type WorkflowNode<TInput, TOutput> = {
id: string;
type: 'intent' | 'extract' | 'normalize' | 'authorize' | 'query' | 'format';
input: TInput;
output: TOutput;
status: 'pending' | 'running' | 'success' | 'failed' | 'skipped';
error?: { code: string; message: string };
duration?: number; // 节点耗时(监控用)
};
// 每个节点都是可独立测试的纯函数
type IntentNode = WorkflowNode<
{ question: string },
{ intent: 'query' | 'compare' | 'trend' | 'detail' }
>;| 维度 | 提示词驱动 | 工作流驱动 |
|---|---|---|
| 业务规则 | 写在提示词里 | 抽成工程节点 |
| 可测试性 | 只能整体跑 | 每节点单独测 |
| 可监控性 | 只看到最终输出 | 每节点有状态和耗时 |
| 可回滚性 | 改提示词全量影响 | 改单节点不影响其他 |
| 权限控制 | 提示词里写规则 | 独立权限校验节点 |
Dify 工作流的核心不是把 Dify 用熟,而是把业务判断从提示词里赶出去。提示词负责语言,工程系统负责业务,两者混在一起就会失控。