ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

用Dify搭建自动复盘工作流:从原始材料到结构化报告

用Dify搭建自动复盘工作流:从原始材料到结构化报告 有一个词叫 hindsight翻译过来就是“事后诸葛亮”。我觉得这个词特别适合形容大多数项目的复盘环节——明明事后什么都看清楚了但下次做的时候照样踩同一个坑。问题出在哪里出在复盘这件事本身没有沉淀成可复用的流程。前阵子我搭了一个叫 hindsight 的 Dify 工作流专门解决这个事给一段原始材料会议纪要、聊天记录、项目说明自动生成一份带决策逻辑还原、盲点标注和行动项拆解的复盘报告。这篇内容是完整的搭建记录包括我为什么选 Dify 而不是直接写代码、工作流节点的设计思路、提示词迭代的三轮过程以及几次真实跑挂又修好的经历。适合想用 Dify 做内部提效工具的产品经理、运营和独立开发者参考。先说一下这不是一个聊天助手。我没有把它做成“你可以追问它”的对话应用而是一个“丢材料进去拿报告出来”的复盘机。这个定位差异很重要后面会展开讲。1. 为什么是 Dify 而不是从零编码hindsight 的选型逻辑1.1 项目要解决的真实问题复盘一直是个高价值但低频率的事。高价值在于事后视角能看到当时的盲点低频率是因为做一次复盘的成本实在太高翻聊天记录、整理事件时间线、对照目标重新梳理决策因果没有一两个小时下不来。hindsight 想压缩的是这个“整理和归因”的环节把原始素材交给大模型做结构化提取人只做最后的判断和补充。我给自己定的使用场景就三个个人项目的阶段回顾比如一个功能上线两周后数据没达预期小团队会议的纪要复盘群里聊完没人整理的决策过程文档化的事件回溯比如一次事故、一次客户投诉的完整处理链路。这三个场景的共同特点很明显素材是现成的但没有人愿意回头翻。我要做的就是一个能把“现成素材”快速变成“结构化复盘”的管道。1.2 Dify 工作流能满足的三个刚需一开始我也犹豫过是不是直接写 Python 脚本调大模型 API 更灵活。后来对比下来发现Dify 有几个特点是正好卡在需求上的。模型接入与多模型切换。hindsight 需要两个阶段的分析先做事实抽取再做推断复盘。这两个阶段对模型能力的要求不同抽取讲求稳定推断讲求逻辑。Dify 工作流里可以分别指定模型后面调试时想换模型直接在节点下拉框里换就行不用改代码。可视化编排和变量管理。复盘的输入不是固定格式可能是文本、可能是 URL、可能是多轮对话粘出来的大段聊天记录。Dify 的开始节点能定义全局变量后续每个 LLM 节点都能引用。这种“一次定义、处处使用”的方式比我在 Python 里维护函数参数还省事。尤其麻烦的 JSON 转义、多行文本传递Dify 都处理掉了。日志和调试能力。Prompt 调久了都会遇到一个问题输出格式偶尔乱掉。Dify 的运单日志能直接看到每一个节点的输入和输出我能快速定位是哪一步把格式搞坏了。这个在裸调 OpenAI SDK 的时候得自己写日志处理比较麻烦。对没精力维护前后端的团队来说Dify 的应用直接自带 API 和网页界面等于后端和前端也省了。这是后面做批处理的基础。1.3 hindsight 的整体架构hindsight 的整体流程分成五层开始节点接收原始输入 → 可选的检索节点从知识库补充背景 → 核心 LLM 节点生成复盘报告 → IF/ELSE 节点兜底检查内容完整性 → 输出节点返回最终结果。注意我把知识检索放在 LLM 之前而不是 LLM 之后。原因是复盘报告里很多结论需要引用历史上下文。比如复盘客服投诉如果能查到同类问题的历史处理记录大模型就不会凭空猜流程。Dify 的知识库可以直接接进来检索放前面的另一个好处是可以把检索到的参考片段和用户输入合并进同一个提示词上下文减少模型幻觉概率。架构上我刻意没做多轮对话。复盘应该是一次性给足材料、拿到完整报告而不是来回追问。追问会引入两个问题一是上下文越长成本越高同一段材料反复进模型二是容易把用户引导到“问什么答什么”的聊天惯性里反而丢了系统性。这也是 hindsight 不叫“复盘助手”而叫“复盘机”的原因。2. 从零搭一条复盘工作流节点设计与变量定义2.1 开始节点把输入设计成五个字段在 Dify 里创建应用时选“工作流”类型不是 Chatflow。开始节点我设计了五个字段覆盖了我能想到的所有复盘输入场景字段名类型必填用途project_name单行文本是复盘对象的名称用于生成标题和上下文raw_material长文本是会议纪要、聊天记录、产品描述等原始素材goals长文本否项目目标或预期指标用于对照实际结果focus_questions长文本否用户关心的具体问题如“为什么上线后转化率没上去”review_mode下拉选项否完整复盘 / 快评 / 盲点专项 三种模式我把 raw_material 设为必填因为没素材模型没法工作。goals 和 focus_questions 设为选填是因为很多复盘场景确实只丢过来一段聊天记录没有成型的 goal。review_mode 是后期加的后面测试时发现“完整复盘模板”太长对短素材是浪费于是做了模式切换。2.2 主 LLM 节点提示词里塞进两轮结构主节点我接入了 GPT-4o温度调到 0.3。温度千万别调高复盘需要稳定输出我不希望同一条材料跑两次结果完全不同。节点里我不会只写一段“请帮我复盘”而是写了一个包含两轮结构的模板你是一名项目复盘分析师。用户提供了原始素材请对素材内容进行结构化复盘。 先执行第一轮事实抽取。从素材中提取以下事实 - 关键决策点 - 关键假设 - 已发生的行为和结果 抽取时只依据素材内容不要自行补全事实 再执行第二轮复盘分析。基于抽取到的事实输出 - 决策逻辑还原当时为什么这么选 - 盲点标注哪些地方缺少验证、讨论、替代方案 - 因果链路哪些行为可能导致了哪些结果 - 可执行行动项针对盲点的下一步建议 约束 - 所有结论必须标注对应原文摘要或引用 - 如果素材中找不到依据明确标注“素材中未提及”不要编造 - 如果用户提供了 goals最后单独对比目标和实际这块提示词的写法我在第 3 节详细展开。这里先强调一个点模型输出严格区分“事实抽取”和“复盘分析”这是防止大模型把“自己的猜测”当成“素材里的事实”。2.3 条件分支与输出节点兜底和格式化主 LLM 节点之后我加了一个 IF/ELSE 节点检查生成结果是否包含“盲点”和“行动项”关键词如果包含就直接输出如果没包含则走一条补救分支——用一条更短、更收敛的提示词“请仅基于以上素材输出三个未经验证的假设”再合并结果。这个分支是在一次实测翻车后加进来的。有一次素材只有两行字主 LLM 直接输出了一段“素材过少无法复盘”的文本整个工作流表面上是成功的但报告是空的。加 IF/ELSE 后至少空报告会变成有内容的假设列表用户可以自己判断哪个有用。输出节点我用了 Jinja 模板把报告生成成结构清晰的 Markdown# {{ project_name }} 复盘报告 ## 一、事实抽取 {{ facts }} ## 二、决策逻辑与盲点 {{ insights }} ## 三、行动项 {{ actions }}这个步骤的坑在于让我意识到输出节点不仅是把 result 丢出来还可以用模板做格式标准化。Markdown 模板会直接展示在页面输出里后续接入别的系统也方便比让模型自由发挥格式稳定得多。3. 让大模型知道“它看到的只是一面之词”提示词工程的核心3.1 事实与推断绝对分离复盘的幻觉通常不是模型瞎编一个不存在的决策而是把素材里没写到的背景补成了“显然的结论”。解决办法是把提示词严格拆成“事实抽取”和“复盘分析”两个阶段并要求“复盘分析”的产出必须能被前面“事实抽取”的产物对应上。举个实际例子。素材里写“团队决定不用 Redis Cluster原因是维护成本高”。如果只让模型“分析决策风险”它很容易直接输出“Redis Cluster 存在水平扩展瓶颈因此切换到自建方案”。这句话看起来有道理但完全是模型自身的库存知识不是素材里的依据。正确的复盘应该写“团队认为维护成本高 → 对应素材依据维护成本高 → 素材未提及具体性能瓶颈”。标注依据引用能逼着模型承认“我不知道为什么”。这个思路在提示词里用显式段落约束如果有结论必须用“以下为相应原文依据”的列表说明。如果素材中没有依据必须写“素材未提供依据”。3.2 三类复盘的三种输出模板hindsight 的 review_mode 字段在提示词里做了三套模板切换实际上是同一个 LLM 节点里利用 Jinja 条件语法选择不同指令段落full完整复盘输出事实、决策逻辑、盲点、因果、行动项适合项目月度和收尾复盘。quick只输出“结论 行动项”适合团队快速回顾一次小会议。blind_spot只输出“假设清单 每条假设的证据强度”适合找风险点。这个设计的目标是控制 token 成本和阅读负担。全量复盘动辄输出两千字对只有十分钟的周会复盘完全没人看。quick 模式把输出压到两百字以内反而使用率高。我在主 LLM 节点里用 Jinja 做了分支{% if review_mode quick %} 只输出核心结论和下一步行动两个章节结论不超过200字。 {% elif review_mode blind_spot %} 忽略常规结论重点输出素材中被当作默认前提的假设清单。 {% else %} 按标准三段式完整复盘。 {% endif %}这个模式实测好使的关键在于review_mode 必须在下拉选项里定义好并且传给 LLM 节点的是字符串不是数组。我在改版时踩过一次把数组值传进提示词导致 Jinja 比较崩溃的坑后面在接入节点前加了一个变量提取节点把数组转成字符串再进模板。3.3 用“反事实问题”激发盲点发现盲点分析是复盘报告里价值密度最高的部分也是单靠“总结”最容易写成空话的部分。只问“有什么盲点”模型会把“沟通不足、需求不明确、测试不充分”这类万金油结论给你一堆。我换了一种问法让模型对每个关键决策问一个反事实问题——“如果当时选了另一个方案会有什么不同需要什么额外信息才能判断这两种方案的好坏”这样它会老老实实基于素材里的信息差作答。事实证明“反事实提问”比“寻找盲点”有效得多因为盲点不能直接看到它只能在假设被推翻时显现。4. 从“像那么回事”到“真的能用”三轮实测与四类修复4.1 第一轮输出完美但底层全是幻觉我拿一段模拟的会议纪要来测“我们决定用自建日志系统因为第三方太贵后端暂时就不做限流了因为用户量不大……”第一版工作流输出里赫然写着“成本压力导致选择自建日志系统”。我查了原始素材“太贵”只有一句话没有算过账更没有“成本压力决策模型”这样的提法。这就是典型的大模型补全——把“贵”扩写成“成本压力决策”。修复方式是第 3 节里的“事实抽取-依据标注”同时把温度固定到 0.3并在提示词里禁止模型使用“显然”“必然”这种强因果断言词。4.2 第二轮变量类型和 Jinja 的玄学崩溃改完提示词后我一连跑了五次三次报错位置都在 IF/ELSE 节点。查日志发现 review_mode 字段传进来的是数组比如 [full]Jinja 里比较根本匹配不上。还没想好修复方案另一个问题又冒出来了raw_material 里含换行符和引号时LLM 节点偶尔把模板里的单双引号串了。我把这两个问题放在一起处理了现象根因修复review_mode 匹配不上导致走错分支Dify 下拉字段实际返回数组在变量提取节点里加数组转字符串步骤素材含引号时输出截断或模板崩溃原样拼接进 prompt模板语法被污染在节点前用文本处理节点过滤控制字符统一转义引号内容过短时输出“无法分析”主模板过长对短素材成本太高增加 IF/ELSE 兜底分支 review_modequick输出偶尔包含“建议咨询专业人士”模型补全模板化套话提示词里禁止输出免责声明式语句这里有个值得说的经验Dify 里的下拉、多选变量传进 LLM 模板时经常是数组。你用 Jinja 直接比较肯定会挂。所以所有枚举字段在进入提示词之前都先过一次变量提取转成字符串这个步骤省不了。4.3 第三轮报告能用了但没人看第三次改进后模型输出已经很稳。但我自己用了一周发现一个更隐蔽的问题报告太长。完整复盘模板下一次普通的群聊天记录能生成 1800 字里面一半是我早就知道的结论。复盘报告如果充斥着“应加强沟通”“建议固化流程”那它就跟往群里转发鸡汤没什么区别。我于是加上了 review_mode 和“行动项评分”逻辑。行动项不是一股脑输出而是分三个优先级P0不解决会影响下次同类事件的、P1需要补充信息验证的假设、P2保持观察即可。这一步对整个工作流的可用性提升很大也是现在 hindsight 和那些“一键总结”工具最大的区别。5. 从单次夹具到复盘库接入外部存储、知识库与批量触发5.1 把报告推送到外部协作工具Dify 的 HTTP 节点可以让我把生成的复盘报告直接推到 Notion、语雀或者飞书文档。我在 HTTP 节点配置了 Notion APIPOST 请求体类似这样{ parent: { database_id: your_db }, properties: { name: { title: [{ text: { content: {{ project_name }} 复盘 } }] } }, children: [ { object: block, type: paragraph, paragraph: { rich_text: [ { text: { content: {{ report_content }} } } ] } } ] }注意自定义变量 report_content 要先把 Markdown 输出转成纯文本否则 JSON 里的换行和转义会被卡住。我后来改用简化方案直接推送一个带报告的 .md 文件到对象存储再在协作工具里引用链接。技术选型要看团队习惯不一定要强上 Notion。5.2 结合 Dify 知识库做历史复盘的二次利用hindsight 的可扩展核心不在单次报告而在知识库。我把同一类复盘的历史输出丢回知识库这样之后复盘新项目时知识检索节点会自动召回过去同类失败模式。比如上一次复盘提到“同类需求在第三个周期转化率下降”下一次做类似功能复盘时模型就会拿旧报告当背景资料。这里有两个要点。第一存入知识库的文档按“项目名 复盘日期”生成标题检索会更精准第二设置召回 top_k 在 3-5 条不要贪多。召回太多会把核心素材冲散反而干扰主 LLM 的判断。5.3 批量复盘用外部调度器触发 Dify API工作流应用自带 API意味着我可以写一个定时任务每天凌晨自动把前一天的新增聊天记录批量扔进 hindsight。我用一个简单的 Python 脚本配合 cron 实现import requests api_url https://your-dify-endpoint/v1/workflows/run api_key app-xxx payload { inputs: { project_name: 客服故障复盘, raw_material: open(/data/chat_records.txt, encodingutf-8).read(), review_mode: quick }, response_mode: blocking, user: scheduler } res requests.post( api_url, jsonpayload, headers{Authorization: fBearer {api_key}} ) print(res.json())Dify 返回的 output 字段可以直接再写入数据库或发送到 IM 机器人。这个方案的好处是历史报告不会丢后续可以用 SQL 查询“行动项完成率”“盲点出现频率”把复盘从一次性产出变成长期数据资产。6. 让 hindsight 真正持续下去的几个个人经验6.1 复盘报告不是越全越好我前面提过完整模板 2000 字反而没人看。一个报告能在 10 秒内被读完、3 分钟内从“看到”变成“改一个行为”它才算合格。所以我后来每次迭代都问自己一句这行输出会导致我做什么不同的事如果不会就删。6.2 提示词模板要版本化Dify 的工作流应用支持导出 DSL 文件YAML我直接用 git 管理这些 DSL。每次改提示词就提交一次这样哪天发现效果回退可以 checkout 回上一个版本对比。这比在网页里手改来回试靠谱得多。6.3 一开始别追求复杂架构先用一个 LLM 节点加一个输出节点跑通确认“报告有人看”之后再往里加知识检索和行动项评分。hindsight 这个名字一直提醒我事后看明白不难难在把明白变成下一次的提前预判。一个能让你每个项目多一次系统性回顾的工作流比任何花哨的 prompt 都值钱。最后再分享一个小技巧Dify 的“变量提取”节点看起来很不起眼但在我这个项目里它是救场最多次的节点。下拉字段转字符串、数组拍平、长文本清洗全是在这里处理的。如果你在搭类似的工作流时发现 Jinja 模板各种报错先别怀疑模型问题回头看一眼变量类型大概率能省下半个小时。
返回列表