它失败了,失败在哪一步、属于哪一类?
本课一问:本课 agent 在真实评测上 15 次全失败。失败在哪一步?属于哪一类?哪一次是模型不会,哪一次是 harness 或环境先撞了墙?
这一课先不碰:这些轨迹是怎么在 Harbor 里跑出来的(第 4 课);用另一个模型自动打标签(本课的标签全部是写明的规则或人工标注,页面不调用任何模型)。
从已有出发
两章前就埋过这件事。A1 岔路 B3:26 次运行里模型自己宣布收工 21 次,验收没过 13 次——「没有工具调用」只说明它不想继续了。A7 第 4 课:32 次运行里最后一句明确声称完成 20 次,验收失败 12 次,所以干活的和评活的要分开。那两课的结论在这里直接用:成败以 verifier 为准。这一课往下多问一层:没过的时候,是怎么没过的。
为什么这一课主要看 TB 任务。贯穿任务 parse_date 在 T6 里 3 次全过,没有失败可读;同一个 harness、同一个模型在 Terminal-Bench 2.0 上的 15 次失败,就是这一课的样本。下面的回放里 parse_date 的 3 次也在,当作「通过的轨迹长什么样」的对照。
先自己设计:只看分数,或只看最后一句话
最省事的两种读法:看 verifier 给了几分;或者读 agent 最后说了什么。
- ① 朴素方案
- ② 它在哪失败
- ③ 改进方案
| trial | reward | 没过的测试 | 停止原因 | 导出字段 claimed_done | 最后一段话(人工按 A7 规则标注) |
|---|---|---|---|---|---|
| fix-git · 1 | 0 | 2 / 2 | no_tool_calls | 是 | 未声称 |
| fix-git · 2 | 0 | 2 / 2 | no_tool_calls | 是 | 未声称 |
| fix-git · 3 | 0 | 2 / 2 | no_tool_calls | 是 | 未声称 |
| regex-log · 1 | 0 | 1 / 1 | length | 否 | 未声称 |
| regex-log · 2 | 0 | 1 / 1 | length | 否 | 未声称 |
| regex-log · 3 | 0 | 1 / 1 | length | 否 | 未声称 |
| log-summary-date-ranges · 1 | 0 | 1 / 2 | no_tool_calls | 是 | 明确声称完成 |
| log-summary-date-ranges · 2 | 0 | 1 / 2 | no_tool_calls | 是 | 明确声称完成 |
| log-summary-date-ranges · 3 | 0 | 2 / 2 | length | 否 | 未声称 |
| openssl-selfsigned-cert · 1 | 0 | 2 / 6 | no_tool_calls | 是 | 明确声称完成 |
| openssl-selfsigned-cert · 2 | 0 | 2 / 6 | no_tool_calls | 是 | 明确声称完成 |
| openssl-selfsigned-cert · 3 | 0 | 1 / 6 | no_tool_calls | 是 | 明确声称完成 |
| cobol-modernization · 1 | 0 | 1 / 3 | no_tool_calls | 是 | 未声称 |
| cobol-modernization · 2 | 0 | 1 / 3 | no_tool_calls | 是 | 未声称 |
| cobol-modernization · 3 | 0 | 1 / 3 | no_tool_calls | 是 | 未声称 |
分数说「没过」,最后一句话说「做完了」——两个信号都不告诉你为什么。要知道为什么,得回到轨迹:模型在每一步想了什么、调了什么、看到了什么、在哪一步决定收工。下面把 15 条轨迹摊开。
上表「最后一段话」一列是本章作者按 A7 第 4 课的同一条规则人工标注的:断言完成且没说还差什么 = 明确声称;只用 should / would / will = 含糊;没有这类断言、说还差一步、把活交还用户、或没写话 = 未声称。依据原句必须逐字出现在最后一段话里(生成脚本 gen_a09_eval.py 里有断言)。
改进:读轨迹,打带步号的标签
失败分类用哪一套?大纲沿用调研里整理的四条证据链,都出自 Anthropic 工程博客(轻量档案,一手来源):
| 失败模式 | 出处 | 原文里的一句 |
|---|---|---|
| one-shot 冒进 | 《Effective harnesses for long-running agents》 | agent 倾向于「一次做太多」,想一次把整个应用做完;另有「过早宣称完工」「验证不足」 |
| 上下文腐化 | 《Effective context engineering for AI agents》 | 上下文里的 token 越多,模型准确回忆其中信息的能力越差 |
| 工具幻觉 | 《Writing effective tools for agents》 | 「call the wrong tools, call the right tools with the wrong parameters, call too few tools, or process tool responses incorrectly」 |
| 自评与结果不一致 | 《Demystifying evals for AI agents》 | 订机票的例子:transcript 说订好了,要看的是环境的数据库里有没有这条预订 |
这四类是起点,不是全集。本批数据里还出现了三种它们装不下的情况,于是本章一共用七个标签;每个标签写明规则,分「自动」(浏览器里由规则现算)与「人工」(本章作者读轨迹标注),都能点到步号:
标签规则与重建规则(点开核对;自动 = 浏览器现算,人工 = 本章作者读轨迹标注)
- one-shot 冒进 · 做完不回头查(自动):没通过、以「不再调工具」收工,且收工前最后一个带调用的步里没有任何检查(发现 / 阅读类调用,或跑 pytest、unittest)。对应 Anthropic《Effective harnesses for long-running agents》里「一次做太多」与「验证不足」。
- 工具幻觉(自动 + 人工补充):某次调用退出码 127,或输出里出现 command not found / No such file or directory;人工补充「调用对了工具、参数给错」或「把工具结果读错」的步。对应《Writing effective tools for agents》那句「call the wrong tools, call the right tools with the wrong parameters … or process tool responses incorrectly」。
- 上下文腐化(自动):某步输入超过上下文窗口(Qwen3-8B 为 40,960 token)的一半,且之后出现与之前完全相同的调用。本批最长输入只有几千 token,这条规则一次也没命中——不是没有这类失败,是这批数据里没有样本。
- 自评与结果不一致(人工):最后一段话明确声称完成,验收没过。判定规则同 A7 第 4 课:断言完成且没说还差什么 = 明确声称;只用 should / would / will = 含糊;没有这类断言、说还差一步、把活交还用户、没写话 = 未声称。依据原句逐字出现在最后一段话里(生成脚本断言)。
- 停在半路(人工派生):未声称完成,却以「不再调工具」收工,验收没过。不在 Anthropic 的四类里。
- 撞上 harness 上限(自动):停止原因是 length(连续三次写满单次输出上限)、max_rounds、wall_clock、dropped_tool_call 或 model_error。不在四类里:这是 harness 配置与模型一起造成的。
- 环境 / 评分器(自动):同一环境里这个任务的参考解(oracle)没通过。本批 5 个任务的 oracle 都通过了,所以一次也没命中。
- 动作分类:list_dir / grep = 发现,read_file = 阅读,write_file / edit_file = 写入;bash 先把引号里的内容换掉,按 && ; | 拆段,每段看第一个词(ls、find、git status… = 发现;cat、head、diff、cmp… = 阅读;mkdir、cp、rm、带 > 重定向… = 写入;其余 = 执行),一条命令取最强的一类(写入 > 执行 > 阅读 > 发现)。
- 工作区重建:只认 write_file / edit_file 的结果,和退出码为 0 的 bash 里的重定向、mkdir、touch、cp、mv、rm。程序自己写的文件(openssl -out、python 脚本里 open(…, "w"))看不见——和 ATIF Trajectory Viewer 作者写明的局限一样,重建的工作区不一定忠实。
数据:本课项目 T6(录制于 2026-09-26;Harbor 0.23.0 + Terminal-Bench 2.0;模型 Qwen/Qwen3-8B-MLX-4bit,本机 mlx_lm.server;harness miniagent 0.5.0)。本机有其他任务同时占用,且 amd64 镜像经 qemu 模拟运行,耗时只能粗看;token、轮数、步数可比。
试四件事:① 看总览最上面三行 fix-git:只有蓝格和绿格(发现、阅读),没有一格红(写入)——三次都在看 git status、git log,没有一次查引用日志或别的分支上的提交,然后把活交还给「用户」;② 展开 openssl 第 1 次:第 3 步一格切成 8 段,6 段红、2 段橙,第 4 步就收工;在「工作区」栏看它重建出哪些文件、少了哪些(openssl 自己写的密钥与证书看不见);③ 展开 log-summary 第 2 次,点标签里的步号 6:终端栏里那条 python3 -c 从 sys.stdin 读文件名;④ 看 regex-log 三行:全是灰色斜纹——三轮都把 4,096 个输出 token 写满在思考上,一个工具都没调。
七个标签在 15 个 trial 上的分布(同一个 trial 可以有几个标签):
| 标签 | 属于 | 怎么判 | 命中的 trial | 典型的一步 |
|---|---|---|---|---|
| one-shot 冒进 · 做完不回头查 | 四类之一 | 自动:以「不再调工具」收工,且收工前最后一个带调用的步里没有任何检查 | 7 | openssl 第 1 次第 3 步:一步发完 8 个调用,第 4 步就说完成 |
| 上下文腐化 | 四类之一 | 自动:某步输入超过窗口一半,且之后重复同样的调用 | 0 | 没有样本:最长一步输入 5,348 token,是 40,960 窗口的 13% |
| 工具幻觉 | 四类之一 | 自动:退出码 127、command not found、No such file;人工补「参数给错、结果读错」 | 4(自动 2) | cobol 第 3 次第 11、13 步调了不存在的编译器 gcoxb;openssl 第 1 次用 write_file 写进字面的 $(openssl …) |
| 自评与结果不一致 | 四类之一 | 人工:明确声称完成,验收没过 | 5 | log-summary 第 2 次:「verified via the exit code 0」 |
| 停在半路 | 四类之外 | 人工派生:没声称完成,却以「不再调工具」收工 | 6 | fix-git 第 1 次:把 4 条命令写给「用户」自己去跑 |
| 撞上 harness 上限 | 四类之外 | 自动:停止原因是 length 等上限 | 4 | regex-log 三次:三轮都在思考里写满 4,096 token |
| 环境 / 评分器 | 四类之外 | 自动:同环境里参考解也没过 | 0 | 本批 5 个任务的 oracle 都过了;第 4 课的 arm64 探测里有一例 |
每一次失败都至少落到一个标签上,这是 M9 验收的第 ④ 条。规则的 JS 实现与生成脚本里独立写的 python 实现,在 18 条轨迹的动作分类、「检查」判定、自动标签(含步号)、工作区重建上逐条一致(test_a09_pure.mjs) 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条算法性质:同一条规则、同一份轨迹,两份独立实现给出相同结果。这证明「规则被正确执行了」,不证明规则本身分对了类——规则是本章定的,页面上写明,读者可以不同意。 出处待补 。
极小真数字:一条规则在一步上怎么判
15 次里有 4 次一个工具都没调就停了:它们撞上的是 harness 设的单次输出上限(4,096 token,开着思考)——这是 harness 配置和模型一起造成的,调大上限会不会过,本章没有数据。第 4 课会看到第一次 oracle 冒烟 0 / 5 是容器的 DNS;arm64 探测里 qemu-startup 的参考解也拿了 0 分,因为评分器现装依赖时 404。别人也遇到过:Docent 在 InterCode 上发现环境缺包,补上后 GPT-4o 的解题率从 68.6% 升到 78% 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条第三方研究机构自报的案例。 出处Transluce · Introducing Docent ↗需联网 ;Anthropic 修好 CORE-Bench 的评分器 bug、换了约束更少的 scaffold,Opus 4.5 从 42% 到 95% 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条官方自报。 出处Anthropic《Demystifying evals》 ↗需联网 。
log-summary-date-ranges 第 2 次的第 6 步:脚本退出码 0,产物是一份全是 0 的 CSV。退出码只说明进程没崩;对不对要看产物,这正是 verifier 的活。system prompt 里明明写着「没用工具核对过,就不许说完成」,它核对的是退出码。
项目的导出脚本把「以不再调工具收工」机械地记成 claimed_done,11 次都是 true;读原文,其中 6 次是在说还没做完、或让用户自己去跑命令。机械字段适合做候选,判断要回到原文——所以本课把「声称」列成人工标注,并附上依据原句。
证据三问
| 问 | 本课的回答 |
|---|---|
| ① 它解决什么问题? | 分数只说成没成;轨迹 + 标签说为什么,并且能指到具体哪一步 |
| ② 为什么这样分类? | 四类来自 Anthropic 工程博客的经验总结 证据等级 · 有理论动机 有数学或机制上的理由说明它可能有效,但没有证明它一定更好。最后是否采用,仍然要看实验。 本条官方一手的经验归纳(调研档案标「轻量」);没有对照实验证明这四类是完备或互斥的。本批数据里有三种情况装不进去,所以另加了三个标签。 出处待补 ;规则是本章定的,页面写明 |
| ③ 实验上呢? | 本课 15 个 trial:改完不回头查 7、工具幻觉 4、自评不一致 5、停在半路 6、撞上限 4、上下文腐化 0 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条项目实测:单一 8B 本地模型、5 个任务 × 3 次、qemu 模拟。分布只描述这 15 次,不能外推到别的模型或任务。 出处待补 |
演进地图:你在这里
- 起点 跑一次,看成败最直觉的做法:一个任务、一次运行、一个布尔值解决了最省事:修好了就说「会修」,没修好就说「不会」。卡在同一套配置只换 seed:pd-v2-unlimited 的 s1 / s2 / s3 是 ✗ ✓ ✓;同为 seed 1、只多了一个没碰到的轮数上限的 pd-v2-cap20-s1 又是 ✓。只跑一次,结论取决于你碰上了哪一次。
- Anthropic《Demystifying evals for AI agents》· Harbor 的 -k 与 pass_at_k.py解决了同配置的 7 次运行过了 6 次:p̂ = 0.857,pass@3 = 99.7%,pass^3 = 63.0%;T6 的 3 次重复全过。卡在拿全体平均成功率套公式:TB 4.0 官方榜第一行(Codex + GPT-6 Astra,max)pass@1 为 58.18%,公式给 pass@5 = 98.7%,榜单实测 71.2%:每个任务的成功率不一样。而且重复再多次,也分不出分数里哪部分是 harness。
- 第二步 统一 harness,才能比模型Vals 统一用 Terminus 2 复测 TB 4.0 · SWE-bench 官方 bash-only 榜统一用 mini-SWE-agent解决了同一个模型换 harness 的差距摆上桌:Fable 5.1 在 Claude Code 上 57.88%、在 Terminus 2 上 49.49%;GLM-5.3 41.82% → 25.25%。卡在分数只告诉你成没成:本课 agent 在 TB 2.0 上 0 / 15,15 次失败各是各的样子,一个数看不出为什么。
- Harbor 的 ATIF 轨迹 · Anthropic 工程博客的四类失败 · 本章写明的标签规则解决了15 次失败都落到了带步号的标签上:改完 / 跑完不回头查 7 次,撞上输出上限 4 次,明确声称完成 5 次、5 次没过。卡在标签分不清是 agent 错还是环境错:第一次 oracle 冒烟 0 / 5,原因是容器里的 DNS;arm64 探测里 qemu-startup 连参考解也拿 0 分(verifier 现装 curl 时 404)。
- Harbor v0.23.0:-a oracle 冒烟 → -a module:Class -k解决了参考解 5 / 5 通过、环境就绪之后,再跑自家 agent:5 个任务 × 3 次。卡在k = 3、单一 8B 本地模型、5 个任务、amd64 镜像靠 qemu 模拟:结论只在这个规模成立。(→ 课程终点:回到 A0,哪些任务值得用 agent?)
数字口径:本课项目 T6(Harbor 0.23.0 + Terminal-Bench 2.0,本机 Qwen3-8B-MLX-4bit,录制于 2026-09-26)与 A1 的同配置运行;TB 4.0 官方榜(更新于 2026-09-21)与 Vals(更新于 9/22/2026),均于 2026-09-27 抓取;由 a09-eval.json 与 a09-public-2026-09-27.json 构建时现算。
一句话
先停在这里:记住三个数——5 次明确声称完成全部没过、4 次一个工具没调就撞上输出上限、上下文腐化 0 次(不是没有,是这批数据太短)。
再深一层:去实验课自己标一遍:勾你认为的标签、写依据,和规则的结果对照。
下一个缺口
把自己的 agent 接上真实评测,要跑通哪几步? → 第 4 课:把自己的 agent 接上真实评测,要跑通哪几步?
「环境 / 评分器」这个标签本批一次没命中,是因为每个任务先用参考解确认过环境。如果没做这一步呢?
你可能会问
- 「能不能让另一个模型来打标签?」 可以,Docent、ATIF Viewer 都这么做;但那样标签本身也成了模型的输出,需要再评。本课先把规则写明、把人工判断标出来,等你有了一批人工标注,再拿它去评自动标注器。
- 「fix-git 到底该怎么做?」 TB 要求任务的参考解与测试不进训练语料,本课没有导出它们;从轨迹能看到的是:三次都没查引用日志,也没看当前分支以外的提交。
- 「上下文腐化这一类是不是不重要?」 在本批短任务里没有样本,不代表不重要。A5 岔路 B1 讲过长上下文的退化;要在自己的数据里看到它,需要长得多的任务。