面向编码智能体的「先学测试,再用测试提升修复能力」框架
论文arXiv原文:https://arxiv.org/html/2609.09133v1
摘要
执行反馈可以引导编码智能体完成仓库级缺陷修复,但前提是生成的测试用例能够捕获issue所描述的预期行为。智能体在同一条执行轨迹中同时编写补丁与测试用例时,二者可能产生一致的错误认知,造成"补丁错误但测试通过"的虚假可信现象。
本文提出**(\mathcal{E})xecCritic**,一套「测试‑验证‑修复」的脚手架框架,配套角色专属强化学习训练流程。框架将测试用例生成与源代码修复完全解耦:Test智能体独立生成适配仓库原生环境的回归测试;故障闭合执行沙箱(fail‑closed harness)校验并冻结该测试包;Repair智能体仅基于固定测试的执行反馈修改源代码,全程不允许改动测试用例。两个角色均以Qwen‑3.5‑35B‑A3B作为主干模型,分开独立训练。
- Learn to Test(学习生成测试):Test智能体学习生成具备行为有效性、可以区分正确/错误补丁的测试用例;
- Test to Improve(借助测试实现修复迭代):Repair智能体同时学习直接完成缺陷修复,以及根据执行反馈迭代修改补丁。
在SW(\mathcal{E})‑bench Verified数据集上,修复效果高度依赖测试质量:固定基础版Repair智能体,使用基础版Qwen生成的测试,任务解决率从无测试基线61.2%下降至57.3%;使用GPT‑5.6‑sol生成高质量测试,解决率提升至65.3%。
经过角色专属后训练后,Qwen Test智能体的Base‑to‑Gold测试成功率由22.2%提升到62.2%;将两个经过训练的智能体组合,整体解决率达到72.6% 。相比原始无测试基线提升11.4个百分点,且评估阶段不依赖更强大模型、也不使用Oracle先知测试。

1 引言
现代AI编码智能体依靠迭代交互与执行反馈提升推理性能,该模式在仓库级缺陷修复任务中尤为关键:issue描述预期行为,但真正的修复还依赖散布在代码库中的实现细节、调用点、边界条件。失败的测试可以暴露遗漏的分支,在提交补丁之前定位下一轮修改方向。SW(\mathcal{E})‑agent、OpenHands、Mini‑SW(\mathcal{E})‑Agent等仓库级智能体都会交替执行代码探索、编辑、执行、迭代修复。
但这套循环的价值高度取决于反馈能否真正衡量issue要求的行为。真实评估器在数据集环境中是隐藏不可见的,智能体必须自己构造检查手段,并自行判断证据是否充分。智能体自行编写的测试往往只探测运行时现象,而非断言issue期望的业务行为;会漏掉关键边界用例;甚至和补丁共享同一套错误理解。同一轨迹同时产出补丁和验证测试时,错误补丁可以通过同样错误的测试,产生虚假验证效果。
由此引出两项核心需求:提升生成测试的行为有效性;并且让验证标准独立于源代码补丁的迭代过程。
生成测试、修复源代码需要完全不同的能力:测试生成需要从issue与代码库推断行为契约,并转换为仓库原生可运行回归测试;修复需要定位故障实现、解读并不完美的执行反馈、修改源码且不能弱化测试约束。通用编码能力并不等价于上述两项专项能力。实验证明:同样的修复智能体,使用质量不同的测试,最终效果既可能提升,也可能下降。因此本文将Test与Repair两个角色分开训练。
(\mathcal{E})xecCritic完整流水线:
- Learn to Test阶段:Test智能体探索仓库,产出完整测试包(测试补丁、精确执行命令、结构化行为契约);故障闭合沙箱校验该包,要求它在原始bug仓库可以干净失败;离线的Gold行为与候选补丁判别结果作为训练信号;
- Test to Improve阶段:沙箱冻结已经校验通过的测试包,针对Repair智能体产出的每一轮源代码补丁执行测试,返回有边界限制的执行反馈。
测试生成与源码修复完全隔离:Test智能体定义行为目标;沙箱固定测试内容;Repair智能体只修改源码;官方评估器保留最终正确性判定权。
SW(\mathcal{E})‑bench Verified实验证明:仅仅增加可执行反馈并不一定带来收益,收益完全取决于测试质量。经过专项后训练,Test、Repair组件均获得显著提升;二者组合之后,不依赖更强模型、不使用先知Oracle测试,解决率达到72.6%。
本文贡献
- 提出面向仓库级缺陷修复的「测试‑验证‑迭代修复」脚手架,将测试生成与源代码修改解耦;独立生成测试并在修复全程保持冻结;
- 设计角色专属强化学习训练范式:Test智能体学习生成具备区分度的有效测试;Repair智能体学习直接修复 + 根据固定测试反馈迭代补丁;
- 实证表明生成测试的质量会决定反馈是增益还是损害修复效果;训练后组件组合在SW(\mathcal{E})‑bench Verified达到72.6%,相比原始无测试基线提升11.4个百分点。
2 问题动机:修复逻辑与验证逻辑互相耦合
当编码智能体处理真实代码库bug,需要产出补丁,并且在提交前评估补丁质量。官方评估器不可见,任务专属验证手段完全依赖智能体自身。智能体可以选择运行自定义检查,也可以完全不做验证直接提交。提交到官方评估器的补丁可能完全没有针对issue的验证证据。
运行自定义检查会带来第二类失败模式:举例,bug只会在传入空列表触发。智能体修复普通非空场景,写的测试也只覆盖非空场景。测试执行通过,但原始bug依旧存在。补丁和测试达成一致,但二者共享对issue的不完整理解。
在同一轨迹内追加更多测试,不一定解决该问题:相同的认知盲区会同时塑造解决方案和用于验证的证据。
共享轨迹带来修复与终止证据耦合
形式化定义:任务实例 x = ( d , R B ) x=(d,R_B) x=(d,RB), d d d为issue描述, R B R_B RB为存在缺陷的代码库(Base版本)。
提交前, ( E ) \mathcal{(\mathcal{E})} (E)代表用于评估补丁 p p p的检查集合; ( E ) = ∅ \mathcal{(\mathcal{E})}=\emptyset (E)=∅代表完全不做验证直接提交。
传统智能体循环中,补丁与验证证据来自同一策略、同一条轨迹:
( p , , ( E ) ) ∼ π ω ( ⋅ ∣ x ) (p,,\mathcal{(\mathcal{E})})\sim\pi_{\omega}(\cdot\mid x) (p,,(E))∼πω(⋅∣x)
该公式体现两类缺陷:
- ( E ) = ∅ \mathcal{(\mathcal{E})}=\emptyset (E)=∅:无任何任务专属验证直接提交补丁;
- ( E ) ≠ ∅ \mathcal{(\mathcal{E})}\neq\emptyset (E)=∅:共享错误认知,检查执行成功,但并不代表解决issue。
V x ⋆ ( p ) ∈ 0 , 1 V_{x}^{\star}(p)\in{0,1} Vx⋆(p)∈0,1为官方评估器,只有它能最终判定补丁是否真正解决任务。
使用独立固定测试,解除轨迹层面耦合
在修复补丁迭代之前就生成测试用例,并且修复全程固定不变。
"独立"指生成上下文、写权限隔离;并不代表Test、Repair智能体一定不会对issue产生相同误解。Repair智能体结合固定测试反馈、issue描述、仓库状态,决定继续迭代还是提交补丁。
(\mathcal{E})xecCritic实现该隔离:Test智能体构造检查;沙箱执行并冻结测试;Repair智能体仅修改源代码补丁。
3 方法:先学测试,再用测试提升修复
(\mathcal{E})xecCritic通过两个角色分离修复与验证,修复迭代过程中测试保持固定。部署阶段,Test产出任务专属可执行证据,引导Repair迭代、辅助Repair决定终止提交。整体分为两个阶段:
- Learn to Test :Test智能体从issue生成聚焦的回归测试包;沙箱验证测试包可执行,并且在原始缺陷仓库 R B R_B RB能够干净失败。
- Test to Improve:Repair智能体使用这份固定测试的输出,迭代源代码补丁。
任务实例 x = ( d , R B ) x=(d,R_B) x=(d,RB),两个智能体都接收issue描述 d d d与缺陷仓库状态 R B R_B RB,但轨迹与写权限完全不同。
Test输出测试包: b = ( Δ b , c b , κ b ) b=(\Delta_{b},c_{b},\kappa_{b}) b=(Δb,cb,κb),包含:仓库原生测试补丁 Δ b \Delta_b Δb、精确执行命令 c b c_b cb、JSON格式行为契约 κ b \kappa_b κb。
Repair智能体只产出纯源代码补丁 p p p。
沙箱执行后返回带边界约束的验证证据 ( E ) ( b , p ) \mathcal{(\mathcal{E})}(b,p) (E)(b,p),包含测试结果与执行输出。最终补丁正确性仍然由官方评估器 V x ⋆ ( p ) V_{x}^{\star}(p) Vx⋆(p)判定。

3.1 Learn to Test:构造可执行回归测试包
在反馈引导修复开始之前,先产出完整可执行回归测试包。给定任务上下文 x = ( d , R B ) x=(d,R_B) x=(d,RB),Test策略生成测试包:
b ∼ π ϕ T ( ⋅ ∣ x ) b\sim\pi^{\mathrm{T}}_{\phi}(\cdot\mid x) b∼πϕT(⋅∣x)
测试包包含三类制品。沙箱校验制品,在干净 R B R_B RB副本上运行声明的测试节点。单条生成episode中,Test最多可以提交5次尝试;第一个有效、并且在Base仓库干净失败的包会被保留。
如果全部尝试都无法达成Base干净失败,则标记该实例为Base‑gate failure,不会启动反馈修复流程;直接使用Round‑0初始补丁送入官方评估,该实例仍然统计在整体任务分母中。
离线训练与评估阶段,还会把 b b b运行在Gold修复版本仓库 R G R_G RG(打上参考正确补丁)。
- B x ( b ) = 1 B_{x}(b)=1 Bx(b)=1:在Base版本干净失败;
- G x ( b ) = 1 G_{x}(b)=1 Gx(b)=1:在Gold版本测试通过;
定义指标Base‑to‑Gold成功率 :
Q x ( b ) = B x ( b ) ⋅ G x ( b ) Q_{x}(b)=B_{x}(b)\cdot G_{x}(b) Qx(b)=Bx(b)⋅Gx(b)
Q x ( b ) = 1 Q_x(b)=1 Qx(b)=1代表:测试在bug版本失败,在正确修复版本通过。执行错误会把对应指标置0。
离线评估还会在一批标注好的候选补丁上运行 b b b,衡量测试是否可以区分正确/错误补丁;这些结果仅用于训练奖励与分析,不会进入Test智能体轨迹 。部署时,只有满足 B x ( b ) = 1 B_{x}(b)=1 Bx(b)=1的测试包才会进入后续Repair流程;Gold补丁与Gold执行结果不会用来过滤Test样本。
Base‑gate只能校验制品合法性、以及在缺陷仓库是否失败;不能保证测试语义真正对齐issue需求。附录B给出证据门控的沙箱演进机制,用于未来迭代校验规则,该机制不会在智能体运行时自动更新沙箱。
3.2 Test to Improve:基于固定测试反馈迭代补丁
h t h_t ht代表第 t t t轮开始时保留的会话、工具调用、观测记录;初始 h 0 = ∅ h_0=\emptyset h0=∅。 s t s_t st代表Repair策略可见信息;设置最大反馈迭代轮次 T m a x = 5 T_{\mathrm{max}}=5 Tmax=5。
{ s 0 = ( x , h 0 ) , p 0 ∼ π R ∗ θ ( ⋅ ∣ s ∗ 0 ) ( E ) ∗ t = ( z ∗ t , o t ) = ( E ) ( b , p t ) , z t ∈ P A S S , F A I L s t + 1 = ( x , h t + 1 , p t , ( E ) ∗ t ) , p ∗ t + 1 ∼ π R ∗ θ ( ⋅ ∣ s ∗ t + 1 ) , z t = F A I L , t < T m a x \begin{cases} s_{0}=(x,h_{0}),& p_{0}\sim\pi^{\mathrm{R}}*{\theta}(\cdot\mid s*{0})\ \mathcal{(\mathcal{E})}*{t}=(z*{t},o_{t})=\mathcal{(\mathcal{E})}(b,p_{t}),& z_{t}\in{\mathrm{PASS},\mathrm{FAIL}}\ s_{t+1}=(x,h_{t+1},p_{t},\mathcal{(\mathcal{E})}*{t}),& p*{t+1}\sim\pi^{\mathrm{R}}*{\theta}(\cdot\mid s*{t+1}),\ z_{t}=\mathrm{FAIL},\ t<T_{\mathrm{max}} \end{cases} {s0=(x,h0),p0∼πR∗θ(⋅∣s∗0) (E)∗t=(z∗t,ot)=(E)(b,pt),zt∈PASS,FAIL st+1=(x,ht+1,pt,(E)∗t),p∗t+1∼πR∗θ(⋅∣s∗t+1), zt=FAIL, t<Tmax
- p 0 p_0 p0:Round‑0,从issue与缺陷仓库直接生成初始补丁;
- 每一轮 p t p_t pt,沙箱重置隔离工作区回 R B R_B RB,打上 p t p_t pt与固定不变的测试包 b b b ,返回结果 z t z_t zt与有边界限制输出 o t o_t ot;
- h t + 1 h_{t+1} ht+1保留Round‑0全部上下文与后续交互历史,不会只用最新反馈覆盖全部上下文;
- 当 z t = P A S S z_t=\mathrm{PASS} zt=PASS,控制器立刻终止Repair episode,直接提交通过补丁;本地通过只是终止条件,不等于官方判定正确。
- 即使测试还在FAIL,智能体也可以主动提交补丁(认为生成测试不完备、过于严格);
- 如果5轮迭代结束依旧没有本地PASS,控制器强制提交最新候选补丁作为最终版本。
操作层面执行错误不会给出行为判定,只会返回诊断信息,不能作为本地接受依据。测试包 b b b在全部轮次完全不变。
提交之后由官方评估器 V x ⋆ ( p t ) V_{x}^{\star}(p_t) Vx⋆(pt)判定补丁是否真正解决任务。附录B.1包含完整形式化执行语义。
4 (\mathcal{E})xecCritic:学习生成测试与学习修复
(\mathcal{E})xecCritic同时学习两项互补能力:Test训练让模型从issue、仓库上下文产出聚焦、可执行回归测试;Repair训练产出高质量初始补丁,同时可以利用测试输出做针对性源码迭代。两套训练都绑定可观测执行结果作为奖励。
4.1 学习生成可靠测试用例
Test策略 π ϕ T \pi^{\mathrm{T}}_{\phi} πϕT生成测试包 b b b。评估指标: B x ( b ) B_x(b) Bx(b)、 G x ( b ) G_x(b) Gx(b),以及在标注候选补丁集上的行为区分能力。训练分为两阶段:监督微调SFT,再GRPO强化学习。
离线轨迹演示:教会生成仓库原生测试
构造可用测试补丁需要:仓库探索、行为意图解读、测试基础设施发现、产出可执行制品。收集高质量教师轨迹做监督微调,演示完整仓库原生工作流。该阶段是off‑policy,轨迹来自固定更强教师模型,训练前已经生成完成。样本准入条件:协议合法、并且Base干净失败;Gold结果不会过滤SFT训练样本,也不会输入给学生模型上下文。
On‑policy RL:奖励行为有效性与判别能力
SFT之后使用GRPO,基于3.1节离线执行结果做优化。
对每个任务 x x x,从 π T ∗ ϕ \pi^{\mathrm{T}}*{\phi} πT∗ϕ采样 K K K条Test轨迹,产出 b 1 ... b K b_1\dots b_K b1...bK。
每个 b b b分别运行在 R B R_B RB、 R G R_G RG,以及最多8个去重、经过 V ∗ x ⋆ V*{x}^{\star} V∗x⋆标记的候选补丁。
- TPR:正确补丁被测试通过占比;
- TNR:错误补丁被测试拒绝占比;
- 平衡准确率: B A ∗ x ( b ) = 1 2 ( T P R + T N R ) \mathrm{BA}*{x}(b)=\tfrac12(\mathrm{TPR}+\mathrm{TNR}) BA∗x(b)=21(TPR+TNR);
当某一类样本为空,召回置0,此时 B A ∗ x ( b ) ≤ 0.5 \mathrm{BA}*{x}(b)\le 0.5 BA∗x(b)≤0.5。
只要任意候选补丁出现执行操作错误,整条轨迹优势置0,屏蔽策略更新。
Test奖励函数:
r x T ( b ) = { − 0.2 , 完整episode没有产出合法提交 , 0 , B x ( b ) = 0 或者 G x ( b ) = 0 , 0.2 , Q x ( b ) = 1 , B A ∗ x ( b ) < 0.8 , 0.5 , Q ∗ x ( b ) = 1 , 0.8 ≤ B A ∗ x ( b ) < 1 , 1.0 , Q ∗ x ( b ) = 1 , B A x ( b ) = 1. r_{x}^{\mathrm{T}}(b)= \begin{cases} -0.2,&\text{完整episode没有产出合法提交},\ 0,&B_{x}(b)=0\ \text{或者}\ G_{x}(b)=0,\ 0.2,&Q_{x}(b)=1,\ \mathrm{BA}*{x}(b)<0.8,\ 0.5,&Q*{x}(b)=1,\ 0.8\le\mathrm{BA}*{x}(b)<1,\ 1.0,&Q*{x}(b)=1,\ \mathrm{BA}_{x}(b)=1. \end{cases} rxT(b)={−0.2,完整episode没有产出合法提交, 0,Bx(b)=0 或者 Gx(b)=0, 0.2,Qx(b)=1, BA∗x(b)<0.8, 0.5,Q∗x(b)=1, 0.8≤BA∗x(b)<1, 1.0,Q∗x(b)=1, BAx(b)=1.
超出最短rollout turns 8步以上,奖励折半。
4.2 学习从执行反馈迭代修复补丁
Repair策略 π R ∗ θ \pi^{\mathrm{R}}*{\theta} πR∗θ生成补丁序列 p 0 , p 1 ... p_0,p_1\dots p0,p1...。训练主配置:每个任务选定一个Oracle F2P先知测试,Repair全程固定该测试,Repair智能体只观察执行反馈,看不到测试源码。每条rollout最多允许Round‑0之后5轮反馈迭代,每轮最多40 turns。
u t u_t ut代表终端补丁官方结果; z ∗ t t r a i n z*{t}^{\mathrm{train}} z∗ttrain代表训练用选定测试的执行结果。
Repair终端奖励函数:
r x R ( p t ) = { 0 , 终端补丁无效 , 0.1 , z t t r a i n = F A I L , 0.2 , z t t r a i n = P A S S , u t = F A I L , 1.0 , z t t r a i n = P A S S , u t = P A S S , t > 0 , 1.5 , z t t r a i n = P A S S , u t = P A S S , t = 0. r_{x}^{\mathrm{R}}(p_{t})= \begin{cases} 0,&\text{终端补丁无效},\ 0.1,&z_{t}^{\mathrm{train}}=\mathrm{FAIL},\ 0.2,&z_{t}^{\mathrm{train}}=\mathrm{PASS},\ u_{t}=\mathrm{FAIL},\ 1.0,&z_{t}^{\mathrm{train}}=\mathrm{PASS},\ u_{t}=\mathrm{PASS},\ t>0,\ 1.5,&z_{t}^{\mathrm{train}}=\mathrm{PASS},\ u_{t}=\mathrm{PASS},\ t=0. \end{cases} rxR(pt)={0,终端补丁无效, 0.1,zttrain=FAIL, 0.2,zttrain=PASS, ut=FAIL, 1.0,zttrain=PASS, ut=PASS, t>0, 1.5,zttrain=PASS, ut=PASS, t=0.
- 无效补丁得到0;
- 测试失败得到0.1;
- 测试通过但是官方评估失败得到0.2;
- 迭代轮次后测试与官方全部通过:1.0;
- Round‑0直接一次全部通过给予更高奖励1.5,鼓励模型优先产出高质量初始补丁,同时依然学习反馈迭代能力。
训练奖励区分"满足训练测试"和"完整通过官方套件"。评估阶段只看官方评估器 V x ⋆ V_{x}^{\star} Vx⋆结果,与训练奖励解耦。
5 实验
实验回答3个核心问题:
- 固定Test补丁,能否提升开箱Repair智能体解决率;效果如何受测试质量影响;
- 后训练能否提升Test智能体产出有效行为检查的能力;
- Repair后训练是否同时强化初始补丁质量、以及基于反馈迭代修改的能力。
5.1 实验设置
模型与训练数据集
- 可训练主干:Qwen‑3.5‑35B‑A3B;
- 更强参考模型:GPT‑5.6‑sol;
- 训练集:SW(\mathcal{E})‑ReBench;评估集:SW(\mathcal{E})‑bench Verified;
- 全部训练、rollout、评估基于开源Orchard框架(可复用沙箱生命周期)。
Test‑agent设置
- SFT:DeepSeek‑V4‑Flash‑0731产出5000条CoT轨迹;
- GRPO:200步,DAPO动态采样;每组保留16issue,每组采样8 rollout,得到128样本;
- 每个issue最多5次提交尝试;无法Base干净失败直接走Round‑0补丁评估。
Repair‑agent设置
训练只选取Base模型Round‑0准确率低于0.4的SW(\mathcal{E})‑ReBench样本(有较大迭代提升空间)。100步GRPO,同样动态采样配置。episode只有Test通过Base‑gate才会进入反馈修复,否则直接评估Round‑0补丁。每episode最多5轮反馈迭代,单轮最多40 turns。
评估条件
测试生成侧对比:Base‑35B、SFT、RL‑35B、Codex‑5.3、DeepSeek‑V4‑Flash、GPT‑5.6‑sol。
修复侧5种反馈来源:无测试、Base‑35B生成测试、RL‑35B生成测试、GPT‑5.6‑sol生成测试、Oracle先知F2P测试。
每个issue每个测试源只运行一次测试生成;修复重复运行3次,复用同一份测试包。只要测试Base‑gate不通过,保留Round‑0补丁送入官方打分。
5.2 主要实验结果
5.2.1 开箱即用编码智能体
核心现象:生成测试反馈不一定带来收益,收益取决于测试质量;劣质测试反而降低修复性能。
| Repair模型固定 | 反馈来源 | 解决率 | 相对变化 |
|---|---|---|---|
| Qwen Base Repair | 无测试(Round‑0) | 61.2% | --- |
| Qwen Base Repair | Base‑35B测试 | 57.3% | −3.9pp |
| Qwen Base Repair | GPT‑5.6‑sol测试 | 65.3% | +4.1pp |
| Qwen Base Repair | Oracle F2P | 69.4% | +8.2pp |
使用Base版Qwen自己产出的测试,修复效果反而下降,说明低质量测试会误导迭代方向。
5.2.2 Test‑Agent训练结果(Base‑to‑Gold成功率)
| Model | Base→Gold成功率 |
|---|---|
| Qwen3.5‑35B‑A3B(原始Base) | 22.2% |
| + SFT监督微调 | 39.6% |
| + SFT + RL强化学习 | 62.2% |
| Codex‑5.3 | 61.0% |
| DeepSeek‑V4‑Flash | 73.4% |
| GPT‑5.6‑sol | 87.8% |
- SFT带来+17.4pp;在此基础上RL再提升+22.6pp;训练后RL‑35B达到与Codex‑5.3相当水平。
- 消融:SFT数据集增大超过5K样本,收益出现收益递减;SFT提供基础仓库操作范式,On‑policy RL专门修正学生模型自身分布内的错误,带来额外收益。
- 不带SFT直接跑RL,奖励震荡、很难收敛;SFT是RL有效初始化的必要条件。
5.2.3 Repair‑Agent训练结果
| 测试源 | Base Repair | Trained Repair | ||
|---|---|---|---|---|
| 解决率 | Δ(pp) | 解决率 | Δ(pp) | |
| None (Round‑0) | 61.2 | --- | 68.3 | --- |
| GPT‑5.6‑sol | 65.3 | +4.1 | 73.5 | +5.2 |
| Oracle F2P | 69.4 | +8.2 | 77.6 | +9.3 |
| Base‑35B | 57.3 | −3.9 | 64.6 | −3.7 |
| RL‑35B | 64.1 | +2.9 | 72.6 | +4.3 |
- Repair训练后无测试Round‑0基线由61.2%提升至68.3%,初始补丁质量得到增强;
- RL‑35B测试 + Trained Repair组合达到72.6%,相比原始Base无测试基线提升11.4pp;
- 组件收益互补:升级Test、升级Repair,二者单独换都可以带来提升;
- 反馈迭代带来的4.3pp提升,平均仅增加13轮agent turns,计算开销可控。
5.3 补充分析与消融实验
消融:Direct‑solve奖励对初始补丁与迭代修复的平衡
| 训练目标 | Round‑0 | 最终解决率 |
|---|---|---|
| 标准Repair训练(无T2I) | 68.7 | 70.3 |
| T2I,去掉直接求解bonus | 66.4 | 71.4 |
| 完整T2I目标 | 68.3 | 72.6 |
direct‑solve bonus可以保留Round‑0的修复能力,同时仍然学习反馈迭代能力。去掉该奖励,迭代提升幅度更大,但初始补丁性能会明显下降。
SFT教师轨迹对比
| SFT教师 | 是否保留CoT推理 | SFT后 | +RL后 |
|---|---|---|---|
| GPT‑5.6‑sol | 不保留推理 | 35.4% | 36.2% |
| DeepSeek‑V4‑Flash | 保留CoT推理 | 39.6% | 62.2% |
带有可见推理过程的演示样本,对后续RL优化的初始化效果远好于单纯高质量输出。更强的独立教师模型,不一定产出更好的RL初始化数据。
跨语言泛化(仅Python训练)
| Python | Rust | C++ | C | Java | |
|---|---|---|---|---|---|
| Base‑to‑Gold成功率 | 62.2 | 66.7 | 58.3 | 26.1 | 2.4 |
Rust、C++具备不错泛化;C、Java效果很差。
训练时反馈源消融
| 训练反馈来源 | Round‑0 | 最终解决率 |
|---|---|---|
| 生成测试 | 67.6 | 70.9 |
| Oracle先知测试 | 68.3 | 72.6 |
Oracle先知测试训练得到更好性能;生成测试会引入噪声,会影响信用分配。
6 相关工作
执行反馈引导编码智能体
传统自动测试生成(Randoop、(\mathcal{E})voSuite)从执行生成输入;自动程序修复领域出现预言机问题:补丁可以通过现有测试,但语义依旧错误(测试集过拟合)。衍生工作:生成额外测试拒绝过拟合补丁、比较补丁行为、从开发者修复生成测试、检查补丁是否不破坏修复区域外行为。
仓库级智能体SW(\mathcal{E})‑agent、OpenHands将探索、编辑、执行、迭代集成;LIBRO从issue生成复现测试;TDD‑Bench Verified专门评估issue条件下的测试生成质量。
部分系统允许修复过程中同步更新/修改测试用例;(\mathcal{E})xecCritic采用相反的设计:测试一旦进入修复阶段就完全冻结。固定测试提供稳定修订目标,但测试本身的缺陷不会被修复过程修正。动态更新测试可以修正弱证据,但会在episode过程中改变验收标准。
已有审计表明,LLM生成测试经常只有观测输出、缺少强断言;固定测试 + 外部官方评估,是(\mathcal{E})xecCritic的核心设计。
面向测试与修复的编码智能体后训练
CodeLutra、SW(\mathcal{E})‑Fixer、SW(\mathcal{E})‑Dev、SW(\mathcal{E})‑Gym、SW(\mathcal{E})‑RL等工作使用成功轨迹、软件演化数据、可执行环境、奖励信号改进编码Agent。
RL(\mathcal{E})F、CUR(\mathcal{E})、UTRL、Code‑A1、Repair‑R1、ReVeal、TaPR分别训练测试生成、修复迭代能力。
(\mathcal{E})xecCritic区别:将问题解耦。Test角色训练目标是Base‑to‑Gold行为改变、判别候选补丁;Repair角色训练目标是直接解决任务 + 在固定、不可见测试反馈下迭代源码。评估时两个训练后角色组合;Repair全程不能修改测试制品。
7 局限性
当前实现Test与Repair是两套完全独立权重,仅能在训练结束之后做组合。理想状态一套权重,依靠角色提示区分"生成测试"与"修复源码"。
但是两类角色动作空间、轨迹结构、训练信号差异巨大;联合训练需要平衡异构信号、跨轨迹信用分配,还要避免两个角色互相共谋适应,而不是对齐任务规范。
联合端到端优化是未来重要方向。
8 结论
本文提出(\mathcal{E})xecCritic框架,将测试生成与源代码修复解耦:Test智能体产出行为检查;沙箱冻结测试包并执行;Repair智能体仅修改源码,依据有界反馈迭代;官方评估器掌握最终正确性判定。
SW(\mathcal{E})‑bench Verified实验表明:
- 测试质量决定反馈增益,劣质测试会损害修复效果;
- Test、Repair分别角色专项后训练,都带来可观收益;
- 训练后二者组合达到72.6%,对比原始无测试基线提升11.4个百分点,不需要评估时使用更强模型或Oracle先知。
未来方向:支持多检查用例沙箱、提升Test智能体能力、降低推理时延与成本。
资源清单
- HTML原文:https://arxiv.org/html/2609.09133v1
- PDF论文:https://arxiv.org/pdf/2609.09133
- 开源代码仓库:https://github.com/MSR‑Orchard/execcritic
- 训练数据集:SW(\mathcal{E})‑ReBench;评估数据集SW(\mathcal{E})‑bench Verified、SW(\mathcal{E})‑bench Multilingual
- 运行框架:Orchard,用于可扩展智能体建模与可复用沙箱生命周期管理。
附录(摘要版,完整数学、伪代码、超参、prompt、协议详见原论文)
附录A 实验补充
- A.1 Test‑agent训练:SFT使用教师轨迹,GRPO基于离线执行;超参:学习率 1 × 10 − 6 1\times10^{-6} 1×10−6,Adam优化,动态采样DAPO;最大上下文48k tokens。
- A.2 Repair‑agent训练:Oracle F2P测试做训练反馈;最大5轮迭代,每轮40 turns;无效执行轨迹置0优势,不参与梯度更新。
- A.3评估配置:指标定义、统计、revision轮次观测:120条进入修复的轨迹平均新增13 turns;可复现边界:检查点公开,但原始数据集、沙箱凭证不对外发布。
- A.4 测试提交制品定义:
test.patch(测试diff补丁)、test_command(精确运行命令)、test_contract.json行为契约。 - A.5 定性案例分析:Django #16901递归XOR编译、Sphinx #9230参数解析两个完整轨迹案例。
附录B Harness沙箱完整语义规范
B.1 Fail‑Closed故障闭合语义
- 每一个候选补丁,都是相对于Base仓库完整源代码diff;
- 行为失败 vs 操作无效执行要严格区分:环境崩溃、安装失败属于操作无效,不能作为bug行为证据;
- 两种终止条件:本地测试PASS直接终止;或者预算耗尽强制提交最新补丁。
B.2 沙箱演进:证据门控更新
沙箱自身版本迭代需要完整匹配证据,运行时episode不会自动更新沙箱逻辑。每次版本变更必须预先声明ID、指标、预算;全部声明门控通过,才允许升级沙箱;运行时沙箱保持不变。
B.3 Prompt与控制器完整协议
- B.3.1 Test‑Agent完整System/User提示词、提交协议;
- B.3.2 Repair‑Agent提示词、控制器协议:补丁导出规则、会话种子机制、运行时反馈边界、门控输出决定控制器消息、源码‑补丁恢复边界。>
完整prompt、JSON字段、控制器消息模板见原论文附录B.3。