很多人第一次用 Dify 做知识库问答,路径很顺:上传文档,建一个聊天应用,接入模型,然后问几个问题,答案看起来还不错。但一到真实交付就会发现,客户的问题更杂,资料会更新,答案有时太长、有时跑偏,排查时也说不清到底是文档、检索、提示词还是模型的问题。
这时就不能只把 Dify 当成“上传文档然后聊天”的工具,而要把它当成一套可维护的工作流。工作流能不能稳定,关键在变量设计:用户输入是什么变量,检索结果是什么变量,提示词怎么引用变量,答案输出怎么命名,质检又看哪些变量。本文就用一个知识库问答场景,拆一套适合小团队交付的 Dify 工作流变量设计方法。
如果你刚开始搭 Dify 知识库,可以先看 Dify 知识库怎么搭?从文档切分、召回测试到 RAG 问答上线;如果你更关心自动化交付,可以把本文和 AI智能体与自动化专题、AI工具评测专题 放在一起看。
为什么Dify项目要先设计变量
变量的作用不是让流程显得高级,而是让每一步有名字、有边界、可复用、可排查。一个没有变量意识的知识库问答应用,常见问题有四类:
- 输入混乱:用户问题、场景、语言、历史对话都塞在一起,后面节点不好判断。
- 检索不可控:不知道模型到底看到了哪些资料,也不知道 Top K、阈值和元数据过滤是否合适。
- 提示词难维护:每次改提示词都牵一发而动全身,客户要求新增场景时容易重写。
- 质检缺失:答案错了只会怪模型,没有记录问题、检索片段、最终答案和失败原因。
Dify 官方文档中,知识检索节点会根据查询变量去检索知识库,并把检索结果作为下游节点可用的上下文;变量聚合、迭代、调试等节点也都围绕“数据在流程中如何流动”展开。实际交付时,我们不一定把所有节点都用上,但必须先把关键变量想清楚。
一条可交付的知识库问答链路
一个基础但足够实用的 Dify 知识库问答工作流,可以拆成五段:
- 输入:接收用户问题、场景、语言、用户身份等信息。
- 检索:根据问题从知识库中取回相关片段。
- 组装提示词:把用户问题、检索结果、回答规则合成模型可理解的上下文。
- 生成答案:让模型基于检索结果输出回答。
- 质检与兜底:判断答案是否引用资料、是否覆盖问题、是否需要转人工。
不要小看这五段。很多项目之所以不稳定,是因为输入和检索混在一起,检索和提示词混在一起,答案和质检又混在一起。拆开之后,每一步都能单独调整。
第一组变量:输入变量,决定问题怎么被理解
输入变量建议至少保留四个:
question:用户原始问题,尽量不要在前面节点过度改写。scene:问题场景,比如售前咨询、售后处理、内部制度、产品使用。chat_history:必要的对话历史,不要无限塞入,保留最近几轮即可。language:输出语言或地区表达,比如zh-CN、en。
如果是给客户交付,不建议只有一个“用户问题”输入。因为客户后来一定会问:能不能区分售前和售后?能不能让内部员工和外部客户看到不同答案?能不能输出不同语气?这些需求本质上都要靠输入变量承接。
例如一家培训机构的问答助手,可以把 scene 设为“课程咨询”“报名流程”“退费规则”“内部教务”。同样的问题“怎么申请”,在不同场景下应该走不同知识库、不同回答边界。
第二组变量:检索变量,决定模型看到什么资料
知识库问答的质量,很大程度取决于检索结果。Dify 的知识检索节点通常会根据查询文本变量去检索知识库,并输出检索结果变量。交付时建议把检索相关变量拆清楚:
retrieval_query:真正用于检索的查询,可以等于用户问题,也可以经过轻量改写。top_k:返回多少条候选片段,过小容易漏,过大容易噪音多。score_threshold:最低相关性阈值,资料质量高时可以更严格。metadata_filter:按产品线、年份、部门、客户类型等字段过滤。retrieval_result:检索节点输出的片段数组,用于后续上下文。
如果客户的知识库很大,元数据过滤尤其重要。比如同一个“报销流程”,销售部门、项目部门和管理层可能看到不同制度;同一个“产品价格”,不同地区也可能不同。把这些差异提前设计成变量,比后期在提示词里硬写规则更稳。
这个部分可以结合 Dify 官方的 Knowledge Retrieval 文档 理解:检索节点不是简单“搜一下”,而是要配置查询、知识库、检索设置和输出变量。项目交付时,最好把这些配置写进交付说明,方便客户后续维护。
第三组变量:提示词变量,决定答案如何组织
提示词不要写成一整坨。更好的方式是把不同职责拆成变量或模板片段:
system_rule:角色、回答边界、不得编造、需要基于资料回答。context:来自知识检索的资料片段。question:用户问题。answer_format:答案格式,比如步骤、表格、要点、引用说明。fallback_rule:资料不足时怎么回答,什么时候转人工。
一个可维护的提示词结构可以这样写:
你是企业知识库助手,请只基于给定资料回答。
如果资料不足,请说明“当前资料不足以确认”,并给出需要补充的资料。
用户问题:
{{question}}
相关资料:
{{context}}
回答要求:
{{answer_format}}
兜底规则:
{{fallback_rule}}
这样做的好处是,每次客户要改“回答语气”或“输出格式”,你不必重写整条提示词,只需要替换对应变量。团队协作时,也更容易分清到底是谁改了什么。
第四组变量:输出变量,决定结果能不能被复用
很多 Dify 应用只输出一段自然语言答案,这对演示够用,对交付不够。建议至少拆出三个输出:
answer:给用户看的最终答案。confidence_note:答案可靠性说明,比如“基于3条资料片段”“资料不足”。handoff_needed:是否建议转人工,值可以是 true/false。
如果后面要接 n8n、飞书、企业微信或表格系统,这些结构化输出会非常有用。比如 handoff_needed=true 时自动发给人工客服;confidence_note 标记资料不足时,自动记录到知识库补充清单。
这也是为什么我在 Dify 和 n8n 怎么一起用?给小团队交付 AI 自动化的组合方案 里强调,Dify 负责理解、生成和判断,n8n 负责表单、消息和任务流转。变量设计清楚,两边才能接得稳。
第五组变量:质检变量,决定项目能不能长期维护
上线前一定要做测试问题集。不要只问三五个最简单的问题,而要覆盖:
- 标准问题:资料里明确存在答案。
- 近似问题:用户换一种说法提问。
- 跨文档问题:答案需要综合多个片段。
- 资料不足问题:知识库里没有答案,测试是否会编造。
- 敏感边界问题:价格、合同、法律、医疗、财务等需要谨慎回答的场景。
对应的质检变量可以这样记录:
test_question:测试问题。expected_behavior:期望行为,不一定是标准答案,也可以是“应转人工”。retrieved_docs:实际命中的资料。final_answer:最终答案。issue_type:问题类型,比如未命中、答非所问、资料过期、表达不清。
这套记录会让交付从“感觉还可以”变成“可以复盘”。后续客户新增资料、调整业务规则、换模型,都能通过同一组测试问题验证效果。
一个小团队可直接复用的变量命名表
| 阶段 | 建议变量 | 用途 |
|---|---|---|
| 输入 | question, scene, language |
保留用户问题、业务场景和输出语言 |
| 检索 | retrieval_query, top_k, retrieval_result |
控制知识库检索范围和返回内容 |
| 提示词 | context, answer_format, fallback_rule |
把资料、格式和兜底规则分开维护 |
| 输出 | answer, confidence_note, handoff_needed |
方便前台展示和后续自动化处理 |
| 质检 | test_question, expected_behavior, issue_type |
记录测试结果,持续优化知识库 |
老达建议:变量少一点,但每个都要有用
变量不是越多越好。小团队做 Dify 项目,最怕把流程做成一张看不懂的大网。我的建议是先用最少变量跑通闭环:问题、场景、检索结果、上下文、答案、是否转人工、测试记录。等客户真的有分支、权限、渠道、多语言需求,再逐步增加。
如果你准备把 Dify 项目做成可收费服务,可以把变量表、测试问题集、知识库更新规则一起交付给客户。这比单纯交一个聊天入口更专业,也更容易形成维护费。相关路线可以继续看 AI资料整理副业怎么做?用Dify知识库给小团队交付问答助手 和 n8n表单获客自动化怎么搭?从线索收集到AI分拣和人工审核。