Terminal-Universe:轨迹回炉成环境,追不上没跑过的领域
轨迹堆积如山,后训练为什么还是缺数据?
如果把终端 agent 的每次工作都录下来,录像带已经堆成山了。一个 agent 在终端里跑任务,敲什么命令、读哪个文件、改哪几行、调什么工具,全被记成一条条轨迹。Qwen 团队这次用来做实验的公共轨迹池里有 359,593 条,够拍几十年的连续剧。可论文一开头就泼了盆冷水:数据多,不等于训练原料够。agent 后训练真正缺的,是环境(environment)。
一条轨迹只是单次冻结的演示(frozen demonstration)。它忠实记录了"某个 agent 当时是怎么做的",但仅此而已。它不能重放成新任务,不能在你解错时告诉你错在哪,更没法检验"另一种解法行不行"。环境恰恰相反。一个可执行环境是一台可以反复出题的机器:往里丢不同的任务,让它跑,用测试自动判对错,拿执行反馈当训练信号。同一条轨迹只能教一次,同一个环境能养出无数条高质量轨迹。下面是两者的对比:
| 维度 | 轨迹 | 环境 |
|---|---|---|
| 本质 | 单次执行的冻结演示 | 可反复运行的 workspace 加测试 |
| 复用性 | 一次性,看过就废 | 可再生,反复查询出新任务 |
| 反馈 | 无,只能模仿 | 执行反馈,可自动验证 |
| 对后训练的价值 | 低,质量受制于产出它的模型 | 高,能支撑验证驱动的训练 |
为什么这个区别现在才成为问题?因为终端 agent 的评测基准把"可执行环境"变成了硬通货。Terminal-Bench 2.1 的 89 个任务,每个都配齐 Docker 容器、人工写的指令和可执行测试,评分只看最终状态过不过测试。Terminal-Bench 2.1 的协议细节见 Terminal-Bench。EvoCode-Bench v2 则更进一步,26 个任务铺开成 227 轮多轮对话,工作区全程保留、验证器逐轮累计,考的是 agent 在需求不断演化时能不能不崩,协议见 EvoCode-Bench。这些基准全都在说同一件事:想让 agent 变强,就得有成批可验证的环境当训练场。
于是问题来了:环境这么好,为什么大家不去造?因为从零造一个环境贵得离谱。同样在给智能体生产训练环境的 SWE-Gym,为了 2,438 个实例花了约 200 人工小时外加一万 CPU 小时,见 SWE-Gym。手工配依赖、写测试、保证可复现,每一步都烧人力,这条路很难铺到十万级规模。
那有没有更便宜的路子?Terminal-Universe 的答案是:别从零造,去回收。海量轨迹里其实藏着一批环境的"底片",把它们冲洗出来就行。这就是论文的核心反转,全部内容见 Terminal-Universe。
轨迹是环境的底片:工具调用历史为什么能反推环境?
想想 agent 在终端里干活时都留下了什么。它要完成一个任务,几乎必然要读文件、写文件、编辑文件。读的时候,文件当前内容进了它的上下文;写和编辑的时候,改动前后的状态都被记录。换个角度看,这些工具调用其实就是环境的"反向投影":环境长什么样,决定了 agent 能读到什么、改到什么。既然投影是可逆的,那从轨迹反推环境就有了解。
论文最关键的观察就在这里:File Read、Write、Edit 这类工具调用,本身就暴露了它运行所在工作区的文件结构与内容。agent 不会凭空想象一个文件,它读到的每一行、改掉的每一处,都是环境真实存在的证据。所以重建不需要从零生成(generation),只需要把操作历史当成证据来重建(reconstruction)。前者是凭空造出一个世界,后者是根据线索还原一个已经存在过的世界,两者的工作量完全不是一个量级。
论文把这件事讲得很漂亮:一条轨迹和一个环境,是同一个 episode(回合)的两种视图。传统流程是先有环境,再让 agent 在里面跑,rollout(采样)出一条轨迹,这是从环境到轨迹。Terminal-Universe 把箭头掉了个头:从轨迹出发,recover(恢复)出它曾经运行过的那个环境。左边那条路是前人走的路,右边是这篇论文要走的路。

图注:论文总览图。左侧是两条方向相反的箭头:传统路线(Environment → Trajectory)先从环境采样出轨迹,本文路线(Trajectory → Environment)从轨迹恢复环境;中间是重建流水线的简化示意;右侧示意恢复出的环境可被三种方式重新查询。出处见 Terminal-Universe。
这个思路有个贴切的类比:轨迹是底片,环境是照片。底片不是照片本身,它只是记录光线分布的化学层;但只要有正确的冲洗工艺,底片就能还原出照片。轨迹也不是工作区本身,它只记录文件系统在某段时间里被怎么碰过;但只要有正确的重建工艺,就能把工作区冲洗出来。底片能还原出什么,取决于镜头拍到了什么;轨迹能重建出什么,取决于 agent 当时访问过什么。这正是后面所有步骤的边界所在。
可问题紧接着就来了:底片上只有镜头拍到的部分。agent 跑一个任务,通常只碰它需要改的那几个文件,项目里其余几十个文件它看都没看过。光靠轨迹,能冲洗出一个完整可用的工作区吗?论文的答案是:能,但不能只靠一步。
顺便说一句,这套"冲洗工艺"有个容易被忽略的前提:补全和判定这些精细活,都交给了另一个 LLM 去流水线化完成。也就是说,它不是一套纯手写的规则系统,而是"以模型补模型"的工业化装配线。
三步把底片冲洗成工作区:回放、补全、过滤
冲洗分三步走:确定性回放(deterministic replay)、智能体补全(agentic completion)、充分性过滤(sufficiency filter)。
第一步是回放。拿到一条轨迹,按时间顺序处理里面的文件操作,把每个被访问过的文件恢复到 agent 改动前的状态,把 agent 自己新建的文件排除掉,同时保留它的修改记录,因为这些修改之后要用来验证任务。这一步是确定性的,同一条轨迹永远得到同一个结果。但它只能还原 agent 碰过的那一小片世界,残缺是注定的。举个例子:假设 agent 在修一个 Python 项目的 bug,全程只改了 utils.py 和 config.py,回放就只能恢复出这两个文件改动前的版本,项目其余三四十个文件它碰都没碰过,自然也无从还原。

图注:论文整体框架。左侧是重建流水线:记录下的轨迹经 replay 和 completion 变成可执行 workspace,只有通过 sufficiency filter 的才会被保留;中间的 recovered workspace 是所有下游任务的共享底座;右侧是 Intent Recovery、Single-WS、Cross-WS、Multi-Round 四种重查询机制。出处见 Terminal-Universe。
残缺到什么程度,论文给了清点数字。只回放不补全时,Terminal 池里 38,294 个重建环境只有 40.2% 算得上 task-sufficient,也就是"够格支撑原任务";SWE 池的 1,900 个仓库更惨,只有 20.1%。换句话说,纯回放出来的工作区,六成以上根本没法用。这也解释了为什么必须有第二步。
第二步是补全。一个补全 agent 上场,把缺失的文件、残缺的部分、没配好的依赖补齐,让工作区从"能看"变成"能跑"。但这里有一条红线:补全可以补上下文,绝不许泄露答案。补全 agent 的任务是补足项目结构和依赖,让任务变得可解,而不是替未来的 solver 把答案写出来。如果补全顺手把解法也补上了,那这些数据训练出来的模型,学的就不是"如何解题",而是"如何背答案"。
补全的效果立竿见影:Terminal 池的 sufficient 比例从 40.2% 跳到 93.5%,SWE 池从 20.1% 跳到 77.1%。工作区的体量也说明问题,见下图:

图注:补全前后工作区规模对比。Terminal 池(左)的 mean files 从 2.9 涨到 22.4,文本行数从 mean 90 涨到 5,761;SWE 池(右)同构,mean files 从 5.6 涨到 37.9。出处见 Terminal-Universe。回放只能给出 agent 碰过的零星文件,补全才把工作区撑成能跑的项目。
第三步是过滤。补全过的环境也不是都能用,需要一个 agentic judge 用只读工具检查每个工作区,判定它是否 task-sufficient。只有通过检查的环境才进入下游。整个漏斗走到这里,从最初的轨迹里重建出的 68,263 个环境,最终剩下 37,273 个够格的。这三步拼起来,就是把"底片"真正冲洗成可用"照片"的工艺。
环境有了,下一步自然是:怎么让每个环境生出尽可能多的任务?
一个环境能变出多少任务:四种重查询与两条缩放轴
回顾上一章的框架图:中间那条 recovered workspace 总线,是所有下游任务的起点。论文在它上面挂了四种重查询(re-querying)机制,沿着两条互补的轴扩展:广度上跨工作区合成,深度上做多轮对话。
最基础的一种叫 Intent Recovery(意图恢复),它不做新题,而是把轨迹里那个原始任务"找回来"。单轮轨迹通常只有一个实质请求,直接归一化成一个自含任务;多轮轨迹则取首个请求定主题,把后续澄清、约束、扩展的请求合并进来,无关请求剔除。这一步的意义在于:它产出的任务描述是干净的、自足的,而不是散落在对话里的碎片。更重要的是,论文会在重建好的环境上,让一个更强的 teacher 模型重新求解这个任务,得到的轨迹质量远超原轨迹,这点第五章会详细展开。
第二种是 Single-WS(单工作区合成)。一个离线生成器在每个恢复出的工作区上提 5 个候选任务,按是否扎根于工作区、结构是否多样、能否被验证来筛选,最后每个环境随机挑 1 个用于 rollout。它问的问题是:这个代码库里还能派什么新活?答案不会凭空出现,每个候选都要能被这个环境的测试验明真伪。
第三种是 Cross-WS 合成,也就是广度轴。先给每个工作区建 profile,刻画它的技术域和实现能力;再用 TF-IDF 在 profile 之间找候选对;最后由 LLM judge 确认是否存在"方向性依赖",即参考工作区具备、而目标工作区缺失的功能。确认后,参考工作区被只读挂载到独立路径,solver 必须自己导航过去、读懂实现、再回来适配。这模拟的正是开发者跨代码库改接口的真实场景,也解释了为什么这类轨迹明显更难:turns 从 14 涨到 23,tool calls 从 20 涨到 38,连 teacher 自己的 pass@1 都从 72.3% 掉到 49.2%。
第四种是 Multi-Round 合成,也就是深度轴。它让一个 user agent 扮演用户,维护一张需求追踪表,把单轮查询拉长成一场多轮会话。每一轮先提交更新后的规格,由 verifier agent 在容器里写本轮的 acceptance tests,再让 coding agent 执行,测试同时覆盖新增标准和历史需求的回归。三种交互样式让需求自然演化:功能扩展、修复失败的功能、需求冲突。比如用户先让 agent 修一个崩溃 bug,修复验证通过后又追加日志需求,下一轮再要求改动输出格式,需求的演化路径由测试动态把关。最多 6 轮,中途的失败会留在对话历史里,成为后续轮次的 recovery supervision。持久工作区加累计验证器这套设计,在多轮评测里已经流行了好几年,InterCode 等基准早就验证过这种模式的可行性,见 InterCode。Terminal-Universe 的贡献,是把这套评测范式搬到了训练侧。
四种机制跑完,数据漏斗就成型了:37,273 个够格环境,经过四路重查询和 verifier 逐条把关,最后留下 31,977 条 SFT 记录,约 1.42B tokens。看每条记录的长度分布就能明白两条轴各自补了什么:Intent Recovery 的记录中位 12 轮、36.1k tokens,Single-WS 是 14 轮、30.4k,Cross-WS 拉长到 23 轮、46.5k,而 Multi-Round 直接到 92 轮、126.1k tokens。深度轴产出的不是"更长的单轮",而是真正跨多轮、带状态延续的长程任务,见 Terminal-Universe。 两条轴也不是装饰:广度轴上,Single-WS 数据单独训出 56.4 分,混合进 Cross-WS 后涨到 58.4;深度轴上,Multi-Round 把 EvoCode-Bench v2 的 MT@4 从 18.4 推到 21.0。每条轴都实打实地贡献了分数。这批数据训出来的模型,到底值不值?下一章看结果。
3.2 万条重建数据让两个评测齐涨,功劳却不在模仿轨迹
先看这批数据是怎么筛出来的:
数据漏斗:从 359,593 条公共轨迹出发,重建出 68,263 个环境,其中 37,273 个通过充分性过滤,最终经四种重查询加 verifier 筛选,得到 31,977 条 SFT 记录。其中 Single-WS 贡献 25,386 条,Cross-WS 3,512 条,Multi-Round 3,079 条。出处见 Terminal-Universe。
用这批数据对 Qwen3.5-27B 做 SFT,结果在主结果表里:
| 评测基准 | 基座模型 | Terminal-Universe-27B | 提升 |
|---|---|---|---|
| Terminal-Bench 2.0 | 41.6 | 52.8 | +11.2 |
| Terminal-Bench 2.1 | 46.2 | 58.1 | +11.9 |
| EvoCode-Bench v2 MT@4 | 6.3 | 20.1 | +13.8 |
| EvoCode-Bench v2 Case | 67.8 | 76.1 | +8.3 |
单轮评测提升了十来个点,多轮评测的 MT@4 更是从 6.3 翻了三个跟头到 20.1。多轮那栏尤其值得一提:EvoCode-Bench v2 的 227 轮是持久工作区加 fail-stop 记分,任何一轮掉链子之前的努力都可能白费,能涨这么多说明模型真的学会了在多轮需求演化里撑住。换个说法,单轮评测考的是"这道题会不会做",多轮评测考的是"需求变了三轮之后,你还记不记得前面改过什么"。后一种能力最难靠模仿轨迹获得,因为大部分公开轨迹都是单轮任务留下的,而 Multi-Round 合成专门补上了这个缺口。
但光看总分还不够,论文里最反直觉的一张消融表才是重点。同样是 35.8k 条记录、同样规模的数据:一组直接拿源轨迹做 SFT,让模型模仿原 agent 的动作;另一组用 Intent Recovery 在重建环境上让更强的 teacher 重新求解。结果在 Terminal-Bench 2.1 上,模仿源轨迹只有 36.7,重新求解达到 52.1,差了整整 15.4 分。这说明涨分根本不来自"模仿轨迹",而来自"在可验证环境上重新解题"。直接模仿会把原 agent 的犹豫、绕路和错误一起学进去;重新求解则让模型面对完整可验证的环境,自己找出正确答案,再由 verifier 把关。轨迹只是起点,真正值钱的,是重建之后那个能反复验证的世界。
另外两个消融把这条逻辑补完整:agentic completion 这一步单独值 4.2 分(48.7 到 52.9),还把多次运行的方差从 ±3.5 收窄到 ±1.4,说明补全不仅提分还让训练更稳;verifier 过滤在更难合成的 Cross-WS 数据上贡献 2.2 分(53.2 到 55.4)。把 budget 花在恢复更多环境上,比在同一批环境里多出题、多解几遍划算得多。这正好回到论文的出发点:环境才是稀缺资源,轨迹只是原料。
还有个细节值得说:这些轨迹不是哪个团队的私有财产。终端侧的 159,552 条来自 LFM2-Terminal 与 LiteCoder-Terminal,软件工程侧的 199,041 条来自 SWE-rebench、SWE-smith、CoderForge 和 SWE-Gym 等公开数据集,见 Terminal-Universe。也就是说,这套"回炉"工艺吃的是公开原料,谁都能复现。更有意思的是,从 1,900 个 SWE 仓库重建出的 Intent Recovery 数据(10.3k 条)也能迁移到终端任务上,Terminal-Bench 2.1 平均分从 47.0 涨到 50.0,说明"环境化的任务"带来的能力是可以跨域迁移的,见 Terminal-Universe。这比单点涨分更有说服力,它说明学到的是泛化能力,不是背题。
它在环境合成版图上的坐标,和造不出的那部分世界
"怎么给 agent 批量生产可执行环境"这个赛道,这两年已经挤满了选手,但走法各不相同:
| 路线 | 代表工作 | 规模 | 一句话特征 |
|---|---|---|---|
| repository-based | SWE-Gym | 2,438 实例 / 11 仓库 | 从真实 issue 出发,人工配环境 |
| perturbation | SWE-smith | 50,137 实例 / 128 仓库 | 先建环境,再自动往代码里注入 bug |
| procedural-from-commits | R2E-Gym | 8,135 任务 / 13 仓库 | 从 commit 反推问题陈述 |
| procedural-RL | Endless Terminals | 3,255 任务 | 程序化生成任务、容器与测试 |
| taxonomy-guided | CLI-Universe | 6,000 条轨迹 | 用能力分类学引导任务合成 |
| recursive evolution | RST | 37,484 任务 | 从已验证种子任务递归拉长 |
| trajectory reconstruction | Terminal-Universe | 37,273 个环境 | 从轨迹反推环境再出题 |
手工搭环境(SWE-Gym)贵到只能覆盖 11 个仓库。注入 bug 的 SWE-smith 虽然能冲到 5 万个实例,但环境本身还是人造的。从 commit 反推的 R2E-Gym、程序化生成的 Endless Terminals、分类学引导的 CLI-Universe、递归演化的 RST 也都各自卡在不同环节。Terminal-Universe 的独特位置在于:它是唯一同时具备轨迹重建、跨工作区合成和多轮合成三项能力的工作。最干净的对照组是 RST,两家都用 Qwen3.5-27B 训练、都在 Terminal-Bench 2.0 上评测,RST 拿 49.4,Terminal-Universe 拿 52.8,轨迹反推这条路并不输给递归合成。
但论文自己也交代了三道边界,每一道都呼应标题里的半句话"追不上没跑过的领域"。
第一,所有工作区都跑在标准 Ubuntu 24.04 容器里,不走 SWE-Factory、RepoLaunch 这类自动化环境构建,遇到特殊系统依赖和复杂编译步骤,保真度有限。第二,重建出的世界被源轨迹的覆盖度锁死:轨迹里没有的领域、语言、工具链,一个都造不出来。轨迹池里 Python 的轨迹堆成山,冷门语言和专用工具链就是空白,这不是工艺能补的,是原料本身没有。第三,同一个 teacher 既出题又解题又写 verifier,能力上限同时决定覆盖度和自查能力,模型自己验证器抓不住的错,就会漏进训练数据。
所以这套方法真正的边界,不是工艺不够好,而是原料本身的边界:它能回收的世界,只到人类 agent 曾经跑过的地方为止。反过来想,这也给下一批工作指了路:多 teacher 加独立 verifier,把"出题、解题、批改"三个角色拆开互相制衡,或者把回收的触角伸向更偏的领域。轨迹不是废料,而是可以回收的世界,回收半径恰好等于 agent 走过的路。
想深入可以读原文:Terminal-Universe: Turning Agent Trajectories into Scalable Terminal Environments,arXiv:2609.04148。
参考文献
- Terminal-Universe: Turning Agent Trajectories into Scalable Terminal Environments,Qwen Team 与清华大学,arXiv:2609.04148,https://arxiv.org/abs/2609.04148
- Terminal-Bench: Benchmarking Agents on Hard, Realistic Tasks in Command Line Interfaces,Merrill 等,arXiv:2601.11868,https://arxiv.org/abs/2601.11868
- EvoCode-Bench: Evaluating Coding Agents in Multi-Turn Iterative Interactions,Shen 等,arXiv:2605.24110,https://arxiv.org/abs/2605.24110
- InterCode: Interactive Code Generation as a Reinforcement Learning Environment(及 SWE-INTERACT、SWE-Together、ICAE-Bench 等多轮评测前驱),Yang 等,arXiv:2306.14898,https://arxiv.org/abs/2306.14898
- Training Software Engineering Agents and Verifiers with SWE-Gym,Pan 等,arXiv:2412.21139,https://arxiv.org/abs/2412.21139
- SWE-smith: Scaling Data for Software Engineering Agents,Yang 等,arXiv:2504.21798,https://arxiv.org/abs/2504.21798
- R2E-Gym: Procedural Environments and Hybrid Verifiers for Scaling Open-Weights SWE Agents,Jain 等,arXiv:2504.07164,https://arxiv.org/abs/2504.07164
- Endless Terminals: Scaling RL Environments for Terminal Agents,Gandhi 等,arXiv:2601.16443,https://arxiv.org/abs/2601.16443
- CLI-Universe: Towards Verifiable Task Synthesis Engine for Terminal Agents,Hua 等,arXiv:2606.22883,https://arxiv.org/abs/2606.22883
- Recursive Synthesis for Long-Horizon Terminal Tasks (RST),Li 等,arXiv:2608.05466,https://arxiv.org/abs/2608.05466