如果你习惯了用代码拼AI应用,第一次看到Dify的工作流画布,可能会产生一种“这也太简单了吧”的错觉——把节点拖到画布上,用线连起来,再填几段提示词,一个能自动做文本摘要的AI应用就跑起来了。
这是“Dify 入门系列”的第七篇,不聊空泛的理论,直接用一个“文本摘要器”例子带你把AI工作流从零搭出来。整个过程不需要写一行代码,也不需要熟背提示词工程技巧,只靠一个开始节点、一个LLM节点、一个结束节点,五分钟内就能跑通。
适合谁来参考?如果你已经知道Dify是什么,但是还没上手搭过工作流;如果你平时是写代码调接口的人,厌倦了每次都要处理参数拼接和响应解析;又或者你只是有一个“输入长文本、输出摘要”的想法,想快速验证可行性,这篇内容都适合你。沿着这条路径走完,你不但能拿到一个能直接用作API的应用,还能理解Dify工作流最核心的一件事——节点之间的变量是怎么流动的。
1. 拖拽连线到底解决了我的什么痛点
1.1 从写代码到“画”应用的思路转变
以前我做一个文本摘要小工具,通常是Python脚本:读文件、拼prompt、调模型接口、解析返回结果、写回文件。每一步都清晰,但一旦prompt要改一下,或者要加一个“摘要太长就重新生成”的逻辑,就得往代码里插一堆if-else。更麻烦的是,这类脚本基本是给自己用的,同事拿到手以后根本看不懂,跑依赖、配环境、改参数,每件事都要重新解释一遍。
Dify工作流的思路是把“逻辑编排”和“具体实现”分开。我只需要告诉它:第一步接收什么数据,第二步调用哪个模型,第三步输出到哪。真正执行的时候,平台负责把数据传给模型、处理错误、记录日志。连线表达的不是“函数调用顺序”,而是“数据从哪里流向哪里”。对于文本摘要这种单线任务,直观得不能再直观。
1.2 什么场景值得用工作流而不是写代码
我整理过一个对比,方便你判断什么时候该用Dify工作流,什么时候还是老老实实写代码:
| 维度 | 直接写代码 | Dify工作流 |
|---|---|---|
| 修改成本 | 每次都要重新改代码、跑测试 | 改节点配置即可,秒级生效 |
| 可视化 | 无,靠日志想象执行流程 | 节点连线一目了然 |
| 协作门槛 | 需要代码能力和环境配置 | 业务同事也能看懂基本逻辑 |
| 调试方式 | 打印日志,反复重启 | 单节点运行,点击查看输入输出 |
| 复杂算法 | 灵活,自由度最高 | 有代码节点补足,但仍有边界 |
| 部署运维 | 自己管服务、鉴权、并发 | 平台统一处理,发布即API |
从这张表能看出来,Dify工作流特别适合三类场景:快速原型期、需要交付给非技术团队使用的内部工具、以及以“数据处理管道”为核心而不是以“复杂算法”为核心的业务逻辑。反过来,如果你要写一个高性能的自定义排序算法,或者要对海量日志做底层过滤,那还是撞到代码里更合适。但对于“调模型、传参数、拿结果”这种LLM应用的主流形态,可视化工作流的效率和可维护性都非常高。
1.3 为什么文本摘要作为入门案例最好
选文本摘要器作为入门案例,是因为它足够小,又足够完整。它的输入是一段长文本,输出是一段短文本,逻辑上天然就是“开始 → 处理 → 结束”三个节点能表达的最小闭环。同时,摘要任务能清楚展现“提示词”和“模型参数”的影响,方便你在搭建过程中体会到变量传递、模型选择、输出解析这些知识。学会了这个,后面再做文章分类、会议纪要抽取、客服工单总结,都是同一套玩法的延展。
2. 开工前要准备的两件事:部署Dify和配置模型
2.1 本地部署Dify的几种方式
Dify支持本地部署,我最常用的是Docker Compose方式,步骤很直接:
- 从Dify官方仓库或文档获取最新版的docker-compose.yaml配置文件。
- 确保本机已经安装Docker和Docker Compose插件。
- 在配置文件所在目录执行
docker compose up -d,等待容器启动。 - 浏览器访问默认端口,第一次进入会要求创建管理员账号。
- 完成后进入工作台,开始创建应用。
我这里写文章时已经用到了1.17.x的版本,界面细节与旧版可能会有点差异,但工作流的核心逻辑保持一致。如果你用的是社区版,建议保持版本更新,像1.17.1这个版本就修复了不少插件和工作流运行时的问题,实际体验会稳很多。
如果不想本地安装,Dify也提供官方云版本,注册后在线就能创建应用,流程几乎一样。但考虑到团队内部数据隐私,或者需要把应用部署在内网环境,本地部署始终是更稳妥的方案。
2.2 模型配置:工作流真正的大脑
Dify本身不产生模型能力,它需要通过“模型供应商”去调用大模型。进入“设置” → “模型供应商”,你能看到OpenAI、Anthropic、通义千问、智谱AI等选项,也可以添加自定义模型。每个供应商都需要配置对应的API Key,后续工作流节点才能选到模型。
这里有一个实用技巧:如果你用的是国内模型厂商的服务,通常可以选择“OpenAI兼容接口”的方式接入,把Base URL改成对应网关地址,再把模型名改成对方提供的模型标识即可。这种方式非常灵活,尤其是当你有多个供应商、需要随时横向对比生成效果时,省去了来回切换平台的麻烦。
还有一个选择是用本地模型,比如通过Ollama启动一个开源模型,然后在Dify中添加Ollama类型,填入本地API地址。因为模型只运行在自己机器上,所以对于演示环境和断网环境特别友好。不过本地模型的摘要质量通常比不上云端大模型,如果对效果要求高,建议至少使用7B以上参数的模型,或者选择量化版本。
2.3 开一个测试模型就够了
刚开始入门不需要配太多模型,选一个效果相对稳定的就行。比如配置一个支持较长上下文的模型,因为摘要任务经常要吞下一整篇文章,上下文窗口太小的话,后半段会被截掉。我的建议是:主要用同一个模型把第一个工作流跑通,跑通之后再慢慢增加其他模型做对比,不要一开始就把选择困难留给自己。
3. 实操:用三个节点搭一个文本摘要工作流
现在进入正题。打开Dify控制台,从“工作室”创建一个空白应用,应用类型选“工作流”,而不是“聊天助手”。聊天助手的交互方式不同,它自带多轮对话记录,而我们这里只想要“输入一段文本,输出一段摘要”的管道型应用,普通工作流更合适。
3.1 新建工作流,先认识左侧节点面板
进入工作流编排页面后,你会看到画布和左侧的节点面板。节点面板大致分为几类:
- 输入类:开始节点。
- 逻辑类:条件分支、迭代、变量聚合等。
- AI类:LLM、知识检索、问题分类器等。
- 工具类:HTTP请求、代码执行、自定义工具等。
- 变换类:模板转换、变量赋值等。
对于文本摘要器,真正需要关注的只有开始、LLM、结束这三个。如果你以前没用过可视化编排工具,可以把它简单理解为流程图:节点是操作步骤,连线是数据流向。节点从面板拖到画布上,把鼠标放在节点边缘,出现圆点之后拖到另一个节点上,就完成了连线。
3.2 开始节点:把待摘要文本变成入口变量
拖入一个开始节点,双击打开配置面板。默认情况下,Dify会给你一个sys.query字段,对应应用运行时用户输入的Query。但对于摘要器来说,用户输入的可能是一大段文章或会议纪要,我建议自定义一个语义清晰的输入字段。
点击“输入” → 添加输入,字段名填input_text,类型选择“段落”。段落类型可以完整保留换行和空格,适合存长文本。你可以给它一个默认值,比如一段产品介绍,后面测试时就不用反复粘贴。
这里有一个命名建议:变量名尽量只用英文字母和下划线。如果你命名成中文“用户输入文本”,后续在节点里引用时会生成一串编码格式的变量路径,既不美观也容易出错。
3.3 LLM节点:写好提示词,连上数据线
从节点面板拖入一个LLM节点,连一条线从开始节点指向LLM节点。当然,你也可以不连物理线,直接在下游节点里引用上游变量,Dify会通过引用关系自动判断依赖;但连上线以后,整套流程的阅读体验会更好,任何人打开画布都能一眼看出数据从哪来。
LLM节点需要配置的要点:
- 选择你刚配置好的模型。
- 把温度调到0.3左右。摘要任务需要忠实于原文,温度太高模型容易自己发挥,太低又可能过于僵硬。
- System Prompt写清楚角色和任务。
- User Prompt里通过变量引用把开始节点的输入文本传进来。
配置示例:
System Prompt: 你是专业文本摘要助手。请对用户输入的文本进行概括,保留核心信息,忽略无关细节,输出不超过200字的中文摘要。 User Prompt: 以下是需要摘要的文本: {{#start.input_text#}}连线的本质在于它建立了“数据依赖关系”。运行工作流时,Dify会先收集开始节点的输出,作为LLM节点提示词的上下文;如果开始节点里没有input_text字段,整个链路就会直接报错。
3.4 结束节点:把摘要结果暴露给外部
拖入结束节点,从LLM节点拉一条线到结束节点。结束节点里选择输出变量为LLM节点的text字段。这一步相当于告诉平台:等LLM跑完之后,text字段的结果就是这个应用最终返回的内容。
配置完成后点击右上角的“运行”按钮,Dify会弹出一个参数填写面板,让你输入开始节点中定义的字段。这里粘贴一段比较长的文本,比如把一篇新闻稿粘进去,点运行。你会看到画布上的节点依次点亮:开始节点先执行,然后LLM节点,最后结束节点。点每个节点还能分别查看它的输入和输出,如果模型返回的内容不满意,直接改提示词再跑一次。
跑通之后,可以在应用概览页发布为API,拿到一个独立的API端点。以后任何系统都可以通过HTTP POST来调用这个摘要接口,这就是“拖拽连线替代代码”最直接的价值——你完全不需要自己实现模型调用部分。
4. 节点帮你做了什么:变量引用与提示词设计的底层逻辑
4.1 连线本质:上游输出变量如何被下游引用
很多人第一次用Dify会有一个困惑:明明节点之间连了线,为什么有时候改节点名会导致下游报错?原因在于,Dify工作流的运行依赖引用关系,而引用关系靠的是节点ID和变量名。
比如在LLM节点里写{{#start.input_text#}},这里的start是开始节点的节点ID,不是画布上展示的中文名。你可以在画布上把节点改名为“入口”,节点ID通常不会变;但如果你进入节点配置页修改了“节点ID”,下游所有引用这个变量位置的文本都要跟着改。所以我的习惯是:所有节点设置好后先跑一次,确认无误再改节点ID;改完ID后,再打开所有引用该节点变量的下游节点检查一遍。
这样设计其实有它的好处。Dify可以把变量依赖识别成一棵依赖树,从而判断哪些节点可以并行执行。比如你有两个LLM节点同时依赖开始节点,它们之间没有连线,Dify就会尝试并行运行,节省整体耗时。这是手写串行代码时很难天然得到的优化。
4.2 提示词不是随便写:好的摘要提示词要考虑什么
文本摘要看起来很容易,但提示词写得好不好,结果天差地别。我见过不少用户只写一句“帮我总结”,结果模型返回一堆正确的废话。一个合格的摘要提示词,至少要包含这些信息:
- 角色与任务:你是专业文本摘要助手,负责从用户输入文本中提取核心信息。
- 内容范围:只基于输入文本,不要引入外部常识或个人观点。
- 长度限制:不超过200字,或者不超过5个要点。
- 输出风格:中文、口语化、书面语,明确约定。
- 处理边界:输入文本为空或极短时应该怎么办。
把这些约束写进System Prompt,比在User Prompt里临时堆砌更容易得到稳定输出。输入文本放在User Prompt,并用明确的标记包裹,比如“以下是需要摘要的文本:”,这样模型可以清晰区分“指令”和“数据”。
还有一个被很多人忽略的点是温度参数。对于摘要器,温度设在0.2到0.4比较合理。温度过高,模型倾向于“创作”,摘要里可能出现原文没有的结论;温度过低,输出可能过于机械,把列表原样复述。理解这一点,排查结果不稳定问题时也会更有方向。
5. 文本摘要器的两个进阶改造思路
5分钟版本的摘要器只是最小闭环。用起来以后,你会发现现实中的文本往往比想象中长,或者希望摘要结果能直接进入下一个系统。这里分享两个我实际改造过的方向。
5.1 长文本分块摘要:加上迭代节点
单次LLM调用能处理的文本量有限。即使模型支持很大的上下文窗口,一次性塞入几十万字的文稿也可能中途截断、响应变慢、费用飙升。更稳的做法是先把文本切成块,每块做局部摘要,最后把所有局部摘要合并成总摘要。
在Dify里,第一步可以用“模板节点”或“代码执行节点”把长文本按字符数切成数组;第二步用“迭代”节点,把数组逐项传给LLM节点;第三步把每次迭代输出的摘要收集起来,再用一个LLM节点做最终合并。做这个改造的核心是理解迭代节点里“内部变量”和“外部变量”的差别:迭代内部每次循环会把当前项赋值给你指定的变量,累计结果需要存到一个外部变量里。
这个改造会稍微费些心思,但效果实打实。尤其是处理会议纪要、论文、年度报告这类内容时,分块摘要比一次性摘要准确,因为它避免了模型“中间忘掉前文”的问题。
5.2 多格式输出与结构化摘要:加模板和条件分支
另一个常见需求是:摘要结果不只是一段文字,而要同时输出标题、要点列表和关键词列表。这时可以用一个“模板节点”把LLM节点的输出和原始文本一起组装成结构化Markdown或JSON,再交给结束节点。
模板节点示例:
# {{#llm.title#}} ## 摘要 {{#llm.summary#}} ## 要点 - {{#llm.bullets#}}如果想要JSON输出,在模板节点里手写JSON结构,再用变量占位符填充即可。这比让模型直接输出JSON更可控,因为模板节点不依赖模型遵循复杂指令,填充过程是可预期的。
条件分支也有它的用途:如果输入文本小于1000字,直接用LLM节点一次性摘要;如果超过1000字,先走分块逻辑。通过一个“条件分支”节点判断input_text长度,把两条路径汇合到结束节点。这种“路由”能力几乎是可视化工作流区别于单次提示词调用的最大优势——你不需要在代码里写if-else了。
6. 我在实测中踩过的坑和几个小建议
6.1 模型输出不稳定是常态,提前定好评估口径
我搭好摘要器之后,第一次测试是用同一段新闻连续跑了三次,三次结果居然每次都不一样,有些细节时有时无。这很正常,因为大模型本质上是概率采样,不是确定性函数。为了让输出尽量稳定,我后来做了两件事:一是把温度调低到0.2;二是在提示词里加了一条“严格基于原文,不要补充背景信息”的约束。
真正的稳定性评估还是要靠测试集。你可以准备三到五段不同风格的文本,每一段都跑一遍,检查摘要是否覆盖原文核心信息、有没有编造内容、长度是否超限。Dify每次运行都会留下记录,方便你反复对照同一提示词下不同模型、不同参数的输出,这比在脚本里打日志方便多了。
6.2 变量引用错误是最常见的失败原因
在没跑通之前,我最常遇到的报错是“变量不存在”。原因通常是:节点ID被修改后,旧引用还留在提示词里。所以有一个经验:不要在画布上随意修改节点ID,更不要在引用变量后随手改输入字段名。如果真的改了,用全局搜索把旧变量名全部找出来替换掉。
另外,开始节点里的sys.query字段和新增的input_text字段,虽然都能在下游引用,但建议不要混用。如果你把sys.query留空,又把input_text填得满满的,运行时会让人搞不清到底传的是哪个。我通常在开始节点中把用不到的默认字段删掉,只保留必须的字段,这样节点面板更简洁,下游引用也不容易出错。
6.3 发布API之后,别忘了做输入校验和限流
摘要器的接口一旦发布,就可能被外部系统调用。如果调用方传了一个超长字段,模型调用成本会直接翻倍,甚至可能触发供应商限流。我一般会在开始节点后面接一个“代码执行节点”做保护,检查输入长度,超过阈值就截断或直接返回错误。代码执行节点支持Python,写一小段片段很快。
还有一点:API Key不要写死在业务系统里。Dify应用发布后生成的API端点,调用时可以带Authorization头,建议通过后端服务转发,不要在浏览器、小程序前端直接暴露,避免密钥泄露。
6.4 从一个小工具变成业务底座
这个文本摘要器搭完以后,它最好的角色不是终点,而是一个模板。我后来在它基础上扩展了文章分类、会议待办提取、客户反馈情绪识别等工作流,基本都是复用同一个模式:开始节点接收原始数据,LLM节点负责知识加工,结束节点输出结构化结果。
每次新建应用时,我会先把最简链路搭出来跑通,再逐步加条件、加迭代、加知识库。这种“先跑通再迭代”的思路,是可视化工作流给你的最大红利:复杂度可以慢慢增加,但每一步都能被看见、被验证。这一点,是传统写代码方式不容易做到的。