如果你的目标是“尽快能改训练代码”,最有效的路径不是先啃公式,而是:

  1. 先跑通一个最小可运行实现。
  2. 直接改 reward 参数,观察策略行为变化。
  3. 再回头用少量理论解释你看到的现象。

这篇就是这个思路的实战版本。


1. 先跑通:最小 Agentic RL 脚本

我已经在仓库里放了一个可运行脚本:

  • /Users/wangpeng/博客/Hexo_Blog_Source/tools/agentic_rl_code_first.py

它是一个 code-first 的 Agentic 决策实验(contextual bandit):

  • ANSWER_NOW:直接回答
  • USE_TOOL:调用工具再回答
  • THINK_MORE:先思考再回答

完整数据流非常清晰:

  • Environment 给状态(confidence / tool_hint / complexity)
  • PolicyNet 输出动作分布
  • REINFORCE loss 更新策略

直接运行:

1
2
cd "/Users/wangpeng/博客/Hexo_Blog_Source"
python3 tools/agentic_rl_code_first.py --episodes 1500

2. 关键代码(只看最核心三段)

2.1 环境:动作 -> 成功概率 -> 奖励

1
2
3
4
5
6
7
8
9
10
11
12
13
def step(self, action: int):
p_success = self._success_prob(action)
success = self.rng.random() < p_success

if action == A_TOOL:
cost = self.reward_cfg.tool_cost
elif action == A_THINK:
cost = self.reward_cfg.think_cost
else:
cost = 0.0

reward = cost + (self.reward_cfg.success_reward if success else self.reward_cfg.wrong_penalty)
done = True

你要看的重点:奖励函数才是行为杠杆

2.2 策略网络:状态到动作分布

1
2
3
4
5
6
7
8
class PolicyNet(nn.Module):
def __init__(self, obs_dim: int, n_actions: int):
super().__init__()
self.net = nn.Sequential(
nn.Linear(obs_dim, 64), nn.Tanh(),
nn.Linear(64, 64), nn.Tanh(),
nn.Linear(64, n_actions),
)

你要看的重点:先别纠结网络结构,先看输入/输出语义

2.3 训练:REINFORCE 一步闭环

1
2
3
4
5
6
7
8
9
dist = Categorical(logits=policy(obs_t))
action = dist.sample()
_, reward, _, _ = env.step(action_id)

baseline = 0.95 * baseline + 0.05 * reward
advantage = reward - baseline

policy_loss = -dist.log_prob(action) * advantage
loss = policy_loss - entropy_coef * dist.entropy().mean()

你要看的重点:reward -> advantage -> loss 这一条链。


3. 先跑,再改:两个最有效实验

实验 A:提高工具成本,观察策略是否减少“工具依赖”

1
python3 tools/agentic_rl_code_first.py --episodes 1500 --tool-cost -0.6

你会看到 think_ratio 上升,avg_reward 下降(工具更贵了)。

实验 B:给“思考”正奖励,观察是否更倾向先思考

1
python3 tools/agentic_rl_code_first.py --episodes 1500 --think-cost 0.5

你会看到 think_ratio 明显上升。

这就是“先跑通,再拆解”最核心的反馈回路:

  • 改一个 reward 系数
  • 看动作分布怎么变
  • 再解释为什么变

4. CleanRL 的阅读方式(工程师版)

你的目标不是“读完所有算法”,而是读懂一个单文件实现的完整数据流

推荐顺序:

  1. 先看 cleanrl/ppo.py(单文件,主干完整)
  2. 只追这几行:collect rollout -> compute advantage -> policy loss -> optimizer.step
  3. 对照你自己的最小脚本,找“同构位置”

建议做法:

  1. 先跑默认参数,确认可复现。
  2. 只改一个变量(例如 ent_coefclip_coef)。
  3. 只看三类日志:reward / entropy / KL(or clip frac)

5. 理论只补三件事(够用了)

  1. log pi(a|s):因为策略梯度要对概率分布求导。
  2. advantage:告诉模型“这次动作比平均好多少”。
  3. entropy:防止策略过早塌缩到单一动作。

其余理论,等你遇到具体训练问题再补。


6. 下一步(建议)

  1. tools/agentic_rl_code_first.py 的状态特征改成你自己的任务信号(例如工具延迟、检索置信度、错误类型)。
  2. 在同一脚本里增加 reward breakdown 打印(success/cost 各自均值),避免“只看总 reward”误判。
  3. 再把这套 reward 设计迁移到你实际用的 Agentic RL 框架(veRL / RLHF pipeline)。

如果你愿意,我下一篇可以直接给你一个“从这个最小脚本迁移到 veRL 配置项”的对照表(字段级别,一一对应)。