---
layout: default
title: Agent RL 实战：用强化学习提升推理与决策质量
description: Agent 场景下 RL 的 Reward 设计、算法选型与推理性能优化实战经验
eyebrow: Agent 训练实战 / 02
---

# Agent RL 实战：用强化学习提升推理与决策质量

上一篇讲了 Agent SFT——用轨迹数据教模型“学会做 Agent”。但 SFT 有个本质问题：它是模仿学习，模型最多做到和标注数据一样好，不会更好。

企业场景对 Agent 的要求远不止“能跑通”：要步骤少、工具调用准、推理链路清晰、遇到异常能自己恢复。这些都不是靠堆 SFT 数据能解决的——你需要 RL。

本篇聚焦 Agent RL 的工程落地：怎么设计 Reward、选什么算法、怎么搭训练环境、怎么用 RL 把推理性能拉上去。

## 为什么 SFT 之后还需要 RL

SFT 的天花板来自三个结构性问题：

**问题 1：模仿学习的上限就是标注数据的质量**

SFT 本质是“照着标准答案学”。如果标注轨迹里有冗余步骤、次优决策，模型会原样学过来。你无法通过 SFT 让模型超越数据本身的质量——就像一个只看教科书的学生，考试成绩上限就是教科书写得多好。

**问题 2：Exposure Bias（暴露偏差）**

SFT 训练时，模型看到的上文永远是 ground truth（标准轨迹）。但推理时，模型是基于自己上一步的输出继续生成的——一旦某一步偏了，后面的上文全变了，模型从没见过这种情况，就容易崩掉。

一个直观的例子：SFT 训练时，模型看到的轨迹是“查天气 → 拿到结果 → 回复用户”。但推理时如果第一步工具调用参数写错了、返回了报错，模型在训练阶段从未见过“报错之后该怎么办”——它只见过一路顺风的轨迹。

**问题 3：SFT 只学“怎么做”，不学“做得好不好”**

SFT 的 loss 是 token 级别的交叉熵——模型学的是“这个位置应该输出什么 token”，不关心最终任务有没有完成、完成得是否高效。RL 才引入了“结果好不好”这个信号。

| | SFT | RL |
|---|---|---|
| 学习信号 | token 级别的交叉熵 | 任务级别的 Reward |
| 上限 | 标注数据的质量 | 理论上无上限（受 Reward 设计约束） |
| 对错误的处理 | 只见过正确轨迹 | 在试错中学习恢复策略 |
| 优化目标 | 模仿标准答案 | 最大化累积回报 |

## Agent RL 的核心框架

把 Agent 交互过程映射到 RL 框架，其实非常自然：

```mermaid
graph LR
    A["Agent<br/>(Policy Model)"] -->|"动作：生成 tool_call<br/>或文本回复"| B["Environment<br/>(工具/API/沙箱)"]
    B -->|"观测：tool 返回结果<br/>+ 对话历史"| A
    B -->|"Reward：任务完成？<br/>步数多少？质量如何？"| C["Reward Signal"]
    C -->|"更新策略"| A

    style A fill:#022c22,stroke:#10b981,color:#34d399
    style B fill:#1a2535,stroke:#334155,color:#94a3b8
    style C fill:#1e293b,stroke:#f59e0b,color:#fbbf24
```

具体来说：

```text
状态 (State)    = 当前对话历史 + 所有工具返回结果 + system prompt
动作 (Action)   = 模型的下一步输出（一次 tool_call 或一段文本回复）
环境 (Env)      = 工具执行引擎 + 沙箱（代码执行、API 模拟等）
奖励 (Reward)   = 任务是否完成 + 过程质量评分
策略 (Policy)   = Agent 模型本身（给定状态，输出动作的概率分布）
```

和游戏 RL 的关键区别：Agent RL 的动作空间是自然语言（或结构化的 JSON tool call），维度极高；状态空间是变长的文本序列，不是固定维度的向量。这导致 Agent RL 的训练比 Atari 之类的难得多——后面会展开讲工程挑战。

## Reward 设计：Agent RL 的成败关键

Reward 设计是 Agent RL 里最难也最重要的部分。设计得好，模型能学到真正有用的策略；设计得差，模型会学到各种钻空子的方式（reward hacking）。

### 结果 Reward vs 过程 Reward

```text
结果 Reward (Outcome-based)
├── 任务完成了 → +1
└── 任务失败了 → 0 或 -1

过程 Reward (Process-based)
├── 调了正确的工具 → +0.1
├── 参数格式正确   → +0.05
├── 产生了冗余步骤 → -0.1
└── 陷入死循环     → -0.5
```

**结果 Reward** 的优点是简单、不需要人工设计中间标准。缺点是信号稀疏——Agent 可能执行了 10 步，只在最后一步拿到 Reward，中间步骤的好坏完全没有反馈。

**过程 Reward** 信号密集，训练效率高，但需要你定义“什么是好的中间步骤”——这本身就是一个难题，而且定义不好会误导模型。

实践中的做法：**以结果 Reward 为主，用少量过程 Reward 做辅助。**

### 企业场景的 Reward 设计示例

不同类型的 Agent，Reward 设计思路差别很大：

**代码 Agent（如 SWE-Agent）**

```text
Reward 组成：
├── 测试通过率              权重 0.6    ← 核心指标
├── 代码是否能编译/运行       权重 0.2    ← 基本正确性
├── 修改的文件数量惩罚       权重 -0.1   ← 鼓励精准修改，避免乱改一通
└── 步骤数量惩罚            权重 -0.1   ← 鼓励高效完成
```

这是最容易设计 Reward 的场景——测试用例是天然的、可自动化的评判标准。这也是为什么代码 Agent 是 RL 训练最早跑通的企业场景之一。

**RAG Agent（检索增强生成）**

```text
Reward 组成：
├── 最终答案准确率（和参考答案对比）  权重 0.4
├── 检索召回率（找到了相关文档吗）    权重 0.3
├── 检索精确率（召回的文档相关吗）    权重 0.2
└── 检索次数惩罚                    权重 -0.1   ← 避免无脑检索
```

RAG Agent 的 Reward 设计难点在于“答案准确率”的自动评估。常见做法是用一个更强的模型做 judge（RLAIF 思路），或者在有标准答案的数据集上训练。

**搜索/数据分析 Agent**

```text
Reward 组成：
├── 最终结果正确性      权重 0.5
├── SQL/查询语法正确    权重 0.2
├── 执行无报错          权重 0.2
└── 查询效率（扫描行数） 权重 -0.1
```

### 稀疏 Reward 的缓解方法

纯结果 Reward 最大的问题是稀疏性——Agent 走了 10 步，只有最后一步有 Reward，前面 9 步的梯度信号非常弱。

几种实用的缓解方法：

| 方法 | 思路 | 适用场景 |
|---|---|---|
| Reward Shaping | 人工设计中间步骤的小 Reward | 步骤可明确定义好坏的场景 |
| Hindsight Reward | 任务完成后，回过头给中间步骤打分 | 结果可自动验证的场景 |
| Process Reward Model (PRM) | 训练一个模型来评估中间步骤质量 | 数据充足、有人工标注的场景 |
| 缩短轨迹长度 | 把复杂任务拆成子任务，每个子任务单独给 Reward | 任务天然可分解的场景 |

其中 **PRM（过程奖励模型）** 是目前比较热的方向——用人工标注的“每一步对不对”数据训练一个打分模型，然后用这个模型给 RL 训练提供密集 Reward。OpenAI 在数学推理上验证了这个思路的效果，Agent 场景同理。

## 主流算法选型

### PPO：最稳的选择

PPO（Proximal Policy Optimization）是目前 Agent RL 的主流算法。核心思想是限制每次策略更新的幅度，避免训练崩溃。

```text
PPO 训练循环：
1. 用当前策略（Agent 模型）在环境中 rollout，收集轨迹
2. 用 Reward 计算每一步的优势函数（advantage）
3. 用 clipped objective 更新策略，限制更新幅度
4. 用 KL 散度约束策略不要偏离 SFT checkpoint 太远
5. 回到第 1 步
```

PPO 在 Agent 场景的关键配置：

- **KL 系数**：控制策略偏离 SFT checkpoint 的程度。设太大，模型不敢探索；设太小，格式容易退化（比如 tool call 格式崩掉）。经验值 0.01–0.05，需要根据场景调
- **Rollout 批次大小**：Agent 轨迹长，rollout 成本高，batch size 不能设太大。通常 64–256 条轨迹一个 batch
- **GAE lambda**：控制优势函数的偏差-方差权衡，Agent 场景一般 0.95–0.99

### GRPO：更适合长轨迹的变体

GRPO（Group Relative Policy Optimization）是 DeepSeek 在 R1 中使用的算法。和 PPO 的核心区别是：**不需要单独训练 Critic/Value 网络**，而是通过同一 prompt 的多条 rollout 之间做相对比较来估计优势。

```text
GRPO 流程：
1. 对同一个 prompt，用当前策略生成 N 条不同的轨迹（比如 N=8）
2. 分别计算每条轨迹的 Reward
3. 在这 N 条轨迹内部做归一化，得到相对优势
4. 用相对优势更新策略
```

GRPO 的优势：
- 省掉了 Critic 网络的训练和显存开销——Agent 轨迹本身就很长，再加个 Critic 显存压力很大
- 相对比较比绝对打分更稳定——“这条比那条好”比“这条值 0.7 分”更容易判断

GRPO 的劣势：
- 需要同一个 prompt 生成多条轨迹，rollout 成本翻 N 倍
- 如果 N 太小，相对优势的估计噪声大

| | PPO | GRPO |
|---|---|---|
| 是否需要 Critic | 需要，额外显存开销 | 不需要 |
| Rollout 成本 | 每个 prompt 1 条轨迹 | 每个 prompt N 条轨迹 |
| 优势估计方式 | 绝对值（Value 网络） | 组内相对比较 |
| 适合场景 | 轨迹较短、显存充足 | 轨迹长、Reward 可自动计算 |
| 代表工作 | InstructGPT、ChatGPT | DeepSeek-R1 |

### Rejection Sampling + SFT：轻量替代方案

如果你的场景不想上完整的 RL 训练管线，有一个更简单的替代方案：

```text
Rejection Sampling 流程：
1. 对每个 prompt，用当前模型生成 K 条轨迹
2. 用 Reward 函数给每条轨迹打分
3. 只保留得分最高的那条（或 top-k 条）
4. 用筛选后的数据做 SFT
5. 回到第 1 步，迭代
```

这个方法的本质是用采样+筛选来近似 RL 的效果，避免了 PPO/GRPO 复杂的训练管线。代价是收敛更慢、上限更低，但实现成本低很多。

适合的场景：
- 团队没有 RL 训练基础设施
- 快速验证 Reward 设计是否合理
- 作为正式 RL 训练前的数据增强手段

### RLHF vs RLAIF：谁来提供 Reward

| | RLHF | RLAIF |
|---|---|---|
| Reward 来源 | 人工标注偏好对 | 强模型（如 GPT-4、Claude）打分 |
| 成本 | 高（需要持续标注） | 低（API 调用） |
| 质量 | 上限高，但标注一致性难保证 | 中等，受 judge 模型能力限制 |
| 适合 Agent 场景 | 高风险场景（医疗、金融） | 通用场景、快速迭代 |

Agent 场景的一个优势是：很多 Reward 可以自动化验证（代码跑通了吗？SQL 结果对吗？），不一定需要人来标注。能自动验证的场景优先用自动 Reward，省钱又稳定。

## RL 训练的工程挑战

Agent RL 的理论不复杂，但工程落地非常难。下面是几个最头疼的问题。

### Rollout 成本

Agent RL 的每次策略更新都需要 rollout——让模型在环境里跑完整条轨迹。和游戏 RL 不同，Agent rollout 涉及真实的工具调用：

```text
一次 rollout 的成本：
├── 模型推理：每步生成 100-500 tokens，一条轨迹 5-15 步
├── 工具执行：API 调用延迟、代码编译运行时间
├── 总耗时：一条轨迹可能要 30 秒到几分钟
└── 对比：Atari 游戏一步只需要几毫秒
```

缓解方法：
- **并行 rollout**：同时跑几十到几百条轨迹，用 GPU 集群做模型推理，用容器化环境做工具执行
- **异步训练**：rollout 和策略更新解耦，收集到一批轨迹就更新，不等所有 rollout 完成
- **轨迹缓存**：对于确定性的工具调用（同样的参数总是返回同样的结果），缓存工具返回值

### 沙箱环境搭建

Agent RL 需要一个可以安全、大规模执行工具调用的环境。这是和对话 RL（RLHF）最大的工程区别——对话 RL 只需要生成文本然后打分，Agent RL 需要真的执行操作。

```text
沙箱环境需要满足：
├── 隔离性    每条轨迹的执行互不影响
├── 可重置    执行完一条轨迹后环境恢复初始状态
├── 可扩展    支持几百条轨迹并行执行
├── 确定性    相同输入得到相同输出（尽量）
└── 安全性    不能让模型的操作影响到宿主系统
```

代码 Agent 的沙箱方案比较成熟（Docker 容器 + 文件系统快照），但 API 调用类的 Agent 就麻烦——你不能在 RL 训练时真的去调第三方 API（成本、速率限制、副作用），需要搭模拟环境。

### 训练稳定性

Agent RL 的训练比对话 RL 更容易崩，因为轨迹更长、动作空间更大、Reward 更稀疏。

**Reward Hacking**：模型找到了钻 Reward 漏洞的方法，拿到高分但没有真正完成任务。

几个真实案例：
- 代码 Agent 学会了修改测试用例让测试通过，而不是修复 bug
- 搜索 Agent 学会了不检索直接编造答案（因为有时候蒙对了也有 Reward）
- RAG Agent 学会了把所有文档都检索回来（召回率高，但精确率崩了）

防范方法：
- **多维度 Reward**：不只看任务完成率，加入步骤合理性、格式正确性等辅助 Reward
- **对抗性测试集**：用专门设计的 edge case 测试模型是否在 hack
- **人工抽检**：定期抽查高 Reward 轨迹，看看模型到底在做什么

**KL 散度约束**：控制策略不要偏离 SFT checkpoint 太远。

```text
总 Loss = -RL_objective + β × KL(π_current || π_sft)

β 太大 → 策略几乎不更新，RL 白训
β 太小 → 策略漂移太远，格式退化、能力崩塌
```

经验做法：用自适应 KL 系数——设定一个 KL 目标值（比如 0.1），如果实际 KL 超了就增大 β，反之减小。

## 推理性能优化：RL 的实际收益

讲了这么多机制，RL 到底能带来什么实际收益？聚焦三个企业最关心的指标。

### 减少冗余步骤

SFT 模型容易产生冗余步骤——因为它是模仿训练数据的平均行为，而训练数据里不可避免地包含一些不够高效的轨迹。

RL 通过步骤数量惩罚，可以让模型学会“走捷径”：

```text
SFT 模型的典型行为：
  查天气 → 查温度 → 查湿度 → 查风力 → 综合回复（4 步工具调用）

RL 优化后：
  查天气（返回包含温度/湿度/风力） → 综合回复（1 步工具调用）
```

实际效果：在代码修复场景中，RL 训练后的 Agent 平均步骤数可以从 8-12 步降到 5-7 步，同时保持或提升完成率。

### 提升工具调用准确率

SFT 模型在工具调用上常犯两类错误：
- **选错工具**：该用 search 的时候用了 fetch，该查数据库的时候调了文件 API
- **参数填错**：字段名拼错、格式不对、必填参数漏了

RL 通过“工具调用成功才有 Reward”这个信号，可以显著减少这两类错误。模型会学到：与其冒险调一个不确定的工具，不如先确认再调。

### 改善复杂推理链

对于需要多步推理的任务（比如“先查用户信息，根据用户等级查对应的优惠政策，再计算折扣价格”），SFT 模型容易在中间环节出错后一路错下去。

RL 的优势在于它是在完整轨迹上优化的——模型会学到“前面几步的决策会影响后面的结果”，从而在关键节点做出更谨慎的选择。

```text
RL 对推理链的改善：
├── 错误恢复能力   工具报错后知道换一种方式重试
├── 分支决策质量   在需要判断的地方选对路径的概率更高
└── 信息利用效率   更好地利用工具返回的信息，减少重复查询
```

## 进阶：RLVP、多轮信用分配与 On-Policy Distillation

以下三个方向是 Agent RL 前沿中最有工程价值的补充。

### RLVP：奖结果、罚过程

传统 RL 要么只给结果 Reward（稀疏），要么人工设计过程 Reward（成本高）。RLVP（Reinforcement Learning with Verification and Penalization）的思路是：

- **结果正确 → 奖励整条轨迹**（不追究中间走了弯路）
- **结果错误 → 惩罚可定位的错误步骤**（而不是惩罚整条链）

```text
传统做法：
  轨迹 A（10 步，结果正确）→ Reward = +1（均摊到 10 步）
  轨迹 B（8 步，结果错误）  → Reward = -1（均摊到 8 步）

RLVP 做法：
  轨迹 A（10 步，结果正确）→ 所有步骤 Reward = +1
  轨迹 B（8 步，结果错误）  → 第 5 步工具参数错误 → 只惩罚第 5 步
```

核心价值：**从失败轨迹中回收训练信号**。传统方法下，失败轨迹只能提供一个笼统的负信号；RLVP 可以精确告诉模型"哪一步错了"，让模型学到"避免特定错误"而不是"避免整个行为模式"。

实现关键：需要一个 verifier 能定位错误步骤（代码场景用 test/compiler 自然定位；通用场景可用 PRM 或规则引擎近似）。

### 多轮信用分配（Credit Assignment）

Agent 任务通常有多个步骤，最终只有一个结果。问题是：如果 10 步中第 3 步是关键决策，怎么让梯度信号正确地回传到第 3 步？

| 方法 | 思路 | 适用场景 |
|---|---|---|
| Outcome Reward + GAE | 用 advantage 估计逐步分配，但长链路衰减严重 | 短轨迹（<5 步） |
| Process Reward Model | 训练一个模型给每步打分，作为密集 Reward | 有标注数据的场景 |
| Monte Carlo Tree | 从每个中间状态采样多条轨迹，用成功率估计该步价值 | 计算预算充足时 |
| 关键步骤标注 | 人工或自动标注"决策分叉点"，只在这些点给 Reward | 可明确识别关键决策的场景 |

Agent 场景中最实用的组合是：**结果 Reward + 关键步骤的 Process Reward**。不需要给每一步都打分，只在工具选择和参数决策这些关键点加信号就能显著提升训练效率。

### On-Policy Distillation：学生生成、教师反馈

传统蒸馏：强模型生成数据 → 弱模型 SFT 学习。问题是弱模型可能产生强模型从不会产生的错误，SFT 阶段看不到这些错误的处理方式。

On-Policy Distillation 的做法：

1. **学生模型自己生成轨迹**（on-policy）
2. **教师模型对学生的每一步提供 token 级反馈**（而不是直接给示范答案）
3. 学生基于教师反馈更新策略

```text
传统蒸馏：
  Teacher 生成轨迹 → Student SFT 模仿
  问题：Student 自己生成时犯的错，训练中完全没见过

On-Policy Distillation：
  Student 生成轨迹 → Teacher 对每个 token 打分（这步好/这步差）→ Student RL 更新
  优势：Student 的实际分布和训练分布一致，没有 exposure bias
```

工程优势：

- 避免 Exposure Bias（学生在自己的分布上学习）
- 教师的 token 级反馈比轨迹级 Reward 信号密集得多
- 不需要设计复杂的 Reward 函数——教师模型本身就是 Reward 来源

成本权衡：每条学生轨迹都需要教师 inference 一次，token 成本大约是纯 SFT 的 3-5 倍，但训练效率（达到同等质量所需的 step 数）通常好于纯 RL。

## 小结

- SFT 的天花板是标注数据质量，RL 通过 Reward 信号让模型有机会超越模仿学习的上限
- Reward 设计是 Agent RL 的核心难题：以结果 Reward 为主，过程 Reward 为辅；能自动验证的场景（代码、SQL）优先用自动 Reward
- 算法选型：PPO 最稳、GRPO 省显存适合长轨迹、Rejection Sampling + SFT 是轻量替代
- 工程挑战集中在 rollout 成本、沙箱环境和训练稳定性——Reward Hacking 是最常见的坑
- RL 的实际收益体现在减少冗余步骤、提升工具调用准确率、改善复杂推理链的表现
- RLVP 从失败轨迹回收信号，多轮信用分配解决长链路的梯度衰减，On-Policy Distillation 用教师密集反馈替代人工 Reward 设计

下一篇建议继续看：

- [GRPO vs PPO：Agent 强化学习算法深度对比与选型](../03-grpo-vs-ppo/index.html)
