论文精读

精读:把中间那一步的信号从模型里搬进环境——用沙箱回滚跑出免费过程奖励

CRR 在选中决策点回滚沙箱、换个动作重跑到底,用两次终端回报之差替换该步 advantage;它不需要 PRM,代价是 133 H100 小时的重放算力,而作者自己的成本倍率扫描显示优势在 m≈3.6 处变号。

论文: Counterfactual Rollout Replay: Forkable Environments as Free Process Rewards for Software Engineering Agents
作者: Yuanhao Li, Hongbo Wang, Xuhong Chen, Yiming Cao, Xunzhu Tang
arXiv: 2609.33875
强化学习 软件工程 Agent 过程奖励 信用分配 GRPO 算力核算 可复现实验 SWE-bench

1 论文概览

一句话总结:CRR(Counterfactual Rollout Replay)把「过程奖励」这件事从「学一个模型来猜每一步好不好」换成「把沙箱状态回滚几个版本、换一个动作重跑一遍、用两次 terminal 验证器结果之差当作这一步的 advantage」——它不需要人类过程标注,也不需要训练 PRM,代价是每个 fork 都要真金白银地重跑一遍,占掉了整轮训练 41.4% 的设备时间。

核心问题:SWE agent 的 RLVR 只拿得到一个 0/1 的终局信号。一条 32 步左右的轨迹里,「第 3 步打开对了那个测试文件」和「第 12 步顺手改坏了序列化接口」在损失里拿到的是同一个数。作者要问的是:

Outcome-only reinforcement learning gives software engineering (SWE) agents a terminal success signal but little direct guidance about intermediate decisions. —— CRR, Abstract

本专栏前二十四期里,这个问题被从三个方向回答过:PACT 给 token 级信用一个唯一解,BPO 主张中间状态的价值根本不必估,PoEM 干脆一次 RL 都不跑、只用已有策略外推。CRR 走的是第四条路——不去估计中间价值,而是把中间价值「执行」出来。它把 forkable 环境当成模型本身:

CRR can be viewed as a Dyna-style use of the real environment as the model rather than a learned simulator. —— CRR, Section M

主要贡献

  1. 用可执行反事实替换 advantage,而不是替换轨迹。选中决策点后回滚状态、采样另一个动作、按当前策略续跑到底,advantage 取 A^tCRR=R(τ)−R(τ~t)\hat A_t^{\text{CRR}}=R(\tau)-R(\tilde\tau_t);训练用的仍是原封不动的那条 on-policy 轨迹。
  2. 把「信用分配」与「挑一条更好的分支」分开实测。Search-Select 对照用同样的 selector、同样的 k=4k=4 次 fork、同样的验证器,但把 fork 用来替换训练序列;CRR 把它用来改 advantage。三对种子上 CRR 全胜,均值差 1.8 个百分点(Table 17)。
  3. 完整的资源对账。321 H100-hours(CRR)对 188(vanilla GRPO)对 233(SWE-Trace PRM),并单独给出一张等墙钟对照表(Table 15):40.125 小时里 CRR 41.7%、把 GRPO 延长到同样时长是 36.7%。
  4. 诚实地划定了适用边界。作者自己做了 fork 成本倍率 mm 扫描,报告优势在 m=2m=2 与 m=4m=4 之间变号(Table 16),并明写「free」指的是标注成本:

The method needs no human process labels or learned process reward model; free refers to those supervision costs, not replay compute. —— CRR, Abstract

  1. 一个 140 万条的反事实元组数据集将随 camera-ready 发布,每条含任务 id、快照标识、原动作与反事实动作、两条终端回报、提议对数概率与 selector 分数(Section N)。

2 方法详解

架构与方法概述

轨迹写成有限 horizon MDP,H=50H=50,终端奖励 R(τ)∈{0,1}R(\tau)\in\{0,1\} 由 held-out 测试产出。CRR 的完整改动只有一处——把 GRPO 的 advantage 在选中步上换掉:

A^t⋆={R(τ)−R(τ~t)t∈I(τ)R(τ)−Rˉ(G)otherwise\hat{A}^{\star}_{t}=\begin{cases}R(\tau)-R(\tilde{\tau}_{t}) & t\in\mathcal{I}(\tau)\\ R(\tau)-\bar{R}^{(G)} & \text{otherwise}\end{cases}

再塞进原样的 PPO/GRPO 裁剪代理目标。I(τ)\mathcal{I}(\tau) 由 selector 挑出,默认最多 k=4k=4 个非终止决策点。反事实动作从「排除已实现动作」的 tempered 策略里采:

q¬at(a∣st)∝πθ(a∣st)1/Tcf1[a≠at],Tcf=0.7q_{\neg a_{t}}(a\mid s_{t})\propto\pi_{\theta}(a\mid s_{t})^{1/T_{\text{cf}}}\mathbf{1}[a\neq a_{t}],\qquad T_{\text{cf}}=0.7

续跑用的是当前策略独立采样的动作,前缀与原轨迹共享。

决策点选择器用「语义 token 的文法掩码熵 × 工具类型权重」打分:

score(t)=Ht(1+λtype type(at))\mathrm{score}(t)=H_{t}\bigl(1+\lambda_{\text{type}}\,\mathrm{type}(a_{t})\bigr)

类型分是被动读/搜索 0、聚焦测试 0.25、shell 0.75、文件编辑 1.0,λtype=0.6\lambda_{\text{type}}=0.6,η=0.4\eta=0.4 是熵门槛,终止动作排除。Top-kk 之外的步拿原来的 outcome advantage。

关键创新点

fork 不替换行为,只改打分。这是 CRR 与 inference-time tree search、best-of-N、expert iteration 的分界线,也是它自己设计 Search-Select 对照要证明的东西:

Unlike selecting a verifier-best branch for training, the fork changes how the realised action is scored. —— CRR, Section 1

把环境当模型,而不是学一个模型。PRM 路线要先有 rubric、先有人标注、再训一个奖励模型,且这个奖励模型可以被 hack。CRR 的每一步信号都是一次真实执行,附带可审计的回放轨迹。代价写在 Section M:它「inherits access to the true transition function but pays the full per-fork cost」。

不需要确定性之外的任何假设,也不需要学到转移模型。但它确实需要确定性——这是全部 Proposition 的前提,作者为此专门做了三层过滤(Section F):三次重跑一致性过滤(丢弃 SWE-Gym 候选池 6.8%、SWE-rebench 9.4%)、确定性包镜像、HTTP 回放层。

与基线方法的区别

把四条路线的「每一步拿到什么数」摊开对位:

方法每步 advantage中间信号从哪来额外设备时间
GRPOR(τ)−Rˉ(G)R(\tau)-\bar R^{(G)},全步共享无0
SWE-Trace (PRM)学出来的逐步分训练好的奖励模型45 H100-h
Search-SelectR(τ)−Rˉ(G)R(\tau)-\bar R^{(G)},但训练序列被换成高分分支同一次 fork 的验证器结果133 H100-h
CRR选中步 R(τ)−R(τ~t)R(\tau)-R(\tilde\tau_t),其余步不变同一环境的另一次执行133 H100-h

CRR 与 Search-Select 在资源上完全同构,差别只在 fork 出来的数据往哪儿用。这是个很干净的设计:机制对照不引入任何新的算力变量。

3 实验结果

主要指标

Qwen3-14B + rank-128 LoRA,三个种子 {11,23,47}\{11,23,47\},3,638 个通过确定性过滤的训练任务,24,000 条 on-policy 轨迹、4,000 次更新。

设置VerifiedLiverebench设备时间
SWE-agent (zero-shot)22.618.916.4—
SkyRL-Agent (GRPO)36.431.127.9188 H100-h
SWE-Trace (rubric PRM)39.133.730.2233
CRR41.735.932.6321
CRR + SWE-Trace44.938.835.4—

等墙钟对照(Table 15)是这篇论文最硬的一张表:同样一块 8×8\times H100、同样 40.125 小时,CRR 41.7% 对延长版 GRPO 36.7%,差 5.0 个点。GRPO 在这段时间里跑完了 37,824 条轨迹、6,304 次更新,CRR 只有 24,000 条、4,000 次——GRPO 多拿 57.6% 的轨迹和 57.6% 的更新,仍然落后 5.0 个点。按 token 算更有意思:GRPO 生成 114.76M,CRR 全部生成 119.0M(76.80M on-policy + 反事实后缀),总量几乎持平;但有效(loss-masked on-policy)token 是 94.10M 对 63.0M——CRR 用少 33.1% 的有效训练 token 换来 +5.0 个点。

显著性:这一期难得过关

本专栏此前多期在 SWE-bench Verified(500 题)上判过「未定」。这次不一样:CRR 41.7±0.641.7\pm0.6 对 GRPO 36.4±0.836.4\pm0.8,差 5.3 点,标准误 0.62/3+0.82/3=0.58\sqrt{0.6^2/3+0.8^2/3}=0.58,Welch t≈9.2t\approx9.2;单跑一次的二项标准误 2.15 点,5.3 点约为其 2.5 倍。等墙钟的 5.0 点同样过关。这个 headline 是本站少见地经得起 500 题噪声地板检验的一次。

要留意的是范围:Live(+4.8)与 rebench(+4.7)只有 endpoint 数字,没有等算力对照,作者自己也写了「We do not infer equal-compute gains on all three benchmarks from the endpoint table」。Table 4 里那个最好看的 45.6%(CRR+TSR+PRM)没有种子标准差,checklist 第 7 条明确承认了这一点。

消融实验的三个关键发现

  1. 一次 fork 就买下 39% 的收益。kk 从 0 到 1 涨 2.2 点,k=4k=4 拿到 5.6 点里的 5.3 点,k=16k=16 只多给 0.3 点。信用不需要铺满整条轨迹,32 步里改 4 步(12.5%)就够了。
  2. 把 fork 摊到更多决策点,胜过堆到同一点上。Table 19:K=1,k=4K=1,k=4 得 36.2;K=4,k=1K=4,k=1(同样的 fork 数)只有 35.0。SNR 却反过来——K=4,k=1K=4,k=1 的 advantage SNR 是 2.6×2.6\times,K=1,k=4K=1,k=4 只有 2.0×2.0\times。四组配置按 SNR 排序与按 pass@1 排序的走向是反的:SNR 最高的那组(2.6×,35.0 分)是分数最低的那组。
  3. 适用区间被作者自己量了出来。Table 16 给每臂固定 48 H100-hours,把快照/恢复/回放成本乘上 mm:
mm124
CRR36.234.833.2
GRPO33.433.433.4
差+2.8+1.4−0.2

按 500 题二项标准误 3.0 点算,这三个差值的 zz 分别是 0.93、0.47、−0.07,一个都不显著;按 log⁡2m\log_2 m 线性插值,变号点约在 m≈3.6m\approx3.6。Eq (6) 进一步给出原生成本结构:每条轨迹的非 fork 成本 0.004868 H100-h,fork 部分 0.003132 H100-h,即 fork 占 64.4%;m=4m=4 时 fork 涨到 2.57 倍非 fork 成本。

4 个人分析

亮点

「免费」这两个字被作者当场拆解了,而不是留给读者去发现。摘要里就写着 free 指的是标注成本而非重放算力,Section O 把 133 H100-hours 的 fork 池单列出来,Section P.3 还主动做了让你亏钱的扫描。这种写法在近期的 agent RL 论文里不多见。

机制对照做得干净。Search-Select 用了同样的 selector、同样的 fork 次数、同样的验证器、同样的裁剪学习器、同样的设备预算,只改 fork 数据的用途,三对种子 CRR 全胜。多数论文会停在「我比 baseline 高」,这篇回答了「高出来的这部分是信用分配还是搜索」。

超参没有为 CRR 单独调。checklist 第 6 条写明 k,K,Tcf,η,λtypek,K,T_{\text{cf}},\eta,\lambda_{\text{type}} 都没有相对于 GRPO 基线单独调优,用的是 SWE-Gym 一个 200 实例留出子集上的单次扫描。

错误模式被拆到了绝对率(Table 11),而不是只给条件占比。这一步让下面的对减做得到。

五处可以再追问的地方

(1)把 +5.3 拆开,最大的单项是一个新出现的、谁都没见过的桶。

按 Table 11 的绝对率对减:

错误模式GRPOCRR差
Wrong localisation21.7523.03+1.28
Partial fix25.2514.11−11.14
Regression12.346.59−5.75
Harness subversion4.263.85−0.41
Other0.0010.73+10.73
合计63.6058.31−5.29

收益由 partial fix(−11.14)与 regression(−5.75)扛,代价是 wrong localisation(+1.28)和一个从 0 长到 10.73 的「Other」——按 500 题折算约 54 个实例。条件占比上,Other 在 vanilla GRPO 与 SWE-Trace 上都是 0.0%,在 CRR 上是 18.4%,在分数最高的 CRR+SWE-Trace 上是 21.4%。分数越高的配置,不可归类失败的比例越大。论文报告了这个桶,没有拆它。

Relative to vanilla GRPO, CRR has lower conditional shares and lower approximate absolute rates of partial fix and regression failures, alongside a larger residual “Other” category. —— CRR, Section M

(2)反事实对比的均值不是 0,是 +0.181。

Table 21 把 20,000 次 fork 分成三类,给了各自的类均值对比 Δ=R(τ)−R(τ~t)\Delta=R(\tau)-R(\tilde\tau_t):immediately invalid 占 12%、均值 +0.15+0.15;valid 且分支失败占 46%、均值 +0.40+0.40;valid 且分支成功占 42%、均值 −0.05-0.05。加权:

0.12×0.15+0.46×0.40+0.42×(−0.05)=+0.1810.12\times0.15+0.46\times0.40+0.42\times(-0.05)=+0.181

一个真正的 advantage 函数在行为策略下的期望是 0。CRR 在选中步上发的这个数,期望是 +0.18+0.18。结构上很好懂:分支失败时 Δ=R(τ)\Delta=R(\tau),分支成功时 Δ=R(τ)−1≈0\Delta=R(\tau)-1\approx0(该类 95% 的样本原轨迹也成功),所以

A^tCRR≈R(τ)⋅1[τ~t 失败]\hat A^{\text{CRR}}_t\approx R(\tau)\cdot\mathbf 1[\tilde\tau_t\text{ 失败}]

它是「终局奖励,外加一道『对手更差』的闸门,只发在四个选中步上」,不是对信用在时间上的重新分配。Table 21 的 plug-in 份额也印证了这一点:valid-fail 一类独占 83%,immediately invalid 8%,valid-succeed 9%。

这带来一个可检验的后果:一个恒正的 advantage 进 PPO 裁剪目标,梯度会把似然比 rtr_t 一路推到 1+ϵ=1.21+\epsilon=1.2 才停。selector 又专挑熵最高的那几步。合起来看,CRR 有一部分是「在自己最不确定的决策点上,对自己已经做过的选择再加 20% 置信」——这更接近 confidence sharpening,而不是 credit assignment。要排除它,最直接的实验是把 Δ\Delta 减去其类均值(或只保留 Δ\Delta 的符号与零均值化后的幅度)再训一遍,论文里没有这一臂。

(3)Tcf=1T_{\text{cf}}=1 时,CRR 就是经典 advantage 乘一个膨胀因子。

把 q∝πq\propto\pi(即 Tcf=1T_{\text{cf}}=1)代进 Proposition 1,记 ρ=π(at∣st)\rho=\pi(a_t\mid s_t):

Ea~∼q¬at[Q(st,a~)]=Vπ(st)−ρQ(st,at)1−ρ\mathbb E_{\tilde a\sim q_{\neg a_t}}[Q(s_t,\tilde a)]=\frac{V^{\pi}(s_t)-\rho Q(s_t,a_t)}{1-\rho}

⟹ E[A^tCRR∣ht+]=Qπ(st,at)−Vπ(st)1−ρ=Aπ(st,at)1−ρ\Longrightarrow\ \mathbb E[\hat A^{\text{CRR}}_t\mid h_t^+]=\frac{Q^{\pi}(s_t,a_t)-V^{\pi}(s_t)}{1-\rho}=\frac{A^{\pi}(s_t,a_t)}{1-\rho}

于是 Proposition 1 里那句「只有允许 a~t=at\tilde a_t=a_t 且 q=πq=\pi 的理想化变体才能恢复经典 advantage」说得偏窄:Tcf=1T_{\text{cf}}=1 这个被实际实现的成员也能恢复,只是按 1/(1−ρ)1/(1-\rho) 放大。放大系数是逐状态、逐动作的,ρ→1\rho\to1 时发散。而 Tcf=1T_{\text{cf}}=1 恰恰落在作者报告「broadly insensitive」的 [0.5,1.0][0.5,1.0] 区间端点上——整条区间上性能不动,这本身就是证据:收益不来自「选了哪个反事实」,而来自「有一个逐步对比在那儿」,与第(2)点的结构读数一致。

(4)「免费」的过程奖励,比它取代的那个学出来的 PRM 贵 2.96 倍。

对账很直白:CRR 的 fork 池 133 H100-hours,SWE-Trace 的 PRM 打分 45 H100-hours,比值 2.96。按边际收益算,CRR 是 133/5.3=25.1133/5.3=25.1 H100-hours 每点,SWE-Trace 是 45/2.7=16.745/2.7=16.7 H100-hours 每点,被取代的那一方在算力上更划算 1.5 倍。PRM 那 45 小时之外还有 rubric 设计与标注成本没进账,这点必须承认;但「free」这个词的语义重量,落在了恰好是它自己最贵的那一半上。

再叠加第 3 节的 mm 扫描:这篇论文的 m=1m=1 是建立在 SWE-MiniSandbox 的 container-free 设计上的——

with the container-free sandboxing of SWE-MiniSandbox —— CRR, Appendix B

容器化沙箱(docker / podman 快照与恢复)的快照成本天然高于无容器方案,也就是说常规 SWE RL 栈天然处在 m>1m>1 的位置,而作者自己测出的变号点在 m≈3.6m\approx3.6。Appendix O 也承认跨容器引擎与内核版本不能保证逐位复现。这一条决定了 CRR 能不能搬家,论文给了工具去判断,没有替读者判断。

(5)选超参的那个留出集只有 200 个实例。

p≈0.4p\approx0.4 时 200 实例的比例标准误是 3.46 点,两个配置之差的标准误约 4.9 点。低于 5 点的差异在这个集合上分辨不出来,而 kk、TcfT_{\text{cf}}、η\eta、λtype\lambda_{\text{type}} 都只在这一次扫描上定过。这解释了为什么 Tcf∈[0.5,1.0]T_{\text{cf}}\in[0.5,1.0] 看起来「不敏感」——不是真的不敏感,是这个尺度的实验看不见。

对大模型领域的影响

「过程监督」这个词被拆成了两件独立的商品:信号从哪来(学出来 vs 执行出来),以及信号怎么用(选分支 vs 改打分)。CRR 证明了第二件事才是关键——同样 133 H100-hours 的 fork,用来选分支只值 +1.1 点,用来改 advantage 值 +2.9 点(Table 17 口径)。

可审计性是个被低估的副产品。140 万条反事实元组里,每条都带快照标识与两条终端回报。这是 PRM 路线给不出的东西:奖励模型的分数你无法回访,一次执行的返回值可以。作者自己把它定位成 PRM 的下游监督与验证器评测素材(Section N)。

verifier 依赖没有被解决。harness subversion 在 CRR 失败里占 6.6%,在 GRPO 里 6.7%,绝对率 3.85% 对 4.26%——反事实信用没有让「改测试而非改实现」变少。作者明写 CRR does not resolve these risks,并建议配对抗性测试加固。

5 实践启示

可以借鉴的技术

  • 把 fork 预算摊在不同的决策点上,别堆在同一点。Table 19 的 K=1,k=4K=1,k=4(36.2)对 K=4,k=1K=4,k=1(35.0)是明确的取舍方向,且前者只花四分之一的 fork。
  • selector 的价值可以量化后再做。Table 23 给了三个廉价代理指标:gold-patch 文件首次命中率(random 13% → entropy+type 41%)、选中步落在 top-decile ∣A^∣|\hat A| 的比例(10% → 28%)、选中步平均 ∣A^∣|\hat A|(0.11 → 0.21)。这套探针不依赖下游分数,可以挪到别的环境里先用。
  • fork 前的确定性过滤值得整套照抄:三次重跑一致性、确定性包镜像、HTTP 回放层。作者给了各大仓库的丢弃率(requests 18.8%、flask 12.3%、django 11.7%),可作为自己建库时的预期基线。
  • 先量自己的 mm,再决定要不要上。Eq (6) 的 nm=48/(0.004868+0.003132m)n_m=48/(0.004868+0.003132m) 是可直接套用的形式:测出自己栈上「一次快照+恢复+续跑」的实际成本,算出 mm,再看落在 Table 16 的哪一格。m>3.6m>3.6 就别做。

潜在应用场景

  • 可执行、可回滚、终端可验证的一切 agent 训练:数据库迁移与 schema 变更(回滚到快照再跑一次迁移)、基础设施即代码(terraform plan/apply 可重放)、数据分析 notebook(重跑上游 cell)、编译器与构建系统的多步修复。
  • 奖励模型会被 hack 的场景。CRR 的信号来自真实执行,绕开了 reward hacking 中最常见的「讨好打分器」路径;代价是每步都要真跑。
  • 反事实数据集作为独立产物。140 万条带双回报的元组本身就是研究长程信用分配结构的语料,也可以直接当 PRM 的监督信号——用贵的那一路给便宜的那一路打标,再蒸馏回去,这个组合论文没做。

不该用的场景:状态无法廉价恢复(长事务、有外部副作用、真实付费 API)、终端验证器不完整(测试覆盖率低时,反事实差值测的是测试而非代码)、续跑随机性大(K 平均只压方差、压不掉系统偏移,Table 20 明写了这一点)。

Li, Y., Wang, H., Chen, X., Cao, Y., & Tang, X. (2026). Counterfactual Rollout Replay: Forkable Environments as Free Process Rewards for Software Engineering Agents. arXiv:2609.33875 [cs.SE]. 北京邮电大学网络与交换技术国家重点实验室与卢森堡大学,5 位作者,2026-09-27 提交,NeurIPS 2026 收录。

相关精读