论文链接:ExecCritic: Learn to Test, Test to Improve for Coding Agents 代码仓库:github.com/MSR-Orchard/execcritic 发表时间:2026年9月 机构:University of Wisconsin–Madison(Leitian Tao、Sharon Li 等)、Microsoft Research(Baolin Peng、Jianfeng Gao 等)、Georgia Tech —— 典型"高校+企业"合作:第一作者为 UW-Madison 博士生(微软研究实习期间完成),MSR 提供研究与算力支持,UW-Madison 主导方法设计 领域标签:cs.AI / Coding Agents / SWE-bench / Reinforcement Learning

一、论文背景

仓库级代码修复是当前编码 Agent 的核心战场:给 Agent 一个 issue 描述和一个有 bug 的代码库,让它产出能通过官方评测的补丁。SWE-agent、OpenHands、Mini-SWE-Agent 等系统的标准打法是迭代式交互——探索代码、编辑、跑测试、根据反馈再修。

这个循环的前提假设是:执行的测试反馈反映了 issue 要求的行为。但真实场景中,官方评测器是隐藏的,Agent 必须自己构造检查手段。自产测试可能出三种问题:只测运行时行为而不断言 issue 要求的行为;漏掉决定性的边界情况;或者——最隐蔽的——与补丁共享同一个错误理解。

最后一种情况值得展开:假设 bug 只在函数收到空列表时出现。Agent 没意识到这个条件,修好了常见的非空情况,然后写了一个只覆盖非空情况的测试。测试运行、补丁通过、Agent 宣告任务完成——而原始 bug 安然无恙。补丁和测试在同一个盲区上达成了一致。更糟的是,让同一个轨迹"再多写几个测试"无济于事:同一个盲区塑造了补丁,也同样塑造了用来验证补丁的证据。

这就是论文说的修复与验证的耦合:当一条轨迹既写补丁、又写验证证据、还决定何时提交时,“通过自测"与"真的修好"之间没有必然联系。反馈循环不仅可能无效,还可能主动有害(错误的负反馈把正确的修复改坏)。

二、论文定位和关联工作

脉络一:执行反馈用于调试与修复。已有系统把执行反馈用于调试(Reflexion 系)、候选选择、bug 复现、修复验证(Agentless、SWE-agent 的测试环节)。这些工作默认"有测试比没测试好”,本文用数据证明这个默认假设可以反过来:测试质量差时,有测试比没测试更糟(57.3% < 61.2%)。

脉络二:测试生成的可靠性研究。Chen et al. 2026 等工作记录了 Agent 生成测试偏重运行时行为、遗漏边界的问题。本文进一步把"测试质量"从"评测脚注"提升为"决定反馈价值的自变量",并证明它是可训练的。

脉络三:角色分工与 RL 后训练。将复杂任务拆角色分别训练是 Agent 工程的通用思路。本文的贡献是给出了角色边界应该切在哪里的原则性答案:切在"定义行为目标"与"满足行为目标"之间,而不是切在"写代码"与"审代码"之间。

维度常规 Agent 循环ExecCritic
补丁与测试的生成同一策略同一轨迹独立 Agent 独立轨迹
测试是否可变随时可以改(容易被"改到通过")资格审查后冻结,Repair 无写权限
反馈的信任度盲信自产测试测试质量本身被 RL 优化
停止决策自行判断局部通过→显式提交,fail-closed

定位结论:本文把软件工程"测试与实现分离"的经典纪律第一次完整翻译成 Agent 训练问题,并证明两个角色都需要专门的 RL 训练。

三、问题定义

具体问题:仓库级修复中,Agent 自产的执行反馈何时有效、如何让它可靠。

核心洞察(抽象):补丁 p 与验证证据 ℰ 由同一策略同一轨迹生成时,(p, ℰ) ~ π_ω(·|x)——两者相关。共同的误解可以让 p 通过 ℰ,让"自我验证"沦为"自我确认"。解耦的本质是把联合分布拆开:测试 b = (Δ_b, c_b, κ_b)(测试补丁、执行命令、行为契约)由独立轨迹生成并被冻结,Repair 只产出源码补丁,官方评测器 V*_x(p) 保留最终裁决权。

形式化:给定 issue d 与有 bug 仓库 R_B:

  • Test agent 产出测试包 b,harness 校验其在 R_B 上干净失败(fail-closed 资格)后冻结;
  • Repair agent 迭代产出源码补丁 p₁, p₂, …,每步获得冻结测试的执行反馈 ℰ(b, p_i);
  • 约束:Repair 的写权限不含测试文件;b 在整个修复过程中不变。

抽象的精妙之处:它把"反馈可靠性"从玄学变成了两个可操作的子问题——(1) 如何生成判别性测试(能区分 Base 与 Gold 行为);(2) 如何在不削弱判据的前提下利用测试反馈。两个子问题分别对应两个可训练的角色。

四、问题解法

4.1 test–verify–revise 脚手架

Test agent:探索仓库,产出三件套——仓库原生测试补丁 Δ_b(用项目自己的测试框架)、精确执行命令 c_b、JSON 行为契约 κ_b。关键设计:一个测试包针对一个连贯的 issue 行为,可含多个测试节点,但语义上收敛。

Fail-closed harness:对测试包做资格审查——测试必须可执行、且必须在有 bug 的 Base 上干净失败。通过的测试被冻结;任何执行异常视为失败而非跳过(fail-closed 语义:不确定就按失败处理,绝不给模糊的通行证)。

Repair agent:接收 issue、仓库状态和冻结测试的执行反馈,只修改非测试源码。局部通过后显式提交;每轮反馈有界、结构化。

4.2 角色专用 RL(Learn to Test / Test to Improve)

两个角色都用 Qwen-3.5-35B-A3B 骨干,分开训练:

  • Learn to Test:奖励可执行且具判别性的测试——能在 Base(有 bug)上失败、在 Gold(修复后)上通过的测试得分。训练信号来自离线的 Base/Gold 行为对比与候选判别性评估。这教会 Test agent"什么叫针对 issue 的行为断言"。
  • Test to Improve:Repair agent 同时学两种能力——直接解题(Round-0 无测试解析)与反馈引导的修订(根据失败测试定位并修正)。冻结测试保证了训练时它也无法通过弱化测试来作弊。

五、评估指标与实验证据

核心数据集:SWE-bench Verified(500 个人工验证过的真实 GitHub issue)。论文自己的实验设计就先证明了"测试质量是自变量":

动机实验(换测试不换 Repair agent):

测试来源解决率
无测试基线61.2%
Qwen-3.5 自产测试57.3%(-3.9,有害)
GPT-5.6 生成测试65.3%(+4.1,有益)

同一个 Repair agent,测试来源不同,结果差 8 个百分点、方向相反。这一张表就是全文的合法性证明:反馈的价值由测试质量决定,而测试质量天差地别。

主结果(角色 RL 后):

配置指标数值
Test agent RLBase-to-Gold 判别成功率22.2% → 62.2%
Repair agent RLRound-0 无测试解决率61.2% → 68.3%
两角色组合(无更强模型/Oracle 反馈)SWE-bench Verified72.6%(+11.4 vs 原基线)

72.6% 距离用 GPT-5.6 生成测试的 65.3% 又高出 7.3 点——训练过的 35B 测试 Agent 比 GPT-5.6 的零样本测试更可靠,这是"Learn to Test"假设最直接的验证。

指标含义辨析:Base-to-Gold 判别率衡量的是"测试能否区分有 bug 与修复后行为"——它是反馈可靠性的代理指标;解决率是最终能力。论文诚实标注:组合成绩包含额外的测试生成与修订算力,不是算力匹配的对比——这是结果解释的边界,也是未来 compute-matched 研究的空间。

六、效果优势的根源解释

常规循环的根本缺陷:不是"缺反馈",而是反馈生成与被评对象共享同一认知盲区。形式化地看,(p, ℰ) 的相关性意味着 ℰ 不能作为 p 质量的独立证据——这在测量理论里就是"考生自己出评分标准"。误判的代价是双向的:假阳性让错误补丁被提交,假阴性把正确补丁改坏(57.3% < 61.2% 的机制就在这里)。

ExecCritic 的机制改变与因果链:

  1. 生成解耦 → 误差独立化 → 假确认概率下降。Test 与 Repair 走独立轨迹、持有不同写权限,同一盲区同时塑造补丁与测试的概率大幅降低。这直接作用于"错误补丁通过错误测试"的联合概率:P(通过|错误) 从"高相关"降到"近似独立"。
  2. 冻结测试 → 判据不可协商 → 反馈信号稳定。Repair 改不了测试,就没有"把测试改到通过"这条作弊路径;冻结还保证跨轮反馈可比——第 3 轮的失败与第 5 轮的失败语义一致,修订策略才有稳定的优化目标。
  3. 判别性 RL → 反馈从"有"变"可靠" → 反馈引导修订生效。Test RL 把判别率从 22.2% 提到 62.2%,意味着执行反馈的信息含量(能区分对错的程度)提升了近三倍;Repair RL 学到的"读懂失败测试并定位"能力,在此信息基础上才能兑现。两个 RL 缺一不可——只训 Repair 不训 Test,反馈仍是噪声(GPT-5.6 测试+训练前 Repair 只有 65.3%,且这个数依赖外部更强模型)。

反事实证据:去掉角色训练(off-the-shelf Qwen 双角色),测试甚至有害(57.3%);去掉冻结(常规 Agent 循环),回到 61.2% 基线。两个反事实分别锁定"Learn to Test"与"解耦冻结"的必要性。

七、必要知识反推

领域知识层:

  • 软件测试理论:回归测试的判别性概念、fail-closed vs fail-open 语义、测试框架的仓库原生性(pytest/tox 与项目配置的耦合);
  • SWE-bench 评测协议:FAIL-to-PASS / PASS-to-PASS 双集、官方评测器权威性;
  • Agent harness 设计:工具权限、沙箱、轨迹记录。

方法论知识层:

  • RLVR 的可验证奖励设计与过程奖励的折中(Test agent 的奖励来自离线 Base/Gold 对比而非在线交互);
  • 角色分解原则:按"定义目标 vs 满足目标"切分,而非按表面职能;
  • 因果推断直觉:反馈有效性要求证据生成与被评对象独立。

工程知识层:

  • 测试资格校验的规则引擎(可执行性、干净失败判定);
  • 有界结构化反馈的格式设计与 token 预算控制;
  • 35B-A3B 级模型的 RL 训练配方(rollout 管理、奖励归一化)。

知识融合的关键节点:融合发生在"测量理论 的独立性原则“与”Agent 工程的权限系统“之间。“反馈必须独立于被评对象"是实验科学的常识,但在 Agent 领域,大家默认了同一轨迹自我验证的便利性。作者把独立性原则翻译成了工程约束(独立轨迹+写权限分离+冻结),再进一步意识到这两个角色各自的能力缺口都可被 RL 填补——科学方法论、系统工程、RL 训练三个知识域在一个脚手架里闭环。

八、论文中可以提取的通用性灵感

1. 自产证据的独立性必须被工程强制,而不能被提示词约定。 核心思想:评价者与被评对象的利益分离要靠架构(独立轨迹+权限隔离+冻结),不是靠"请你客观一点”。 论文证据:同轨迹测试有害(57.3%),解耦+冻结后反哺(72.6%)。 推广场景:LLM-as-judge 与生成模型的车道分离;自评估报告的交叉审计制度;模型自博弈训练的裁判模型冻结。

2. 反馈的价值是变量,不是常量。 核心思想:任何"根据反馈改进"的循环,第一步应该度量反馈本身的可靠性。 论文证据:61.2%→57.3%(坏测试)vs→65.3%(好测试),同循环相差 8 点。 推广场景:用户调研先行验证问卷信度;A/B 测试的埋点质量审计;绩效反馈 360 度的评估者校准。

3. 把"定义目标"与"满足目标"设为角色边界。 核心思想:多角色系统的分工切面应该切在目标定义与目标实现之间,让两者互为制衡。 论文证据:Test agent 定义行为契约、Repair agent 只对实现负责。 推广场景:产品经理与工程师的职责界面;合同起草与合规审查分离;立法与执法的机构分立逻辑。

4. Fail-closed 是模糊环境下的安全默认。 核心思想:证据不足时按失败处理,绝不把不确定性兑换成通行证。 论文证据:harness 要求测试在 Base 上干净失败才获资格;执行异常一律视为失败。 推广场景:安全系统的默认拒绝策略;医疗检查的"无法排除即视为阳性复检”;金融风控的可疑交易拦截。

5. “教人测试"与"教人修复"是两种独立能力。 核心思想:构造判别性标准的能力,与在标准下解决问题的能力,训练信号不同、应分别优化。 论文证据:Test RL 判别率 22.2%→62.2%;Repair RL 无测试解析 61.2%→68.3%;两者正交且可组合。 推广场景:教育评估中"出题能力"与"解题能力"分开培养;组织里的 QA 职能与研发职能的专业化;基准构建者的独立训练体系。


本文基于 arXiv:2609.09133 全文精读撰写。数据与结论均引自原文。