错误归因
把失败归到工具、数据、推理、规则,而不是“换个模型试试”。
一句话理解:错误归因就是把每一个失败案例追到“最先出错的那一环”,再按数量与影响排序修复。它决定你该改工具、补数据、调指令、改规则,还是真的需要换模型。
评测结果出来了:100 个客服工单案例,正确 87、错误 8、无法判断 5(示例数字)。评审会上,最常听到的一句话是:“要不换个更强的模型试试?”
换模型也许有用,但在不知道失败原因之前,这是在赌。如果 13 个失败里有 10 个是工具返回的数据有问题,换任何模型都救不回来,还白白增加了成本。Hamel Husain 与 Shreya Shankar 在评估 FAQ 中把错误分析称为评估中最重要的活动。这一课用这 13 个失败案例,完整演示一次归因。
四类根因,外加“评测本身出错”
失败分类讲的是运行时的分类,目的是决定当下怎么恢复;这里的归因是离线分析,目的是决定系统该怎么改。所以要追到根因层面:
| 根因 | 判断问题 | 常见表现 | 典型修复 | 通常由谁修 |
|---|---|---|---|---|
| 工具错误 | 工具的实现、描述或返回是否有问题? | 返回缺字段或排序混乱;两个工具描述相似导致选错;错误信息无法指导重试 | 修接口;改工具名称与描述;精简或补全返回;改进错误信息 | 研发 |
| 数据缺失 | Agent 需要的信息,在它做决定时拿得到吗? | 源系统没有记录;有数据但没有工具能查;上下文里没带进去;权限不够 | 补工具或数据源;调整上下文组装;为缺失情况定义“无法判断” | 研发、数据团队 |
| 推理错误 | 信息齐全、规则明确,Agent 仍然判断错了吗? | 误读字段含义;忽略关键事件;时区与数值计算错误 | 把计算交给程序;在指令中补充字段说明与示例;拆分步骤;最后才考虑换模型 | 产品、研发 |
| 规则错误 | 指令或 SOP 中的规则本身对吗? | 规则过时;规则之间冲突;规则没覆盖某类情况 | 与业务方确认后修改规则与指令;必要时改由程序强制执行 | 产品、业务方 |
| 评测问题 | 失败是真的失败吗? | 标准答案错了;评分器把有效解法判为失败;题目有歧义 | 修正答案、评分器或题目 | 评测负责人 |
最后一行常被忽略。Anthropic 在《Demystifying evals for AI agents》中提醒,任务失败时读运行记录,能分辨是 Agent 真的犯了错,还是评分器拒绝了一个有效的解法。
归因流程
一次归因按以下顺序进行:
有三个关键动作:
- 先写开放式笔记,再归类。 Hamel Husain 与 Shreya Shankar 的 FAQ 把这个过程描述为先做开放编码(自由记录发现的问题),再做轴向编码(把笔记归纳成失败分类体系)。先入为主地套分类,很容易把新问题硬塞进旧类别。
- 找第一个出错的步骤。 日志工具返回的事件顺序是乱的,Agent 据此把“支付回调失败”误判成“用户未付款”。表面上是推理错了,根因却在工具。
- 读到不再有新发现为止。 上述 FAQ 建议持续查看运行记录,直到新的记录不再暴露新的失败模式。
以第 2 点中的 case-007 为例,表面症状和根因之间隔着一步连锁反应:
实例:13 个失败案例的归因表
以下是 8 个错误和 5 个无法判断的逐条归因(全部为示例):
| 案例 | 结果 | 现象 | 第一个出错的步骤 | 根因 | 修复建议 |
|---|---|---|---|---|---|
| case-007 | 错误 | 判为用户未付款,实为支付回调失败 | 日志工具返回的事件没有按时间排序,Agent 把列表最后一条当成最新事件 | 工具错误 | 工具按时间倒序返回,并增加 latest_event 字段 |
| case-019 | 错误 | 查成了同一邮箱下的另一张工单 | 调用了按邮箱查询的工具,而不是按工单号查询的工具,两个工具描述几乎一样 | 工具错误 | 改名并重写描述,写明各自的适用场景 |
| case-023 | 错误 | 判为工单未关联订单 | 订单号记录在工单的扩展字段里,上下文中没有组装订单信息 | 数据缺失 | 工单查询结果中附带关联订单摘要 |
| case-031 | 错误 | 结论遗漏已部分退款的事实 | 支付工具不返回退款记录 | 数据缺失 | 为支付工具补充退款字段 |
| case-048 | 错误 | 判为用户未付款 | 历史迁移订单在支付系统中没有记录,Agent 把“查不到”理解为“未付款” | 数据缺失 | 工具区分“无记录”与“未付款”;无记录时输出无法判断 |
| case-052 | 错误 | 超时时长少算 8 小时,未触发退款阈值 | 日志时间为 UTC,Agent 与北京时间直接相减 | 推理错误 | 时长改由程序计算,统一时区 |
| case-066 | 错误 | 判为仍在处理中 | 日志中有“用户已撤销”事件,Agent 忽略了它 | 推理错误 | 在指令中列出关键事件优先级,并补充一个撤销示例 |
| case-090 | 错误 | 建议对企业客户自动退款 | 指令中的退款规则没有写企业客户的例外 | 规则错误 | 与业务方确认后补充例外,并由程序校验退款资格 |
| case-013 | 无法判断 | 称日志不可用 | 日志接口超时一次,Agent 没有重试就放弃 | 工具错误 | 工具层对超时自动重试一次,并返回可重试标记 |
| case-058 | 无法判断 | 称日志不可用 | 同上 | 工具错误 | 同上 |
| case-071 | 无法判断 | 称支付状态未知 | 支付工具返回通用错误,没有说明是参数问题(订单号带了空格) | 工具错误 | 参数预处理,错误信息写明原因 |
| case-084 | 无法判断 | 称缺少关联订单 | 与 case-023 相同,上下文未包含订单信息 | 数据缺失 | 同 case-023 |
| case-095 | 无法判断 | 称无法确认最后的处理人 | 处理人信息存在于客服排班系统中,但 Agent 没有能查询该系统的工具 | 数据缺失 | 评估是否需要新增只读的排班查询工具 |
汇总如下:
| 根因 | 错误 | 无法判断 | 合计 | 占全部失败 |
|---|---|---|---|---|
| 工具错误 | 2 | 3 | 5 | 38% |
| 数据缺失 | 3 | 2 | 5 | 38% |
| 推理错误 | 2 | 0 | 2 | 15% |
| 规则错误 | 1 | 0 | 1 | 8% |
| 合计 | 8 | 5 | 13 | 100%(四舍五入) |
从 100 个案例到根因分布,可以画成一个漏斗:
结论一目了然:13 个失败中有 10 个(约 77%)来自工具与数据,换一个更强的模型也解决不了;真正可能受益于更强模型的,只有 2 个推理错误,而这两个都有更便宜、更确定的修法。
别忘了还要看 87 个“正确”案例。如结果评估与轨迹评估所说,其中可能有“蒙对”的情况,它们也应该进入归因清单。
从归因到修复:排优先级
不是所有问题都值得先修。一个简单的排序方法是看三件事:覆盖多少失败、影响有多严重、修复成本多高。
| 修复项 | 覆盖的失败 | 影响 | 修复成本 | 优先级 |
|---|---|---|---|---|
| 工单结果附带关联订单摘要 | 2 个(023、084) | 中 | 低 | P0 |
| 日志工具:排序、超时重试 | 3 个(007、013、058) | 中 | 低 | P0 |
| 补充企业客户退款例外,由程序校验退款资格 | 1 个(090) | 高:直接涉及资金 | 中 | P0 |
| 时长改由程序计算 | 1 个(052) | 高:影响退款判断 | 低 | P0 |
| 两个查询工具改名并重写描述 | 1 个(019) | 中 | 低 | P1 |
| 支付工具区分“无记录”与“未付款”,补充退款字段,改进错误信息 | 3 个(031、048、071) | 中 | 中 | P1 |
| 关键事件优先级说明与示例 | 1 个(066) | 中 | 低 | P1 |
| 新增排班查询工具 | 1 个(095) | 低 | 高 | P2,先观察频率 |
注意 case-090 只有 1 个案例,却排在 P0:它涉及错误退款,影响远大于数量。
每修一项,都要把对应的失败案例放进回归集,然后全量重跑评测集。改 Prompt 修好了 case-066,可能会让另外几个原本正确的案例出错,参见 Prompt 的迭代与版本管理。
什么时候才真的该换模型
满足以下条件时,换模型才是合理选项:
- 工具与数据问题已经修完,Agent 做判断时需要的信息都拿得到;
- 规则明确、指令清晰,业务专家看同样的信息能稳定地做出正确判断;
- 剩余失败集中在推理错误,而且无法改由程序计算;
- 在同一套评测集上做小规模对比,候选模型确实有明显提升,并且成本与延迟可以接受。
模型对比与选型的方法见模型选型与路由。
常见误区
- 只看汇总分数,不读运行记录。 不读记录的归因只是猜测。
- 把所有失败都归为“模型不够聪明”。 这是最省事、也最没用的归因,通常掩盖了工具和数据问题。
- 归因到最后一个出错的步骤。 最后一步往往只是症状,要往上游找第一个出错的地方。
- 没有检查评测本身。 标准答案错误、评分器过严,会让团队在不存在的问题上浪费时间。
- 分类标准只在一个人脑子里。 每类根因要有书面定义和示例,换人归因时结果才能保持一致。
产品经理检查清单
- 每轮评测之后,是否有人逐条阅读失败案例的运行记录?
- 根因分类是否有书面定义?是否包含“评测本身出错”这一类?
- 归因时是否定位到“第一个出错的步骤”?
- 修复优先级是否同时考虑了数量、影响与成本?
- 每个修复是否都配有回归案例,并且全量重跑过?
- 提出“换模型”之前,是否已经排除了工具、数据与规则问题?
练习
用本课的 13 行归因表做一次“复核”,或用你自己 Agent 的至少 10 个失败案例做一次完整归因,用 30–60 分钟完成:
- 为每个失败案例写一句开放式笔记,再归入五类根因之一。
- 至少找出一个“表面是推理错误,根因在上游”的案例,写出你的判断依据。
- 做出汇总表,并按“覆盖数量、影响、修复成本”排出前三个修复项。
- 为排第一的修复项写出对应的回归案例(输入与期望结果)。
延伸阅读
- AI Evals: Everything You Need to Know(Hamel Husain、Shreya Shankar):错误分析、开放编码与轴向编码、读多少条记录才够。
- Demystifying evals for AI agents(Anthropic):读运行记录、区分 Agent 错误与评分器错误。
下一步
离线归因、修复、回归之后,还要确认改动在真实流量里同样有效。下一课「线上评估与回归」讲离线测试、灰度、A/B 实验,以及每次变更后的回归检查。