很多 agent harness 把搜索、重试、验证和停止都交给 LLM。即使连续处理的是同一类任务,模型仍要在每条 trajectory 里重新做这些控制判断。Growing Harness 从一个几乎为空的 scaffold 开始,根据失败 trace 修改 harness code,让可重复、可判定的控制逻辑留在程序里,把语义判断继续交给模型。
Q1. 为什么要让 harness 增长,而不是继续扩充 context?
因为同一 task family 会反复需要相似的控制,context 却会在每次任务结束后丢失。 普通 Tool-Calling agent 每一步都把历史交给模型,让它再次决定搜索什么、是否继续、怎样恢复错误。这样做很灵活,但模型调用、输入 token 和上下文压力都会随 trajectory 增长。
作者提出三个具体要求。第一,训练任务上学到的行为要能复用于同分布的新任务;第二,重复控制要从在线推理移到低成本代码,语义判断仍由 LLM 处理;第三,起点不应预设完整 controller,否则最后得到的结构可能只是手工模板的小修小补。
这项工作的目标不是让一个 harness 适配所有问题。作者为 BrowseComp-Plus 和 WebArena-Verified 分别训练一套 specialist harness;复用范围是同一 task family 内的新任务。
Q2. 它和 workflow search、skill library、memory 以及其他 harness work 有什么区别?
最清楚的比较轴是:训练后到底留下什么,以及部署时还要让 LLM 做多少控制。
| 路线 | 持续积累的对象 | 部署时怎样运行 | 与 Growing Harness 的边界 |
|---|---|---|---|
| ReAct / Self-Ask / IRCoT | 固定 loop 和当前任务 history | LLM 在线重做大部分控制判断 | 本文把跨任务重复的控制固化为 executable code。 |
| ExpeL / Agent Workflow Memory | 可检索的文字经验或 workflow | LLM 取回并解释经验 | 本文让积累后的 controller 直接执行。 |
| Voyager / LATM / CRAFT | skill 或 tool library | 既有 agent 选择并调用 skill | 本文修改共享 harness 本身,包括主控制流。 |
| AFlow / ADAS | 代码化 workflow 或 agent design | 运行搜索得到的结构 | 本文从失败出发,用 execution trace 限定局部 edit,并持续累积。 |
| AutoHarness / Meta-Harness | harness code 或 config | 固定模型运行优化后的 harness | 本文强调 strategy-free 起点、multi-failure repair 和可整段回滚的 held-out gate。 |
| Harness-Zero | 从 source harness 产生的行为数据 | 训练后的模型在更小 target harness 上运行 | Harness-Zero 想移除 source harness;本文保留并部署长出来的 specialist harness。 |
它和 Meta-Harness 最接近,但解决的问题更窄、更具体:如何让一份不断变大的程序继续从失败中局部修复,同时防止新 patch 破坏旧能力。论文没有训练模型权重,也没有尝试跨 benchmark 共用一套 controller。
Q3. 一条失败怎样变成可复用的 harness code?
完整路径是:执行当前 harness,记录 function-level trace,把多条失败放进窗口,局部生成候选代码,重跑失败窗口,再用 held-out gate 决定接受或整段回滚。
3.1 Trace 先把失败定位到有限的代码面
每条执行 trace 记录 task、function-call DAG、LLM call、tool call、输入输出、runtime error、最终 verdict 和资源用量。Optimizer 只能修改入口 main、当前失败 trace 实际调用过的函数,以及少量新增 helper。已有但未进入 trace 的函数不能被顺手重写。
这条限制解决了一个实际问题:harness 越长,整份程序交给 optimizer 的搜索空间越大。Function-level trace 把本轮 edit 限制在与失败有直接执行关系的代码上。Edit budget L 继续限制被改函数与新增函数的数量。
训练时,offline optimizer 还会看到 evaluator feedback、retrieved-document identifiers、evidence、action statistics 和 errors。这些诊断信息只用于生成 repair,不会暴露给部署中的 harness。论文因此把“训练监督”和“Agent 执行时可见的信息”分成了两层。
3.2 Failure window 让一次 repair 同时解释多条失败
当前 harness 顺序处理 training stream。成功 task 直接离开;失败 task 连同最新 trace 进入容量为 K 的窗口。Optimizer 看到整个窗口,再提出一份完整 candidate harness。Candidate 必须重新跑窗口内所有任务,至少修复 Q 条才进入下一关。
未解决任务会保留新 trace 并累计尝试次数,达到 Rmax 后退出。若一个完整窗口里的任务都耗尽预算,系统恢复到该窗口开始前保存的 checkpoint,防止一串无效 edit 留在程序里。
3.3 Held-out gate 只守成功率,不拿便宜换退化
Candidate 修过当前窗口后,还要与最近一次 accepted checkpoint 在 50 条 gate tasks 上比较。只有 SR_G(candidate) ≥ SR_G(checkpoint) 才接受。若 gate success 下降,系统会回滚从上个 checkpoint 以来的整个 repair sequence,包括 harness、窗口、task cursor、计数器和元数据。
Gate 是 success-first:成本会被记录,但更便宜不能补偿成功率下降。训练结束后,如果最后一段改动还没有经过 gate,系统会再跑一次最终 gate。
3.4 Repair 31:答案已经找到,却被 prompt compaction 删掉
BrowseComp-Plus Task 819 的完整因果链
- 题目来源与可见输入。这是一条 BrowseComp-Plus training task,要求找出一篇 2013 年访谈里描述某种声音的五个词。Agent 能看到问题、固定 search tool 和自己的执行历史;final split 及答案不会提供给它。
- Search 已经成功。Harness 找到包含正确引文的材料。正确答案仍保存在
_collection_search_evidence的输出中:Energetic; melodic; banging; clubby; bacon. - 第一个坏输出来自 prompt 组装。
_evidence_for_prompt把每篇文档截到 2,600 characters,包含答案的片段被切掉。后续 LLM call 从未看见正确证据,最终final_answer为空。 - Optimizer 改的是参与失败的函数。它把上限从 2,600 提到 9,000 characters,把两轮分析放宽到最多四轮,为 final call 预留预算,并加入 targeted search 与 quote-aware judge。
- 修复仍需重新执行。Candidate 先重跑 active window;达到修复阈值后,还要在 held-out gate 上不退化,才能写入共享 harness。
这个 case 也说明 trace-local 的含义:task-level 0/1 只能告诉你失败了;DAG 和中间 I/O 才能区分 search failure、evidence loss 与 final answer failure。
Q4. Benchmark 怎样分、怎样判,结果到底有多强?
两个 benchmark 都按 200 train / 50 gate / 50 final 划分,seed 为 42。Final evaluation 每题只有一次 rollout,每个 setting 独立运行三次;论文报告所有 task-run pair 的平均成功率。
4.1 Task、可见边界与 judge
BrowseComp-Plus 是固定且人工核验 retrieval corpus 上的 deep-search benchmark。Agent 看到问题和同一 search tool;Growing Harness、Tool-Calling、Self-Ask、IRCoT 共用 split、工具、模型与预算。最终答案交给 LLM-based equivalence judge 判断语义是否等价。本文没有给出 judge model、prompt 或人工复核率。
WebArena-Verified 是经过审计和修正的 multi-step web benchmark。本文只取 shopping、reddit、map 三类站点,并按 intent template、task type 和 website 分层抽样。所有方法只拿 accessibility-tree text,不用截图;任务结束后运行 benchmark 自带 evaluator。Growing Harness 与 Tool-Calling、WebDreamer、AgentOccam 使用相同 tool API、split、deployment model 和调用上限。
每题最多 50 次 online LLM calls,每次最多输出 8,192 tokens,temperature 1.0,reasoning effort 为 Medium,timeout 1,800 秒。Agent 不会收到“还剩几次调用”的文本提醒,预算由 harness 执行。
4.2 指标如何聚合
若 final set 有 50 个 tasks、每个 setting 跑三次,则分母是 150 个 task-run pairs:
不是给同一道题三次机会后取最好结果。Calls、tokens 和 time 在 150 个 task-run pairs 上取平均。Total Online Cost 是一次 50-task run 的 deployed-agent LLM 费用,再对三次 runs 取平均;它排除了 judge 与 offline optimizer。
置信区间使用 task-level cluster bootstrap:重复 10,000 次,每次按 task 有放回抽取 50 个 cluster,并保留该 task 的三次 runs。表里的 ± 是 1.96 × bootstrap SE,即 normal-approximation 95% CI half-width,不是标准差。
4.3 六组主结果
| Benchmark / model | Tool-Calling SR | Growing Harness SR | Calls | 一次 50-task run 的在线成本 |
|---|---|---|---|---|
| BrowseComp / gpt-oss-120b | 40.0 ± 11.6 | 49.3 ± 11.7 | 32.7 → 6.0 | $6.70 → $0.87 |
| BrowseComp / gpt-oss-20b | 40.0 ± 11.7 | 39.3 ± 12.6 | 24.8 → 6.0 | $2.03 → $0.52 |
| BrowseComp / Qwen3.5-4B | 12.0 ± 7.1 | 29.3 ± 11.8 | 29.6 → 5.5 | $8.33 → $0.81 |
| WebArena / gpt-oss-120b | 30.0 ± 11.4 | 45.3 ± 13.4 | 26.3 → 3.8 | $2.72 → $0.10 |
| WebArena / gpt-oss-20b | 12.7 ± 7.3 | 44.7 ± 13.4 | 22.3 → 1.8 | $0.39 → $0.03 |
| WebArena / Qwen3.5-4B | 6.7 ± 4.9 | 45.3 ± 13.4 | 37.8 → 5.4 | $7.26 → $0.10 |
五组设置中,Growing Harness 的平均成功率最高;BrowseComp + gpt-oss-20b 低于 Tool-Calling 0.7 个百分点。相对 Tool-Calling,六组减少 76.0% 至 91.8% 的 LLM calls 和 74.4% 至 98.6% 的 deployed-agent online cost。
WebArena 的结果尤其醒目:模型从 120B 缩到 4B,Growing Harness 仍在 44.7% 至 45.3%;Tool-Calling 则从 30.0% 降到 6.7%。这与“代码承担重复 browser control,小模型保留语义判断”的解释一致。这项实验没有进行跨模型训练:同一 benchmark 的 harness 由指定 training-time model 长出,再换三种 deployment model 评测。
4.4 Ablation 说明三个机制都有效,但证据强度有限
BrowseComp-Plus + gpt-oss-20b 的 single-run ablation 是:Full 36%,去掉 Failure-Window 为 28%,去掉 Gate Validation 为 22%,去掉 Function-Level Guidance 为 18%。每个 variant 只优化一次、共 10 steps,也没有重复 run 的误差条,因此可以说明组件与这一次训练结果相关,不能当成稳定的效应量。
训练阶段的固定超参数也值得保留:BrowseComp 用 gpt-oss-20b 作为 deployment LLM、GPT-5.6-terra High 作为 optimizer,K=8, Q=1, Rmax=5, L=10;WebArena 用 gpt-oss-120b 与 GPT-5.4 High,K=4, Q=8, Rmax=5, L=10。每一步只生成一个 candidate。
Q5. 对 Claude Code、Codex 这类完整 harness 有什么启发?
最值得迁移的是一套变更协议:让生产 harness 的失败可定位、让一次修复覆盖多个同类失败、让每个候选都经过独立回归门禁。
对 coding agent,可以把 function-call DAG 换成 repository-aware execution trace:记录 prompt module、tool adapter、hook、sub-agent、command、文件 diff、test result 和 timeout。Optimizer 只能改与失败路径有关的 harness module,并保留接口与权限边界。
Failure window 在实践中可以按 failure pattern 组织。例如把“误读测试输出”“反复读取同一文件”“工具错误后丢失状态”分别聚类,再要求一个 patch 至少修复多个仓库中的同型失败。这样更接近论文想得到的 reusable control。
Held-out gate 需要覆盖旧任务家族、不同代码库、权限拒绝、长上下文和不同模型版本。对 Claude Code 或 Codex,成功率相等还不够;生产 gate 还应约束 destructive action、token/call budget、wall time、用户中断和可恢复性。
如果沿这条路线继续做论文,我会补三个实验:第一,比较 whole-harness edit、trace-local edit 和 module-level edit 的样本效率;第二,报告 offline optimizer 总成本与 amortization break-even;第三,把同一 learned harness 交叉部署到不同模型、不同 repo distribution 和模型升级版本,测 portability 与 regression。
Q6. 这篇论文最后该怎样评价?
论文把“agent 从经验中学习”落到了一个可执行、可回滚的程序更新过程上。 它从空 controller 开始,给出了清楚的 trace、window、candidate、gate 与 checkpoint 边界;Repair 31 也让读者看到一次 0/1 失败怎样定位到具体函数和具体数据丢失。实验同时报告成功率、调用、token、时间和在线成本,主结论不靠一个单独指标支撑。
还需要保留以下限制:
我的判断是:它应该和 Meta-Harness、Harness-of-Harness、Harness-Zero、Multi-Harness RL 一起读。Meta-Harness 关注如何搜索 harness;Harness-of-Harness 关注多日任务中的上层调度;Harness-Zero 研究怎样把 source-harness 行为带到更小 runtime;Multi-Harness RL 讨论跨 harness 训练是否真的带来 portability。Growing Harness 补上的问题是:当任务会重复到来时,一份 specialist harness 怎样从失败中持续长大,又不把已有能力改坏。
来源与授权说明:论文为 arXiv:2609.26760v2,arXiv 页面标注 CC BY 4.0。本文直接引用原论文 Figures 1 至 6 与 Algorithm 1 并逐一注明来源;结果表、消融数字、评测公式与超参数来自 Tables 1 至 5。论文 PDF、HTML、附录和 arXiv metadata 于 2026-09-29 核查;未找到本工作的官方代码或数据发布。
留言