Hindsight 实战:在 Dify 工作流中构建自我优化系统
1. 从“事后诸葛亮”到系统能力hindsight 到底在解决什么问题第一次看到 “hindsight” 这个词是在一个做 AI 应用的朋友群里。有人甩了张截图说“这玩意儿终于把事后复盘做成了产品”。我当时的第一反应是这不就是“事后诸葛亮”吗但仔细琢磨了一下发现事情没那么简单。hindsight 这个词本身的意思是“后见之明”中文语境里最贴切的翻译就是“事后诸葛亮”。但作为一个项目名称它指向的是一类非常具体的技术需求让系统能够回顾已经发生的事情从中提取出可复用的经验并且把这些经验反馈到未来的决策中。这听起来像是人类在做的事情但 hindsight 要解决的是机器如何做这件事。为什么这件事突然变得重要了因为现在越来越多的 AI 应用不再是“一问一答”就结束的。比如一个智能客服系统它每天要处理成千上万条对话一个自动化工作流它可能连续运行几个月中间经历各种状态变化。这些系统产生的大量交互记录如果只是躺在日志文件里那就是死数据。hindsight 要做的就是把这些死数据变成活的经验。具体来说hindsight 通常涉及几个核心能力。第一是轨迹记录也就是把系统运行过程中的关键节点、输入输出、决策路径都保存下来。第二是模式提取从这些轨迹里找出反复出现的成功模式或者失败模式。第三是经验注入把提取出来的模式转化成可以影响未来行为的规则、提示词或者微调数据。这三步走下来一个系统就具备了“吃一堑长一智”的能力。我之所以对这个方向特别感兴趣是因为在实际做 AI 应用开发的时候最头疼的就是“同样的错误反复犯”。你调好了一个提示词在测试集上跑得挺好一上线遇到真实用户的各种奇怪输入立马就崩了。崩了之后你去修修完又崩在另一个地方。整个过程就像打地鼠永远打不完。hindsight 提供的思路是不要每次都靠人去修让系统自己从失败中学习把那些踩过的坑变成系统的一部分。这个思路听起来很美好但落地的时候有一堆细节要处理。比如什么样的轨迹值得记录记录得太细存储成本爆炸记录得太粗提取不出有用的模式。再比如提取出来的模式怎么保证是“正确”的万一系统从一次偶然的成功里总结出了错误的经验下次反而更糟。这些问题我在后面的章节里会逐一展开。如果你正在做 AI Agent、自动化工作流、或者任何需要长期运行和持续优化的系统hindsight 这套思路值得你花时间研究。它不是一个具体的库或者框架而是一种系统设计理念。理解了它你再看 dify 这类平台的工作流设计会有完全不同的视角。2. hindsight 与 dify 的结合点工作流复盘到底怎么做2.1 为什么 dify 工作流特别需要 hindsightdify 是一个做 AI 应用编排的平台你可以用拖拽的方式把各种节点连起来形成一个完整的工作流。比如一个典型的 RAG 问答流程用户输入 → 意图识别 → 知识库检索 → 重排序 → 大模型生成 → 输出。这个流程跑一次两次没问题但跑上几百次之后你就会发现有些环节特别容易出问题。我拿自己搭过的一个客服工单分类工作流举例。流程是这样的用户提交工单 → 提取关键词 → 匹配分类规则 → 如果置信度低就转人工。刚上线的时候准确率还行但跑了两周之后发现“退款”类的工单经常被分到“咨询”类。我去查日志发现是因为很多用户会用“我想问一下能不能退”这种表达关键词提取出来是“问”和“退”规则匹配的时候“问”的权重更高就分错了。这个问题如果靠人工发现可能要等用户投诉才会注意到。但如果工作流本身有 hindsight 能力它就能在运行过程中自动记录哪些工单被转人工了、人工最终改成了什么分类、原始分类和修正分类之间的差异是什么。积累几十条这样的记录之后系统就能自动总结出“包含‘能不能退’、‘想退’这类表达的工单应该优先匹配退款类”这样的规则。这就是 hindsight 在 dify 工作流里的核心价值把人工修正的过程变成系统自我优化的燃料。dify 本身提供了工作流运行日志但日志只是原始数据hindsight 要做的是从日志里提炼出可执行的改进策略。2.2 在 dify 里落地 hindsight 的三个层次第一个层次是记录层。这一步最简单但最容易被忽略。很多人搭工作流的时候只关注“跑通”不关注“跑通之后留下了什么”。我的做法是在每个关键节点后面加一个“记录”节点把输入、输出、时间戳、节点状态都写到一个结构化的存储里。dify 支持自定义代码节点你可以用 Python 写一个简单的记录函数把数据写到数据库或者文件里。这里有个细节要注意不要只记录成功的结果。失败的结果、超时的结果、被人工干预的结果这些才是最有价值的。我见过很多人只记录最终输出中间过程全丢了等到出问题的时候根本不知道是哪一步错的。第二个层次是分析层。有了记录之后你需要定期跑一个分析任务从记录里找模式。最简单的分析是统计哪个节点的失败率最高哪类输入的异常率最高稍微复杂一点的是聚类把相似的失败案例聚在一起看看它们有没有共同特征。再复杂一点的是因果推断某个节点的输出变化是不是导致了后续节点的失败在 dify 里做分析我通常会用两种方式。一种是外挂一个定时任务每天凌晨跑一次分析脚本把结果写到一张报表里。另一种是在工作流里直接加一个“分析”分支当某个节点的失败次数超过阈值时自动触发分析。两种方式各有优劣前者适合做全局优化后者适合做实时响应。第三个层次是注入层。分析出来的结果要能反过来影响工作流的行为。最简单的注入是修改提示词如果发现某类输入经常导致模型输出格式错误就在提示词里加一句“遇到这类输入时请严格按照以下格式输出”。复杂一点的注入是调整流程结构如果发现某个分支的命中率极低就把它合并到另一个分支里。注入层最难的地方在于验证。你改了一个提示词怎么知道改得对不对我的做法是每次注入之后先在小流量上跑一段时间对比注入前后的关键指标。如果指标变好了再全量如果变差了就回滚。这个过程听起来很笨但比盲目全量安全得多。2.3 一个具体的 hindsight 循环示例我拿一个实际跑过的例子来说明。这是一个内容审核工作流流程是用户提交内容 → 敏感词过滤 → 大模型判断 → 人工复核仅对模型判断为“不确定”的内容。运行一周后记录层积累了 500 条人工复核记录。分析层跑了一遍发现一个模式模型对“讽刺性表达”的判断准确率特别低很多被模型标为“不确定”的内容人工复核后其实是正常的。进一步分析发现这些内容都有一个共同特征包含“呵呵”、“真是太好了”这类反语表达。注入层的操作是在提示词里加一段说明——“当内容包含反语表达时不要仅凭字面意思判断要结合上下文分析真实意图”。同时在敏感词过滤节点后面加一个“反语检测”分支把包含反语特征的内容直接送到人工复核不再经过模型判断。改完之后又跑了一周人工复核量下降了 40%模型判断的准确率从 72% 提升到了 89%。这个提升不是靠换模型或者调参数纯粹是靠 hindsight 循环把人工经验转化成了系统能力。这个例子里有几个关键点值得注意。第一分析层不是一次性做完的而是先发现“讽刺性表达”这个大类别再细化到“反语表达”这个子类别。第二注入层的改动是局部的没有动整个流程只加了提示词和分支。第三验证周期是一周不是一天因为内容审核的样本分布有周期性短时间的数据波动说明不了问题。3. 构建 hindsight 能力时最容易踩的五个坑3.1 记录粒度失控要么太粗要么太细我刚开始做 hindsight 的时候犯的第一个错误就是记录得太细。每个节点的输入输出、每个变量的中间状态、每次模型调用的完整 prompt 和 response全都存下来。结果一周不到数据库就爆了。更麻烦的是数据太多之后分析脚本跑一次要几个小时根本没法快速迭代。后来我调整了策略把记录分成三个级别。必须记录的是每个节点的输入输出摘要、节点的执行状态成功/失败/超时、人工干预的标记。选择性记录的是模型的完整 prompt 和 response只在节点失败或者被人工干预时才存。不记录的是中间变量的每一次变化只记录最终值。这个分级策略的核心逻辑是记录的目的是为了分析不是为了存档。如果一条数据你永远不会去分析它那就不要记。我见过有人把工作流的每一步都录屏存下来说是“以备不时之需”结果从来没看过。这种记录就是纯粹的浪费。还有一个细节是记录格式。我强烈建议用结构化的格式比如 JSON而不是纯文本日志。JSON 的好处是分析脚本可以直接解析不用写复杂的正则表达式。字段命名也要统一比如所有节点都用node_id、input、output、status、timestamp这几个字段不要这个节点叫input_text那个节点叫user_query。3.2 把相关性当成因果性分析层最容易犯的错误是看到两个事情经常一起出现就认为它们有因果关系。比如发现“模型输出格式错误”和“用户输入包含特殊符号”经常同时出现就得出结论说特殊符号导致了格式错误。但实际上可能只是巧合或者有第三个因素同时影响了这两者。我踩过的一个真实坑在一个翻译工作流里发现“翻译质量差”的案例中有 80% 都发生在下午。于是得出结论说下午的翻译质量差可能是模型负载高导致的。后来仔细分析才发现下午的案例里有很多是特定类型的文档这些文档本身就更难翻译。时间只是一个混淆因素真正的原因是文档类型。避免这个坑的方法是做对照实验。如果你怀疑 A 导致了 B那就找一组有 A 的案例和一组没有 A 的案例对比它们的 B 发生率。如果差异显著再考虑是不是因果关系。在 dify 里做对照实验很方便你可以复制一个工作流改掉一个变量然后两个版本同时跑对比结果。还有一个更简单的方法问三次为什么。看到“下午翻译质量差”问为什么下午差因为下午的文档类型不同。为什么下午的文档类型不同因为下午的提交流程不一样。为什么提交流程不一样因为下午是另一个团队在提交。问到第三层往往就能找到真正的原因。3.3 注入层的改动没有回滚机制注入层是 hindsight 循环里风险最高的一步因为你在直接改变系统的行为。如果改错了系统可能会变得更差。我见过最惨的案例是有人根据分析结果把某个节点的提示词改了一大段结果上线之后整个工作流的成功率从 85% 掉到了 40%花了半天才回滚。我的做法是任何注入层的改动都必须有回滚方案。具体来说每次改动之前先把当前的工作流版本完整备份一份。改动之后先在小流量上跑同时监控关键指标。如果指标下降超过 5%自动回滚。如果指标持平或者上升再逐步扩大流量。在 dify 里实现这个机制可以用“版本管理”功能。dify 支持工作流的版本快照你可以把每次改动都存成一个新版本然后通过 API 控制不同版本的流量比例。我通常会设三个阶段5% 流量跑一天20% 流量跑三天100% 流量跑一周。每个阶段结束之后对比新旧版本的关键指标决定是否进入下一阶段。还有一个经验是不要一次改多个地方。如果你同时改了提示词和流程结构出了问题你根本不知道是哪个改动导致的。每次只改一个变量改完验证有效之后再改下一个。这样虽然慢但稳。3.4 忽略了“负样本”的价值大多数人在做 hindsight 的时候注意力都在“怎么把失败的案例变成成功的”。但我的经验是成功的案例同样有价值尤其是那些“差点失败但最后成功了”的案例。举个例子。在一个意图识别工作流里大部分成功的识别都是“一眼就能看出来”的简单案例。但有一小部分案例模型的置信度很低最后却识别对了。这些案例才是最有价值的因为它们代表了模型的“能力边界”。如果你能分析出这些案例的共同特征就能知道模型在什么情况下是“勉强能行”的从而在提示词里加一些针对性的引导。我在实际操作中会把案例分成四类高置信度成功、低置信度成功、高置信度失败、低置信度失败。高置信度成功不用管高置信度失败要重点分析说明模型有系统性偏差低置信度成功要提取特征说明模型在边界上还能救低置信度失败要加人工兜底。这个分类方法看起来简单但能帮你把有限的精力放在最有价值的案例上。我见过有人把所有失败案例一视同仁地分析结果花了大量时间在那些“明显是输入有问题”的案例上真正需要优化的系统性偏差反而被忽略了。3.5 分析频率和业务节奏不匹配最后一个坑是关于节奏的。hindsight 循环不是越快越好。我一开始设的是每天分析一次结果发现很多“模式”其实是当天的随机波动第二天就消失了。频繁的分析不仅浪费计算资源还会导致过度拟合——你根据一天的噪声数据改了系统第二天噪声没了改动反而成了负担。后来我把分析频率调整成日常监控每天跑但只做统计不做决策深度分析每周跑一次基于一周的数据做模式提取和注入决策。这个节奏和大多数业务的自然周期是匹配的比如客服工单的分布通常以周为单位变化内容审核的样本也有工作日和周末的差异。还有一个节奏问题是不要在工作流刚上线的时候就做 hindsight。新上线的工作流样本量不够数据分布也不稳定这时候分析出来的模式很可能是错的。我的经验是至少等积累 500 条以上的有效记录再开始做深度分析。在此之前只做基础的监控和告警。4. 从零搭建一个 hindsight 模块我的实操步骤4.1 环境准备与数据存储选型在 dify 里搭建 hindsight 模块你不需要额外的服务器但需要一个地方存记录。我的建议是用 PostgreSQL因为 dify 本身就用 PostgreSQL 存元数据你可以直接复用同一个数据库实例省得再维护一套。建表的时候我通常建三张表。第一张是trajectory存每次工作流运行的完整轨迹字段包括run_id、workflow_id、start_time、end_time、status、input_summary、output_summary。第二张是node_record存每个节点的执行记录字段包括record_id、run_id、node_id、node_type、input、output、status、duration_ms、error_message。第三张是human_intervention存人工干预的记录字段包括intervention_id、run_id、node_id、original_output、corrected_output、operator、timestamp。这三张表的关系是一个trajectory对应多个node_record一个node_record可能对应零个或多个human_intervention。查询的时候通过run_id关联。注意input和output字段建议用 JSONB 类型不要用纯文本。JSONB 支持索引和查询分析的时候方便很多。如果数据量特别大可以考虑按时间分区比如每个月一张表。存储成本方面我实测下来一个中等复杂度的工作流10 个节点左右每次运行的记录大约 5-10 KB。如果每天跑 1000 次一个月大约 150-300 MB。这个量级对 PostgreSQL 来说毫无压力。但如果你的工作流每天跑几十万次那就需要考虑采样记录了比如只记录 10% 的运行。4.2 在工作流里埋点哪些节点必须记录不是所有节点都需要记录。我的原则是只记录“决策节点”和“外部交互节点”。决策节点是指那些会根据输入做出不同选择的节点比如意图识别、条件分支、分类器。外部交互节点是指那些调用外部服务的节点比如大模型调用、API 请求、数据库查询。为什么只记录这两类因为 hindsight 的核心是分析“系统在什么情况下做了什么决策结果如何”。纯计算节点比如字符串拼接、格式转换不需要记录它们的输出完全由输入决定没有分析价值。在 dify 里埋点有两种方式。一种是用“代码节点”在节点里直接写数据库插入逻辑。这种方式灵活但每个节点都要写一遍比较繁琐。另一种是用“HTTP 请求节点”把记录数据发到一个统一的记录服务由记录服务负责写库。这种方式更干净但需要额外部署一个服务。我通常用第一种方式因为 dify 的代码节点支持 Python写几行psycopg2的插入语句就行。为了减少重复代码我会写一个通用的记录函数放在每个代码节点里调用。函数签名大概是这样的def record_node(run_id, node_id, node_type, input_data, output_data, status, duration_ms, error_messageNone): # 连接数据库插入记录 # 如果插入失败只打日志不抛异常避免影响主流程 pass这里有个关键点记录失败不能影响主流程。我见过有人因为记录服务的数据库连接超时导致整个工作流卡住。所以记录逻辑一定要用 try-except 包起来失败就失败不能抛出去。4.3 分析脚本的编写从统计到模式提取分析脚本我通常用 Python 写跑在定时任务里。第一步是基础统计比如每个节点的成功率、失败率、平均耗时每种错误类型的出现频率人工干预的频率和分布这些统计用 SQL 就能做不需要复杂的逻辑。比如查每个节点的失败率SELECT node_id, COUNT(*) as total, SUM(CASE WHEN status failed THEN 1 ELSE 0 END) as failed, ROUND(SUM(CASE WHEN status failed THEN 1 ELSE 0 END)::numeric / COUNT(*), 4) as fail_rate FROM node_record WHERE timestamp NOW() - INTERVAL 7 days GROUP BY node_id ORDER BY fail_rate DESC;第二步是模式提取这一步需要一些简单的机器学习。我常用的是聚类和关联规则。聚类用sklearn的 KMeans 或者 DBSCAN把相似的失败案例聚在一起。关联规则用mlxtend的 Apriori找出“哪些输入特征经常和失败一起出现”。举个例子在一个问答工作流里我把所有失败的案例拿出来提取它们的输入特征问题长度、是否包含数字、是否包含英文、问题类型等然后跑聚类。结果发现有一类失败案例的共同特征是“问题长度在 10-20 字之间且包含‘怎么’这个词”。进一步分析发现这类问题通常是“怎么退款”、“怎么修改地址”这种操作类问题而工作流的知识库主要是产品介绍没有操作指南。这就是一个明确的改进方向补充操作类知识库。第三步是生成改进建议。这一步我目前还是半自动的脚本会输出分析结果但具体的改进方案由人来定。比如脚本说“发现一类失败案例特征是 X”我会去看这些案例的具体内容然后决定是改提示词、加分支、还是补充知识库。4.4 注入与验证小流量灰度怎么做注入层的操作我通常分三种。第一种是提示词注入把分析出来的模式写成一段说明加到相关节点的提示词里。第二种是规则注入在条件分支里加一条新规则把特定类型的输入导向特定处理路径。第三种是知识注入把分析出来的常见问题补充到知识库里。不管哪种注入都要走灰度流程。我的灰度流程是这样的备份当前工作流版本存为v_old修改工作流存为v_new在 dify 的 API 网关层配置流量分配v_new占 5%跑 24 小时对比v_old和v_new的关键指标如果v_new的指标不差于v_old把流量调到 20%再跑 72 小时再次对比如果仍然不差全量切换到v_new关键指标的选择取决于业务。对于问答类工作流我看的是“回答准确率”和“人工转接率”。对于分类类工作流我看的是“分类准确率”和“置信度分布”。对于生成类工作流我看的是“格式合规率”和“用户反馈评分”。对比的时候要注意统计显著性。5% 流量跑 24 小时如果每天总请求量是 1000 次那v_new只有 50 次请求。50 个样本的指标波动很大不能仅凭这个就下结论。我的经验是每个阶段至少积累 200 个样本再对比。如果请求量小就延长灰度时间。5. hindsight 在不同场景下的变体玩法5.1 客服场景从工单修正中学习分类规则客服场景是 hindsight 最容易出效果的场景因为人工修正的数据天然存在。每个被转人工的工单人工客服都会重新分类或者重新回答这些修正记录就是最好的学习材料。我在一个电商客服项目里用 hindsight 循环把工单分类准确率从 68% 提升到了 91%。具体做法是每天收集被人工修正的工单提取原始分类和修正分类的差异然后用一个简单的文本分类模型比如 TF-IDF 逻辑回归去学习这些差异。学到的模式会转化成规则注入到分类节点里。这个场景的关键是修正数据的质量。有些人工修正其实是随意的比如客服心情不好就改了个分类这种数据会引入噪声。我的做法是只采纳“多个客服对同类工单做出一致修正”的数据。比如三个客服都把“退款咨询”改成了“退款申请”那这个修正就是可信的。还有一个细节是时效性。电商的业务变化很快上个月有效的分类规则这个月可能就过时了。所以 hindsight 循环要持续跑不能跑一次就完事。我通常设的是每周跑一次分析每月做一次全量规则更新。5.2 内容生成场景从人工编辑中学习风格偏好内容生成场景的 hindsight 循环稍微不一样因为“正确”的标准更主观。一篇文章生成出来好不好没有绝对的标准取决于编辑的偏好和平台的调性。我的做法是把编辑的修改记录作为学习信号。比如工作流生成了一篇初稿编辑修改了标题、调整了段落顺序、替换了一些词汇。这些修改就是“风格偏好”的体现。积累几十篇修改记录之后就能提取出一些模式比如编辑总是把长句拆成短句、总是把被动语态改成主动语态、总是把专业术语替换成通俗表达。这些模式可以注入到生成节点的提示词里。比如加一句“请使用短句每句不超过 30 字请使用主动语态请避免使用专业术语用通俗表达替代”。改完之后编辑的修改量会明显下降。这个场景的难点是修改记录的获取。如果编辑是在外部工具里修改的你拿不到修改前后的对比。我的建议是尽量让编辑在工作流内部完成修改或者用一个 diff 工具把修改前后的版本都存下来。dify 本身不提供这个功能但你可以外挂一个简单的版本对比服务。5.3 自动化工作流场景从异常恢复中学习容错策略自动化工作流比如数据同步、定时任务的 hindsight 循环重点不在“优化效果”而在“提高稳定性”。这类工作流最怕的是某个环节挂了整个流程卡死。我的做法是记录每次异常的发生位置、异常类型、恢复方式。比如某个 API 调用超时了系统自动重试了三次第三次成功了。这个“重试三次成功”的记录就是有价值的。积累多了之后就能总结出“哪些 API 在什么时间段容易超时重试几次比较合适”。这些模式可以注入到工作流的容错配置里。比如把默认重试次数从 1 次改成 3 次或者把超时时间从 5 秒改成 10 秒。改完之后工作流的异常中断率会明显下降。这个场景的关键是区分“可恢复异常”和“不可恢复异常”。可恢复异常比如网络抖动值得重试不可恢复异常比如参数错误重试多少次都没用。hindsight 分析的时候要把这两类分开否则会得出错误的结论。5.4 多 Agent 协作场景从对话历史中学习协作策略多 Agent 场景是 hindsight 最复杂的应用场景。多个 Agent 互相协作完成任务每个 Agent 都有自己的决策逻辑整体行为很难预测。我的做法是把整个协作过程当成一个“对话历史”来记录。每个 Agent 的发言、每个 Agent 的行动、最终的结果都按时间顺序存下来。分析的时候重点看“哪些协作模式导致了成功哪些导致了失败”。比如在一个“研究员 写手 审核员”的三 Agent 协作里发现成功的案例通常是研究员先给出大纲写手按大纲写审核员提修改意见写手修改。失败的案例通常是研究员直接给了一堆素材写手自由发挥审核员大改写手再改来回好几轮。这个模式提取出来之后就可以注入到协作流程里强制研究员先出大纲写手必须按大纲写。改完之后协作效率明显提升。这个场景的难点是状态空间太大。三个 Agent每个 Agent 有多个可能的行动组合起来就是指数级的复杂度。我的建议是先固定其他 Agent 的行为只优化一个 Agent 的策略。等这个 Agent 稳定了再优化下一个。不要试图一次性优化所有 Agent。6. 我踩过的三个真实坑和对应的解法6.1 记录数据污染了生产库有一次我在生产环境的工作流里直接写记录逻辑结果因为一个 bug记录函数把整个node_record表锁住了导致所有工作流都卡住。那次事故让我明白了一个道理记录逻辑必须和主流程隔离。解法是记录数据先写到一个本地的消息队列比如 Redis 的 list然后由一个独立的消费者进程异步写库。这样即使写库失败也不会影响主流程。Redis 的 list 操作是 O(1) 的几乎不会成为瓶颈。如果不想引入 Redis也可以用文件系统。每个工作流实例把记录写到一个临时文件里然后由一个定时任务批量导入数据库。这种方式更简单但实时性差一些。6.2 分析结果过拟合了短期波动有一段时间我每天跑一次分析然后根据分析结果调整工作流。结果发现工作流的表现忽好忽坏今天调好了明天又不行了。后来才意识到我是在拟合每天的随机波动。解法是拉长分析窗口并且用滑动平均。不要只看一天的数据至少看七天。而且不要看单点的指标要看七天的滑动平均。如果滑动平均在上升说明改动有效如果只是单点上升很可能是噪声。还有一个技巧是保留一个对照组。每次改动的时候留 10% 的流量跑旧版本作为对照。这样即使整体指标在波动你也能通过对比实验组和对照组来判断改动是否真的有效。6.3 注入的规则互相冲突有一次我根据分析结果往工作流里加了三条新规则。结果上线之后发现这三条规则在某些输入上会互相冲突导致工作流进入死循环。解法是规则注入之前先做冲突检测。具体来说把新规则和现有规则放在一起用一批测试输入跑一遍看看有没有规则同时命中但导向不同结果的情况。如果有就说明有冲突需要调整规则的优先级或者合并规则。在 dify 里做冲突检测可以建一个测试工作流把所有规则都放进去然后用一批覆盖各种情况的输入跑一遍。如果某个输入触发了多条规则就人工检查一下应该走哪条。这个过程比较繁琐但比上线之后出问题强。还有一个更根本的解法是规则数量不要太多。我现在的原则是一个节点的规则不超过 10 条。超过 10 条就说明这个节点太复杂了应该拆成多个节点。每个节点只负责一个维度的判断规则之间就不容易冲突。7. 关于 hindsight 的一些个人体会做 hindsight 这件事最大的挑战不是技术而是心态。技术上的东西记录、分析、注入都有成熟的工具和方法。但心态上你需要接受一个事实系统的优化是一个持续的过程没有终点。我刚开始做的时候总想着“这次改完就一劳永逸了”。结果每次改完跑一段时间又发现新的问题。后来我想通了hindsight 本质上是在对抗系统的熵增。任何系统如果不持续维护都会慢慢退化。hindsight 就是维护的手段它不是一次性的任务而是日常运营的一部分。还有一个体会是不要追求完美的自动化。我见过有人想做一个全自动的 hindsight 系统从记录到分析到注入全部自动完成人完全不参与。结果做出来的系统要么过于保守什么都不敢改要么过于激进乱改一通。我的做法是记录和分析尽量自动化但注入环节保留人工审核。人只需要看分析报告决定要不要采纳建议以及怎么采纳。这个环节的人工投入不大但能避免很多低级错误。最后一点是hindsight 的价值和系统的复杂度成正比。一个简单的“输入 → 输出”工作流hindsight 的价值有限因为问题一目了然。但一个复杂的多节点、多分支、多 Agent 的工作流hindsight 的价值就非常大因为人很难靠肉眼看出问题在哪。如果你正在做复杂的 AI 应用hindsight 值得你投入时间。如果你只是做一个简单的问答机器人那可能不需要这么重的机制。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →