精读:Terminal-Universe——把轨迹反演回环境,而不是模仿它
阿里 Qwen 团队证明公开 agent 轨迹直接做 SFT 是负收益(−10.3 分),提出从轨迹反推可执行环境的逆变换管道,用 35.9 万条轨迹重建 3.73 万个带验证器的环境,把 Qwen3.5-27B 的 Terminal-Bench 2.1 从 46.2 推到 58.1
1 论文概览
一句话总结:阿里 Qwen 团队与清华大学提出 Terminal-Universe,把 agent 轨迹当成环境的一次”观测投影”,用确定性回放加 agentic 补全把轨迹反推回可执行的 workspace,再从 35.9 万条公开轨迹中重建出 3.73 万个带验证器的环境,让 Qwen3.5-27B 在 Terminal-Bench 2.1 上从 46.2 涨到 58.1。
核心问题
终端类代码 agent 的训练数据正在以两种形态堆积,二者的价值密度差了一个量级。
一边是轨迹。Claude Code、Cursor 这类工具大规模铺开之后,公开轨迹语料已经涨到几十万条量级,LFM2-Terminal 一个源就有 13.9 万条。轨迹的毛病在于它是一次性的:内容被产出它的策略模型封顶,我们拿不到比那个模型更好的行为;它对代码库的改动对不对,没有独立手段核验;同一份素材无法被反复提问。
另一边是环境。Terminal-Bench 这类专家手工基准展示了环境的样子——每个任务配一个定制容器、一条指令、一个可执行验证器。环境可以被更强的模型重解,结果可以被自己的测试判定,同一个 workspace 上还能不断出更难的题。后训练真正需要的正是这个形态。
手工打造环境的产能撑不起后训练所需的数据量,于是环境规模化出现了三条既有路线,论文在引言里把它们拆得很清楚:
- 仓库回溯法,从真实仓库的 git 历史里构造任务(SWE-Gym、R2E-Gym)。真实,但被仓库自身的提交历史锁死,数量有限。
- 扰动法,往能跑通测试的仓库里注入 bug,让 agent 去修(SWE-smith、CLI-Gym)。一个仓库能灌出很多任务,可每个任务都是”修 bug”这一种题型,且受限于可注入的 bug 种类。
- 任务条件合成法,按类别、能力分类法或技能图,把任务和环境一起从零生成(Endless Terminal、CLI-Universe、SkillSynth)。覆盖率可控,环境不挂靠任何真实项目,真实感完全取决于生成器,产出的 workspace 偏小偏整齐。
三条路线的共同点是:环境要么来自一个已经存在的环境,要么和一个新生成的任务绑死。轨迹作为”环境的一次观测”这个身份,没有被当成资源用过。
主要贡献
- 轨迹到环境的逆变换。 提出”轨迹和环境是同一回合的两种视图”这一视角,把既有工作”从环境 rollout 出轨迹”的映射方向掉了个头。重建分两级:确定性回放按时间顺序处理 read/write/edit,把每个被访问路径恢复到 agent 首次改动前的版本;agentic 补全接着补上回放遗漏的缺失文件与依赖。
- 四种重查询机制。 Intent Recovery 重建原始意图任务,Single-WS 在单个 workspace 内合成新任务,Cross-WS 跨 workspace 合成依赖型任务(广度),Multi-Round 把单轮查询扩展成带用户反馈的多轮会话(深度)。每个任务配一个容器内 agent 编写的 pytest 验证器,只保留全部通过的轨迹。
- 规模验证。 从 35.9 万条源轨迹中重建出 68,263 个环境,其中 37,273 个通过任务充分性审查;产出 31,977 条 SFT 演示、约 14.2 亿训练 token。Qwen3.5-27B 微调后 Terminal-Bench 2.0 从 41.6 到 52.8,2.1 从 46.2 到 58.1,EvoCode-Bench v2 的 MT@4 从 6.3 到 20.1。
- 预算分配的定量结论。 在 3.5 万条记录的等预算对照下,扩展环境数带来 +2.8 分,增加每环境查询数只带来 +0.6 分,增加每查询解法数 +0.7 分——多环境压倒性地优于多查询。
- 可迁移性验证。 同一套管道换到 SWE 工作区上(不做任何针对终端域的调整),仅用最简单的 Intent Recovery,1,464 个充分仓库产生约 10.3k 条轨迹,就把 Terminal-Bench 2.1 的跨 scaffold 平均分从 47.0 推到 50.0。
2 方法详解
架构概述
整条管道可以读成一个漏斗:源轨迹池 359,593 条 → 重建环境 68,263 个 → 去重与去污后进入充分性审查的 38,294 个终端环境与 1,900 个 SWE 仓库 → 判定充分的 37,273 个 → 验证器过滤后的 31,977 条 SFT 演示。每一级的损耗都会在 §6 的消融里被单独定价。
论文对轨迹与环境的关系给了一个很干脆的定位:
A trajectory and an environment are two views of the same episode, so prior work rolls out a trajectory from an environment while we invert the mapping and recover an environment from a trajectory.
—— Figure 1 图注,§1
这句话是整篇的支点。既有工作做的是 环境 → 轨迹,这篇做的是 轨迹 → 环境。
三阶段环境重建
阶段一,确定性回放。 把轨迹里的读写改操作按时间顺序归一化成一条事件流。对每个被访问的路径,保留其”首次被改动前”的内容;agent 自己创建的文件全部排除在初始 workspace 之外,agent 的改动单独记录留待后续验证。这一步是纯机械的,不调用模型。
问题也随之而来:轨迹只暴露 agent 碰过的路径,且文件内容常常只有片段(终端输出被截断)。回放产出的 workspace 平均只有 2.9 个文件、90 行文本——这不是一个能干活的项目。
阶段二,agentic 补全。 一个补全 agent 拿到恢复出的请求、残缺 workspace 和文件清单,负责创建缺失文件、补全截断文件、配置依赖。它有一条硬约束:
It must not implement the requested task or reveal where its solution should be made.
—— Appendix B.1
补全之后,终端池的 workspace 平均文件数从 2.9 涨到 22.4,文本行数从 90 涨到 5,761(Table 13)。
阶段三,环境过滤。 一个 agentic judge 用只读的 shell 和文件工具检查每个 workspace,结合恢复出的任务判断”充分/不充分”——判据是源码、配置、数据和结构有没有给一个有能力的 agent 足够的上下文。只有充分的才进入下游。
Table 2 是这条漏斗最关键的对照:
| 池 | 环境数 | 回放后充分率 | 补全后充分率 |
|---|---|---|---|
| 终端 | 38,294 | 40.2% | 93.5% |
| SWE | 1,900 | 20.1% | 77.1% |
53.3 个百分点的工作区内容,是补全 agent 造出来的,不是从轨迹里观测到的。
四种重查询机制
Intent Recovery 从轨迹里恢复原始用户意图作为任务。多轮轨迹的处理有个细节:第一条实质性请求确立任务主题,后续请求只有在澄清、约束或扩展同一任务时才被纳入,跑题的任务切换直接丢弃;判读请求时可以用 agent 动作和文件证据,但保留下来的只有用户明确说出的需求。
Single-WS 让一个离线生成器检查每个 workspace,在”有根据、结构多样、可验证”三条约束下合成五个自包含候选任务,随机选一个去 rollout 与验证。
Cross-WS 是这篇在任务形态上最不一样的一手。它先给每个 workspace 做技术域与已实现能力的画像,用 TF-IDF 近邻检索候选对,再让 LLM judge 判定”目标 workspace 缺少、参考 workspace 已有”的有向依赖边。每个任务配一个可写目标 workspace 加一个挂载在独立路径的只读参考 workspace。查询只给目标行为和参考的挂载路径,不给参考的内部细节,逼 agent 自己去导航、理解、改造参考实现。
Multi-Round 把单轮扩展成迭代会话,靠两个协同机制保证连贯:
- 演进式需求追踪。 用户 agent 维护一张显式的需求表,记录活跃、已满足、被更新的约束,每次追问前先更新这张表。
- 轮级验证与反馈。 每轮扩展先让自动验证器写轮级验收测试,再让编码 agent 行动;测试跑完后,用户 agent 把结构化结果翻译成自然的、用户可见的抱怨——solver agent 与测试脚本和 traceback 严格隔离。
追问的交互风格分三类:特性扩展(验证通过后的新需求)、特性修订(测试失败后要求修 bug)、特性冲突(覆盖先前规格以反映需求变更)。会话最多六轮追问,或直到发出终止哨兵。筛选规则是剪掉末尾连续的失败轮,只保留至少含两轮验证通过的会话,中间那些先失败后被修好的轮次一律保留。
结果是 3,079 条保留记录平均 4.51 轮,其中 69.6% 含一次会话随后修复了的失败。
与基线方法的区别
Table 1 把定位摆得很清楚(节选):
| 方法 | 策略 | 环境 | 任务 | 验证器 | 多轮 | 跨 WS |
|---|---|---|---|---|---|---|
| Endless Term. | 任务条件生成 | 3,255 | 3,255 | ✓ | ✗ | ✗ |
| TMax | 组合采样 | 14.6k | 14.6k | ✓ | ✗ | ✗ |
| CLI-Gym | 环境扰动 | 29 | 1,655 | ✓ | ✗ | ✗ |
| CLI-Universe | 分类法引导 | 6k | 6k | ✓ | ✗ | ✗ |
| RST | 递归演化 | 37.5k | 37.5k | ✓ | ✗ | ✗ |
| CalibForge | 对抗式校准 | 5,431 | 5,431 | ✓ | ✗ | ✗ |
| OpenThinker-Agent | 多源策展 | – | 100k | ✓ | ✗ | ✗ |
| Terminal-Universe | 轨迹重建 | 37.3k | 32.0k | ✓ | ✓ | ✓ |
有两个细节值得单独拎出来。
它是唯一 Env ≠ Tasks 的方法。 其余每一行的环境和任务数都相等——一个环境榨一个任务。Terminal-Universe 是 37.3k 个环境配 32.0k 个任务,环境比任务多。这不是统计口径的差异,而是方法论主张:环境是可复用资产,任务只是环境的一次投影。
它是唯一把多轮与跨 workspace 两件事都做了的方法。 广度与深度这两条扩张轴,此前没有任何一条环境规模化路线做过。
3 实验结果
主要指标
基座是 Qwen3.5-27B,SFT 两轮,学习率 7×10⁻⁶,全局 batch 256,序列长度 256k token。训练前做 13-gram 去污,并从全部四种重查询变体中排除 Terminal-Bench 派生的源数据集。教师模型是 Qwen3.7-Max(xhigh effort),跑在 Claude Code 脚手架里。Terminal-Bench 分数是六次独立运行的均值。
| 模型 | 基座 | 数据量 | TB2.0 | TB2.1 | EvoCode MT@4 | Case Score |
|---|---|---|---|---|---|---|
| Qwen3.5-27B | – | – | 41.6 | 46.2 | 6.3 | 67.8 |
| Qwen3.7-Max | – | – | 69.7 | 74.5 | 39.8 | 83.4 |
| TerminalTraj-32B | Qwen2.5-Coder-32B | 50.7k | 22.0 | 28.5 | 0.0 | 15.9 |
| Nemotron-Terminal-32B | Qwen3-32B | 490k | 27.4 | 27.9 | 0.0 | 13.7 |
| OpenThinker-Agent-32B | Qwen3-32B | 100k | 26.2 | 30.7 | 0.0 | 19.7 |
| TMax-27B | Qwen3.6-27B | 14.6k | 42.7 | 44.9 | 17.1 | 72.5 |
| RST-27B | Qwen3.5-27B | 37.5k | 49.4 | – | – | – |
| CalibForge-35B-A3B | Qwen3.5-35B-A3B | 5.4k | 47.6 | – | – | – |
| Terminal-Universe-27B | Qwen3.5-27B | 32.0k | 52.8 | 58.1 | 20.1 | 76.1 |
Full Mixture(验证器过滤后的 Single-WS + Cross-WS + Multi-Round,32.0k 条)在 Terminus2-XML 下拿到 TB2.0 52.8、TB2.1 58.1,相对基座 +11.2 与 +11.9;在 Claude Code 下 TB2.1 58.2,+10.4。EvoCode-Bench v2 上 MT@4 从 6.3 到 20.1,Case Score 从 67.8 到 76.1。
换 scaffold 只掉 0.1 分(TB2.1 的 58.1 对 58.2),说明增益没有绑死在某套工具解析格式上。
与 SOTA 的对比
几个对读要点:
- 同基座横向比,RST-27B(Qwen3.5-27B,37.5k 数据)TB2.0 是 49.4,Terminal-Universe 是 52.8,数据量更少而分数更高。
- TMax-27B 用了更强的 Qwen3.6-27B 基座,14.6k 数据,TB2.1 44.9;Terminal-Universe 58.1。
- EvoCode-Bench v2 的多轮指标上,只有 Qwen3.7-Max(39.8)和 Terminal-Universe(20.1)拿到了非零的 MT@4。TerminalTraj、TermiGen、Nemotron-Terminal、OpenThinker-Agent 清一色 0.0。这个 0.0 不是评测失败,而是 MT@4 的 fail-stop 计分口径:一次运行只计首次失败之前连续通过的轮次。这四个模型在第一轮就撑不住。
- 教师 Qwen3.7-Max 自己 MT@4 只有 39.8、TB2.1 74.5。学生 20.1 / 58.1,落在基座与教师之间,符合蒸馏的预期区间。
消融实验关键发现
论文把消融组织成四个问题,逐个定价。
① 重建环境再重解,值不值? 这是全篇最有杀伤力的一张表。
| 变体 | 数据量 | Claude Code | Terminus2-XML | 平均 |
|---|---|---|---|---|
| Qwen3.5-27B 基座 | – | 47.8 | 46.2 | 47.0 |
| 源轨迹 SFT | 35.8k | 33.0 | 40.3 | 36.7 |
| Intent Recovery | 35.8k | 51.3 | 52.9 | 52.1 |
数据量完全对齐(都是 35.8k),模板与工具调用 schema 一致,验证器不参与。结果是:拿公开轨迹直接做 SFT,平均分比不训练还低 10.3 分;同样的素材逆变换成环境、让更强的教师重解一遍,就是 +5.1 分。两者相差 15.4 分。
② 补全 agent 值不值? 等数据量对照下,纯回放 48.7(±3.5),回放加补全 52.9(±1.4)。+4.2 分,且方差减半。作者还补了一句观察:纯回放环境下,教师常常先忙着修复缺失文件和安装依赖,再去做任务——于是部分监督信号花在了”修工作区”上而不是”解题”上。
③ 验证器过滤值不值?
| 变体 | 记录数 | TB2.1 |
|---|---|---|
| Single-WS 无验证器 | 35.1k | 56.0 |
| Single-WS 有验证器 | 25.4k | 56.4 |
| Cross-WS 无验证器 | 7.1k | 53.2 |
| Cross-WS 有验证器 | 3.5k | 55.4 |
Single-WS 上丢掉 28% 数据换 +0.4 分,Cross-WS 上丢掉 51% 数据换 +2.2 分。论文的结论是”验证器在更难的任务上更值钱”。
④ 固定预算怎么花? 从 17,558 个环境、每环境一查询一解法的 17.6k 基线出发,沿单一轴翻倍到约 35k 记录:
| 变体 | 环境数 | 查询/环境 | 解法/查询 | 记录数 | TB2.1 |
|---|---|---|---|---|---|
| 基线池 | 17,558 | 1 | 1 | 17.6k | 53.2 |
| 扩展环境 | 35,116 | 1 | 1 | 35.1k | 56.0 |
| 扩展查询 | 17,558 | 2 | 1 | 35.1k | 53.8 |
| 扩展解法 | 17,558 | 1 | 2 | 35.1k | 53.9 |
环境扩展 +2.8,查询扩展 +0.6,解法扩展 +0.7。作者在正文里解释得很直白:每个新环境带来一个独立的可执行上下文,所以带来新的监督;同一 workspace 上的第二个查询或第二个解法,基本是在重复模型已经看过的东西。
⑤ 跨 workspace 数据加在哪? Single-WS 56.4 → 加 Cross-WS 后 58.4,Cross-WS 单用也有 55.4。按类目拆开看,最大的软件工程类(26 个任务)从 46.9 到 49.1,模型训练 +15.0,调试 +10.0;三个类目下降 2.1 到 2.5 分,作者说明这个幅度落在”最多 8 个任务的类目”的跑间波动范围内。
Table 8 给了 Cross-WS 为什么不一样:中位轮数 14 → 23,中位工具调用 20 → 38,中位 token 30.4k → 46.5k,教师 pass@1 从 72.3% 掉到 49.2%。
4 个人分析
亮点
第一,它做了一件没人愿意做的脏活:证明存量轨迹是负资产。
Table 4 那行 36.7 是整篇论文最刺眼的数字,而作者在 §6.1 只用了一句话把它带过——“suggesting that regenerating demonstrations under a consistent teacher policy provides more effective supervision”。这个措辞把 −10.3 包装成了”另一种方法更好”,可它真正说的是另一件事:在终端 agent 这个域里,35.8k 条公开轨迹作为 SFT 数据是有毒的,训完比不训更差。
再回头看 Table 3,会发现一整片印证。TerminalTraj-32B(50.7k 数据)TB2.1 28.5,Nemotron-Terminal-32B(490k 数据)27.9,OpenThinker-Agent-32B(100k 数据)30.7——这批模型的基座各不相同,不能直接横向比较,但它们的共同点是都走”大规模轨迹策展 + SFT”,且 EvoCode MT@4 全都是 0.0。数据量的数量级差异没有换来分数差异,这是”堆轨迹”路线给出的集体答案。
把 Table 4 的控制变量条件和 Table 3 的横截面放在一起读,结论就硬了:轨迹作为监督信号,其价值不在于它记录了什么,而在于它泄露了什么。 它泄露的是环境的结构与内容——Read 展示了文件内容,Write 与 Edit 展示了 workspace 如何变化。这个信息量足以重建一份可执行副本,而那份副本可以被反复提问。直接模仿轨迹,等于拿一个更弱策略的上界当监督。
第二,Table 10 是论文里最被低估的一张表。
它给出的不是”怎么做得更好”,而是”别把钱花在哪”。等预算下,查询扩展 +0.6、解法扩展 +0.7,都落在噪声量级。这直接反驳了一条当下很主流的扩张策略——在同一批环境上做组合采样、多任务采样、多解法采样。TMax 的 combinatorial sampling 正是这条路线,14.6k 数据换 TB2.1 44.9。
顺着这张表还能推出 Cross-WS 为什么有效。论文把 Cross-WS 的增益解释为”更难”(Table 8 的 pass@1 72.3% → 49.2%),可 Table 10 恰恰说明难度本身不值钱——不然查询扩展也该涨分。换个读法:Cross-WS 每条记录消耗两个 workspace,把”环境数 / 记录数”的比值从 1 抬到 2。它之所以有效,是因为它是另一种形式的环境扩展,不是因为它更难。难度只是环境扩展的副产品。
这个读法顺带把 Cross-WS 的单位效率算清楚了:3,512 条记录占 Full Mixture 的 11%、约 13% 的 token,换来 +2.0 分。按每条记录算,Cross-WS 的增益效率是 Single-WS 的约 1.4 倍(0.00057 对 0.00040 分/条);按每个 token 算两者基本打平,因为 Cross-WS 每条记录要长 1.58 倍。稀缺的不是 token,是独立的可执行上下文。
第三,两个表的数字可以对读出一个论文没点破的等式。
Table 6 的过滤保留率:
- Single-WS:25.4k / 35.1k = 72.4%
- Cross-WS:3.5k / 7.1k = 49.3%
Table 8 的教师 pass@1:
- Single-WS:72.3%
- Cross-WS:49.2%
两组数字各自吻合到小数点后一位。这不是巧合——它说明验证器过滤掉的,和教师没能一次做对的,几乎是完全同一批 rollout。
这个吻合把 §3.3 那个”专门写 pytest 套件的验证器 agent”的真实贡献摆到了聚光灯下。在 Single-WS 上,它花掉的算力换来了 +0.4 分。既然它筛掉的东西和”教师 pass@1”高度重合,那么真正起作用的可能是教师有没有做对这件事本身,而不是那套 pytest。
论文没有做这个对照——§6.3 的设计是”保留全部”对”验证器通过的子集”,第三臂”用教师 pass@1 替代独立 pytest 做筛选”是缺的。补上这一臂才能分离出验证器的独立贡献:如果 pass@1 筛选也能拿到 ~56.4,那么 Single-WS 上的整个验证器环节就是可省的;如果有明显差距,才证明独立测试套件在教师做对的那些题里还抓出了别的东西(比如蒙对的、或测试覆盖不足的)。这是一个可以立刻上机验证的判别实验。
第四,Multi-Round 的真实产出被标题掩盖了。
“多轮会话数据”听起来是在造轮数,实际统计是 3,079 条记录、平均 4.51 轮、69.6% 含一次先失败后被修好的转折。粗算下来是约 2,143 条”翻车—诊断—修好”的样本。长程 agent 训练里最稀缺的监督信号恰恰是这个——成功轨迹的示范价值早就边际递减了,错误恢复的监督却几乎没有规模化来源。
Multi-Round 的消融还给了个佐证:去掉轮级验证反馈,MT@4 掉 2.2 分、Case Score 掉 3.7 分。作者观察到,没有”还剩什么没做对”的接地信号,续写就失去了方向,产出更长但质量更低的多轮轨迹。轮级验证不是质量过滤器,是导航仪。
局限性
论文自陈的三条(§7):
First, we use standard Ubuntu 24.04 containers for all workspaces rather than building tailored, repository-specific environments via automated pipelines like SWE-Factory or RepoLaunch. […] Second, the domain, language, and toolchain distributions of our reconstructed workspaces are fundamentally bounded by the coverage of the collected source trajectories. […] Third, a single teacher generates tasks, solutions, and verifiers.
—— §7 Limitations
三条都成立,其中第三条被作者自己轻放了半档。论文说单一教师的风险是”能力缺口限制任务覆盖”和”解里的错误被它自己的测试漏掉”,这只说了一半。
第三条的真实形状是:任务、解、验证器三者同源,构成了一个闭合的自证循环。 教师出题、教师答题、教师判卷。任何自博弈系统都有这个退化模式,而它最典型的症状不是”判错”,是题出得太简单没人拦得住。Table 8 里 Single-WS 的教师 pass@1 是 72.3%——这个数字从自博弈的角度读,是”模型给自己出的题,四分之三它本来就会做”。验证器与出题者同源,它检查的是”解有没有满足题面”,检查不了”题面值不值得做”。论文没有讨论这一层,也没有报告任务难度分布的独立度量(比如用一个更强的外部模型测 pass@1)。
第二条可以量化到有点难看。 论文自陈分布受源轨迹覆盖限制,也在 §4.2 引 Figure 5 给出了这个限制的形状:Python 占主语言的 84.7%,数据处理、DevOps、安全三类合计超过 80%。所以”终端任务”在这里的实际含义是”以 Python 为主的终端任务”。C++ 和 C 被点名是次要语言,但没给具体份额。
还有一条论文没列:37.3k 个环境只用了 SFT 这一种用法。
这些环境自带容器内验证器、可重复 rollout、可判分——这是 RLVR 的标准 rollout 场。论文一个字没提 RL,全部收益来自”教师重解一遍然后模仿”。§7 讨论扩展性时讲的是”更丰富的源轨迹能重建出更复杂的环境”,方向仍然锁在 SFT 数据生产上。
这个选择在当下可能是对的(SFT 便宜、稳、好复现),可它意味着这篇论文真正的资产——3.73 万个可验证环境——其价值远未被 32.0k 条 SFT 记录兑现。Table 10 说”同一机制下多问一遍收益低”,这否证的是 SFT 路线的边际收益,否证不了 RL 路线:RL 消耗环境的方式与 SFT 完全不同,它要的正是”同一个环境上反复试错并按结果加减分”。
对大模型领域的影响
训练数据的重心正在从”轨迹”移到”环境”。 这篇论文和它同日在 arXiv 出现的 Environment Evolution for Terminal Agents(arXiv:2609.04128)从两个相反方向说了同一件事:前者把存量轨迹反推成环境,后者把已有环境演化得更难。两条路的交汇点是同一个判断——agent 后训练的瓶颈已经不在模型和算力,在于有东西可练。
“数据飞轮”正在变成”环境飞轮”。 数据飞轮的复利来自”更多用户 → 更多数据 → 更好模型”。环境飞轮的复利结构不一样:模型越强 → 产出的轨迹越复杂 → 反推出的环境越丰富 → 能出的题越难。论文 §7 把这个机制明确写了出来:
Trajectories with richer operational dynamics, such as multi-file manipulations and long tool-use chains, expose broader workspace state, which in turn supports more diverse and more demanding synthesized tasks.
复利方向是一致的,而且不需要更多用户。谁把昨天的轨迹变成明天的难题的成本最低,谁就能在别人练无可练之后继续涨。
“幻觉补全 + 可执行验证”是一个可复用的模式。 补全 agent 造出了 53.3 个百分点的工作区内容,这些内容严格来说是模型生成的、不是观测到的。论文没有回避这点,而是用两道闸门兜底:补全 agent 不许实现任务,验证器只放行测试全绿的轨迹。这是一个干净的范式——让模型去补它自己观测不到的缺口,再用可执行的判据把补错的部分筛掉。凡是需要从部分观测重建完整上下文的场景(日志回溯、配置恢复、损坏仓库修复)都能套这个模式。
存量 agent 日志不能直接当训练数据。 对任何一个有线上 agent 产品的团队,Table 4 都是一个警告:35.8k 条对齐条件下的源轨迹 SFT 是 −10.3 分。内部日志的价值不在模仿,在反推。
5 实践启示
可以借鉴的技术
① 轨迹 → 环境的逆变换,是存量日志的最高杠杆用法。
三步就能落地:把 agent 的工具调用流归一化成 read/write/edit 事件流;对每个路径取首次改动前的内容,agent 新建的文件排除在外;再让一个模型补全缺失文件与依赖,硬约束是”不许实现任务本身”。作者给的规模参考是——终端池回放后平均 2.9 个文件、补全后 22.4 个。补全前后的充分率从 40.2% 跳到 93.5%,这一步值 +4.2 分且方差减半。
有两点工程注意。回放要按事件流严格保序,跨源语料的文件操作编码方式不统一(论文附录 B.1 明确提到需要先归一化)。补全 agent 的权限要卡死在”只读任务描述 + 可写 workspace”,任何让它看到解法的泄漏都会让重建出的环境失去训练价值。
② 预算分配有了一条定量规则:优先扩环境数,别扩查询数。
等预算下环境扩展 +2.8、查询扩展 +0.6、解法扩展 +0.7。这条规则的适用范围要守好边界——它被验证的场景是”同一 workspace、同一合成机制”。它没有否证”换一种机制重查同一批环境”(Single-WS → Cross-WS 就是 +2.0),也没有否证 RL 路线。
③ 验证器的投入强度应当随任务难度走。
论文的数据是:教师 pass@1 72.3% 的 Single-WS 上,过滤掉 28% 数据换 +0.4;pass@1 49.2% 的 Cross-WS 上,过滤掉 51% 数据换 +2.2。落地的读法是——简单任务上不要重投验证器,把预算挪去出题;难任务上验证器是必需品,且值得为它多花算力。
再结合 §4 里那个待验证的等式(过滤保留率 ≈ 教师 pass@1),可以先做一个便宜的版本:用”教师有没有一次做对”做初筛,只在难题子集上投入完整的 pytest 编写。这个组合的成本比”全量写 pytest”低一个量级。
④ 多轮数据的采集目标应当是”失败转折”而非”轮数”。
采集时保留中间的失败轮,只剪掉末尾连续的失败;保留门槛设为”至少两轮验证通过”。论文跑出来的自然分布是平均 4.51 轮、69.6% 的记录含一次修复。轮级验证不能省——去掉它,MT@4 掉 2.2、Case Score 掉 3.7。solver 与测试脚本必须隔离,失败信息只能以”用户可见的自然抱怨”回传,这个设计一手保证了真实感,一手保住了训练价值。
⑤ 通用容器能跑,但要接受保真度折价。
论文统一用 ubuntu:24.04 而不是仓库定制镜像,理由是成本和部署复杂度,代价是需要特殊系统依赖或复杂编译步骤的边缘场景保真度下降。如果目标场景集中在单一语言栈,这是笔划算的买卖。
潜在应用场景
企业内部 agent 日志的资产化。 客服工单系统、运维 runbook 执行记录、内部开发助手的调用日志,长期以来只有一种用法——脱敏后当 SFT 语料。按这篇的结论,那条路大概率是负收益。改成反推环境之后,同一批日志变成可复用的训练场,还能持续产出新题。
长程任务的训练数据供给。 Cross-WS 在模型训练类目上 +15.0、调试类目上 +10.0,这两个类目的共同点是”需要跨多个信息源做协调”。凡是涉及多仓库、多服务、多配置源的内部工程场景,都可以照搬”可写目标 + 只读参考”的挂载结构来合成任务,且不要求参考实现与目标是同一个项目。
模型能力边界的测绘。 Cross-WS 的教师 pass@1(72.3% → 49.2%)是一个便宜的能力探针:同一批环境、同一位教师,换一种任务组织方式就能测出能力断崖在哪。这个用法论文没提,但数据现成。
回归测试语料的自动生成。 验证器 agent 在容器内迭代编写 pytest 套件、直到能判定题面规定的公开接口与预期行为——这本身就是一个可独立取出的能力。重建出的 37.3k 个环境配上各自的验证器,是一份规模可观的”行为契约”语料。
参考文献
Wu, J., Zhang, Z., Zhang, B., Wang, X., Su, Y., Chen, M., Wang, P., Wang, Z., Shen, Q., Zhou, H., Yang, A., Huang, F., Yang, Y., & Liu, D. (2026). Terminal-Universe: Turning Agent Trajectories into Scalable Terminal Environments. arXiv:2609.04148 [cs.AI]. Qwen Team, Alibaba Group; Tsinghua University.
相关精读
本专栏连续四十三期追问同一个问题:轨迹数据到底该怎么用。
- 精读:DART-SD——用状态拓扑定位断点,只修补该修补的那一段:把标注单元从整条轨迹换成状态图上的子结构,问的是「监督信号打在哪个粒度」。
- 精读:SPADE——把环境设计本身变成可训练的组件:让模型自己生成环境,问的是「没有外部数据时题目从哪来」。
- 精读:OPSA——把教师从 on-policy 蒸馏里彻底移除:用控制实验剥离教师监督,问的是「题目有了,教师还省得掉吗」。
- 精读:Compile by Training——把提示词编译成本地权重:续篇。前四期问「拿什么练」,本篇问「练会的能不能固化下来不重复付费」,把大模型从运行时依赖降级为构建期依赖。
- 精读:One-Shot OPD —— 一条 query 够不够,取决于它走出多宽的状态:续篇。用状态覆盖率与吸收速率两把尺子证明,OPD 阶段数据量砍到全量的 1/17000 也基本不掉,绑定约束在优化器那一侧。
- 精读:OPD-then-RL——两阶段为什么打过单步融合:续篇。把 OPD 与 RLVR 从同一步内加权混合改成前后两阶段执行,逻辑推理 pass@1 领先七种联合方法 11.7–26.7 分,并用「教师天花板」解释联合方法为何集体卡在教师水平。
- 精读:Co-Evolving Harnesses and Models——同一份专家轨迹,换个脚手架符号就反过来:续篇。同一批专家轨迹在进化脚手架上是 −14.9 分、在未进化脚手架上是 +6.3 分,说明监督信号的价值不是信号自身的属性,而是信号与运行环境的联合属性;它给的处方是把纠正粒度从整条轨迹压到单轮。
- 精读:NSD 负向自蒸馏——不靠近看过答案的自己,只远离粗心的自己:续篇。把自蒸馏的目标函数翻成负号——推离「被提示成粗心解题者的自己」,全程不用金标也不用外部教师;纯噪声负条件在策略梯度设定下三个尺寸全部第一,说明起作用的是扰动本身而不是扰动的内容。
- 精读:E-SFT——只留推理轨迹的首尾,中间整段删掉:续篇。按位置删掉中间约 20% 的 token 再做 SFT,零额外算力胜过五种过滤基线;解码时再删 75%,精度只掉 0.02 分。
- 精读:TrimSFT——只让「中间那一段置信度」的 token 参与 SFT:续篇。用 gold token 与最强竞争者的 logit gap 做高斯带通加权,剪掉已掌握与学不会的两端;按其附录重算,真正与精度强相关的是「参与训练的 token 有多少」(R_eff 相关 −0.83),而不是权重曲线的形状。
- DataFlex-RL:13 种 RLVR 数据策略,没有一个跑赢均匀采样:续篇。前十一期默认了「挑对数据就有收益」,这一期在 RLVR 层次上问这个收益大到量得出来吗。
- 精读:把「做不出来」的题变成训练信号:续篇。数据选点推到端点——连一条 rollout 都做不对的题,用教师的部分推理轨迹装上难度旋钮照样榨得出梯度;按其 Table 2 重算,按题量加权后 MFC 对 GRPO 的领先只剩 0.78pp,每条 headline 优势都落在一个标准误以内。
- 精读:NGU 与 RL 里的马太效应
- 一条响应里只给三个位置价值监督:SP³O
- 精读:ActObs——把被 mask 掉的那 45% 观察 token 重新纳入损失:续篇。这十五期都在问「一条轨迹里哪些 token 配得上监督」,本篇按 token 的来源(动作 vs 环境)作答,代价为零而收益只有 1–3 道题。
- 精读:Score Centering——把训练-推理失配里的漂移项减掉
- 精读:把公开代码库里已实现的功能翻成 RL 环境
- 精读:按梯度可估性给 token 分配蒸馏监督
- 精读:给 token 级信用一个唯一解,然后把它求和掉
- 精读:把中间状态的价值估计整体消掉
- 精读:把后训练配方本身当成果,再逐阶段对账
- 精读:不跑 RL,先把新奖励的结果预测出来
- 精读:把特权信息从损失搬到采样器——多轮 agent 里自蒸馏为什么会崩
- 精读:把中间那一步的信号从模型里搬进环境——用沙箱回滚跑出免费过程奖励
- 精读:把 prompt 课程从「排难度」换成「排目标」——Fisher–Rao 弧长上的高斯课程 ARCUS
- 精读:SCAPO——用「扰动下不动」给 token 记一笔负账
- 精读:GMC-GRPO——把重要性比从逐条裁剪换成整组收缩
- 精读:把 off-policy 专家数据 MCMC 投影成 on-policy 数据
- 本篇给出第四种答案:轨迹不该被模仿,该被反演。前三期都在优化「怎么从轨迹里榨出监督」,这一期把映射方向掉了个头——从
环境 → 轨迹换成轨迹 → 环境,并用 Table 4 的那个 −10.3 分说明前三期共同的前提(轨迹本身是正资产)未必成立。 - 精读:CARM——把响应级掩码的判据从净位移换成双向漂移
- 精读:Mesh Learning——把 RLVR 的坍塌解释成策略容量的供需冲突
- 精读:跨分词器 OPD——把对齐覆盖度补满反而掉点
- 精读:SRD——把事后回顾蒸成事前先见
- 精读:ZCPO——把参考 KL 从损失支搬进组内系数
- 精读:Residual Advantage——让教师只重分信用,不改响应总分
- 精读:TAPO——把重要性比的记账区间从「当前 token」挪到前缀
- 精读:GPPO——把 PPO 的裁剪区间拆成「散度」与「估计器」两维
- 精读:RTI——把干预从优化期搬到采样期
- 精读:LVRL——把价值函数从「训出来的部件」换成「冻结的前沿 LLM」
- 精读:Thinking Leakage——no-think 的 RL 增益有多少是从 think 漏过来的
- 精读:Ares——把 RLVR 的更新秩交给梯度谱,账本落在截断之后
- 精读:GracefulRL——给退避一个中间价,代价是 74% 的题不再作答
- 精读:MRTPO——把每个奖励的优势拆回到它自己读的那几个 token 上