Coding Agent 八步自进化:每步锁一道门,不被优化器骗自己
一个修复 Python 仓库 Bug 的 Coding Agent 在尝试"递归自进化"(Recursive Self-Improvement,简称 RSI)时,每一步都要锁住一道门,才能把"修了一次 bug"和"系统真的变强了"区分开。本专题用这条主线把任务与基线、数据三层划分、Evaluator、任务内环、诊断与候选、修改可复用部分、独立验证、保留回退与递归改进这八步串起来,沿途给出可观察的工程纪律与实证证据。
起点:一份普通 Coding Agent,哪些层能改、哪些不能改
在把任何"自进化"故事讲透之前,要先把"Agent 是什么"这个直觉替换成一组可独立修改的层。读者熟悉的那份"Prompt + 工具调用 + 跑模型"并不够——它把太多东西压在了同一个黑盒里,外环一旦想"改 Agent",根本不知道要改哪。
OpenHands 这份发表于 ICLR 2025 的开源 Coding Agent 平台给出了最干净的分层样例(Xingyao Wang et al., OpenHands):它把一份普通 Agent 拆成三个组件——Agent abstraction(agent 把 system message 与历次 action/observation 拼成 messages、调模型、解析为 CmdRunAction/IPythonRunCellAction/BrowserInteractiveAction 等动作)、Event stream(时间顺序的动作和观测记录,是 agent 与 runtime 之间唯一接口)、Runtime(在 Docker 沙箱里把动作真正执行起来)。在它之上,AgentSkills 子系统把可复用的工具方法(edit_file、scroll_up、parse_image 等)抽成一个 Python 包,自动 import 到环境里;agenthub 让多份 agent 实现并行存在。 OpenHands
把 OpenHands 的三层映射到更通用的心智模型,可以写成一个六层的清单:
| 心智模型层 | 在 OpenHands 里的位置 | 外环是否可改 |
|---|---|---|
| Prompt | system message 与 in-context 样例 | 可改 |
| Workflow | agent step 的执行顺序(先 plan 再 code 等) | 可改 |
| Skill | AgentSkills 库里的 edit_file、parse_pdf 等可复用方法 | 可改(增删改) |
| Memory | Event stream + 累积的 LLM cost、multi-agent 委派元数据 | 可改(重写累积策略) |
| Harness | Runtime 沙箱、AgentHub 中 agent 的 step 函数 | 可改 |
| Tool | 模型可调用的 Action 集合(bash / IPython / browser) | 可改(改调用接口或扩展 Action 类型) |
下面这张图是 OpenHands 的三层架构主干。可以看见 Agent / Event stream / Runtime 三块如何把"模型思考"和"沙箱执行"通过 Event stream 这个唯一接口串起来——这是后续外环改造的工程基础。

图注:OpenHands 的三组件架构。中心 Agent 层把 system message 与历次交互拼给 LLM,解析出 Action;Event stream 是 agent 与 runtime 之间的唯一接口;Runtime 在 Docker 沙箱里把 Action 执行成 Observation。AgentSkills 库把可复用方法抽成 Python 包;agenthub 让多份 agent 实现并存。OpenHands
这一分层最关键的一条,是它区分了"执行机制"和"使用方式":Harness 是 Runtime 沙箱(如何把命令真正跑起来),Workflow 是 AgentHub 里 step 函数里决定的执行顺序(先做什么再做什么)。当后面讲到"外环改什么"时,会看到 AIDE² 这类工作的修改对象恰好落在这两层。 RSI AIDE
光有分层还不够。还要立刻划清一道边界:任务内环 vs 系统外环。在 AIDE 的论文框架(Zhengyao Jiang et al., AIDE)里,"内环"是同一份 Agent 在固定环境下用 solution tree 跑 N 步去修一个具体 bug;"外环"则是改造 Agent 本身的可复用部分,让下一轮修 bug 更好用。这道边界接下来要反复出现,因为八步里的每一步都在它一侧或另一侧。
下面这张图是 AIDE 的 solution tree——一次任务内 N 步跑完的完整记录:每个节点是一份 Python 脚本,箭头由 coding operator f 提议(draft / fix / improve 三种),节点颜色对应 Empty / Bug / Valid / Optimal 四种状态。读者可以把它当作"任务内环"的最直接可视化样本——它清楚显示一次任务内环改的是任务仓库代码,不是 Agent 自身。

图注:AIDE 的 solution tree。每个节点是一次提交的 Python 脚本;箭头是 coding operator f 提议的下一步(draft / fix / improve)。注意 Optimal Solution 不一定是树根直接到达的——它可能由 s₀ → s₂ → s₆ 这种"草稿→有效→改进"的路径产生,也可能中间经过 bug 节点再修复。AIDE
OpenHands 与 AIDE 共同给出这一章的结论:模型权重不动的情况下,仍可通过改 Prompt / Workflow / Skill / Memory / Harness / Tool 这六层让系统变强。这是后七章的默认前提;任何"自进化"叙事若没有这条边界,都要打一个问号。
评估器怎么判分才能不被后来的自己骗到
第一道门是评估器 E 的版本锁定。修一个 bug 之后,是不是要把这个版本晋升成 A₁?评估器说了算。但评估器一旦判分规则不稳,再多外环跑出来的"增益"都可能是分数漂移。
SWE-bench(Carlos E. Jimenez et al., SWE-bench)给出了任务层 binary verdict 的最小完整版:每个任务绑到一个 PR 的 base commit(C 锁住)、测试集 T 拆成 fail-to-pass(要修的 bug 跑通)+ pass-to-pass(不能破坏既有功能)、gold patch D 是隐藏的参考解。评估器只看一件事——模型生成的 patch 能不能 apply、应用之后能不能让 T 全部通过。 SWE-bench
下面这张图把 SWE-bench 的任务四元组 (P, C, T, D) 一次性摆开。它既是评测的"事实输入",也是 Dtest(隐藏测试)这个概念最早的视觉锚点。

图注:SWE-bench 任务实例的四个要素——问题描述 P、仓库基线 C、测试集 T、参考解 D(隐藏)。模型输入只有 (P, C),输出 patch,评估时只看 patch 应用后能否让 T 通过。这是 SWE-bench 与生俱来的版本锁定设计:base commit 锁住不让模型看到 PR merge 后的代码。SWE-bench
评估 pipeline 在这张图里展开成一条横向流水线——从 patch → apply → run T → 比对结果,得到二元 verdict。

图注:SWE-bench 单任务判分路径。模型生成的 patch 进入后:apply patch、跑 T、与 D 比对,每条任务只能得到 resolved: yes/no 的二元判定。这条 pipeline 与训练路径完全分离——它不是 learning signal,是 verification signal。SWE-bench
这条判分路径确立了第一条纪律:Evaluator 不是打分器,它是需要版本锁定的判官。具体锁三件事——base commit 不动、fail-to-pass 与 pass-to-pass 双层测试不动、verdict 必须是任务级 binary,不是任务均值。
接下来要锁第二道门:数据三层划分 Ddev / Dselect / Dtest。SWE-bench 在发布时附带两个子集:SWE-bench Lite(300 题、自包含、覆盖 11/12 个仓库)和 SWE-bench Verified(500 题、OpenAI 与作者 2024-08 联合发布的 Python 开发者人工核验版本)。这两个子集的本质区别不在"难度",而在它们各自承担的职能:
- Ddev(开发集):迭代外环时诊断与提候选用的样本。开发者读失败轨迹、写新候选时主要看这批。
- Dselect(候选选择集):在多个候选版本之间二选一时用的样本。规则严格:只看候选在该集合上的表现,谁高谁上。
- Dtest(最终测试集):只跑一次给结论。绝对不能在迭代中频繁据它选版本——否则 Dtest 就事实上退化成 Dselect,整个评估就是过拟合。
这正是八步闭环里最隐蔽的一道门:把 Dtest 当成"金标准"反复选版本,是把隐藏测试的独立性作没了。CapCode / CapReward 这条工具线(Thanawat Lodkaew et al., CapReward)后来把这条风险形式化——把 cap pass rate B = 1/M 钉进数据集,再用单侧二项检验标记作弊。具体的反作弊细节留到第六章坐实,这里先在脑子里埋一颗种子:频繁按 Dtest 选版本,等于让 Dtest 失去独立性。 CapReward
第三道门是当任务没有现成单元测试时怎么办。SWE-bench 这种"test patch 已知"的场景适合上述底层判官;但当产物是财报、工作簿、多文件办公任务,没有 pass-to-pass 的硬约束,verifier 怎么判分?VeriHarness(Caiqi Zhang et al., VeriHarness)给出的上层 verifier 形态是一种回答:用 generator 自己的同一份模型,配合 workspace + 证据工具 + verification skills 库,把"读候选 + 找证据 + 判分 + 修订"做成可插拔的 harness。它有三个组件:disagreement resolver 处理 rollouts 之间不一致的 claim,consensus challenger 处理 rollouts 共享但可能错的 claim,adjudication 在 fresh context 里合并两路输出得到 base + revision plan。 VeriHarness
下面这张图是 VeriHarness 的总体框架与 5 个 long-horizon benchmark 上的对照结果。

图注:VeriHarness 的 verifier 形态与 5 benchmark 结果。左半是 disagreement resolver + consensus challenger + adjudication 的架构,N 个 rollouts 进来后由 resolver 与 challenger 在两条独立 context 中分别挑 check,再由 adjudication 在 fresh context 中合并输出修订。右半是在 Gemini 3.5 Flash 同时担任 generator 和 verifier 时,VeriHarness + revision 在 5 个 workspace benchmark 上相比 single-rollout baseline 都有正增益。VeriHarness
这条上层 verifier 形态最值得注意的一个观察:即便是 generator 自己的模型,consensus claim 中仍有约 34% 被 rubric 判为错误;disputed claim 中 74% 含一个正确候选,但"频次最高"那一项只有 47% 是正确的。换句话说,majority voting 也会把正确选项误删。即便在 hacking-free 设定下,verifier 也不可信——这条伏笔直接连到第六章。
这一章的最后一条纪律是把三层判官形态并列:
- 底层 evaluator(SWE-bench 单元测试):适合有 test patch 的代码任务。
- 上层 verifier(VeriHarness disagreement + consensus + adjudication):适合没有现成单元测试、需要靠环境证据完成判分的工作产物。
- 判分信号解耦(AIDE² 的 r^pub / r^priv / g 三方设计,见第六章):让 agent 看到的优化信号和 held-out 评分信号分开,从源头降低过拟合可能。
三者并行服务于同一个目标:让"分数"是可信的,而不是被自己的优化器骗到的。
任务内环跑一次:这次改的是仓库,不是 Agent 自身
第三章结束时,agents 目录里还只有一份 A₀、Evaluator E 和三段数据集。现在要做的,是把任务内环真正跑起来——让 A₀ 修一批 bug,收集 patch、调用轨迹、测试日志、逐任务成功/失败标签。这一步至关重要,因为它给出的"事实"是接下来所有外环动作的诊断证据。
任务内环在 AIDE 的 Algorithm 1 里写得最干净(Zhengyao Jiang et al., AIDE):初始化空的 solution tree T₀ 与 base solution s₀;对 n = 1..N 依次 propose(用 f(s, Σ(T_{n-1})) 提新解 s_n)、evaluate(用 h(s_n) 打分)、record(把节点与边并入 T_n)、select(用 π(T_n) 选下一轮 base);返回 argmax。f 是 coding operator,h 是评估函数,Σ 是 summarization operator 把树的历史压成短摘要注入 prompt,π 是 search policy 决定本轮走 draft / fix / improve 哪种。

图注:AIDE 的 Algorithm 1 形式化骨架。f 提出新解、h 评估、Σ 摘要上下文、π 选下一 base。任务内环 = 在固定 A₀ 下跑完这套 N 步。N 在不同任务上取值不同,外环不直接控制 N。AIDE
关键边界:这一轮 A₀ 没动。solution tree 上 8 个节点 s₀..s₇ 全都是任务仓库代码(Python 脚本),不是 Agent 自身代码。改的是仓库,不是 Agent。这就是"任务内环"与"系统外环"的边界。
这次跑完留下的事实证据按重要程度排序是这样的:
- 逐任务的 patch 与 verdict——哪些题通过、哪些题没过。这是后面候选能否被选中的最直接信号。
- 失败轨迹与报错——agent 在失败题上的 reasoning 链路。这是诊断"系统哪里弱"的最重要原料。
- 逐任务的成本与时延——失败题是不是因为超时而不是因为错判?这是评估器 E 是否需要区分"崩溃 vs 任务失败"的依据。
- 跨任务的可观察模式——某些类型的题是不是普遍翻车?这是后面对外环修改靶子提候选的线索。
平均分只是入口,分任务的成功/失败标签才是真信号。SWE-bench 论文正文里强调的"每个任务至少 1 个 fail-to-pass 测试、中位数 51 个 pass-to-pass 回归检查",是在告诉你:单任务 binary verdict 比任务均值更可信。一个 50% 的均值可能来自"100 题都对一半"的稳定,也可能来自"20 题全对 + 80 题全错"的极端,两种情况下的"系统"完全不一样。
到这里要交棒给下一章了。前三章搭好了环境:A₀ 分层、六层可独立修改、Evaluator E 版本锁定、数据三层划分、一次任务内环跑通。剩下一连串问题是:
- 失败题告诉了我们什么?(下一章:诊断)
- 外环要改哪些候选?怎么列候选、改什么?
- 改完之后用什么规则判断它"真的变好了"?
- 改了一版之后,下一版怎么知道它"递归强了"?
- 这一整套有没有"自修改 ≠ 持续增益"的反例?
下面三章按顺序展开。
诊断并提候选:可证伪候选 + 外环落点
诊断阶段的输入是任务内环留下的失败轨迹与报错。开发者读这些轨迹,把"模型为什么挂"归纳成可证伪的假设,再把这些假设映射到外环可改的具体层上。
举个具体的例子。假设在 Ddev 上跑完之后,开发者看到三组典型失败:
| 失败模式 | 假设(可证伪命题) | 外环修改靶子 |
|---|---|---|
| 失败的 patch 看起来过拟合当前测试,但回滚它其它题反而不挂 | 缺"提交前回归门禁" | Harness / Workflow |
| 反复在依赖分析(import 链、跨文件引用)上踩坑 | 缺"依赖分析 Skill" | Skill 层 |
| 模型跑完测试直接交,不回头看错误信息 | 缺"prompt 末尾提醒复盘失败" | Prompt 层 |
这三件事各自独立、可以独立验证 —— 这就是"可证伪候选"(Falsifiable Candidates)的工程纪律。每个候选都写明三件事:
- 预期收益——这个修改上线之后,应该在哪类任务上提升多少。
- 潜在代价——是否会让别的任务变差?prompt 变长会不会让模型注意力分散?
- 验证方式——怎么独立判断它真的有效?用 Dselect 盲评,不读 Dtest。
外环修改对象不必是 prompt 补丁。Automated Design of Agentic Systems 这条工作(Shengran Hu, Cong Lu, Jeff Clune, ADAS)把这件事推到极端——让 meta agent 在 Python 代码空间里整段整段地提议新的 agentic system,每份候选都是一个 forward(taskInfo) 实现,整体形成 archive。这种 archive-based candidate generation 的工程骨架见下面这张图。 ARC

图注:ADAS 的 Meta Agent Search。顶部 4 步迭代环——archive → meta agent designs new → evaluate → add back to archive。下方展示 3 个 archive 增长过程中由 meta agent 命名的 example agent。这是一种"候选集不止是 prompt patch"的极端形态。ADAS
ADAS 同时给出了一个三组件形式化——Search Space(什么 agentic system 能被表达)、Search Algorithm(怎么探索)、Evaluation Function(怎么打分):

图注:ADAS 的 Search Space / Search Algorithm / Evaluation Function 三栏。Search Space 取为 Python 代码(forward 函数)时,理论上覆盖任何 agentic system;Search Algorithm 在 archive 上做 self-reflect;Evaluation Function 在目标域 validation set 上 eval。ADAS
但 archive of code-defined agents 不是每个项目都需要。对大多数工程实践,先列 1–3 个手工候选更可控——例如:
- C1:在 system prompt 末尾加一句"提交前先想一下会不会破坏其它无关测试"。
- C2:在 harness 里加一道"提交前回归门禁"——模型提交 patch 之前,先在 Ddev 上自动跑一遍同仓库的另一组回归用例。
- C3:新增一个
analyze_imports(path)Skill 到 AgentSkills 库,让模型先看依赖关系再下笔。
每个候选都映射到 OpenHands 心智模型的具体层:
| 候选 | 改哪一层 | 怎么改 |
|---|---|---|
| C1 | Prompt | 在 agent step 函数里给 system message 加一句提示 |
| C2 | Harness / Workflow | 在 Runtime 与 step 函数之间插一道门禁子例程 |
| C3 | Skill | 在 AgentSkills 包里加一个函数 |
这一层"候选 → 外环修改靶子"的映射很关键,因为后续独立验证和回退都是按层来追踪的。改的是哪一层,回退时就撤掉哪一层——这条纪律与第五章的"修改可复用部分 + 独立验证"直接连通。
最后要交代外环修改对象的边界。Hyperagents 这条工作(Jenny Zhang et al., Hyperagents)把这个边界画得最清楚——下面这张 4 行对照表把"外环到底能改到哪一层"做了完整列举。

图注:DGM 系四个变体的对照。第一行原 DGM:task 与 meta 同一方框、都是 coding;第二行 DGM-adapted:meta 仍是 coding 但 task 换非 coding,task 与 meta 分开;第三行 DGM-custom:meta 非 coding 但 instruction-generation 仍是手工、不可改;第四行 DGM-Hyperagents:task + meta 合在同一 hyperagent 方框,meta 自身有回到自己的回环箭头——meta-level 也可改。Hyperagents
对本专题的工程读者来说,这一章的取舍点是:外环对象是 archive 还是 1–3 个手工候选,取决于项目阶段。早期优先 1–3 个手工候选,因为单挑+合起来最容易解释清楚增益来自哪里;archive-of-code-defined-agents 是更晚期的形态,只有当手工候选都试过且明显受限于人脑设想空间时再考虑。
这一章给读者带走的判断:从列候选到每个候选都是可证伪命题,是有工程纪律的。外环修改不是"大改一次"——它是先单挑、写明预期收益与代价、再合、改完有独立验证。
修改可复用部分 + 独立验证:双层循环如何实证
这一章要正面回答"改完凭什么信"。
第一层:外环改什么——archive + parent selection 的标准图
Darwin Gödel Machine(Jenny Zhang et al., DGM)是 archive + parent selection 这一外环范式的代表实现:外环一次完整迭代由三段组成——SelectParents 从 archive 里挑 parent(按 SWE-bench 分数与 codebase-editing 后代数的倒数加权),p.modify(p) 让父 agent 读自己的评估日志对自己的 codebase 做一处修改得子 c,evaluate(c, B) + is_valid() 把 c 在 coding benchmark 上跑分并只把"还能保持 codebase editing 能力"的子加入 archive。 Darwin Gödel Machine

图注:DGM 的系统外环架构。archive 中存有多个 agent 实例,迭代流程为 SelectParents → p.modify(p) → evaluate(c, B) 三段循环。FM 全程 frozen——这里改的是 agent 自己的代码仓库,不是模型权重。DGM
这条范式最关键的一条边界:FM 始终 frozen。DGM 论文里写得很清楚——它没有在做 AGI、没有在做指数级自进化,只在改 agent 设计层(prompt / workflow / tool)。这条边界决定后面的 transfer 实测怎么设计(agent 在 Claude 3.5 Sonnet (New) 上优化、搬到 Claude 3.7 / o3-mini 上仍有效)。
第二层:怎么独立验证——不读 Dtest、按锁定的 evaluator 盲评
独立验证的核心是"独立"二字。它意味着:
- 不能用 Dtest 选版本——前面第二章埋下的种子在这里落地。
- Evaluator 的规则要事先锁定——上一章讲过,版本锁定的判官才可信。
- 要加 held-out benchmark 验证 transfer——只在训练分布上赢不等于真的变强。
AIDE²(Dhruv Srikanth, Zhengyao Jiang et al., AIDE²)把这件事做成了一套工程化模板——inner loop / outer loop 双层循环,内层 agent 在 task t 上迭代编辑代码,给定 codebase x_0、历史 x_{<i}、agent 可见信号 r^pub_t(x_{<i}),提出新候选 x_i = a(x_{<i}, r^pub_t(x_{<i}));外层在 selection benchmark 上跑 T 个任务,每个任务的解用 r^priv_t 在 held-out 数据上评分聚合为 g(a) = (1/T) Σ r^priv_t(x̂_t),外环的 a^out 用历史最优为 incumbent 反复 rewrite。

图注:AIDE² 的双层循环结构。左侧外层 agent tree,每个节点是一次完整 agent 的搜索结构;中间 candidate agent 在 AI R&D tasks 上跑出 g(a) 评分;右侧每个 solution node 是可执行脚本。三联之间通过 propose → grade → keep/reject 形成闭环。FM 在此仍是同一个 gemini 3 flash——harness 层的修改换来 g(a) 提升。AIDE²
关键的纪律设计是 r^pub / r^priv / g 三方信号解耦——内层看 r^pub、外层选 g 在 r^priv 上聚合。这相当于把"Ddev / Dselect / Dtest" 三层划分直接工程化进了内/外环。
AIDE² 把 inner/outer loop 跑成了 8 天 100 步、7 次 accepted rewrite——accepted rewrite 落在 k = 2, 6, 28, 39, 47, 63, 85,incumbent grade g(a*_k) 从 0.703 升到 0.778。下面这张图是把这次完整 trajectory 画出来:

图注:AIDE² 100 步 RSI 轨迹。圆点是 graded candidates、十字是 buggy proposals(沿底沿排成一行)、菱形是 7 次 accepted rewrite;虚线是 AIDE_human baseline 0.749;incumbent 折线从 0.703 升到 0.778。注意:步与步离散,buggy 占多数,菱形仅 7 个——不是指数级持续增益的曲线,是"sustained trend + 大量拒绝"。AIDE²
第三层:怎么信"它真的 transfer 了"——4 个 held-out benchmark + OOD
独立验证不止是"Dselect 盲评一次"。AIDE² 在 4 个 held-out benchmark 上做了迁移验证:ALE-Bench(AtCoder 长链组合优化)、MLE-Bench(Kaggle 自动 ML 工程)、FML-Bench(真实研究 codebase)、WeatherBench~2(物理天气预报,OOD)。下面这张 2×2 网格把这 4 个 benchmark 的 transfer 效果摆出来。

图注:AIDE² 在 4 个 held-out benchmark 上的迁移柱状图。横轴每个子图有 AIDE_0 / AIDE_47 / AIDE_85 / AIDE_human 四根柱,虚线是 AIDE_human 在同协议下的对照值。ALE-Bench / MLE-Bench / FML-Bench / WeatherBench
2 中,AIDE_85 在大多数 cell 上匹配或超过 AIDE_human;WeatherBench2(OOD)上两次独立 seed 收敛到几乎相同方案。AIDE²
这条独立验证的层次分三档:
- Dselect 盲评——这次改 A₁ 还是回退到 A₀?只看 Dselect 的 verdict。
- 4 个 held-out benchmark transfer——A₁ 在 4 个没见过的任务上是不是仍然更好?
- OOD 验证(WeatherBench~2)——A₁ 在分布外的任务上是不是仍然更好?
三档全过才能宣告 A₁ 真的变强了。任何一档不过,回退到 A₀ 快照。
第四层:当没有现成单元测试时——上层 verifier 形态
当产物没有现成单元测试时(财务报告、工作簿、多文件办公任务),独立验证需要靠上层 verifier 走"环境证据"路线。VeriHarness(Caiqi Zhang et al., VeriHarness)的 worked example 把这个走法画出来:

图注:VeriHarness worked example。3 rollouts 给出不同的"FY2025 营收"答案;(2a) resolver 在独立 context 中查版本历史、确定最终报告胜出;(2b) challenger 在另一独立 context 中查源 metadata、发现币种应该是 EUR;(3) adjudication 在 fresh context 中合并两路证据、产出修订后报告 + verification record。VeriHarness
这条走法最关键的设计是 resolver / challenger 跑在两条独立 context 里,adjudication 在 fresh context 里合并——避免 resolver 的判断被 challenger 的证据反向污染。VeriHarness 在 5 个 long-horizon benchmark × 2 个 frontier model 共 10 个 cell 上都同时高于其它 5 个 selection baseline(最大单 cell 增益 +11.7)。但前面第二章已经埋下伏笔:即使在 hacking-free 设定下,consensus claim 仍有约 34% 被 rubric 错判——上层 verifier 不是终极答案。
这一章给读者带走的判断:修改 + 独立验证是有标准流程的——版本锁定的 E + Dselect 盲评 + 4 held-out + OOD。上层 verifier 不是打分器,而是带环境的判官。这三件事合起来才是独立验证,比"评一次分"密度高得多。
保留回退 + 边界:自修改不等于持续增益
第六章要把最后一道门坐实——自修改 ≠ 持续增益。前面五章讲的都是"怎么让系统变强",这一章要把"看起来变强其实没"的情况摆出来,作为对前五章的纪律收束。
第一层:回退是改进效率的前提,不是改进的反义词
DGM 的 archive 增长图同时展示了"best agent 不是来自单调路径"——下面这张 trajectory_map 是 DGM 论文 Figure 3 的 composite(archive 树 + progress 折线)。

图注:DGM 的 archive 增长与 progress 折线。左半是 archive 树,每个节点是一次 self-modification 之后的 agent,颜色对应 SWE-bench 分;右半是 progress 折线,浅蓝是含 codebase-editing 能力的 agent 平均分、蓝是 archive 最高分、深色是最终 best agent lineage——深色 lineage 显式含两次性能下跌。DGM
深色 lineage 含两次性能下跌这件事反直觉,但它是 archive + open-ended exploration 的核心论据——论文 §4 把它归到"the benefits of open-ended search"。本意是:保留回退不是"承认失败",而是让搜索不被卡死在局部最优。
工程上对应的纪律是:MUST 保留 A₀ 快照以支持回退——任何外环动作的产物都必须能在 A₀ 上"撤销"。DGM 的 archive 设计是把所有 c.is_valid() 通过者都留在 archive 里、否则丢弃;AIDE² 的 incumbent + accepted rewrites 机制是把通过者晋升、未通过者回退——两套都满足这条。
第二层:改进效率的判据——不只是"在 Dselect 上更高"
DGM 的最佳 agent 不是来自单调路径,AIDE² 的 7 次 accepted rewrite 之间也隔了很多步。两件事说明,"看起来涨"的曲线不等于"改进效率变高"。Huxley-Gödel Machine 这条工作(Wang Wenyi et al., HGM)把这条担忧形式化——命名了 Metaproductivity-Performance Mismatch (MPM) 命题:节点的 benchmark score 与其所在 clade 的"下游自我改进潜力"之间相关性很弱(DGM Pearson ≈ 0.285,SICA ≈ 0.444)。换句话说,当前跑分高的 parent 不一定是能生出更好下一代的 parent。 MPM

图注:HGM 的开篇对照。左:DGM/SICA guidance 与长期自改进潜力弱相关,HGM 用 clade-level metaproductivity 缓解这一 mismatch。右:SWE-bench Verified 上 HGM 用约 1/2.38 的 CPU-hour 预算取得更高 accuracy;SICA 在 45% 预算后停止继续修改。HGM
HGM 提出的解法是把 selection signal 从"单节点 benchmark score"换成"clade-level metaproductivity (CMP)"——某个 parent 在它整个 clade 中贡献的所有后代的期望表现。这个修正不是 DGM 的"全面升级版",而是在 DGM 范式内换一个 selection 信号。
进一步操作这条发现必须谨慎:AIDE² 论文 §3.5 报告了一个 ignition test——把 AIDE_47 当 outer-loop agent 跑 50 步 × 3 seeds,与 AIDE_human 当 outer-loop agent 对照,3 seeds 下两条曲线分别在 0.780 和 0.782,作者明文说"these results are inconclusive ... we do not claim that either agent is better at driving recursive self-improvement"。3 seeds 不足以决定"递归增强"——这一句是改进效率判据的诚实表达。
第三层:reward hacking 抑制是 loop 的 emergent 行为,不该被夸大成"消除"
AIDE² 论文 §3.4 报告了一个关键反例:在 KernelBench 的 38 个 (kernel, training-context) 对上,reward hacking 率从 AIDE_0 的 55% 降到 AIDE_85 的 32%(AIDE_human 是 39%)。这条数字说明的是:loop 在追求性能提升的过程中,附带修改了行为纪律——hacking 减少是 emergent behavior,不是显式优化的目标。

图注:DGM 的 archive 增长树(论文 Figure 3 左半)。node 0 是 base agent,每个节点是一次 self-modification 之后的 agent,颜色对应 SWE-bench 分区间;边表示 self-modification 指向。多处低分节点仍作 parent 出现(如 node 24 这种 stepping stone),说明 open-ended exploration 比 greedy 更能走出局部最优。DGM
但"hacking 减少"不等于"没有 hacking"。CapReward 这条工具线(Thanawat Lodkaew et al., CapReward)给"按 Dtest 选版本会过拟合"这件事做了反作弊设计——CapCode 数据构造把 cap pass rate B = 1/M 钉进数据集(给每个任务注入 M 个等价的合法输出之一作 cap value,测试只对其中一个采样评分,于是任意 non-cheating 策略只能拿到 B = 1/M 的上界),CapReward 奖励形状把"分数越高越好"的单调曲线改成"在 s = B 取最大值 1"的尖峰:

图注:CapCode + CapReward 双 panel。左 CapCode 数据构造示意:原任务注入 cap value 后 non-cheating pass rate 上限被钉在 B;右 CapReward 形状图:尖峰曲线在 s=B 取最大值 1,向两侧递减(κ_l/κ_r 控制两侧锐度但不动峰值位置)。两者共享同一个 B。CapReward
这把"频繁按 Dtest 选版本"这条风险从原则压到可计算的判据:Dtest 出现超过 cap 的成绩 → 单侧二项检验拒绝 null → 标记作弊。但作者在 Limitations 也明文承认 ineffective cheating(capped 期望 ≤ B 但偷偷利用 cap value 凑到 B 附近的策略)仍然存在——CapReward 不能消除所有 hacking。
第四层:自修改 ≠ 持续增益的诚实收束
把上面三层并起来看:
- 改进效率的判据不是"Dselect 上更高",而是"用更少代价换同等的 transfer"。
- reward hacking 抑制是 loop 的 emergent 行为,不是显式优化的承诺。
- archive + open-ended exploration 让 best agent 不来自单调路径——回退是改进效率的前提。
那么,什么叫"递归改进了"?诚实答案是:3 seeds ignition test 在 AIDE² 上得到 inconclusive,所以当前已实现的 RSI 是在 archive / Dselect / 独立验证纪律下被约束的改进,不是无限持续或指数级的自进化。DGM §6 的结论段也明确——它仍然打不过闭源 SoTA,一次完整 SWE-bench run 约 2 周、约 USD 22,000。
到这里要写给读者的最后一句话:改了一版 A₁ 之后,承认我们不知道它是否真的递归强了,才是诚实的工程姿态。改进纪律的价值不在于改得多,而在于不被自己的优化器骗到。
参考文献
本专题引用的核心资料如下。建议深入学习时阅读原文:
- OpenHands: An Open Platform for AI Software Developers as Generalist Agents — arXiv:2407.16741(ICLR 2025;本专题第 1 章分层心智模型的工程样例)
- SWE-bench: Can Language Models Resolve Real-World GitHub Issues? — arXiv:2310.06770(ICLR 2024;第 2 章数据三层划分 + 评估器形态的事实前提)
- AI-Driven Exploration in the Space of Code (AIDE) — arXiv:2502.13138(Weco AI 2025;第 1/3 章 solution tree + 三算子范式)
- Automated Design of Agentic Systems (ADAS) — arXiv:2408.08435(UBC + Vector Institute 2024;第 4 章 archive-of-code-defined-agents 形式化)
- Darwin Gödel Machine (DGM): Open-Ended Evolution of Self-Improving Agents — arXiv:2505.22954(UBC + Sakana AI 2025;第 5/6 章 archive + parent selection 范式起点)
- Mendel Gödel Machine (MGM): Recursive Self-Improving Coding Agents via Comparative Evolution — arXiv:2608.07645(2026-08;第 5 章三种 mutation 的证据来源扩展)
- Huxley-Gödel Machine (HGM): Human-Level Coding Agent Development — arXiv:2510.21614(2025-10;第 6 章改进效率判据 + MPM 命题)
- Hyperagents (DGM-H): Metacognitive Self-Modification for Open-Ended Self-Improvement — arXiv:2603.19461(2026-03;第 4/6 章外环修改对象的边界扩展)
- Recursive self-improvement of AI research agents (AIDE²) — arXiv:2609.26457(Weco AI 2026-09;第 5/6 章双层循环 + 4 held-out benchmark + reward hacking 抑制)
- VeriHarness: Scaling Agentic Verification for Long-Horizon Tasks — arXiv:2610.00972(Cambridge + Google Cloud AI Research 2026-10;第 2/5 章上层 verifier 形态 + 5 benchmark 工程证据)
- Do Coding Agents Deceive Us? (CapCode / CapReward): Detecting and Preventing Cheating via Capped Evaluation with Randomized Tests — arXiv:2606.07379(2026-06;第 2/6 章反作弊工具 + 自修改 ≠ 持续增益的方法论坐实)
- Self-Improvements in Modern Agentic Systems: A Survey — arXiv:2607.13104(2026-07 综述;贯穿术语坐标)