10.12概念更新于 2026年9月28日

Harness 工程:用轨迹和评测迭代

读轨迹找失败模式,改工具、提示与环境,再用评测验证改进。

10.12 · 课时讲解

Harness 工程:用轨迹和评测迭代

跑出轨迹、找到失败模式、每次只改一处,再用同一组任务验证。

1 / 13

一句话理解:Harness 工程就是用固定任务集跑出轨迹,从轨迹里找到失败模式,每次只改工具、提示或环境中的一处,再用同一组任务验证有没有变好;靠证据迭代,而不是凭感觉改提示。

Agent 上线后总会出错。最常见的反应有两种:往系统提示里再加一句“请务必……”,或者直接换一个更强的模型。前者往往改好一个、坏掉一片;后者成本高,而且很多时候问题根本不在模型。前面几课拆开了 Harness 的每个零件,这一课讲怎么让这些零件越改越好:用轨迹定位问题,用评测证明改进。

为什么同一个模型,换个 Harness 差这么多

模型每一步能做的判断,取决于 Harness 给它什么:看到哪些信息、能用哪些工具、工具出错时收到什么反馈、什么时候必须停下来检查。这四样东西任何一样出问题,再强的模型也会表现失常。Anthropic 在《Demystifying evals for AI agents》中说得很直接:评估“一个 Agent”时,评估的其实是 Harness 和模型的组合。

两个一手案例:

  • Anthropic 在《Building effective agents》中提到,为 SWE-bench 构建 Agent 时,他们花在优化工具上的时间比优化整体提示还多。例如模型离开根目录后经常用错相对路径,把工具改成只接受绝对路径后,这类错误就消失了。
  • LangChain 在 2026 年 2 月的文章中报告,他们的编程 Agent 在 Terminal Bench 2.0 上的得分从 52.8 提升到 66.5,模型(GPT-5.2-Codex)不变,只改了 Harness:结束前强制自检、启动时注入目录结构与可用工具、检测反复修改同一文件,以及时间预算提醒。

所以 Agent 表现不好时,先把“模型不行”当作最后一个假设,而不是第一个。更多背景见 模型与 Harness。

迭代闭环:从轨迹到改动

Harness 工程是一个反复转动的闭环:

Harness 迭代闭环:跑固定任务集、读轨迹、归类失败模式、选一处改动、重跑对比、沉淀回归用例,再回到第一步 01 跑固定任务集 同一模型、同一配置 02 读轨迹 找到第一个出错的步骤 03 归类失败模式 按频率 × 影响排序 04 选一处改动 工具 · 提示 · 环境 05 重跑并对比 开发集 + 保留集 06 沉淀为回归用例 修好的失败不再复发 迭代闭环 一次只改一处
图 1 · Harness 迭代闭环:每转一圈,只改一处,并留下一条回归用例

轨迹(Trajectory,也叫 Transcript 或 Trace)是一次运行的完整记录:输入、每次模型调用、工具调用的参数与结果、错误、耗时和最终输出。没有轨迹,你只能看到“答错了”;有了轨迹,你才能看到“第 3 步查了订单但没查支付,就下了结论”。怎么记录轨迹见 Tracing。

读轨迹的要领是 找第一个出错的步骤,而不是盯着最后的答案:后面的错误常常只是第一处错误的连锁反应。同时留意模型没做的事,Anthropic 在《Writing effective tools for agents》中提醒,Agent 在反馈里遗漏的内容,往往比它写出来的更重要。

找到第一处错误后,给它贴上失败模式的标签:

失败模式 轨迹里的信号 通常的根因
不调用或选错工具 直接编造,或拿 A 工具干 B 的事 工具描述没写清何时调用
参数反复出错 同一工具连续报参数错误 Schema 缺少格式约束或示例
被工具结果淹没 结果很长,之后答非所问 返回值没有精简、没有截断
原地打转 相同参数的调用重复出现 错误信息不可行动,缺重复检测
违反业务规则 工具都用对了,结论却违规 规则不在上下文里,或只写在提示里
过早宣布完成 没有验证就结束 缺少结束前检查
环境问题 超时、依赖缺失、权限被拒 执行环境本身有问题
评分器误判 轨迹合理却被判失败 评测写错了,而不是 Agent 错了

最后一行常被忽略。Anthropic 的评测文章专门强调:不读轨迹,你就不知道评分器是否在正常工作。把失败逐条归类并统计频率,先修出现最多、影响最大的那一类。归因方法的细节见 错误归因。

改工具、改提示,还是改环境

同一个失败,往往可以在好几层修。原则是:在问题产生的那一层修,能用程序保证的就不要交给提示。可以按下面的顺序逐个排除:

从失败轨迹到改动层的判断顺序:先排除评分器和环境,再看硬规则、工具和上下文,最后才改提示 一条失败轨迹:定位第一个出错的步骤 评分器把合理的结果判错了? 修评分器,而不是改 Agent 是 否 超时、缺依赖、权限配置出错? 改环境:沙箱、依赖与配置 是 否 违反了必须 100% 遵守的规则? 写成 Hook 或权限规则 是 否 选错工具、参数出错、结果难读? 改工具:描述、参数与返回值 是 否 关键信息缺失,或被无关内容淹没? 改上下文:装配顺序与预算 是 否 以上都不是:模型的判断出错 改提示:写原则,不写特例
图 2 · 判断改哪一层:先排除评测与环境,再用确定性手段兜住硬规则,提示放在最后

几条经验:

  • 先怀疑评测和环境。评分器误判、沙箱缺依赖、下游接口超时,都会伪装成“模型不行”。改提示修不好这类问题,只会让提示越来越臃肿。
  • 硬规则交给程序。“写操作必须确认”“卡号必须脱敏”这类规则,写在提示里只是“请模型遵守”,做成 Hooks 或 权限规则 才是“程序保证执行”。
  • 工具是性价比最高的改动点。改名称和描述,让模型知道何时调用;收紧参数格式,让错误的调用更难发生;精简返回值、写清错误信息,让模型读得懂结果。原则见 工具设计原则,运行时的截断与超时见 工具运行时。
  • 信息问题改装配。规则没进上下文,模型当然不会遵守;工具结果太长,关键信息就会被淹没。见 上下文装配。
  • 改提示时写原则,不写特例。“承诺日期已过的订单要标注已超时”是原则;“如果是 ORD1001 就说已超时”是在背答案。

用固定任务集验证改进

改完之后,用同一组任务、同一个模型和同样的配置重跑,前后对比。几个要点:

  1. 任务来自真实失败。Anthropic 建议从 20–50 个取自真实失败的简单任务起步,不必等到攒够几百个。构建方法见 构建评测集。
  2. 每个任务跑多次。Agent 的输出每次都不同,只跑一次的差异可能是噪声。Anthropic 区分了两个指标:pass@k 是 k 次里至少成功一次的概率,pass^k 是 k 次全部成功的概率。面向用户、要求稳定的 Agent,更该看后者。
  3. 不只看通过率。Anthropic 在工具文章中建议同时记录工具调用和任务的总耗时、工具调用次数、Token 消耗和工具报错数。一次改动可能不改变成功率,却让 Token 减半。
  4. 过程也要评。结果对了但多查了三次、或者差点执行了不该执行的写操作,同样是问题。见 结果评估与轨迹评估。
  5. 一次只改一处,并记改动日志:改了什么、基于哪条失败、预期改善什么、实际结果如何。同时改三处,你永远不知道是哪一处起了作用。

避免对评测集过拟合

在同一批任务上反复调,分数总会涨,但涨的可能只是“背题”能力。LangChain 在上面那篇文章中也提醒,针对单个任务的改动不利于泛化,可能导致其他任务回退。Anthropic 在改进工具时,则用 保留测试集(held-out test set)来确认没有对“训练用”的评测过拟合。

评测任务分为开发集、保留集和回归集三份,改动上线需要同时满足三个条件 来源:真实失败、线上轨迹、边界用例 开发集 可以反复读轨迹、调试 保留集 只看分数,不拿来调参 回归集 修好的失败,必须一直通过 上线条件:开发集提升 · 保留集不下降 · 回归集全部通过
图 3 · 三份任务集各司其职:在开发集上调,在保留集上验,用回归集守住底线

过拟合的信号很好认:提示里出现越来越多的具体订单号或具体文件名;开发集分数一路上涨,保留集纹丝不动;评分器被“钻了空子”,比如只检查关键词,Agent 就学会堆关键词。

应对办法:

  • 分三份用:开发集用来读轨迹和调试,保留集只看分数,回归集收录每一个修好的失败。
  • 定期换血:从线上新出现的失败里补充任务,淘汰已经饱和、人人都能过的题。
  • 区分两类评测:Anthropic 的建议是,能力评测应从较低的通过率起步,给改进留出空间;回归评测则应接近 100% 通过,用来发现“以前能做的现在做不了”。
  • 警惕漂亮的平均分:总分上涨时,逐类看失败模式有没有此消彼长。

这套闭环一旦跑通,就可以接到线上:把线上轨迹里的新失败补进评测集,每次改动后自动回归,见 持续改进闭环。

常见误区

  • “表现不好就换个更强的模型。” 先读轨迹。如果失败集中在工具参数、规则缺失或环境超时,换模型只是用更高的成本掩盖问题。
  • “在提示里多加几句‘务必’就行。” 提示越堆越长,规则之间会互相冲突;必须遵守的规则应该交给 Hook 和权限,而不是更大声的提示。
  • “开发集分数涨了,就说明变好了。” 没有保留集的提升可能只是背题;没有回归集的提升可能伴随着旧问题复发。

产品经理检查清单

  • 我们有固定的评测任务集吗?任务来自真实失败,还是凭空想象的?
  • 每次运行都留下完整轨迹了吗?失败时能回放到具体哪一步?
  • 失败有没有按模式归类,并统计每类的频率?
  • 这次改动针对哪一类失败?改的是工具、提示、环境,还是评测本身?
  • 对比时每个任务跑了几次?除了通过率,还看了步数、耗时和 Token 吗?
  • 有没有保留集和回归集?上线标准写清楚了吗?

练习

用上一课的 最小 Agent 做一次完整的迭代(约 60 分钟):

  1. 写 10 个订单售后问题,覆盖正常诊断、订单不存在、支付记录缺失等情况,为每个问题写一条通过标准。
  2. 每个问题跑 3 次,保存每次的工具调用记录。
  3. 读失败的轨迹,按上面的表格归类,找出出现最多的失败模式。
  4. 按图 2 的顺序决定改哪一层,只改一处。
  5. 重跑全部问题 3 次,对比改动前后的通过率、工具调用次数和报错数,写三行结论:改了什么、哪里变好了、有没有变差的地方。

延伸阅读

下一步

迭代多了你会发现,有些能力值得自己写,有些直接用现成的更划算。下一课「框架与 SDK 选型」帮你决定哪些 Harness 能力买现成的、哪些自己写。

试试:上下文、MCP、沙箱、Prompt 注入、外链