同一个模型 30% 到 100%?拆解 Harness 工程的 5 个机制,附 8 个坑的自检清单
引子:同一个模型,两份成绩单
先看一组数字。
8 月 21 日,NVIDIA 在开发者博客上放了一个结果:他们的 agent 系统 AVO 在 ARC-AGI-3 的公开集上拿到 100.00 RHAE,25 个环境 183 关全通。给它供能的模型是 Claude Opus 5。同一个 Opus 5 单独跑这个榜单,成绩是 30.16%。
差距不是一点半点。更扎心的是动作数:AVO 用了 6624 个环境动作走完全程,另一个用同模型的系统 VISTA 用了 7542 个,AVO 少 12%。也就是说它在完成度碾压的同时,还更省动作。
同一套架构最早不是拿来打游戏的,是拿来优化 GPU kernel 的。在 DGX B200 上连续跑了 7 天,探索了 500 多个优化方向,提交了 40 个 kernel 版本,最后比 cuDNN 快最多 3.5%,比 FlashAttention-4 快最多 10.5%。
模型一个权重都没改。
同一时间,另一边的开发者社区在流传几句话。Claude Code 的负责人 Boris Cherny 说,他现在不写 prompt 了,他写循环。OpenClaw 的作者 Peter Steinberger 说,你不该再给 coding agent 写 prompt,你该设计会自己写 prompt 的循环。Google 的 Addy Osmani 给这件事起了名字:loop engineering。
这两件事其实是同一件事。一个从实验室给出了数字,一个从工程现场给出了说法:模型之外的那一圈东西,比模型本身更决定结果上限。
但我们大多数人手里的 agent,跑三到五轮就开始原地打转。同一个 Opus 5,同一个 Claude Code,为什么别人能跑 7 天,你跑 3 轮就崩?
问题拆解
"我的 agent 跑不长"是一个症状,不是一个问题。直接回答它会变成一堆散装建议,所以我先把这个症状拆成三个可以各自解决的失败模式。
症状:同一个模型,别人的 agent 能长时间自主推进,你的跑几轮就退化、空转、或者宣布完成但其实没完成。
拆开看,它其实是三个独立的失败:
- 记忆断了。上下文一满,前面试过什么、哪条路走不通、profiler 吐了什么,全部清零。下一轮它又从头把同样的坑踩一遍。
- 循环断了。没有外部评估器,判断"做完了没有"的是模型自己。它说 done 就是 done。
- 兜底断了。没有停滞检测,也没有硬停止条件。要么在死胡同里空转烧一晚上 token,要么在预算耗尽前一直假装还在推进。
这三个失败模式共享一个总根:你把 agent 当成了一个更强的单次生成器,而它其实是一个跨时间运行的系统。
单次生成的能力在模型里。跨时间的能力不在模型里,它在系统组件的耦合里:什么状态能活到下一轮、什么时候该换策略、走错了能不能爬回来。换模型只换掉了"提议质量",没换掉这三样。
下面 5 个问题按"先立总根 → 分治三个症状 → 守住底线"的顺序分别说明。
问题 1:那 70 分到底是谁挣的
先说一句必须说的:NVIDIA 自己讲清楚了,30% 和 100% 不是一次受控消融。两次跑的推理设置、观察格式、评测方法都不一样。严格的对照实验应该只换 harness、其他全固定,而他们没做这个。
那这个数字还剩什么价值?
同模型横向对比:AVO 6624 动作 vs VISTA 7542 动作,两个系统用的是同一个 Opus 5,分歧只在架构。这 12% 是干净的架构收益。
架构迁移:一个为 CUDA kernel 优化写的 agent,只换了任务接口和工具,就在一个从没见过的、无规则说明的互动推理基准上打满。这件事单靠"模型更强"解释不了。
AVO 的结构可以拆成四件:
-
循环:inspect(看当前状态)→ plan(定假设)→ implement(改)→ evaluate(跑评估)。这不是新东西,现代 coding agent 都在跑。
-
记忆:带着之前的实现版本、每次评测的分数、编译器和分析器的输出、累积下来的推理过程,跨过上下文窗口的边界。上下文重置之后,它是从当前状态接着干,不是从零重建搜索。
-
监督者:它不干活,只盯整条搜索轨迹。发现进展停滞或者开始反复做无用功,就把主 agent 拽向别的策略。注意分工,主 agent 仍然决定看什么、改什么、测什么、提交什么,supervisor 只有建议权。
-
工具:这是"通用"的来源。kernel 场景的工具是编译器和 profiler,游戏场景的工具是环境动作接口,中间那个循环没动。
用公式说得更清楚。
经典 LLM 辅助进化搜索的变异步骤是:
模型拿到采样出来的父代,生成一个新候选数据。AVO 把它换成了:
agent 可以查看完整谱系 P_t、查领域知识库 K、调用打分函数 f,然后自己决定下一步试什么。
所以那 70 分是谁挣的?模型挣的是"每一步的提议质量",harness 挣的是"这些提议能不能累积起来"。前者决定单步上限,后者决定你能不能走完 183 关。
顺带说一个细节:AVO 跑 ARC-AGI-3 全程是纯文本,每一帧观察是一个精确的 64×64 文本网格,一个图像 token 都没花。在一个满屏像素的游戏里,模型从头到尾一眼没看见画面。
问题 2:persistent memory 到底存什么
最常见的假记忆,是把历史对话全量塞回上下文。
这不是记忆,这是把垃圾和金子一起往窗口里倒。窗口里堆着旧的推理、走不通的死胡同、已经被改掉的文件内容,模型的注意力被稀释,token 成本线性上涨,而且它依然不知道"哪条路试过了"。
AVO 的做法是结构化的。谱系里的每一条是一个候选方案加它的分数:kernel 场景下就是源码加内联 PTX 加吞吐分数。知识库是固定的领域资料(CUDA 编程指南、PTX 指令集手册、Blackwell 规格、已有实现)。评估结果是数值,不是描述。
还有一层更意外的:上下文重置本身是个功能,不是缺陷。
Geoffrey Huntley 在 2025 年 7 月搞过一个叫 Ralph 的东西,形如:
while ! grep -q "ALL TASKS DONE" STATUS.md; do
claude -p "读 PLAN.md 和 STATUS.md,挑下一个未勾选项,实现它,跑测试,通过就提交,更新 STATUS.md。然后停下。"
done
每一轮都是一个全新的 agent,上下文是空的,它从磁盘上读当前仓库状态和任务清单,做且只做一个单元的工作,提交,退出。Huntley 用这个办法造了一门编程语言,花了大概 297 美元。
关键在那句"全新的 agent"。长会话会随着窗口填满而退化,因为里面混着过期的推理和过期的文件内容。Ralph 绕开了这件事:状态放在模型改不到的磁盘上,每一轮只把必要的最小上下文灌进去。
判断你的记忆是不是真的,用一个问题就够:上下文清零之后,你的 agent 能不能接着上次的状态继续,而不是重头再来一遍? 不能,那你有的只是日志。
还有一点容易被忽略。AVO 的 40 个 committed 版本是过滤后的结果,不是它生成过的全部程序。失败的和倒退的尝试留在 agent 的私有轨迹里,不进谱系。也就是说,"试过什么没用"这件事本身是被记录的,只是不污染对外可见的候选集。
问题 3:评估器从哪来
循环和"多轮对话"的区别只有一个:有没有一个独立于模型的评估器。
一个生产级循环有四件套。
Trigger:什么启动它。定时任务、PR 打开、测试挂了、工单落地。它的作用是让循环不需要你坐在那儿按开始。
Goal:一个可验证的终点。注意"可验证"这三个字。"重构得更好""提升性能""让它更好维护"都不是目标,是愿望。评估器验不了愿望,只能验事实。"npm test 退出码 0 且没有 skipped 用例""首页 Lighthouse 四项 ≥ 90""src/ 下没有文件超过 300 行",这些才是目标。
Verifier:谁来判断做没做完。这里值得偏执一点。优先用确定性检查,测试套件的退出码、schema 校验、linter。让写代码的模型给自己的作业打分,是那种会悄悄污染其他所有防护措施的失败模式。真需要模型当评委,用另一个 agent、另一套指令,别让写的人批自己的卷子。
Stop rules:多个独立出口。至少三个:验证器确认目标达成时的成功退出、防止卡死循环的硬迭代上限、防止失控循环的预算上限。
AVO 的评估器是硬件接地的:数值正确性加实测吞吐,正确性失败直接记 0 分。候选要成为 committed 版本,得同时满足"通过正确性检查"和"分数不低于当前最佳"。500 多个方向最后留下 40 个,这个 8% 的过滤率就是评估器的威力。
有个坑值得单独讲,因为它很隐蔽。Claude Code 的 /goal 文档里写得很明确:评估器不会自己去跑命令、读文件,它只能判断 agent 已经呈现在对话里的东西。如果你的完成条件依赖一条永远不会出现在 transcript 里的证据,那不管条件写得多漂亮,都是不可验证的目标。
所以写目标的时候顺手写上"怎么证明":比如pnpm build 退出 0、git status 干净、三个 Makefile target 连续跑通。
问题 4:supervisor 和三个停止条件
AVO 里我最喜欢的是 supervisor 这个角色,因为它承认了一件很多人不愿意承认的事:主 agent 判断不了自己是不是卡住了。
它盯着的是轨迹,不是单步。停滞信号长这样:连续 N 轮评估分数没有提升、同一个文件或同一段逻辑被反复修改、候选项之间相似度越来越高、失败原因在重复。
Supervisor 的动作是"重定向",不是"接管"。它说往别的方向试试,主 agent 依然决定具体怎么干。这个分工是有道理的:让一个组件同时负责执行和判断自己执行得好不好,等于没有判断。
停止条件这块,我见过太多只有一个的循环:"模型说它做完了"。这是把终止权交给了最没有资格做这个决定的一方。
三个出口各管一件事:
- 成功出口:验证器确认目标达成。注意是验证器确认,不是 agent 声明。
- 迭代上限:比如 20 轮。到了就停,不管它觉得自己离终点多近。
- 预算上限:token 或金额。这是防止隔夜循环的唯一硬约束。
第三个尤其重要。跑得越久的循环越容易在死胡同里烧钱,而烧钱这件事在失败的时候是没有任何意义的,纯浪费钱。
问题 5:怎么证明你的 harness 真的有用
harness 工程最大的风险不是做不出来,是做出来之后无法判断它有没有用。你换了架构,感觉变好了,但可能是模型升级了、任务变简单了、或者你只是在好的样本上加了一些权重。
要让这件事可证伪,至少测五个量:
| 指标 | 为什么测 |
|---|---|
| 动作数 / 环境交互次数 | 同样的活干了多少步,AVO 靠这个赢了 12% |
| 恢复频率 | 失败后爬回来的次数占总轮次的比例,这是 harness 的核心产出 |
| 每轮 token 与总成本 | 长时程任务的真实约束在这里,不在准确率 |
| wall-clock 时间 | 动作少不一定快,supervisor 很重的话可能又慢又贵 |
| 对照基线 | 同一个模型裸跑一遍,没有基线就没有收益 |
最后一条是分水岭。没有裸模型基线,你所有的改进都是自我感觉。NVIDIA 那份报告之所以还值得读,就是因为它至少给了一个同模型横向对比(6,624 vs 7,542)。
还有个严谨性问题要说清楚:AVO 的 100 分跑的是公开集的 25 个环境。ARC Prize 把私有环境定为主评测依据,公开集只是演示接口。而且截至 8 月 22 日,没有官方开源实现,也没有独立复现。
所以"照着 AVO 抄一遍就能拿 100 分"是误解。可以借鉴的是它那四件套,不是那个分数。
小结:从 5 个小问题回到那个大故障树
| 小问题 | 结论 | 对应症状 |
|---|---|---|
| 问题 1:70 分谁挣的 | 模型出提议质量,harness 出累积能力,两者是独立变量 | 把 agent 当单次生成器 |
| 问题 2:记忆存什么 | 结构化状态 + 外部持久化 + 上下文重置,不是历史回灌 | 治记忆断 |
| 问题 3:评估器从哪来 | 确定性优先,目标是事实不是愿望,证据必须落在 transcript 里 | 治循环断 |
| 问题 4:怎么兜底 | supervisor 管重定向不管执行,三个独立停止条件 | 治兜底断 |
| 问题 5:怎么证明有用 | 动作数、恢复频率、成本、wall-clock,加一条裸模型基线 | 守底线 |
三个失败模式各自有了对应机制,根本原因也清楚了:模型不是系统,模型是系统里的一个组件。你的 agent 跑不长,大概率不是模型不行,是那一圈没人认真设计。
循环的三种形态
理解了机制之后,看看现在工程现场在跑的三种循环形态。
进化式搜索。AVO 属于这类。特点是有明确的候选谱系、分数、保留规则,agent 扮演变异算子。适合有客观打分函数的场景(kernel 优化、参数搜索、编译优化)。它的强项是不需要你定义"完成",只需要你定义"更好"。
目标循环。Ralph 和现在的 /goal 属于这类。特点是一个可验证目标加一个 while 循环,每轮重置上下文,状态在磁盘上。适合任务清单明确、可以拆成独立单元的工作(迁移、批量重构、补齐测试)。门槛最低,一个下午能搭起来。
自我改进循环。LangChain 在《The Art of Loop Engineering》里给的四层嵌套:执行循环 → 验证循环 → 学习循环 → 修改 harness 本身 → 更好的执行循环。前两种循环优化的是"任务怎么完成",这一种优化的是"系统怎么变好"。适合已经在稳定跑、想进一步压成本的团队,但它要求你有足够的 trace 数据,否则学习循环学到的是噪声。
8 个坑的自检清单
按四个位置归位,每条只给症状和解法。
记忆层
-
把多轮对话当循环。症状:轮次越往后输出越差,但它"记得"前面的所有事。解法:区分 agent loop 和 harness loop,内循环是工具调用,外循环是"它说 done 之后你按条件核验,不通过就重灌上下文发回去"。
-
历史全量回灌。症状:token 成本线性涨,注意力被稀释,它仍然不知道哪条路试过。解法:状态结构化放外部(文件、git、队列),每轮只灌最小必要上下文。
-
只存成功不存死胡同。症状:同一个错误隔几轮又犯一次。解法:失败轨迹也要落盘,只是不进对外可见的候选集。
循环层
-
让模型给自己的作业打分。症状:自评通过率接近 100%,上线后一塌糊涂。解法:换确定性检查;非用模型不可就换一个 agent、另一套指令。
-
目标是愿望不是事实。症状:条件里出现"更好""更优雅""提升性能"。解法:改成可执行的判断语句,
npm test退出码 0、Lighthouse ≥ 90。 -
证据不会出现在 transcript 里。症状:目标写得很清楚,但评估器永远判不了。解法:目标里附上"怎么证明",并把证据的产生过程安排进 agent 的动作里。
兜底层
-
只有"模型说 done"这一个出口。症状:要么空转一整晚,要么在预算耗尽前一直装作在推进。解法:三个独立出口,成功、迭代上限、预算上限。
-
没有停滞检测。症状:轨迹上是一段长长的平台,token 一直在烧。解法:监控连续无提升轮次、同文件反复修改、候选相似度上升,触发就重定向。
度量层(这条算附赠,因为它决定了上面 8 条有没有被真正修好)
只测最终成功率,不测动作效率和恢复频率。解法:把动作数、恢复频率、每轮 token、wall-clock 记下来,再加一条裸模型基线对照。没有基线,所有改进都是感觉。
我一开始对"harness 比模型重要"这种说法是怀疑的,觉得像是卖课的口号。看完 AVO 那份报告我改了主意,但改的不是我想的那个方向。
真正说服我的不是 30% 到 100% 这个跳跃,而是它的架构迁移:一个为 CUDA 写的 agent,换套工具就去打游戏了。如果收益真的来自"对某个领域的精细调优",这种迁移不会发生。能迁移的东西是那四件套的结构,不是任何具体内容。
这件事对我们的实际含义是,模型能力的进步是别人给你的;harness 的进步是你自己能做的。当模型差距在收敛的时候,系统架构是少数还能拉开差距的地方。
参考来源
- NVIDIA 开发者博客(2026-08-21)《AVO Reaches 100% on ARC-AGI-3》:
developer.nvidia.com/blog/nvidia-avo-reaches-100-on-arc-agi-3-... - AVO 论文(2026-03-25,arXiv 2603.24517)《AVO: Agentic Variation Operators for Autonomous Evolutionary Search》:
arxiv.org/abs/2603.24517 - ARC Prize ARC-AGI-3 基准与 RHAE 评分定义:
arcprize.org - Boris Cherny(Claude Code 负责人)"I don't prompt Claude anymore, I have loops":2026 年 6 月访谈
- Peter Steinberger(OpenClaw 作者)"You shouldn't be prompting coding agents anymore. You should be designing loops that prompt your agents."
- Addy Osmani(Google)loop engineering 定义:"a recursive goal where you define a purpose and the AI iterates until complete";"A decent model with a great harness beats a great model with a bad harness"
- Armin Ronacher(Flask 作者)agent loop 与 harness loop 的区分
- Geoffrey Huntley,Ralph 循环(2025-07),约 $297 造一门编程语言
- LangChain《The Art of Loop Engineering》:执行 → 验证 → 学习 → 修改 harness 四层
- Claude Code
/goal文档:可验证目标的三个组件与"评估器只能判断 transcript 中的内容"这一约束 - AlphaSignal / ExplainX 对 AVO 结果的独立报道与严谨性讨论(public set、非受控消融、无开源实现)
- CSDN《2026 年 8 月开发者生态月报》:Agent 基础设施成为新战场