0x00 概要
本系列的目的是:借着对 OpenClaw-RL 源码的学习,来梳理强化学习的一些相关概念和思想。所以,会有一些基础知识、扩展和发散,OpenClaw-RL 只是一个切入点。而且,因为整篇系列是一个整体,所以有些概念的解读/学习会在不同的文章中出现,还请大家谅解。

OpenClaw-RL 是一个用于在线强化学习(Online RL)的框架,专门针对智能体工具使用场景。它通过从环境反馈中提取过程奖励信号来训练语言模型,支持三种主要模式:

openclaw-rl:基于二元奖励的强化学习(Binary RL / GRPO)
openclaw-opd:基于后见之明提示的在线策略蒸馏(On-Policy Distillation, OPD)
openclaw-combine:联合方法,在同一 PPO 更新中同时利用 RL reward 和 OPD teacher signal
framework

前文提到了,Reward 理论上属于 environment 的一部分, 实践中是独立的 Reward Judging 阶段。在 OpenClaw 这种工程系统中, 把它看作独立阶段更有助于理解架构。因此,我们本篇继续看看 Reward Judging。

0x01 Reward 基础
1.1 RL 和 Agentic RL 中常见的 Reward 类型
常见的 Reward 分类框架如下:

Reward 来源分类
├─ Environment Reward
│ ├─ 确定性(游戏)
│ └─ 可验证(代码/数学)
├─ Model-Based Reward
│ ├─ Trained RM(RLHF)
│ └─ LLM Judge(Constitutional)
└─ Human Reward
└─ 偏好标注(RLHF)
如果从Reward 来源谱系来分类,则可以把上图细化为:

硬件级(deterministic):
游戏得分、机器人传感器
→ 完全客观、零噪声

规则级(verifiable):
数学答案正确性、代码测试通过
→ 客观但有边界(正则表达式匹配、test suite 覆盖率)

人类级(subjective):
RLHF 中人类标注者的偏好
→ 主观、昂贵、不可复现

LLM Judge 级(proxy): ← OpenClaw 在这里
LLM 解读 next_state 后的评分
→ 主观的自动化版本,便宜但可能有偏
经典 RL
经典 RL 的 Reward如下,全部是 environment reward - 由模拟器/物理世界直接产生。

领域 Reward 来源 类型
Atari 游戏 游戏引擎分数 Environment(确定性)
机器人控制 传感器信号(距离目标) Environment(连续)
棋类/围棋 赢/输/平 Environment(稀疏)
对话 用户反馈/评价 Environment(隐式/稀疏)
导航 到达目标点 Environment(稀疏)
交通调度 等待时间、吞吐量 Environment(设计的)
LLM RL 的 Reward(非 Agentic)
LLM RL 的 Reward(非 Agentic)如下,这是混合Reward:有 environment reward 也有 model-based reward。

场景 Reward 来源 类型
数学推理 答案正确性(regex/计算验证) Environment(verifiable)
代码生成 测试通过率 Environment(verifiable)
RLHF 人类标注偏好 → 训练 Reward Model Learned Model
Constitutional AI LLM 自评(符合原则?) LLM Judge
DPO 隐式 reward(偏好数据) Implicit
Agentic RL 的 Reward
Agentic RL 的 Reward 举例如下:

场景 Reward 来源 是 Environment Reward?
SWE-agent(代码修复) CI 通过 / 测试 pass ✓ Environment
WebShop(网购) 买到目标商品 ✓ Environment
ALFWorld(家务) 任务完成 ✓ Environment
ScienceWorld 实验成功 ✓ Environment
Browser agent 网页操作成功 ✓ Environment
Terminal agent(SETA/AReaL) 命令执行结果 ✓ Environment
对话 agent(OpenClaw) LLM Judge 评估 × Proxy Reward
Search agent(ASearcher) 搜索质量分 部分 Env + Judge
Customer service 问题解决率 部分 Env + Human
Agentic RL 的关键特点:大部分有 Environment Reward。为什么 Agentic RL 通常有 environment reward?这是因为 Agent 与工具/环境交互 → 环境给出确定性反馈:

代码执行:pass/fail(确定性)
终端命令:exit code 0/non-0(确定性)
网页操作:目标元素出现/消失(确定性)
API 调用:200 OK / 4xx error(确定性)
这些反馈直接可以作为 reward:成功 → +1,失败 → -1,不需要 LLM Judge 做中介!

1.2 Reward 函数 vs Advantage 函数
我们再来对比下Reward 函数和Advantage 函数的区别。

Reward 是"原材料", Advantage 是"加工品", 梯度是"最终产品"。
Reward=环境打的原始评分:告诉你"这个回答有多好”

Advantage=加工后的信号:告诉你"这个回答比基线好多少”,是"相对化+细化"后的训练信号 →直接乘进梯度。

Reward→Advantage→PPO clip → 梯度更新,层层加工。

角色分工
┌──────────────┐ R ┌──────────────┐ A ┌──────────────┐
│ 环境/评委 │ ──────→ │ Advantage │ ──────→ │ 策略梯度 │
│ (Reward) │ │ (估计器) │ │ (更新 θ) │
└──────────────┘ └──────────────┘ └──────────────┘
“打分” “相对化” “更新”
Reward是input(来自环境/评委)
Advantage是processing(去偏、归一化、细化到token)
PPO loss是output regulation(限速器)
梯度更新是execution(实际改参数)
核心区别
Reward 函数 R(o) Advantage 函数 A(o,t)
是什么 对一条 response 打分:好/差/中性 对一条 response 的相对优势评估
粒度 通常 per-response(1 个标量) 可以 per-response 或 per-token
包含 baseline 吗 ❌ 不包含 ✅ 已减去 baseline (A = R - baseline)
语义 “这条回答有多好” “这条回答比平均水平好多少”
梯度流 不直接进入梯度 直接乘进 policy gradient
是否可以直接使用Reward
我们再来看看是否可以直接使用Reward。假设Reward和Advantage如下:

Reward = 考试卷子的绝对分数(90分)
Advantage = 你比班级平均分高多少(+14分)
方案1:直接用reward(REINFORCE原始版)

∇θ ≈ R·∇logπ(o|q)
该方案的问题:

全班平均分考90分→R=90→梯度很大→但其实没有学习信号!
假设你考90,别人考85→ 但是R依然为90→你的梯度和全班90一样大
因此,只看 reward 无法训练——全班都 90 分时没有方向感。只有 Advantage 才能告诉 model “你的回答比别人好在哪”。

方案2:用advantage(减去基线)

∇θ ≈ A·∇logπ(o|q)其中 A=R-baseline
假设你分数为90。

全班平均分为 90:A=90-90=0→无梯度←正确!没信号就不更新
假设全班平均分为87.5:A=90-87.5=+2.5→正向梯度←正确!你比平均好
因此,还是用方案2好。

直觉总结

Reward:“考试卷子发回来了,你得了90分”
Advantage:“你比班级平均高5分,其中第3题特别好(+2),第7题不太行(-1)”
PPO clip: “不管分数多高,每次调整不能超过限定步长”
梯度更新:“针对第3题的方法多练,第7题的方法少用”
Advantage的三重作用
1.去除baseline(减少方差):
A=R-b
→消除共同偏移,只保留相对差异
→ 梯度方差从 Var(R·∇logπ) 降到 Var((R-b)·∇logπ)

2.确定方向(token级别):
A_t > 0 → 增大 token t 的概率
A_t < 0 → 减小 token t 的概率
A_t = 0 → 不变

3.确定步长:
|A_t| 大 → 梯度大 → 更新幅度大
|A_t| 小 → 梯度小 → 更新幅度小
转换方式
RL中常见的Reward→Advantage转换方式如下:

9-转换方式

0x02 OpenClaw-RL 的Reward 函数
2.1 RL 变体 & Reward 函数
本项目全部 RL 变体一览

OpenClaw-RL-main/
├── openclaw-rl/ ① Binary RL (对话)
├── openclaw-opd/ ① OPD (对话)
├── openclaw-combine/ ③ Combine: RL+OPD (对话)
├── swe-rl/ ④ SWE-RL (代码修复)
├── gui-rl/ ⑤ GUI-RL (桌面操控)
├── terminal-rl/ ⑥ Terminal-RL (终端Agent)
├── toolcall-rl/ ⑦ Tool-Call RL (数学+代码)
└── openclaw-tinker/ ⑧ Tinker (轻量实验后端)
7 种 RL 变体对比
9-7 种 RL 变体对比

按奖励来源分类
┌──────────────────────────────────────────────────────────────────────────────┐
│ 纯环境奖励 (确定性, ground truth) │
│ ④ SWE-RL: 测试套件 pass/fail │
│ ⑤ GUI-RL: OSWorld evaluator (预定义验证脚本) │
│ ⑥ Terminal-RL: 任务完成检测 │
│ ⑦ Tool-Call: 数学答案正确性 (\boxed{} match) │
├──────────────────────────────────────────────────────────────────────────────┤
│ 纯代理奖励 (LLM Judge, 非确定性) │
│ ① Binary RL: zero-shot Judge {-1, 0, +1} │
│ ① OPD: Teacher hint + log-prob distillation │
│ ③ Combine: ①+② │
├──────────────────────────────────────────────────────────────────────────────┤
│ 环境 + PRM 混合 (环境为主, PRM辅助) │
│ ④⑤⑥⑦ 的 PRM 模式: │
│ final_reward = outcome ± prm_coef × step_mean │
└──────────────────────────────────────────────────────────────────────────────┘
关键洞察
对话场景 (①②③) 是最难的 - 没有环境信号, 全靠 LLM Judge
Agent 场景 (④⑤⑥⑦) 都有确定性环境奖励 - PRM 只是补充 dense signal
PRM 在不同场景中角色相反:
对话: PRM = 唯一奖励来源
Agent: PRM = 辅助过程奖励 (解决 sparse reward 问题)
共享基础设施: 所有变体都用 Slime + GRPO + PPO clip, 只是 rollout 和 reward 不同
2.2 对话 RL 的 Reward 函数
OpenClaw-RL 的对话RL只有 1 种 reward 函数,唯一的 Reward 产生机制:PRM Judge(zero-shot LLM judge)。即,PRM majority vote → {-1, 0, +1}。

方法 Reward 来源 输出
Binary RL LLM Judge (PRM) zero-shot 评分
OPD 同上(用于监控 eval_mode)
Combine 同上(用于 RL 路径)
具体参见下图:

OpenClaw 的 reward 100% 来自 Reward Judging (LLM Judge)

┌───────────────────────┐
│ SGLang PRM (GPU 6-7) │
│ ├── Binary RL: ±1 评分 │ ← Judging
│ └── OPD: hint 生成 │ ← Judging
└───────────────────────┘

没有 environment reward
(用户对话本身不提供可验证的正确答案)
2.2.1 为何不使用环境Reward?
传统 RL vs OpenClaw 的 reward 来源
传统 RL(游戏/机器人):
Environment → reward(确定性,规则定义)
例:走了一步棋 → 赢/输/平 → +1/0/-1

LLM RL(数学/代码):
Environment → reward(确定性,可验证)
例:生成代码 → 执行测试 → pass/fail → +1/-1

OpenClaw-RL(开放域对话):
✘ 没有传统意义上的 “environment reward”
✔ 只有 LLM Judge 的主观评估
对话场景
OpenClaw 的场景 = “开放域对话 agent”。对话场景的本质如下:

没有客观正确答案(不像数学题)
没有可执行验证(不像代码)
"好坏"是主观判断
用户的"下一条消息"是最接近 environment 信号的东西:

用户说"谢谢" → 可能是好
用户说"不对,重来" → 可能是坏
用户说"另一个问题" → 不确定
为什么一种 reward 就够了
对于 Binary RL, - {-1, 0, +1} 一种就够了,这是因为:

单维度评分已经覆盖了"好/坏/不确定"
对话场景下很难设计多维度 reward(前面讨论过)
简单 = robust = 不容易被 hack
Hint judge(OPD)的评分格式类似但目的不同(选最佳 hint)
OPD: reward 仍然来自 PRM judge(同一个函数),但 advantage 不只靠 reward,还有 teacher_lp - student_lp

Combine: reward 来自 PRM judge + OPD teacher advantage → 两种"信号"混合,但 reward 来源是同一个

2.2.2 Reward Design
因为OpenClaw 的 reward 100% 来自 Reward Judging (LLM Judge),所以在 OpenClaw 语境下, Reward Design = Reward Judging。

openclaw_api_server.py L77-116: PRM Prompt

评估规则:

\boxed{1} (good): 下一状态表明任务正常推进

\boxed{-1} (bad): 下一状态表明助手输出错误/不完整

\boxed{0} (neutral): 下一状态模糊,无法判断

输入:Assistant output + Next state(用户的下一条消息或 tool return)

输出:{-1, 0, +1}

加强:

- Majority vote(m=3次独立调用)

- 平局 → 0.0

- At-least-one guarantee(session内至少一个sample有loss_mask=1)

2.2.3 阶段
需要区分"reward 的产生"和"reward 的读取"两个阶段。Reward 传递到 Slime 的两步如下:

步骤1:API Server 产生 reward(PRM judge 评分) → sample.reward =

步骤2:Slime 读取 reward(passthrough,不做任何额外计算) → reward_func(args, sample) 只是读取 sample.reward[“score”]

需要注意两点:

在OpenClaw OPD中,reward(PRM±1)不参与advantage计算,仅用于如下:
监控(wandb日志中记录prm_eval_score)
loss_mask 筛选(reward=0 时可能跳过样本)
reward_func (位于 openclaw-rl/openclaw_api_server.py) 并非评分函数本体,而是一个简单的查表穿透函数(空壳)——它仅从 sample.reward dict 中读取已预先计算好的 “score” 字段返回。实际的评分逻辑在 _prm_evaluate() 中(异步调用 LLM Judge + majority vote)。reward_func 被 Slime Trainer 回调以获取每轮 reward。具体如下:
async def reward_func(args, sample_or_samples, **kwargs):
# 直接从 sample.reward 中取出已经算好的 score
return {“score”: s.reward.get(“score”, 0.0)}

为什么? 因为 Slime 的 --custom-rm-path 接口要求提供一个 reward_func,但 OpenClaw 的 reward 已经在 API server 里算好了(在 sample 被提交到训练队列之前)。所以这个 func 只是"取值",不是"计算"。

2.2.4 修饰/后处理
Reward 函数需要一些后处理。

处理 说明
Majority vote m=3 独立评估取多数
平局处理 无多数时返回 0.0
At-least-one session 内全0时强制一个为 loss_mask=1
Score → loss_mask ±1→训练,0→跳过
–disable-rewards-normalization 不做 batch 内标准化
2.2.5 完整 reward 流水线
用户发消息 → Model 回复 → 用户再发消息(next_state)

PRM Judge(GPU 6-7)
├─ 调用 m=3 次
├─ 每次:看 response + next_state
└─ 输出:\boxed{1} / \boxed{0} / \boxed{-1}

majority_vote → final score

sample.reward = {“score”: final_score}


score=+1.0 score=0.0 score=-1.0
loss_mask=[1] loss_mask=[0]* loss_mask=[1]
*除非 at-least-one


提交到 Slime 训练队列

reward_func(passthrough):取出 score

GRPO: advantage = score(broadcast)
0x03 OpenClaw-RL 的Reward 函数 vs Advantage 函数
所以整个 OpenClaw-RL 项目,对话RL中:

Reward 函数 = 1 种(PRM Judge {-1,0,+1})
Advantage 函数 = 3 种(GRPO / OPD / Combined)
3.1 Advantage 函数
OpenClaw 中三种方法用不同的 advantage:

方法 Advantage 公式 粒度
Binary RL (GRPO) A_t = R (标量 broadcast) per-response
OPD
A
t

l
p
t
e
a
c
h
e
r
t

l
p
r
o
l
l
o
u
t
t
per-token
Combine
A
t

w
r
l

R
+
w
o
p
d

(
l
p
t
e
a
c
h
e
r
t
l
p
r
o
l
l
o
u
t
t
)
per-token
这里我们有一个问题:为什么OPD的advantage 计算时候不需要reward?这是因为:teacher本身就是"奖励信号"的载体,teacher 的log-probs 本身就是比 reward更丰富的信号。

传统RL:环境给reward→转化为advantage→梯度方向。

OPD:teacher 模型→直接给出per-token的"好坏判断"→梯度方向(OPD的advantage 是:A_t=teacher_lp_t-old_lp_t )

teacher_lp_t>old_lp_t→teacher更喜欢这个token→A>0→增大概率
teacher_lp_t<old_lp_t→teacher 不喜欢这个token →A<0→减小概率
teacher_lp_told_lp_t→已经对齐→A≈0→不变
reward告诉你"整个回答好不好"(1bit),而teacher log-probs告诉你"每个token应该往哪走、走多远"(per-token dense signal)。

3.2 信息流
信息流关系如下,Reward 是评分原材料({-1,0,+1}),Advantage 是训练实际用的信号。三种方法 reward 相同但 advantage 差异巨大。

9-信息流

3.3 配合的完整链路
阶段 1: 产生 Reward
用户对话 → PRM 评分 → R ∈ {-1, 0, +1}

阶段 2: Reward → Advantage
├─ Binary RL: A = R(broadcast 到所有 token)
│ 信息量:1 bit per response

├─ OPD: A_t = teacher_lp_t - old_lp_t
│ 信息量:~32 bits per token
│ (reward 只用于 loss_mask 筛选,不进入 advantage)

└─ Combine: A_t = w_rl·R + w_opd·(teacher_lp_t - old_lp_t)
信息量:混合

阶段 3: Advantage → 策略梯度
ratio = π_new / π_old
loss = -min(ratio · A, clip(ratio) · A) ← PPO clip

阶段 4: 梯度 → 参数更新
θ_new = θ_old - lr · ∇loss ← Adam optimizer
3.4 对比
环节 Binary RL OPD Combine
Reward 信息量 1 bit 1 bit(仅监控) 1 bit
Advantage 信息量 1 bit × T tokens(全相同) ~32 bits × T(每位置不同) 混合
信息放大比 1× ~32T× 中间
0x04 奖励函数设计的问题
本节我们看看为什么奖励函数设计是环境设计最容易失败的环节。

奖励是设计者价值判断的唯一编码,因此,对奖励函数有两个要求:

必须定义"什么算好" ---- 这是价值判断。
价值判断是主观的、不完整的、随语境变化的:
→ 奖励 = 你脑子里所有隐性假设的显式编码
→ 任何未明确编码的假设 = 可以被利用的漏洞
4.1 失败模式
我们来看看奖励函数的几个失败模式。

失败模式一:Reward Hacking
经典案例(非LLM领域)如下:

Atari划艇游戏:

奖励 = 速度作为分数;
期望行为 = 赢得比赛
RL发现:在起点附近绕圈吃分 → 正常竞速 → 得到了最高分,但从未完成一次比赛 → 奖励函数被"精确地最大化了”,但与设计意图完全背离 LLM对话领域:
LLM对话领域:

奖励=judge 打分(偏好详细、有条理的回复)
期望行为=简洁准确地帮助用户
RL发现:
格式为:“首先…其次…再次…总结来说…” → judge打+1
直接回答"是的"→judge 打 0
这样 → 模型学会了用格式骗judge,而非真正理解用户需求 → 用户说“你每次回答都太长了”,但RL信号依然继续强化长度
失败模式二:Goodhart’s Law(古德哈特定律)
当一个度量指标变成目标时,它就不再是一个好的度量指标。

原始意图:用"next_state 是否有意义” 来衡量回复质量

RL优化后:

模型发现"给出一个会让用户追问下去的神秘答案" → 用户的 next_state 内容丰富 (追问) → judge 打高分 → 但实际上用户是因为"没搞懂"才追问的,并不是真正被帮到了
度量变成了目标→度量失效
失败模式三:隐性假设的不完整性

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐