1. 先从整体上搞清楚Dify工作流解决的是什么问题1.1 没有工作流时一个应用有多难伺候我最早接触Dify的时候其实不是奔着“工作流”去的就是想快速搞一个能回答问题的AI助手。当时最简单的做法就是填一个提示词把模型接进来看起来能聊了。但聊了两轮就发现问题用户问的是“我们公司内部报销流程是什么”我的助手完全不认账因为它根本没有知识来源也不懂该先判断什么。你可能会说那直接把资料塞进Prompt里不就行了小数据量可以但一旦资料上千份、用户意图分散这种做法就完全失控。更麻烦的是真实业务场景里往往不是“一问一答”这么简单而是要串联多个步骤先识别问题属于哪一类再决定走哪个知识库可能还要查一下外部系统里的数据最后才让大模型生成答案。这些步骤如果全靠代码写逻辑很繁琐如果全靠人肉在对话里做又累又容易出错。Dify工作流解决的就是这个问题。它把AI应用的搭建变成了可视化画布你可以在上面拖各种节点然后把它们按照业务逻辑连起来。每个节点负责一个明确动作比如调用大模型、查知识库、跑一段代码、发一个HTTP请求数据在节点之间流转最终拼成一个完整的智能服务。新手用它不用一开始就啃复杂的后端代码但又能理解AI应用背后的骨架。1.2 工作流的核心逻辑节点、连线、数据流想用好Dify工作流先记住三个词节点、连线、变量。节点就是画布上的功能块。比如开始节点负责接收用户输入LLM节点负责调用大模型生成文本知识检索节点负责从已上传的知识库里找相关内容条件分支节点负责判断下一步走哪条路代码节点可以跑Python或JavaScriptHTTP请求节点可以去调用第三方接口。每个节点都像一个工位干一件事。连线决定工位之间的顺序。从开始节点出发A节点处理完结果传给B节点B再传给C这就是工作流。连线不是随便连的它代表的是数据流动方向也代表逻辑先后关系。你可以做串行流程也可以做并行流程还可以用条件分支让流程长出多个岔路。变量则是工位之间传递的“单据”。节点的输入输出都通过变量引用比如开始节点里有一个用户问题变量sys.query你在LLM节点的Prompt设置里用{{#sys.query#}}引用它就会被替换成用户真正说的话。理解了这个后面所有配置你都不会懵。Dify工作流有三种主要形态工作流Workflow、聊天流Chatflow和Agent。工作流适合后端处理类的自动化流程比如文档生成、数据处理不直接面向多轮对话聊天流适合做聊天机器人天然支持多轮对话也是新手最常见的入口Agent则偏向自主决策让模型自己决定调用哪些工具。新手可以从聊天流切入先别碰太复杂的Agent编排。1.3 新手最容易产生的误解第一个误解是“工作流就是可视化编程我又得学一门新语言”。其实工作流比编程友好得多你不需要掌握完整代码能力只需要把业务逻辑拆成节点即可。即使要写代码也只是在代码节点里写一小段函数体不是独立项目。第二个误解是“工作流等于把Prompt写得更长”。恰恰相反工作流的优势是拆分。把“判断意图”“检索资料”“生成回答”分别做成节点每个节点只关注一个小任务反而比一段超长的Prompt更可控、更容易调试。第三个误解是“连线越多越厉害”。我见过新手拖了二十个节点画布密密麻麻最后根本不知道哪个变量是从哪来的。好的工作流应该尽量简单能用两三个节点解决就不要拖到十个。后面排错时你会发现结构清晰比功能堆砌重要一百倍。2. 环境准备与第一个工作流的骨架搭建2.1 本地部署和云端的选型建议Dify的部署方式主要分两种官方云端版和自托管部署。新手选云端版的好处是不用操心服务器、数据库打开注册完就能用适合先体验功能。但如果你有数据隐私要求或者想深度定制系统就需要自己部署。自托管最常见的方式是用Docker Compose安装准备好一台2核4G以上的服务器装好Docker和Docker Compose一条命令就能把整个服务跑起来。我自己的建议是如果你是零基础先用云端版把教程跑通再考虑自托管。因为新手一上来就折腾部署很容易被环境问题劝退反而忽略了工作流本身的学习。等你在云端至少建过一个能跑的流程再去本地部署你的目标感会清晰很多。不管哪种方式部署完成后的界面都有几个核心入口应用列表、知识库、工作流画布、日志与标注。后期监控工作流运行情况主要看“日志”和“监控”两个页面。2.2 创建工作流从“聊天流”和“工作流”选哪个说起在Dify里新建应用时会让你选择应用类型。有的新手看到“聊天助手”“Agent”“工作流”“文本生成”一堆选项就懵。这里我直接给结论如果你要做的是像客服机器人、AI助手一样用户发一句话应用回一句话并且需要多轮对话记忆就选聊天助手然后在其编排方式里选择聊天流。如果你要做的是一个自动化处理任务比如“根据上传的Excel自动生成总结报告”用户只需触发一次不需要来回对话就选工作流。Agent适合让模型自主决策调用多个工具的复杂场景新手暂时可以放一放。为了讲清楚核心机制本文下面的例子都以聊天流为框架来演示。你新建应用后在编排页面找到工作流画布初始画布上会自动出现三个节点开始节点、LLM节点或结束节点根据不同模板版本略有差异。你只要改动它们的配置就能跑通第一个流程。2.3 把第一个hello流程跑通开始节点LLM节点结束节点我带你做一个最简单的流程用户输入任意问题LLM节点生成一段固定格式的回答然后返回给用户。第一步点击开始节点在“输入变量”里设置一个字段建议命名为question类型选“段落”它表示用户输入的问题。同时你也会看到系统内置变量sys.query它代表整个对话中用户当前说的这句话。两者区别在于自定义变量是为了给后续节点提供更明确的字段而sys.query是Dify自动捕获的当前对话内容。第二步配置LLM节点。模型选一个你已有的模型比如GPT或DeepSeek等模型提供商需要在“设置”里先把API密钥配置好。在“提示词”区域我建议这样写你是一个乐于助人的问答助手。 用户的问题是{{#startNode.question#}} 请先复述一遍用户问题然后用不超过两句话给出一个简单回复。注意这里引用了开始节点的变量格式是{{#startNode.question#}}。写的时候可以从输入框的“变量”标签里选择插入不用手敲避免出错。第三步把LLM节点的输出连接到结束节点。结束节点里需要指定“回复变量”也就是它把什么内容当成最终回答返回给用户。选择LLM节点的text输出即可。保存后点击“运行”按钮在调试输入框填入“你好”你会看到输出就是一句话包含了你刚才Prompt要求的结构。第一个流程跑通后你会有一种非常直观的感受原来工作流就是把一个个变量通过节点串起来挺简单的。3. 核心节点逐个拆解把它们当积木对待3.1 LLM节点配置模型和Prompt的实操要点LLM节点是工作流里最常用的节点没有之一。它做的事情就是输入一段文本经过模型处理后输出一段文本。但你千万别以为它就是“填个Prompt就好”实际使用中有几个关键配置要留意。模型选择不同模型在能力、速度、成本上差异很大。新手容易犯的错是统统选最强模型结果一个月跑下来成本爆炸。我建议简单任务选便宜快速的模型复杂推理任务才选强模型。Dify支持你在不同节点指定不同模型这是个很有用的能力。提示词结构尽量把内容分成“系统指令”和“用户查询”两部分。系统指令描述你希望模型扮演的角色和输出规范用户查询放实际要处理的内容。这样模型更稳定。例如做客服助手时系统指令里明确“只根据知识库内容回答不要编造”用户查询引用前面环节传过来的输入。温度参数如果你做的是事实问答温度设置为0到0.3之间避免模型自由发挥如果你做的是创意写作可以调到0.7以上。输出变量LLM节点的默认输出是text你可以把它改成结构化输出配合“结构化输出”功能或代码节点做二次处理。很多新手不知道LLM节点还可以选择输出JSON格式这对后面接条件分支非常有用。3.2 知识库检索节点带RAG的工作流怎么做想让AI回答得准确光有模型不够还得给它喂资料。Dify的知识库功能可以把文档、网页、结构化数据切分并向量化存储之后通过知识检索节点在运行时找回相关内容。工作流里的知识检索节点配置包括两步。第一步是在Dify的“知识库”页面把资料准备好支持上传PDF、DOCX、Markdown等格式。第二步在画布里添加知识检索节点选择已经建好的知识库设置检索策略和TopK。这里解释两个参数TopK返回最相关的多少条内容片段。设置太小容易信息不够设置太大会把无关内容也塞进Prompt。典型场景下3到8比较合适。Score阈值低于该相似度分数的结果会被过滤掉。如果你的问题类型跨度很大建议设置0.2到0.4之间避免“啥都搜出来”。知识检索节点的输出是一组result文本通常包含多个匹配片段。接下来你可以在LLM节点里引用这些片段组成Prompt比如请参考以下资料回答用户问题。 资料内容 {{#knowledgeRetrieval.result#}} 用户问题 {{#startNode.query#}}这样就构成了一个标准的RAG检索增强生成流程。新手最容易犯的错误是检索完直接把大段原文丢给模型没有处理可能存在的重复或无关内容。建议在进入LLM之前先用简单规则或者代码节点把检索结果做去重和截断。3.3 条件分支与代码执行让工作流学会“思考”和“计算”只有“查资料生成”的流程还不太智能因为很多时候你希望流程能根据用户输入走不同的路。比如用户问“你们公司有哪些产品”就直接返回产品列表用户问“我的订单怎么还没到”就先去查订单系统。这种逻辑在Dify里用条件分支节点实现。条件分支节点支持多种分组判断包含、等于、不为空、大于、小于等。你可以在节点里设置“当前变量”和“判断值”。例如判断开始节点里的question是否包含“订单”二字如果包含则走“查询订单”分支否则走“通用问答”分支。如果你需要更灵活的判断逻辑Dify还提供代码节点。代码节点支持Python和JavaScript函数入口接收你指定的上游变量返回你定义的结构化结果。我经常用代码节点来处理一些“模型做不到”的事比如解析JSON、计算数值、清洗字符串。举个例子def main(question: str) - dict: # 简单判断是否包含订单相关词 order_keywords [订单, 发货, 物流, 退款] hit [kw for kw in order_keywords if kw in question] return { is_order: bool(hit), matched_keyword: hit[0] if hit else }这段代码把结果返回给工作流后面的条件分支节点就可以判断is_order为真还是假。用代码节点做判断比用条件分支的“包含”更灵活适合需要关键词列表匹配的场景。3.4 HTTP请求与工具节点连接外部系统再进阶一点如果工作流需要访问你们公司自己的系统比如查库存、查客户信息、提交工单就需要用HTTP请求节点。它可以发送GET、POST等请求携带Header、Body参数并接收外部接口的响应。配置HTTP节点时新手有几个容易卡住的地方一是请求地址常常写错记得不要漏掉完整URL和必要的查询参数二是鉴权很多系统需要在Header里加Authorization: Bearer xxx或者自定义Token在Dify的“发送的Headers”区域里配置三是超时默认超时时间不长如果外部接口比较慢建议在工作流里先设定一个合理的重试策略或者用代码节点做好兜底。工具节点则相当于把一些现成的第三方能力接入工作流比如搜索、图片生成、数据库查询等。你可以在“工具”列表里添加之后像使用普通节点一样把它拖到画布。到这里你会发现Dify工作流所谓的高级功能拆开就是一个个积木。LLM提供语言理解知识库提供事实来源代码节点提供计算能力HTTP节点连接外部世界条件分支做决策。理解了这些你已经能搭出大部分常见AI应用了。4. 完整实战搭一个带身份识别和知识问答的工作流4.1 场景设计与变量设计光讲节点太散了我带你实际搭一个案例。假设要做一个小型客服助手它要能识别用户是不是会员然后根据用户身份和问题从不同的知识库里检索答案并生成回复。工作流开始前先设计几个变量query用户提出的问题文本。user_id用户编号这里用自定义字段模拟实际中可以由端上系统传入。is_member是否是会员由代码节点或条件分支判断得出。你不需要一次把所有变量都想清楚但建议至少先在纸上标出流程走向判断会员身份 - 选择对应知识库 - 检索 - 生成回答。设计阶段多想一步后面配置时能省大量时间。4.2 从开始节点到意图判断新建聊天流后开始节点接收两个变量query和user_id。接下来添加一个代码节点做两件事解析会员ID、判断是否命中会员名单。示例代码如下def main(user_id: str) - dict: member_ids {1001, 1002, 1003} return { is_member: user_id.strip() in member_ids, valid_id: len(user_id.strip()) 0 }代码节点之后接一个条件分支节点判断is_member是否等于true。如果为真走“会员知识库”路径如果为假走“通用知识库”路径。有的新手会问为什么不直接用数据库查会员因为真实环境下你可能把用户信息放在内部系统或者有现成的会员查询接口。这里为方便演示我用代码节点模拟。你理解了之后可以把这一块替换成HTTP请求节点去请求真实接口。4.3 接入知识库和LLM生成回答在会员路径上添加一个知识检索节点关联“会员专享文档”知识库在通用路径上添加另一个知识检索节点关联“公开产品文档”知识库。两个知识检索节点分别输出检索结果然后都连接到同一个LLM节点。这里有个重要技巧所有路径最终合并到同一个LLM节点是可以的前提是确保任何一条分支里都有知识检索节点并且LLM引用的变量在该路径上存在。如果某条路径不经过知识检索直接进LLM那LLM里直接引用检索变量就会报错。在LLM节点的Prompt中可以这样写开头部分的系统指令你是客服助手。如果用户是会员请优先使用会员资料回答如果不是会员请使用公开文档回答。 请严格按照提供资料表述不要编造。 会员资料{{#knowledge1.result#}} 公开资料{{#knowledge2.result#}} 用户问题{{#sys.query#}}你可能会想两个检索节点只会有其中一个执行那另一个变量的内容为空会不会影响回答Dify会对未执行的节点输出置为空字符串所以LLM节点里引用也不会报错只要你在Prompt里做好“优先使用非空内容”的说明即可。4.4 变量传递与结果输出最后LLM节点输出连接到结束节点。结束节点里除了回复内容你还可以额外返回一些调试信息比如是否命中会员、走了哪条分支。这在实际运营中很有用方便追溯某次回答的依据。在结束节点中回复内容选llm.text再增加两个自定义输出项is_member和matched_keyword分别从代码节点和上游变量获取。这样当客服或后端团队查问题时一眼就能判断这次回答的上下文。到这里一个带身份识别和知识问答的客服工作流就跑通了。你可以试着用“1001”和“2999”两个不同的用户ID各跑一次观察它是否分别命中不同知识库以及回答是否有差异。5. 调试、测试和上线这步新手最容易忽略5.1 单节点运行的调试方法很多人搭工作流时满腔热情可一运行就报错然后开始瞎改。我要告诉你的是Dify画布本身就提供了特别好的调试能力你可以对单个节点单独运行测试。选中任意节点在节点编辑面板里能看到“预览”或“运行”按钮。它会以上游变量模拟数据为输入只跑当前节点让你确认单个节点是否正常。比如代码节点报错你不用把整个流程跑完直接用一组测尝试数据运行它就能看到Python代码是否抛异常。这里有个排错顺序建议先跑“开始代码节点”确认输入来源没问题再跑“知识检索节点”看检索结果是否为空最后跑“LLM节点”看Prompt渲染出来是否正确。不要一上来就点“运行整个工作流”那样输出信息太多很难定位问题。调试时要特别留意画布下方展示的“节点执行结果详情”它会显示每个节点的输入参数、输出内容和耗时。我遇到变量引用错误时几乎都是在这里面看出端倪的某个变量显示为空说明上游节点没执行成功。5.2 用对话预览功能模拟真实用户单节点调试通过不代表整个流程没问题你还需要在“预览”页面像真实用户一样去对话。这个页面会展示完整的对话界面你输入一句话应用按照工作流逻辑返回结果。多轮对话场景尤其要测当用户连续问两三个问题时工作流是否还能正确追踪上下文比如第一个问题问“会员有什么权益”第二个问题问“那怎么申请”你的工作流是否能识别“那”指的是“会员申请”如果做不到你可以在聊天流里加上“对话记忆”或把之前的用户输入和AI回复作为上下文变量传给LLM节点。另外要测边界情况空输入、超长输入、输入只有标点符号。这些异常输入如果没处理好轻则返回乱答重则导致代码节点崩溃。我一般会在代码节点里加一层空值判断比如输入为空时返回一个默认提示。5.3 版本发布与运行时日志工作流改好了别急着直接用。Dify支持版本管理你在编辑页面改的是草稿发布后才成为正式版本。这样你可以先把草稿调试好再一键发布避免把半成品暴露给真实用户。发布后建议立刻打开“日志”页面观察几次真实调用。日志里记录了每次运行的完整链路每个节点的输入输出、耗时、状态。如果用户反馈某次回答不对你可以根据对话时间定位到那条日志逐节点回放找出是哪一步出了问题。我个人的习惯是重大改动先发布为测试版本用小范围用户跑一天看日志里有没有异常再决定是否全量发布。如果不方便分版本至少要在发布后的头几小时多盯日志防患于未然。6. 常见踩坑与性能优化经验6.1 变量类型不匹配、节点引用错误等高频问题新手报错时最爱问的问题就是“为什么我的节点参数没生效”我整理几个高频坑你遇到了可以直接对照。第一变量引用写错。Dify引用变量的格式是{{#节点路径.变量名#}}节点路径通常按你在画布上给节点起的名字来。如果你改名了之前的引用不会自动更新容易出现类似{{#answer.text#}}但节点名其实是answer_1的情况。建议配置好节点后立刻在下一个节点用“插入变量”功能重新选一次防止手写错。第二数据类型不匹配。比如条件分支判断变量“是否为空”时如果上游变量是段落文本判断结果可能不符合预期。字符串的空和null是不同的你在代码节点返回时要明确返回布尔值true/false不要返回字符串true。第三知识库检索为空。如果你发现回答一直说“不知道”先检查是不是知识库本身没有上传文档、或检索Score阈值太高。你可以单独运行知识检索节点查看输出内容是否为空然后调整TopK和阈值。第四模型API额度不足或Key填错。运行时报401或429错误时去模型提供商账号后台查看配额。我做了一个简单的排查表方便你对照使用症状可能原因处理办法节点报错变量未定义上游节点未执行或引用路径错误检查画布连线用插入变量重新选择回答质量明显偏离Prompt没有明确限制范围增加系统指令提供参考知识库内容流程运行成功但回复为空结束节点未配置回复变量在结束节点选择具体输出字段知识库答案缺失检索结果为空或阈值过高降低Score阈值增大TopK重新检查文档切分运行很慢模型太强、检索量过大、外部接口慢换轻量模型减少TopK给HTTP节点设置超时6.2 Prompt太长导致费用高、响应慢怎么办工作流用久了你会发现每个LLM节点都会循环引用一大堆对话上下文、检索片段Prompt越拼越长最后既费钱又慢。控制Prompt长度有几个实用方法限制检索返回数量不要一股脑把知识检索的全部结果塞进去只保留最相关的3到5条足以。使用数据预处理在代码节点里截断过长的用户输入或检索结果例如只取前1000个字符。拆分长流程如果一个工作流里塞了太多任务考虑把它拆成多个应用或多次调用来完成。比如“先判断意图再调用另一个工作流回答问题”这样每个环节的Prompt都能保持精简。成本控制还有一个容易被忽略的地方你要关注每个节点的模型调用次数。并行节点会同时调用多个模型如果它们不是必须的建议改成顺序执行或合并成一个节点减少总token消耗。6.3 工作流设计的演进建议当你已经能熟练搭建工作流我建议你回头审视一下自己的设计是不是存在可以简化的地方。比如经常有人把“用户输入正则清洗”放在代码节点里再把结果丢给LLM。但如果你其实只是想让LLM忽略某些乱码完全可以在LLM节点的Prompt里直接写一条规则省掉一个节点。再比如某个判断逻辑既有条件分支又有代码节点导致维护时要改两个地方那不如统一放在一个代码节点里让逻辑更集中。另外工作流不是一次设计成型的。你先跑通一个粗糙版本然后从日志中观察真实用户都在问什么再决定增加哪些分支、调整哪些知识库。没有人能第一版就把工作流设计得完美持续迭代才是正确姿势。最后说一个我个人的体会用Dify工作流最重要的不是把画布拖得花里胡哨而是让每一步都清晰可靠。开始节点管好输入中间节点各司其职结束节点输出明确中间再留好日志和调试信息。这样一个工作流不管是交给别人接手还是过一个月自己回来看都能很快看懂。新手真正上手的捷径不过是把一个简单流程彻底跑明白再在这个基础上慢慢加复杂度。