论文解读 · Terminal Agent RL · Reward & Critic

T1:用"通过断言的绝对数"做稠密奖励,用满血 critic 做唯一基线

腾讯混元团队把一个 122B(激活 10B)的 MoE 模型放进真实 shell 沙箱里跑 PPO,单任务最多 300+ 轮工具调用。论文最有信息量的部分不是榜单,而是他们如何把 verifier 的逐条断言结果变成 reward、以及一个与 actor 同尺寸的 critic 是怎么被调稳的——包括那些没做成的尝试。

T1: Terminal Agent Reinforcement Learning for Long-Horizon Tasks
Junyao Yang*, Yucheng Shi*, Zhongzhi Li, Ruhan Wang, Zongxia Li, Haitao Mi, Leowei Liang · Tencent Hy Foundation Model Frontier 等 · arXiv:2609.11042v1(2026-09-10)
基座:Qwen3.5-122B-A10B;框架:slime + Megatron + SGLang;沙箱:Daytona;评测 harness:Harbor / Terminus-2

一句话:Reward 取"通过的断言数 ÷ 固定常数 20"而不是通过率,只打在轨迹末 token 上、不做任何归一化;时间上的功劳分配全部交给一个预热过、学习率高 15 倍的满血 critic。这套组合把 SFT 检查点的 Terminal-Bench 2.1 从 49.4% 推到 64.0%,而同样的数据用 GRPO 训不动。

核心结论速览

01论文在做什么

T1 是一个纯靠"执行结果"做 RL 的终端 agent:任务是一个自包含的目录(指令、Docker 环境、资源限制、held-out verifier、参考解),agent 在云沙箱里逐轮发 shell 命令、读输出,直到完成或耗尽预算,然后 verifier 跑一遍,把每条断言的通过/失败写成结构化报告(CTRF)。这份报告就是 reward 的唯一来源,没有任何 reward model。

论文自述的三块贡献:

  1. 稠密 verification reward(第 5 节):按通过断言的绝对数计分,外加两个失败的 shaping 变体。
  2. MoE 大模型 agentic RL 的稳定栈(第 4 节):TITO(token-in-token-out,训练侧直接消费采样时的 token id)+ R3(rollout routing replay,训练时重放采样时的专家选择)+ 有调度的 critic。训练–推理 log-prob 差从 0.021 降到 0.013,loss 区域内 token 漂移精确为零。
  3. 完全 OOD 的训练集(第 3 节):合成任务与 Terminal-Bench 2.1 无交集,涨分来自能力迁移而不是刷榜。

训练框架是一步异步的 PPO:推理副本和训练后端各占一批 GPU,step t 训练与 step t+1 采样并行;每步过采样 560 条轨迹、收前 512 条就截断长尾;每步约 57 分钟,其中约 16 分钟采样被约 41 分钟训练完全遮住。上下文 84k,T1-15k 上跑 3 个 epoch,第 110 步取到最优。

02Reward 设计从数据合成就开始了

论文有一句很准确的话:"No reinforcement signal can be richer than what its verifier can measure." 三个训练池的差别正好说明这一点:

训练池规模verifier 粒度用途
TMax-15k14,601只有二值结果,没有逐断言记录只能做 binary reward;后来用来预热 critic
RST-38k37,484逐断言未过滤的合成池,dense reward 训到 59.9%
T1-15k15,000逐断言(抽样 93% 的任务确认有记录)生产 run,训到 64.0%

RST(Recursive Synthesis for Terminal tasks,同一团队的前作)在合成任务时就刻意给每个任务配足够多、覆盖各个子需求的断言,而且难任务配更多断言、每条断言大致对应可比的工作量。这是后面"绝对数而非比率"这个 reward 决策的前提假设。

LLM 审计:verifier 质量占 45% 权重

T1-15k 是 RST 合成轮次里经 DeepSeek-V4-Pro 语义审计存活的子集。八个维度里,"指令与 verifier 对齐"权重最高(20%),理由直白:verifier 强制要求了指令里没写的东西,就是隐藏需求,agent 会因为一个它从没见过的标准被罚。按方面聚合:verifier 45%、solution 25%、instruction 20%、任务训练价值 10%。四种情况直接 hard reject:隐藏需求、测试泄漏、解法捷径、verifier 弱到验不了任务目标。

15 个改写轮次、五个阶段筛选,语义审核一轮的结果是 5,902 通过、3,251 边界、5,847 拒绝,另有 6,875 个任务做了"只改指令"的修复后再审。

评注:这是他们对 reward hacking 的主防线

论文在 5.4 节明确说,数据侧审计是"唯一针对任务可利用性的防御"。verifier 在 agent 可控的沙箱里跑,没有运行时防篡改(只读挂载、校验和都列在 future work)。也就是说,防 hacking 的责任几乎全部前移到了造数据的阶段,而不是 reward 函数本身。

03Reward 设计(重点)

3.1 为什么从 binary 换成 dense

动机是纯经验的:刚在 T1-15k 上跑 RL 时,很多任务模型根本做不完。binary reward 下这些轨迹全是零,哪怕已经满足了一部分需求。完全成功太稀有,部分进度又完全不可见。一批 rollout 要烧几百个沙箱小时,换回来每条轨迹一个 bit——第一次 binary 战役从头到尾没超过 SFT 基线。

3.2 定义:绝对通过数 / 固定常数

r = P / S, S = 20 (式 20) P:verifier 报告的通过断言数 S:全局固定常数,整个 run 不变 注意:r 可以大于 1(任务断言数超过 20 时)

论文强调了三个决策,每个都带理由:

1

绝对数,不是比率。训练池混合难易任务且不做课程、随机打散,一个 batch 里难易都有,所以跨任务的 reward 尺度是实打实要紧的。难任务过 10/20 和易任务过 2/4 的通过率都是 0.5,但前者可能要长得多的工具交互链。用 S=20 统一尺度后分别得 0.5 和 0.1,每多过一条断言固定加 1/20,"难任务上多做几步"和"易任务上少做几步"的差别被保留下来。

2

全局固定尺度。S=20 是量了 T1-15k 断言数分布之后定的:中位数 4,最大约 35,20 大约在第 90 百分位。之所以不用 per-batch 最大值做分母,是因为那会让 reward 尺度逐步漂移,critic 拿到的回归目标每步都不一样;跨 step 一致性正是 value function 可学的前提

3

回退。逐断言报告缺失或解析失败时,退回二值终态结果 b,保证"真解出来的任务永远不会得零分";解析失败按原因打标签便于观测。

另外保留了一个早期的比率版变体用于对照:r = max(b, 0.4·P/T),截断到 [0, max(1, b)],T 是断言总数。生产 run 用的是式 20。

3.3 Reward 实际长什么样

训练 reward 曲线
论文 Figure 8。生产 run 的平均 rollout reward(归一化前的原值)。蓝色 T1-15k:前 50 步从 0.250 爬到约 0.345,之后 60 步稳在 0.34–0.36,峰值 0.365 在第 58 步附近。暗红 RST-38k(未过滤池):几乎平在 0.25。

几个值得读出来的点:

3.4 Credit assignment:时间上的功劳全交给 critic

论文特意区分了两种"稠密":式 20 的稠密是值域分辨率上的(每条断言 +1/20),不是时间放置上的。整条轨迹(含所有 chunk)只在最后一个 response token 上收到一个标量。由此两条推论:

结论就是那句 "The critic is thus the only baseline"——critic 校准从此进入关键路径,这也是第 04 节的全部动机。

Algorithm 2(生产 reward 计算) for each trial: b ← 终态 verifier 结果 ∈ {0,1} if 有逐断言记录: r ← P / 20 # r 可超过 1 else: r ← b # 解出的任务绝不给 0 把 r 广播到该 trial 的每个 chunk # 轨迹级 credit return r(不归一化,没有组 baseline) r 放在最后一个 response token;GAE(γ=λ=1) 对 critic 做差分配到整条轨迹

3.5 防 reward hacking:数据侧 + reward 侧 + shuffling

评注:绝对数 reward 的两个隐含代价

04Critic 设计(重点)

4.1 一个与 actor 同尺寸的满血 critic

Critic 是同架构的第二份 122B 拷贝,只把最后 pipeline stage 的语言模型头换成标量 value head。它不额外占卡,与 actor 分时复用同一批设备,训练侧强制 offload,因此两个网络各自必须单独塞进 95 GiB——这是第 7 节整套容量模型的约束来源。

4.2 更新顺序与目标函数

每步 critic 先更新,把更新前的 value Vold = Vφt−1 交给 actor,让 advantage 估计和 value clip 都锚在同一个固定函数上:

δ_j = r̂_j + γ·V_old(s_{j+1}) − V_old(s_j) Â_j = Σ_{n≥0} (γλ)^n · δ_{j+n} (式 16) L_V(φ) = E_j[ max( (V_φ(s_j) − R̂_j)², (V_clip(s_j) − R̂_j)² ) ] (式 17) V_clip = V_old + clip(V_φ − V_old, −ε_v, ε_v) L_π(θ) = −E_j[ min( r_j·Â_j, clip(r_j, 1−ε, 1+ε)·Â_j ) ] (式 18) γ = λ = 1,ε = 0.2(actor),ε_v = 0.2(critic)

把 GAE 和 ±0.2 的 value clip 锚在 Vφt−1 而不是训练中的 Vφt,让 value clip 真正成为一个围绕固定函数的信任域(附录 B.4)。

4.3 Critic Warm-Up

做法很朴素但效果决定性:在 TMax-15k 上先跑一个 epoch 的 actor-critic 训练,只保存 critic 权重,policy 步骤一步都不用。生产 run 加载这些权重时只加载权重、不带优化器动量(避免跨 run 的状态污染),然后只需要 2 个 re-calibration rollout 就能对齐。对照组是 binary 战役的冷启动 critic。

critic explained variance 对比
论文 Figure 7。Critic explained variance(式 19)。蓝色:生产 run,critic 来自 TMax-15k 预热;红色:TMax-15k 战役的冷启动 critic。冷启动开局 EV=−33.6(图中 2–13 步太离谱没画),58 个记录步里 30 步为负;预热版从第一次更新起就没低于 0,平台在 0.71–0.86。
EV = 1 − Var_j[ R̂_j − V_φ(s_j) ] / Var_j[ R̂_j ] (式 19) 两个方差在 context-parallel 和 data-parallel 所有 rank 上全局 reduce (先按 rank 算再平均是有偏的) EV 无下界;EV < 0 意味着减掉 V_φ 反而给 Â_j 加了方差

冷启动 critic 大约用了半个战役来偿还这个初始亏空——这个时间窗口正好对应 binary 战役"涨到 47.2 后再也不动"的阶段。

4.4 学习率:critic 比 actor 高一个数量级

参数相对 canonical(5e-7)
critic lr ηφ1.5 × 10−530×
actor lr ηθ1.0 × 10−6
critic / actor15×

摘要里写的"critic trained at 30× the actor learning rate"与附录 Table 3 的定义(ηφ=30ηcanon,ηθ=2ηcanon)不一致,按具体数值算是 15 倍。理由是 critic 的目标是监督回归而不是 policy improvement,能吃更大的步子。27B 探路实验里把这个比例从 10× 提到 20×,EV 从 −39 提到 +0.11;30× 进一步缩短了预热时间。

4.5 让 value 目标"好回归"的两个条件

论文把这叫 value-target conditioning:

这实际上是把 critic 变成了一个"进度预测器":给定到目前为止的交互历史,估计最后会过几条断言。它不需要预测任何中间奖励,也没有折扣衰减,这大概是 122B critic 能在 EV 0.7+ 稳定工作的原因。

4.6 Critic 不做 routing replay

R3 只用在 actor 上。Critic 的目标是对回报的监督回归,不需要对采样策略保持行为保真,所以它自由选专家(φt−1, TopKk)。此外 critic 的 batching 方式不同,强行共享 buffer 会破坏"token 与路由记录同分片"的不变量。

4.7 为什么不用 GRPO:三条都与长程有关

在确定用 PPO 之前,他们在同样的 harness、reward 和设备预算下跑了 GRPO。结果是 reward 无趋势地波动,第 10 步和第 20 步的 held-out 评测完全一样:51.7%,都是 89 题里的 46 题。

GRPO reward 曲线
论文 Figure 16。GRPO 在 T1-15k 上的 rollout reward,与生产 run 同 reward 同 harness。(注意纵轴是组内采样后的 reward,与 Figure 8 尺度不同,不能直接比高低。)
  1. advantage 恰好在需要信号的地方退化。组内标准化 Ai=(ri−μ)/σ,全失败或全成功的组贡献零梯度;在难到需要稠密 reward 的任务上,这种组是常态,少数有方差的组主导更新。而且一条轨迹所有 token 共享同一个 advantage,GAE 提供的时间 credit 没了。
  2. 组大小和任务多样性在长程任务上互斥。每个任务要采 G 次才换来一个 advantage,固定采样预算下每步不同任务数按 G 倍缩水。PPO 用 critic 提供 baseline,同样的预算全花在不同任务上。
  3. 重复采样的代价在长尾上结算。一个组要等最慢的成员结束;终端轨迹在轮数和 token 上都是重尾,独立 trial 可以截尾,组内不能(截了比较就没了)。采样端在这个估计器最需要的配置上空转。

论文的总结:组 baseline 是 value function 的替代品,单轮场景下便宜,代价随 horizon 增长;critic 的代价真实但有界。

4.8 教训:critic 校准好不代表 policy 会变好

这是第 9 节第一条,也是我认为全文最有价值的一段。27B 探路实验里,提高 critic lr 把首次 EV 转正从第 50 步提前到第 30 步,rollout reward 在各设置间纹丝不动。critic 在更好地预测回报,actor 拿到的 reward 没变。

原因:critic 学的是 reward 函数分配的回报。难任务大多拿同一个零,预测得再准也不能揭示 verifier 从没奖励过的部分进度。任务池和 reward 粒度决定哪些改进可观测;critic 校准决定 baseline 对这些回报建模得多好。两者要分开诊断:EV 是关于 value function 的证据,通过测试数、任务完成率、held-out 评测才是 policy 是否在进步的证据。校准在涨而 reward 不动时,该看的是任务难度和 verifier 粒度,而不是继续调优化器。

Reward 与 Critic 的耦合关系,一张表
Reward 侧决策对 critic 的意义
绝对数 / 固定 S=20回归目标跨 step 同尺度,value 可学
只打在末 token,γ=λ=1回报分段常数,value = 预测最终分数
不归一化,每任务 1 样本没有组 baseline,critic 是唯一 baseline,校准进入关键路径
每 epoch shufflecritic 看到的 reward 分布平稳,不随质量排序漂移
逐断言粒度(数据侧)让"部分进度"可观测;critic 再准也补不回 verifier 没给的信号

05稳定栈简述:TITO 与 R3

这部分不是本文重点,但要理解为什么他们的 PPO 敢关掉 KL,得知道它。核心观察是:PPO 的重要性比 rj(θ)=πtt−1 只有在分母能被训练侧精确复现时才有意义。有两个东西会破坏它:

训练推理 log-prob 差
论文 Figure 6。loss 区域内 mask 加权的 |Δlog p|。TITO+R3 把均值从 0.021 降到 0.013;残差来自 kernel 数值差,缓慢上升是 policy 真实移动(version skew)的合法成分。

由此带来的 PPO 配置:对称 clip ε=0.2;两个 KL 项都关掉(冻结的参考模型用自己的路由,会为簿记差异冤枉 policy);MoE 负载均衡系数置零(均衡压力要求 router 重新分配的恰是 replay 要求它复现的);Adam β=(0.9, 0.98)、weight decay 0.1、常数 lr;batch 560 过采样收 512。

06主结果与训练动态

模型(同 harness:Harbor/Terminus-2)规模TB 2.1 (%)LHTB
Claude Opus 4.7/66.1
T1122B-A10B64.027.9
Claude Opus 4.6/63.8
Muse Spark/62.2
Qwen3.5-122B + RL (RST-38k)122B-A10B59.925.4
Hy3-Preview295B-A21B58.0
DeepSeek V4 Flash (high)295B-A21B56.9
Kimi-K2.51040B-A32B56.4
GPT-5.4/54.827.2
Claude Sonnet 4.6/51.537.3
RST-SFT(RL 起点)122B-A10B49.423.6
Qwen3.5-122B + RL (TMax-15k, binary)122B-A10B47.220.3
Qwen3.5-122B-A10B (base)122B-A10B43.818.9

Harness 对分数影响很大:Opus 4.6 在 Claude Code 下是 70.1,Terminus-2 下 63.8;GPT-5.4 在 Codex CLI 下 77.3。T1 是专门为 Terminus-2 训的,对比模型不是。LHTB 是平均 reward 而非解决率,且排序与 TB 2.1 并不一致(Sonnet 4.6 在 LHTB 上 37.3 远超 T1)。

训练过程中 TB2.1 评测
论文 Figure 12。每 10 步评一次 held-out TB 2.1。第 10 步就到 56.2%(超起点 6.8 个点),20–60 步在 55.1–57.3% 平台,第 70 步 61.8%,第 110 步 64.0%。两次跃升都落在 Figure 7 中 EV 最高的区间——论文据此认为最大的可用 actor 改进只在 critic 校准好之后才出现。
轮数与序列长度动态
论文 Figure 13。训练中每条轨迹的平均工具调用轮数(10.4 → 约 20.7)和总长度(11.5k → 约 18k token)都翻倍后在第 60 步附近走平。论文区分这与 length hacking 的两个依据:增长有界(加性长度惩罚那次是 50 轮以上无界增长),且平台期与 reward、榜单同步。

增益落在哪里:Easy 组三个检查点都是 100%;Medium 组 56 → 58 → 78;Hard 组 20 → 30 → 33。RL 的提升主要在 Medium。评测时 T1 平均用 94.4 轮,SFT 31.5、base 41.1——成功率的提高是用大约 3 倍的交互换来的。六个代表性失败案例里 T1 花 164–473 轮后超时,GPT-5.6 Sol 只用 6–40 轮;论文自己的判断是"更长的交互只有配上有效的诊断、恢复和停止决策才有用,单纯加轮数预算解决不了"。

附录的两个 case 很直观地说明 RL 改变了什么:build-pov-ray 里 SFT 模型在总结里准确诊断出"下载源已死、该换镜像",却继续重试同一个死链接直到 51 次上下文溢出;T1 得出同样诊断后换了 FTP 镜像,65 轮零溢出通过。polyglot-c-py 里两者都写对了 polyglot,差别只是 T1 在收尾前删掉了编译产物,让目录恰好只剩 main.py.c。RL 改的不是推理能力,是"放弃失败假设"和"把最终机器状态当交付物"这两个行为。

07没做成的事与局限(论文自述)


08值得带走的几点

  1. 先问 verifier 能测出什么,再谈 reward。T1 的 dense reward 之所以可行,是因为 RST 合成任务时就把"难任务多配断言、每条断言可比"写进了生成规则。TMax-15k 那种只给 0/1 的池子,reward 怎么设计都是一个 bit。
  2. 绝对数 + 固定分母,是为 critic 服务的选择。比率会封顶抹平难度差,per-batch 归一化会让回归目标漂移。若你的 baseline 是 learned value,reward 的跨 step 一致性比它"看起来是否在 [0,1]"重要得多。
  3. 长程 + 一任务一样本的场景,critic 是必需品,且必须预热。冷启动 122B critic 要花半个战役偿还 EV 亏空。用一份便宜数据先训 critic、只存权重不存优化器状态,是很便宜的保险。
  4. EV 和 reward 要分开看。EV 涨 reward 不动,说明 reward 粒度或任务难度出了问题,不是学习率。
  5. 轮数增长不要急着罚。先检查上下文压缩是否丢了记忆、截尾是否丢了难任务;T1 的加性长度惩罚反而导致无界增长。
  6. 关 KL、关负载均衡,只有在训推一致性被真正解决后才合理。TITO + R3 是这套"极简 PPO"能成立的前提,不能单独抄配置。
← 全部解读