从0训练LLM · 现代大模型体系 阅读 + 实验 ≈ 35 分钟 页内实验 ×4
C12 后训练:从续写到听话、推理、做事 第 8 课

从答题到做事:多轮调用工具、看环境反馈,怎么训?

Agentic RL:从答题到做事
修一个 bug 要读文件、跑测试、改代码、再跑测试。用 SFT 模仿这样的轨迹,格式学得会,修得对的却不多;在环境里做多轮 RL,奖励直接来自「测试过没过」。新问题随之而来:工具返回的 token 不能训、一组全失败就没有梯度、最慢的那条轨迹拖住整批。这一课用 Agent 课的真实运行记录把这三件事算出来,然后把模型交给 Agent 课。
❓

本课一问:前七课的模型都在「答题」:一个问题,一段回答,一个分数。可修一个 bug 要读文件、跑测试、改代码、再跑测试,几十步,每一步都要看环境的反馈。这种「做事」的能力怎么训?

这一课先不碰:agent 的循环、工具、权限、上下文管理怎么搭(Agent 课 A1–A9);这一课只讲模型这一侧:这样的轨迹怎么变成训练信号。

从已有出发,换一个例子

从已有出发 · 后训练流水线 点已学的站看数据、损失与模型数

为什么这里换例子:「苹果在谁手里」是单轮问答,没有环境、没有工具返回,讲不出多轮 RL 的难处。这一课改用 Agent 课的贯穿任务——让失败的 test_parse_date 通过,数据来自 Agent 课项目的真实运行记录(Qwen3-8B 在本机修 bug,成败由测试判定)。

一条带工具调用的轨迹,套上 Qwen3.8 官方模板长这样(内容按 Agent 课的任务手写,token 由真 tokenizer 现算):

这条两轮的轨迹共 443 个 token,模型真正写出来的只有 73 个(思考、工具调用、最后的回答、两个结束符);工具返回的 42 个 token 夹在 user 角色里,系统提示和工具说明占了 296 个。工具调用也只是 token:<tool_call> 是词表里的一个特殊 token(id 248058),模型写出一段 <function=run_tests> 格式的文字,由外面的程序去解析、执行。

演进图 · 每一代都是被上一代的失败逼出来的本课高亮
  1. 第一代 SFT:用示范教格式 FLAN 2021 · LIMA 2023
  2. 第二代 RLHF:奖励模型 + PPO Christiano 2017 → Ziegler 2019 → InstructGPT 2022
  3. 第三代 · 离线 DPO:不训奖励模型 Rafailov et al. 2023(Stanford)
  4. 第三代 · 在线 GRPO 系:去掉 value model DeepSeekMath 2024-02 → DAPO / Dr. GRPO / GSPO 2025
  5. 奖励来源 RLVR:可验证的奖励 Tülu 3 2024-11 命名 · DeepSeek-R1 2025-01 规模化
  6. 岔路 RL 扩展了能力,还是重排? Yue 2025 vs ProRL 2025
  7. 第四代 思考模型:想更久,也能控 o1 2024-09 · R1 2025-01 · Qwen3 2025-05
  8. 第五代 蒸馏:小模型直接继承 Hinton 2015 → GKD 2023 → Qwen3 2025
  9. 第六代 Agentic RL:在环境里做事 SWE-RL 2025-02 · Kimi K2 · GLM-4.5 slime · DeepSeek-V3.2 你在这里
    解决了奖励来自环境本身(测试过没过);Llama3-SWE-RL-70B 在 SWE-bench Verified 上 41.0%。
    卡在→ 交接 Agent 课:模型吐出一段「调用工具」的文字,然后呢?

先自己设计:用 SFT 模仿工具调用轨迹

最直接的做法:收集(或用强模型合成)一批成功的工具调用轨迹,拿来做 SFT。这正是 ReAct、Toolformer 之后很多工作的起点。

  1. ① 朴素方案
  2. ② 它在哪失败
  3. ③ 改进方案
朴素方案SFT 模仿修 bug 的轨迹
SWE-bench Verified(SWE-RL 表 2 与表 3)格式正确给定正确文件时修对端到端(Agentless Mini)
Llama-3.3-70B-Instruct12.2%5.4—
Llama3-SWE-SFT-70B(SFT)96.2%29.636.2
Llama3-SWE-RL-70B(RL)95.6%34.841.0

SFT 把格式教会了,修 bug 的能力提升有限;只学成功的样子,模型没见过「出错之后怎么办」,环境反馈也进不了训练。

改进:在环境里做多轮 RL,奖励来自环境本身

把模型放进一个真实的沙箱:它读文件、跑命令、改代码,最后由 harness 跑测试给一个 0 或 1。这一个数就是整条轨迹的奖励。下面是 Agent 课项目的一次真实运行,拆成「模型写的」和「送进去的上下文」:

🎯

试三件事:① 看 leapyear-s1(通过):5 轮,模型一共写了 2,846 个 token,这些是 RL 要训的,唯一的奖励是最后测试通过的那个 1;② 看第 1 轮和第 2 轮的上下文:只多了 40 个 token,可第 1 轮模型写了 691 个——Qwen3 的模板不把历史轮的思考带进下一轮,训练时喂给模型的上下文必须和它当时真正看到的一致;③ 换成 pd-nothink-s1(关闭思考):前几轮每轮只写二三十个 token,很快就「完成」了,但测试没过。

这和单轮 RL 有三处实质不同:

  1. 只训模型写的 token。工具返回、环境输出不是策略生成的,拿它们算 loss 等于让模型去预测环境——和 SFT 里「不在用户的话上算 loss」是同一个道理,只是这里更要紧:工具输出可能很长,还会随环境变化。
  2. 一条轨迹一个奖励,信用分配更难。几千个 token、十几次工具调用,只拿到最后一个 0 / 1;哪一步出了错,奖励不知道。
  3. rollout 又长又不齐。一条轨迹要跑几分钟、要真的执行命令;同一批里有的一分钟结束,有的跑十几分钟。

后两点,Agent 课项目的真实运行正好能各算一次。

新失败 ①:同一任务全失败,一组白跑

同一任务、同一配置、不同种子的几次运行,就是一个 GRPO 组:

pd-unlimited 这一组 3 次运行全部失败,组内标准差为 0,三条轨迹的优势全是 0——几分钟的 rollout 全部白跑,这就是第 4 课的零方差组。换成 pd-v2-unlimited(改了系统提示):3 次里成功 2 次,奖励 [0, 1, 1],优势 −1.414、+0.707、+0.707。任务太难时一组全错、太容易时一组全对,任务的难度要和模型当前的能力匹配——这也是为什么各家要大规模合成任务(下面)。

新失败 ②:最慢的一条拖住整批

把项目里的全部真实运行当成一批 rollout:同步 RL 要等最慢的一条才能开始训练,生成资源的平均利用率只有两成左右(以组件实算为准);在 70% 的轨迹完成时就开训,利用率升到六成多——剩下的轨迹下一轮接着跑,前半段由旧参数生成(off-policy)。这正是 2026 年的共识:异步 RL。Kimi K3 的部分 rollout 在完成比例达到 λ 时暂停生成、先做优化,用逐 token 的正则容忍陈旧数据;DeepSeek-V4.1 按样本粒度派发、限制 off-policy 比例、给过期的 token 加掩码;GLM-5 用完全解耦的异步框架 。

现代做法:环境与任务成了主要工作量

⚠

常见误解一:「agentic RL 训练的是工具。」 训练的只是模型写出来的 token:思考、工具调用的文字、回答。工具和环境的返回只是上下文。

常见误解二:「多轮 RL 就是单轮 RL 重复几次。」 一条轨迹一个奖励、rollout 长尾、异步带来的 off-policy、训练与推理上下文要一致(历史思考留不留)——这些都是单轮 RL 里没有的。

常见误解三:「SWE-RL 是在环境里跑测试拿奖励。」 它用的是与真实补丁的文本相似度,RL 阶段不执行代码。

证据三问

问本课的回答
① 它解决什么问题?SFT 模仿轨迹只学到格式,不会从错误中恢复,环境反馈进不了训练
② 数学上为什么可能有效?仍然是策略梯度:整条轨迹的奖励乘以模型写出的每个 token 的对数概率梯度;只训策略生成的 token,是「梯度只对策略的动作求」的直接推论
③ 实验上为什么选了它?SWE-RL:端到端 36.2 → 41.0、领域外不降反升;各家前沿模型的 agent 能力主要来自这一步

一句话

📌

做事就是多轮生成:模型写的 token 才训练,工具和环境的返回只是上下文,奖励来自环境里的那个「测试过没过」。

🚦

先停在这里:记住「只训模型写的;一条轨迹一个奖励;零方差组;长尾与异步」。这门课关于「训模型」的部分到这里就走完了。
再深一层:在轨迹组件里对比 v1 和 v2 两版系统提示下的运行:同一个模型,只换提示,成功率就变了——下一门课的 harness 在管的就是这些。

下一个缺口:交接 Agent 课

到这里,模型已经会写 <tool_call> 了。可它写出来的只是一段文字:谁来解析它、执行它、把结果送回去?执行 rm -rf 怎么办?上下文满了怎么办?模型输出了一段「调用工具」的文字,然后呢? 这些问题属于模型外面的那一层——harness。

→ 进入 编码 Agent 课 A0:什么时候需要 agent,什么时候一段代码就够?(「tool call 也只是 token」在 A1 第 1 课兑现)

→ 继续本课程:C13 推理:生成为什么慢、怎么变快——RL 的 rollout 就是 decode,它慢在哪,C13 讲。

你可能会问