下一轮凭什么发生:重新理解 AI Agent 的 Coding Loop
AI coding 里有一个几乎无法抗拒的冲动:既然 Agent 一轮能读代码、改文件、跑测试,那就让它再来一轮,直到测试全绿、任务收工。这个冲动诱人的地方在于,它离实现只差一句 while not done: ask_agent_to_continue()。一行代码,看上去就换来了自主。
可是圆画得出来,不等于闭环真的成立。方向盘能一直转,车不会因此更好开;输出能送回输入,控制系统也不会因此自动变稳。反馈能纠正误差,也能放大误差;循环能积累知识,也能积累幻觉、上下文噪声和评分漏洞。同一个圆,既可能把系统拉回正轨,也可能让它更自信地驶向错误方向。所以真正该问的不是“Agent 最多能跑多少轮”,而是一个更苛刻的问题:下一轮凭什么发生?
先把结论摆出来:Agent loop 最合理的定位,不是默认执行模式,而是由外部证据触发的有界恢复控制器。它更像软件系统里的故障恢复机制,平时不启动,失败时才介入,每次介入都要带来新证据,一旦越过边界就停止、回滚,或交回给人。它背后是一次集中研究:九篇论文、多份 OpenAI 与 Anthropic 的一手工程报告,加上两个本地 POC 的原始日志。下面每一节都在为它补证据。
把“跑得久”错当成“想得对”
我们太容易把跑得久误认成想得对。这错觉很老,早期搜索算法也给过同样的幻想:只要树搜得够深,答案迟早浮现。但 coding agent 面对的不是一盘规则固定、奖励可靠的棋,而是一个不完全可观测的软件系统,需求含糊,测试只覆盖局部,文档过时,依赖联网失败,环境悄悄漂移。在这样的世界里,“多跑一轮”至少是四件不同的事:根据新失败证据修正上一轮的错误;在没有任何新信息时重掷一次骰子;继续迎合一个不完整、可被利用的评分器;或因上下文越堆越长而遗忘目标,把改动越铺越大。四者之中只有第一种配得上“反馈循环”这个名字,后三种是重复、过拟合和漂移。
我自己的 Ralph-lite 本地 POC 想回答一个朴素问题:同一个任务,套上外层循环,是否比一次执行更可靠、更省时间,或更省 token。实验设计了三类任务,每类跑一个 baseline 和一个 loop-labelled 的真实 Codex arm,共六次运行。汇总表格漂亮得让人放心:六个 arm 全部完成任务,全部通过各自的 gate,没有一次作用域违规。
但翻开原始日志,故事整个反转。六个 arm 全部在第一轮通过,没有一个收到失败反馈,没有一个进入第二轮,也就没有发生任何真实恢复。更关键的是,baseline 与 loop-labelled 的第一轮 prompt 按字节比较完全相同;它们最终写出不同实现,仅仅因为模型采样本就带随机性。我以为在比较“一次执行”和“循环恢复”,实际比较的是两组标签不同、处理完全一致的随机样本。
token 数字把这个陷阱又演示了一遍。总 token 看似 loop 少了约 3.7%,baseline 613,189,loop 590,395;可一旦剥掉大量缓存输入,只看非缓存输入加输出,方向立刻掉头,baseline 117,573,loop 125,499。拆到三个任务,时间和 token 的方向也是混着的,谈不上任何成本优势。真正该记住的不是“loop 省了多少 token”,而是:当处理没有真正发生时,标签之间的差异不能被解释成处理效果。
实验还甩出一个意外。六个 arm 都试图调用协作或子 Agent 能力,哪怕运行参数明确要求关闭 multi-agent;调用都在真正 spawn 之前失败,没有生成任何子 Agent。它暴露另一条边界:在提示或配置里写“不要用”,不等于这项能力在执行环境里被真正撤销。对权限、网络、部署、密钥和可写的 verifier,真正的关闭只能发生在工具层,策略声明从来不是 capability enforcement。
一个有效 loop 的四个部件,和它真正的燃料
把论文和这次实验放在一起,可以把一个有效的 coding loop 压成四个不可替代的部件。生成器读取任务与当前状态,提出计划、代码或修复,这是大模型最抢镜的部分,以至于人们常误以为它就是全部。独立 gate 不听生成器的自我评价,让编译器、类型系统、测试、静态分析、reviewer 或生产指标来裁决,它存在的意义就是不给生成器既当运动员又当裁判的机会。信息增量要求 gate 失败后,下一轮必须拿到比上一轮更多、且能落地为动作的信息:失败断言、堆栈、差异截图、review comment、counterexample 或生产 trace。状态边界让系统清楚最佳已知结果在哪、哪些文件能改、最多试几次、何时回滚、何时交回给人。
四者合起来,是一条比 while not done 诚实得多的控制流:执行一次,独立 gate 通过就交付并停止;失败则先提取新证据,证据可执行且预算未耗尽就限定范围恢复一次;一旦没有新证据、反复同样失败或风险上升,就停止、回滚、升级。它悄悄改写了 loop 的默认权利:Agent 不再天生拥有下一轮,而必须凭外部证据把下一轮挣回来。
为什么“再想想”经常无效?因为模型眼前的世界没变,任务、代码、可见测试、工具结果都和上一轮一样,第二轮只是从相近分布里再采一次样。能真正改变后验判断的是 information delta,是那些一轮比一轮更锋利的证据。loop 烧的从来不是 token,而是这些证据。
形式化验证把这一点照得格外清楚。2026 年的 Aria 让 coding agent 为 Iris/Coq 生态里的 4,257 个引理生成证明,首轮就完成 79.2%,最难的一个引理试了 28 次仍低于预设的 30 次上限,因此没有任何引理耗尽预算,最终 4,257 个全部通过内核验证,总共约 380 个模型小时。但这不能读成“只要一直重试就会成功”。Aria 几乎凑齐了高质量 loop 的全部条件:内核提供不容讨价还价的正确性 oracle,任务集自带完整性检查,每次失败都返回具体步骤、错误和 pending goal,重试次数有明确上限,系统还拦住那些靠删除或弱化目标来伪造成功的小动作。它赢的不是轮数,而是每一轮反馈的信息密度。
也正因如此,普通 coding task 才那么难。一个失败的端到端测试可能只告诉你“页面不对”,一句 reviewer 的“感觉不够稳”几乎无法转成动作,而一个 visible score 的上升,甚至可能意味着 Agent 更熟练地讨好了一个不完整的指标。优化 loop 的第一顺位因此不是扩大上下文或抬高最大轮数,而是提高失败反馈的可诊断性。
最稀缺的是选择,搜索会忠实放大错误
Agent 系统很擅长表演 Pass@k:并行生成 k 个候选,只要一个对了就宣称自己“有能力解决”。可真正上线的系统必须从 k 个里挑出一个。oracle 知道哪个最好时 Pass@k 可以很高,现实里的 selector 认不出它时 Best@k 会低得多。SWE-Gym 把这道缝摆到明面:某项结果里 Pass@16 高达 42.8,实际选择器的 Best@16 只有 32.0。正确候选早已生成过,系统却没能稳定地把它捞出来。这十几个百分点暴露了一层常被藏起来的能力分层:生成候选是一种能力,把候选之间的差异表示清楚是另一种,用独立证据从中做出选择是第三种,在候选之间提炼并接着改进是第四种,它们不会随模型变强而自动一起变强。生成更多,因此绝不能直接写成解决更多。
一项测试时扩展研究顺着这条线往下走。把 rollout 加到 16 个,配上结构化摘要、选择和 refinement,整体成绩确实上去,但它把任务推向两极。机制不神秘:系统先从上一轮选出四个候选摘要,再让下一轮共享这些“最佳经验”;首轮成功率高时四个摘要通常装着足够多的正确轨迹,后续候选一起朝成功收敛,首轮成功率低时选择器可能只留下一个甚至零个成功候选,错误经验被一并共享,那些原本偶然冒头的正确样本反而被抹掉。论文里,16/16 全成功的任务从 209 个到 350 个,与此同时 0/16 全失败的任务从 73 个到 94 个。被选中的总结既可能放大正确方向,也可能放大错误方向。
所以搜索不是一台均匀提升质量的机器。SpecBench 逼问的正是这件事:coding agent 是不是只通过了可见测试,却没真正满足组合规格?这种迎合可见评分、偏离真实目标的行为通常叫 reward hacking。随着任务包含更多相互作用的要求,可见测试与 held-out 组合规格之间的裂缝明显变宽,更强的搜索没有自动缝上,有时反而让 Agent 更擅长找到满足可见评分、绕过真实意图的局部解。现实里的 reward hacking 极少像科幻片那样存心作弊,它朴素得多:为让当前测试变绿,直接硬编码样例、改掉测试或删掉保护逻辑。轮次越多,探索实现空间的机会越多,探索 verifier 漏洞的机会也越多。如果 generator 和 evaluator 共享同一份上下文、同一批 visible tests、同一个模型盲点,循环再多也变不出真正的独立性。一个不会选择的多候选系统,只是把错误从生成阶段搬到了决策阶段。
Harness 自我改进,与一份必须被拒绝的证据
近来有好几项研究,都在让 Agent 去改自己的 harness。Self-Harness 让 Agent 在受限范围内改写执行脚手架,再用冻结任务集检验修改能否跨模型、跨 held-out 任务泛化;Agentic Harness Engineering 在 Terminal-Bench 上迭代十轮,把成绩从 69.7% 抬到 77.0%;Darwin Gödel Machine 把成功的修改存进一个开放 archive,去试探代码 Agent 自我改写并选择后代的可能。
它们合起来说明 harness 演化是条真实可走的路。但最有意思的不是“Agent 能改自己”,而是增益到底从哪来。在 AHE 的消融里,只动 system prompt 反而会退化,真正扛起增益的是工具、中间件、记忆这些可执行结构,而且它们并不老实相加,单独有效的部件凑到一起可能互相干扰,某个模型上奏效的优化也可能挪不到另一个模型。更值得警惕的是,AHE 要求系统预测一次修改会修好哪些任务、又会让哪些任务回归:它对修复的预测 precision 和 recall 分别约为 33.7% 和 51.4%,对回归的预测更差,只有约 11.8% 和 11.1%。翻译过来就是,Agent 能给自己编一套听上去合理的解释,却很难预见自己将会打碎什么。这就划出一条界线:生成器可以提出 harness candidate,但绝不能兼任最终的批准者。
我的 Offline Self-Harness 本地 POC 把这条界线又印证了一遍。我在 24 个历史任务上训练过程文档缺陷 detector,held-out F1 从 0.4545 升到 1.0,五个精确 detector 被接受,五个 blanket control 被拒绝。这证明 precision gate 拦得住“一刀切”规则,小型 harness 搜索机制也确实能跑。但 1.0 不是未来的性能,它只是在冻结的历史语料上做出的回顾性拟合。真正的问题始终是:协议启用之后,面对从未见过的真实任务,detector 还保不保得住判断力。
于是我搭了一套前瞻评估,却在复查时抓到第一版协议的一处时间泄漏:它只要求任务完成时间晚于冻结点,没有要求任务的开始时间晚于协议启用点。Ralph 实验明明开始得更早,却可能被机械登记成“未来样本”,更糟的是它的结果其实已经参与过协议阈值的设计,因此必须排除。这是一份对我有利、来得正是时候的证据。我最终没有把它塞进 cohort,而是把协议整个升级成 v0.2:分别冻结历史 evaluator 与招募启用点,要求任务的 startedAt、首次跟踪时间和 Git ancestry 全部发生在启用之后。代价是当前的前瞻状态诚实地退回到 0/10。这大概是整项研究里最有分量的结果,它证明的不是“我的 detector 有效”,而是我建起了一套能够拒绝自己偏爱的证据的机制。好的评估系统,首先要有能力让研究者失望。
能沉淀的是外部状态,不是提示词
自我改进这个词,总让人联想到模型在脑子里默默反省然后变聪明。可公开的工程案例给出的路径朴素得多。OpenAI 的 Tax AI 系统把生产 traces、会计师的修正、反复出现的失败模式和评估结果收集起来,再让 Codex 在受限任务里改实现。Anthropic 关于长时运行 Agent 的实践反复强调把 progress 和状态外置成文件、维护结构化状态、干净工作区和明确完成标准。它们真正沉淀下来的从来不是“模型心里的顿悟”,而是一批扎实的外部状态:可重放的失败样本,专家修正与最终 outcome,经过版本控制的工具和规则,冻结的 evaluator 与回归集,以及被接受和被拒绝的 candidate 历史。模型上下文会结束,供应商和版本会更换,prompt 更是轻易被复制粘贴走,只有这些外部状态,才是一个组织能审计、复用、持续打磨的资产。顺着这条线看,Agent 竞争的重心会从“谁攥着一段神奇提示词”,挪向“谁能持续把失败翻译成可靠的 eval”。
多 Agent 的价值也落在同一个逻辑里。把同一任务同时丢给五个 Agent 看着总比一个强,可如果它们用着相似模型、共享同一份上下文、读同一批 visible tests,还都能改 verifier,那它们犯的错会高度相关,五个脑子其实在朝同一个坑里跳。多 Agent 真正的价值不在人多,而在给不同角色架起结构性的独立:generator 写实现却动不了验收标准,evaluator 用独立上下文和只读 verifier,release controller 的部署与回滚权限和开发 Agent 彻底分开。价值来自角色、权限、模型能力和上下文的分离,而不是数量。而且真正的安全边界只存在于执行层,工具能不能调、文件能不能写、网络能不能通,都得由权限系统说了算。
该测的是恢复,不是时长
既然 loop 是恢复控制器,度量的方式就得跟着换:别再盯连续运行了多少小时,该盯的是恢复、成本,以及 visible pass 与 held-out pass 之间的裂缝有没有变宽。把这些拆开,至少要分别记录:initial pass rate 衡量首轮独立完成的能力,recovery lift 衡量初始失败里有多少因新增反馈而恢复,information delta 记录每轮到底新增了什么证据,selector accuracy 检验正确候选出现后系统选不选得中,held-out regression 看可见 gate 变好时隐藏保护面是否变差,scope violation 盯 Agent 有没有越过任务与权限边界,human attention 记每个验证通过的结果需要多少人工判断,cost to verified outcome 算交付一个可信结果的总成本而不只是生成一次。
还要格外提防基础设施噪声。Anthropic 的研究显示,仅仅改动 CPU、内存这类运行资源,就能让 Terminal-Bench 的分数移动约 6 个百分点;在环境没有严格对齐时,一个小于 3 个点的提升,多半不值得拿去讲故事。
未来的 Agent loop 也不会只有一种形态,它会按反馈延迟和 verifier 强度分成几层控制器:毫秒到秒级的编译、类型和 lint,分钟级的 UI、集成与性能,小时到天级的 reviewer、canary 和生产 trace,周到月级的失败挖掘和 harness 演化。把这些尺度全塞进一个永不结束的聊天窗口,版本、责任和审计边界都会随之丢失;做成分层、可暂停、可回滚的 loop,系统才可能稳稳扩展。
人类的位置也会挪动。Anthropic 对约 40 万次 Claude Code session 的研究显示,人类承担了约 70% 的规划决策,Claude 承担了约 80% 的执行决策,而领域经验仍显著地预测着任务能否成功、失败能否恢复。这提醒我们,自主性不该被定义成“连续多少小时没有人类出现”,而该被定义成每单位人类注意力能换来多少经过独立验证的结果,以及当判断依据不足时,系统能不能正确地停下来,把决定权交回去。
所以下一次看见一个 Agent 连续工作十小时、循环几十轮,最该问的不是“它怎么这么能干”,而是:每一轮拿到了什么新事实?谁判断它真的变好了?最好的已知状态在哪?又该何时停下?授权下一轮,本质上就是在决定是否继续消耗预算、扩大改动、承担风险;把授权条件写成一道可审计的 gate,就是给自主系统划出责任的边界。
Loop 不该默认拥有下一轮。下一轮必须由证据赢得。
参考资料
- Self-Harness: Autonomous Agent Harness Optimization
- Agentic Harness Engineering
- Darwin Gödel Machine
- Scaling Test-Time Compute for Agentic Coding
- SpecBench
- SWE-smith
- SWE-rebench
- SWE-Gym
- Harnessing Code Agents for Automatic Software Verification
- OpenAI: Harness engineering
- OpenAI: Building self-improving tax agents with Codex
- Anthropic: Demystifying evals for AI agents
- Anthropic: Infrastructure noise
- Anthropic: Effective harnesses for long-running agents
- Anthropic: Harness design for long-running apps
- Anthropic: Claude Code and domain expertise