把重复控制写进 harness,别让模型在每个 task 里重新想一遍
论文让一个没有预设 controller 的 scaffold 从失败中长出程序:trace 找到出错函数,failure window 让一次修复覆盖多个失败,held-out gate 拒绝破坏旧能力的更新。
Context 是一次运行的临时记忆;harness code 是跨任务复用的控制程序
放进 context
每次任务都让 LLM 重新读 history、判断下一步、决定是否重试和何时停止。灵活,但每个 decision 都要再调用一次模型。
常见形式:ReAct loop、Self-Ask、IRCoT、browser action history。
长进 harness
把稳定、可判定的控制写成函数,例如解析、过滤、重试、状态更新、停止条件。LLM 只保留语义判断。
论文把这种可执行积累称为 persistent program growth。
同类任务会反复出现,控制逻辑却被模型反复付费重建
读取页面、搜索结果或工具输出。
是否改 query、过滤证据、重试、验证或结束。
新 prompt、observation 和 output 继续进入 history。
下一条同类任务再次重建相似的控制判断。
作者的假设:跨任务重复出现的 deterministic control 应该沉淀成代码;依赖当前语义的判断才继续调用 LLM。
训练期间只改 harness;模型 M 和工具接口 T 都固定
固定:M
部署 LLM 不做权重更新。训练出的同一 benchmark harness 之后会在 4B、20B、120B 三种模型上评估。
固定:T
搜索或浏览器工具接口不变。候选代码必须保留函数签名和 runtime contract。
学习:h
优化器可以改 trace 中出现过的函数和入口 main,也能新增少量 helper;不能删除既有函数或写入 task ID、答案。
# Figure 2 中的 strategy-free scaffold
def main(task: str, max_llm_calls: int) -> dict:
return {"final_answer": ""}区别不在“会不会写代码”,而在什么被积累、部署时留下什么
| 路线 | 持续积累的对象 | 部署时仍要做什么 | 与本文的边界 |
|---|---|---|---|
| ReAct / Self-Ask / IRCoT | 固定 loop 或文本 history | 模型在线重做控制判断 | Growing Harness 把重复控制写进代码。 |
| ExpeL / Agent Workflow Memory | 可检索的经验或 workflow | 模型检索并解释经验 | 本文直接执行积累后的 controller。 |
| Voyager / LATM / CRAFT | skill 或 tool library | 已有 agent 结构选择并调用 skill | 本文增长的是共享 harness 本身。 |
| AFlow / ADAS | 代码化 workflow / agent design | 运行搜索得到的结构 | 本文强调 failure-conditioned、trace-local 的持续增长。 |
| AutoHarness / Meta-Harness | harness code / config | 运行优化后的 harness | 本文从 strategy-free scaffold 起步,并用 held-out gate 做事务式回滚。 |

一个候选 edit 要先修够当前失败,再证明没有伤到旧能力
用当前 harness 跑未见 training tasks,只把失败及 trace 放入容量为 K 的窗口。
Optimizer 联合看窗口内失败,只改 trace 覆盖的函数;总 edit budget 为 L。
在整个窗口重跑 candidate。修复少于 Q 条就丢弃。
held-out gate success 下降就回滚整段更新;不下降才成为新 checkpoint。
BrowseComp-Plus
K=8,Q=1,Rmax=5,L=10。
WebArena-Verified
K=4,Q=8,Rmax=5,L=10。
最终测试
训练期间完全不看 50 条 final-evaluation tasks。
Task-level 的 0/1 只说“失败了”;execution DAG 才说明哪段代码参与了失败
trace τᵢ = (
task xᵢ,
execution DAG Gᵢ,
output yᵢ,
verdict oᵢ,
usage uᵢ
)
editable Aₜ = {main}
∪ functions invoked by WₜDAG node
函数调用、LLM call、tool call、return、runtime error;记录输入、输出、父节点和耗时。
允许修改
入口 main、失败 trace 中实际运行过的函数,以及少量新 helper。
禁止修改
未被 trace 覆盖的既有函数;不能删除函数、改接口或硬编码 task identifier 和 expected answer。
为什么有用
Harness 变大后,每轮仍只搜索一个有限 code surface,而不是把全程序交给 optimizer 重写。
Failure window 的目的,是让 optimizer 看见多个失败中的共同控制缺口
新 task 直接成功就离开;失败才进入 Wt。
窗口最多容纳 K 条当前失败,并保留每条最新 trace 和尝试次数。
候选同时修窗口内多条失败。已解决任务离开,未解决任务带新 trace 留下,达到 Rmax 后退休。
Gate 比较的是 held-out success;成本再低,也不能补偿成功率下降
Accept
Candidate 先修够当前窗口,再满足 SRG(candidate) ≥ SRG(latest accepted)。代码、task cursor、窗口、counter 和训练记录一起成为新 checkpoint。
Rollback
Gate success 下降时,回滚的不只是一处 diff,而是从上个 accepted checkpoint 之后的整段 repair sequence 和训练状态。
这是一条 success-first 规则。论文记录运行成本,但不会为了便宜而接受更低的 gate success。
失败发生在 prompt 组装函数,不在搜索:正确证据被找到了,却没送进最后一次 LLM call
问题要找 2013 年访谈里形容一种声音的五个词。
Search 找到正确原句;collector 中仍有答案。
_evidence_for_prompt 压缩为每篇 2,600 字符后,答案消失;LLM 从未看见它,最终返回空字符串。
Optimizer 的修复
把 snippet 上限从 2,600 提到 9,000;两轮分析改为最多四轮;预留最后一次 call;加入 targeted search 和 quote-aware judge。
判定边界
正确答案是 “Energetic; melodic; banging; clubby; bacon.” Candidate 必须重新执行任务,并继续通过 held-out gate,才会进入共享 harness。

每个 benchmark 都是 200 train / 50 gate / 50 final;最终 50 题每题单次尝试,独立跑三次
BrowseComp-Plus
固定、人工核验的 retrieval corpus;LLM equivalence judge 判答案是否等价。
WebArena-Verified
只取 shopping、reddit、map;text-only browser tools;benchmark evaluator 判定。
共同限制
temperature 1.0、reasoning medium、最多 50 次 online LLM calls、每 call 最多 8,192 output tokens、timeout 1,800 s。
五组同时提高成功率并降低调用;唯一落后的是 BrowseComp + GPT-OSS-20B,差 0.7 pp
| Benchmark / model | Tool-Calling SR | Ours SR | Calls | Online cost |
|---|---|---|---|---|
| BrowseComp / 120B | 40.0±11.6 | 49.3±11.7 | 32.7 → 6.0 | $6.70 → $0.87 |
| BrowseComp / 20B | 40.0±11.7 | 39.3±12.6 | 24.8 → 6.0 | $2.03 → $0.52 |
| BrowseComp / 4B | 12.0±7.1 | 29.3±11.8 | 29.6 → 5.5 | $8.33 → $0.81 |
| WebArena / 120B | 30.0±11.4 | 45.3±13.4 | 26.3 → 3.8 | $2.72 → $0.10 |
| WebArena / 20B | 12.7±7.3 | 44.7±13.4 | 22.3 → 1.8 | $0.39 → $0.03 |
| WebArena / 4B | 6.7±4.9 | 45.3±13.4 | 37.8 → 5.4 | $7.26 → $0.10 |


“更便宜”只指部署阶段
论文的 Total Online Cost 只统计 deployed-agent LLM calls,明确排除 evaluator 和 offline optimizer。它证明的是学成后的边际成本更低,没有给出训练投入,也无法计算 amortization break-even。
相对 Tool-Calling,六组设置减少 76.0% 至 91.8% calls、74.4% 至 98.6% online cost。Qwen 4B 反而可能更贵,因为其长 history 产生大量输入 tokens。
三个部件都有效,但消融只跑一次,不能当成稳定效应量


可以借鉴“局部修复 + 多失败归纳 + 回归门禁”;论文没有产出可直接复用的通用 harness
可以带走
- 把稳定控制下沉到代码,把 task-specific semantics 留给模型。
- 用 trace 约束 editable surface,降低大型 harness 的搜索范围。
- 每次更新都跑 held-out regression gate,并能整段回滚。
- 同一 benchmark harness 在 4B 到 120B 模型间仍保持可用。
仍未回答
- 没有公开代码、learned harness、trace、split 或 task-level logs。
- 未报告 offline optimizer / evaluator 成本,无法判断训练多久回本。
- 只在两个 task families 上训练,每个 family 一套 specialist harness。
- Ablation 是 single run;50-task final set 的 CI 较宽。