OpenThoughts-Agent:
训练 Agent 模型的数据「配方」
前沿 agentic 模型几乎从不公开训练数据。这篇工作用 100+ 受控消融实验,把「怎么造 agent 训练数据」这件黑盒拆成一条完全开源、逐环节可复现的流水线。
- 问题:模型权重越来越开放,但「用什么数据训练 agent」几乎全是黑盒——已有开源努力(SWE-Smith、SERA、Nemotron-Terminal)又各自只盯一个 benchmark。
- 做法:设计一条六阶段的 SFT 数据流水线,对每个环节独立做消融(共 100+ 次实验),找出真正影响下游表现的因素,再组装出 10 万条 SOTA 训练集。
- 结果:用它微调 Qwen3-32B,在 SWE-Bench Verified 上达 54.0%、Terminal-Bench 2.0 达 26.2%,7 个 benchmark 平均 44.8%,且在每一个数据规模上都优于其他开源数据集(算力对齐比较)。
- 洞察:RL 阶段中,数据源的「形状」决定了模型学会「更彻底地探索」还是「更高效地压缩」——而不是 reward hacking。
Agent 的训练数据,是一个黑盒
新一代 agentic 语言模型不再只是回答问题,而是能像人一样操作计算机、长链条地使用工具——Claude Code、Codex 这类应用因此爆发。但要把模型训成「广泛能干」的 agent,训练数据怎么造是关键,而公开文献里几乎找不到答案。
开源社区已有一些尝试,但都有同一个局限:各自只针对单一 benchmark,无法回答「如何训练一个能跨多种 agentic 任务泛化的模型」。
- SWE-Smith / OpenSWE:聚焦 SWE-Bench 式的 GitHub issue 解决。
- Nemotron-Terminal:聚焦 Terminal-Bench 式的终端任务。
- 共同问题:几乎都只做 SFT 或 只做 RL,很少研究两个阶段如何交互;也极少在多个 benchmark 上验证泛化。
OpenThoughts-Agent(OT-Agent)正是为填补这个缺口而生:它把目标从「刷某一个 benchmark」改成「跨多个 agentic benchmark 泛化」,并把数据流水线、实验数据、训练集和模型全部开源。
100+ 次消融,浓缩成 4 条结论
在拆解每个环节之前,先看作者从全部实验里提炼出的四条「punchline」。它们既是后文流水线设计的依据,也是最值得记住的经验。点击展开看细节。
六阶段 SFT 数据流水线
本文最核心的贡献是这条六阶段流水线:从采集任务、混合、过滤,到用 teacher 生成 agent 轨迹、再过滤轨迹。每个阶段都被独立消融,挑出最优策略后固定下来,再优化下一阶段。
- Source Tasks(采集任务):从各种初始源收集任务描述(合成的 GitHub issue、人写的 Linux/加密货币问题等),这是「指令」的来源。
- Mix Tasks(混合任务):把排名靠前的多个任务源按比例混合,避免只在单一 benchmark 上过度专化。
- Filter Tasks(过滤任务):用 LLM 等过滤器剔除低质量任务,保留更有训练价值的难题。
- Generate Rollouts(生成轨迹):让 teacher 模型在沙盒里真正去解这些任务,产生 (任务, 轨迹) 训练对。
- Filter Rollouts(过滤轨迹):启发式剔除超时、subagent、过短(<5 轮)的轨迹,保留高质量多轮监督。
- Select Teacher(选择老师):消融不同 teacher 对下游的影响,定下生成轨迹的最佳模型。
- 选择标准:每个阶段独立消融,用三个核心 benchmark 准确率的平均 z-score 排名(各自减均值、除标准差再平均),让三个 benchmark 等权,不被数值范围差异带偏。
- 实验规模:每个策略生成
10,000条轨迹,全参微调 Qwen3-8B(lr 4e-5 cosine,batch 96,7 epoch,32,768 上下文);每次约160 GPU-hours(GH200),可并行跑数十个消融。 - 核心 benchmark:OT-TBLite(100 题)、SWE-Bench Verified-100、Terminal-Bench 2.0(89 题),均在 terminus-2 harness + Daytona 沙盒中跑,每题重复 3 次。
- 留出泛化集:Aider Polyglot、BFCL、MedAgentBench、GAIA、FinanceAgent-Terminal——只在流水线实验全部完成后测一次,检验真实泛化。
逐阶段看:每一步测了什么、谁赢了
下面这个交互组件按流水线顺序展开每个阶段的消融结论。点击阶段,或用「下一步」逐步阅读。
① 采集任务 · Sourcing Tasks
② 混合任务 · Mixing Tasks
10000/N 条任务。③ 增广任务 · Task Augmentation
④ 过滤任务 · Filtering Tasks
⑤ 选择老师 · Teacher Model
⑥ 过滤轨迹 · Filtering Agent Rollouts
从 10K 到 100K:多样性才是瓶颈
消融定稿的流水线只产出 10K 数据。要继续放大规模,有四条朴素的路:
- 方法 1:同样的任务描述,每个任务多生成几条 rollout(最简单的 upsample)。
- 方法 2:从原始源取更多任务描述——但受限于源本身(例如 Tezos 只有 997 个不重复任务)。
- 方法 3:用合成增广创造新的任务描述。
- 方法 4:引入更多初始源。
实验给出了清晰的答案:方法 1 会很快撞墙。从 31.6K 到 100K,纯 upsample 几乎不再带来提升(SWE-Bench +3pp、TB2.0 −2pp,都在标准误内)——这说明真正的瓶颈是任务描述的多样性,而不是轨迹数量。而 方法 3(合成增广)能突破这道墙,在三个 benchmark 上持续上升。
- 三张子图分别是 SWE-bench Verified (100)、OT-TBLite、Terminal-Bench 2.0;横轴是数据集规模(10K → 100K,对数刻度),纵轴是准确率。
- 粉色线 = 方法 1(upsample rollouts):到 31.6K 后明显平台化,在 OT-TBLite 和 TB2.0 上甚至在 100K 处掉头向下——多生成轨迹无法补偿任务多样性的缺失。
- 蓝色线 = 方法 3(synthetic augmentation):三张图里都单调上升到 100K,在 SWE-bench 上达约 0.557、TB2.0 上达约 0.262。
- 两线在 10K / 31.6K 处几乎重合:因为它们共享同一个 10K 基座,差异只在「如何超越 10K」时才显现。
那直接加更多源(方法 4)行不行?也不行:在 100K 规模下,Top-8 并不稳定优于 Top-4,而扩到 Top-16 在每个 benchmark 上都更差。所以作者保留 Top-4 源不变。
| 源混合(100K 规模, 32B) | SWE-Bench Verified-100 | OT-TBLite | Terminal-Bench 2.0 |
|---|---|---|---|
| Top-4(保留) | 45.33 | 36.90 | 21.72 |
| Top-8 | 49.00 | 38.87 | 22.85 |
| Top-16 | 40.33 | 33.14 | 20.60 |
最终的合成增广做法很巧妙:把贡献最少的 Tezos(997 个不重复任务)替换成它的增广版本——用第③步的改写策略把约 902 种表面形式扩展到 2 万多种,不引入任何新的底层问题;再用 gpt-5-nano 的回答长度作为上采样权重(而非硬性 top-k 过滤),保证每个独特任务至少有一条 rollout。这样既保住任务覆盖度,又突破了多样性瓶颈。
- 最左列 = 四个源数据集:SWE-Smith(9,998)、Issue Tasks(4,830)、StackExchange SuperUser(12,817)、StackExchange Tezos(997 个唯一任务 × 11 倍增广)。
- Weighted Upsample(加权上采样):按 gpt-5-nano 回答长度给每个任务分配 rollout 数量,难任务获得更多采样。
- Generate Traces(生成轨迹):用 GLM-4.7-AWQ 作为 teacher 在沙盒中真正解题,产生 agent 轨迹。
- Filter Rollouts(过滤轨迹):统一施加「≥5 轮」过滤,剔除过短 / 超时轨迹(图中分叉处的小损耗)。
- Final Mix(最终混合):四条流最终汇成约 25,000 / 25,000 / 22,848 / 21,486 条,合计约 9.4 万条,构成 v2 数据集。
在 100K 规模,32B SFT 模型达到 SWE-Bench Verified-100 55.7%、OT-TBLite 41.3%、Terminal-Bench 2.0 26.2%,相比 31.6K 单调提升了 +7.7pp(SWE-Bench-100)和 +5.0pp(TB2.0)。
不只是「数据多」,而是每个规模都更强
用最终数据集微调 Qwen3-32B 得到 OpenThinker-Agent-32B,它是同等规模(≤32B、Qwen3 系或更早 base)下、用开源数据训练的最强 agent 模型。更重要的是 Figure 1 揭示的scaling 趋势。
- 三张子图:SWE-Bench Verified (100)、Terminal-Bench 2.0、All Average;横轴是数据规模(316 → 100K),纵轴是准确率。
- 红色加粗线 = OT-Agent Qwen3-32B:在三张图里几乎都位于最上方,且随规模持续上升,100K 处在 All Average 上达约 45%。
- 对比对象:Nemotron-Terminal-Corpus(蓝/青)、SERA 的多种 harness 变体(紫色虚线/点线)、以及 OT-Agent 自己的 8B 版本(橙色)。
- 两条水平虚线:是 Qwen3-8B / 32B 的 base 模型基线——所有数据配方都远高于未训练的 base。
- 关键读法:同一条竖直线(同一数据规模)上,红线几乎总在最高处 → 这就是「compute-controlled 下每个规模都更强」的含义。
| 模型(≤32B, 开源数据) | SWE-Bench Verified | Terminal-Bench 2.0 | 7-benchmark 平均 |
|---|---|---|---|
| OpenThinker-Agent-32B(本文) | 54.0% | 26.2% | 44.8% |
| Nemotron-Terminal-32B(此前最强) | 41.9% | 25.1% | 40.9% |
除了 SWE-Bench 和 Terminal-Bench,OT-Agent 在 Aider Polyglot、BFCL-Parity、GAIA-127、FinanceAgent-Terminal 等更多 agentic benchmark 上也优于此前工作——这正是「跨任务泛化」目标的体现。
RL 阶段:数据源同样决定一切
除了 SFT,作者也研究了 RL 的数据。为控制算力,RL 实验集中在 8B 规模:用 RLOO 算法、基于 verifier 成功与否的二元奖励(所有测试 expect PASS 即 PASS、expect FAIL 即 FAIL),从一个冷启动 SFT checkpoint(OT-Agent-ColdSFT,在 SWE-Smith 轨迹上蒸馏)出发。「hero run」用 24×A100 80GB、batch 64、约 46 小时训练。
和 SFT 一样,他们做了受控的数据源消融——只换训练数据、其余完全不变。结果:六个 RL 数据源的原始平均准确率相差 7.6 个点,远大于 2.0 点的 run-to-run 波动。
最强的源是 pymethods2test:把 Codeforces / CodeChef / TopCoder 风格的竞赛题,重写成单函数 Python 契约——配上 docstring 式描述和自动生成的单元测试。它没有多文件编辑、没有仓库导航、没有跨轮的 shell 状态累积;参考解约 20 行、描述约 200 词。这让它高度可复现、高度可用,且难度天花板适中。
一个有意思的现象是 ID / OOD 解耦:强调单函数代码正确性的数据源(inferredbugs、code-contests)在 ID(同分布)上领先,而更异质的工具使用数据(llm-verifier-freelancer、nl2bash)在 OOD 上有竞争力但 ID 较弱——只有 pymethods2test 同时位居两者之首。
完整的两阶段后训练(SFT + RL)在两个核心 benchmark 和整体平均上都超过基线,相比 Qwen3-8B base 平均提升 18 个点,并超过最强的 ≤8B 基线。一个反直觉的发现:「欠训练」的 SFT 模型反而从 RL 中获益更多——选 SFT checkpoint 时要「为 RL 着想」,而表现很差的 Qwen3-8B base 则根本无法从 agentic RL 中受益。
RL 到底学到了什么?探索 vs 压缩
论文最精彩的部分(附录 F)回答了一个「为什么」:pymethods2test 为什么是最强 RL 源?作者用三种视角(时间分箱的行为统计、前后 checkpoint 的逐轨迹差异、GPT-5 成对裁判)做了机制级分析,得到一个干净的对照——同一套 RL 流程,在不同数据源上会把模型推向相反的方向。
- 思考 token +116%(30.3 → 65.4)
- 自我纠正短语 +81%(0.63 → 1.14)
- 工具调用 +31%(31.3 → 40.9)
- 对话多 12.9 轮(token +29%)
- 裁判偏好 post-RL 25/30(83.3%)
- 思考 token −42%
- 自我纠正 −59%(19.7 → 8.0)
- 工具调用 −8%
- 对话少 7.8 轮
- 裁判偏好 post-RL 22/30(但都是「更短/更少」标签)
为什么是这样?关键在 RL 期间的奖励轨迹。pymethods2test 给出一个中等、不饱和、且难以提升的奖励(在 0.47–0.51 之间徘徊,远离天花板)。在 RLOO 下,这恰恰是「鼓励更努力」的区间——想多拿一点回报,只能想得更多、调用更多工具、尝试更多修复。而 llm-verifier-freelancer 的奖励几乎单调上升(0.54 → 0.73),策略于是学会「少废话、快交付」。
- 蓝线:4 小时分箱的平均奖励,先缓升到约 0.51 的峰值,再急转直下到约 0.13——此时模型「过度探索」,轮数和思考 token 飙升、有效工具调用下降,agent 超时率达约 80%。
- 右侧标记:菱形 = post-RL eval、方块 = pre-RL base 在留出 SWE-Bench-Verified 上的奖励。
- 关键操作:部署的 checkpoint 取自崩溃之前,它把 base 的 eval 奖励翻倍(0.33 vs 0.19)。
- 蓝线:奖励从约 0.54 平滑升到约 0.73,没有崩溃段(点聚在时间轴右侧,因为 pre-RL base eval 早于训练数月)。
- 对应行为:策略一路压缩(更少轮数、工具调用、思考 token),而不是扩张——和 hero run 每个行为维度都相反。
- 代价:压缩利好它自己的 OOD eval(FinanceAgent 上 0.224 vs 0.173),但向偏好「彻底性」的 ID Core benchmark 迁移更弱。
那这会不会只是 reward hacking(钻奖励空子)?作者给出三条反驳:
- 模型发出更多工具调用的同时也产生更多出错的调用(5.9 → 8.8,+48%)——这与「为了骗过脆弱解析器」的行为恰好相反。
- 每次调用的出错率只上升了 4.1pp(31.6% → 35.8%):多出来的错误主要因为调用变多,而非工具使用能力退化。
mark_task_complete调用占比反而上升(1.9% → 3.0%),与「学会提前结束以收割格式奖励」的假设不符。
行为扩张最终转化为留出集上的真实收益:在 100 道共享的 SWE-Bench-Verified 任务上,RL 让 18 道从失败翻转为通过,仅 1 例回退。
一份可复现的开源「配方」
OpenThoughts-Agent 通过对六阶段 SFT 流水线的受控消融,加上对 agentic RL 数据的专门研究,得到 OpenThoughts-Agent-v2 数据集,把 Qwen3-32B 训成 OpenThinker-Agent-32B——在软件工程、终端使用、工具调用、医疗、金融、通用助手等七个 agentic benchmark 的平均上,是最强的开源数据 ≤32B 模型。在 8B 规模,SFT 数据 + pymethods2test RL 数据进一步组合,超过最强 ≤8B 基线,初步证明SFT 与 RL 两个阶段可以被设计成相互配合。
作者也坦诚了局限,这些恰恰勾出了后续值得做的方向:
- RL 只在 8B 做:受算力限制,同样的 RL 配方能否迁移到 32B 仍是开放问题。
- 未消融 base 模型:所有 SFT 都从 Qwen3 系起步,base 预训练对最终表现的贡献没有被单独剥离。
- 规模上限 100K:这些趋势能否外推到百万级轨迹规模,尚未验证。
全部数据、流水线与模型已在 openthoughts.ai 开放——这正是这篇工作的意义:把「怎么造 agent 训练数据」从黑盒变成社区可以共同迭代的公共资产。