【Agentic RL / 强化学习 / OPD】OpenClaw-RL 源码阅读笔记 --- (1)---基础
目录
- [【Agentic RL / 强化学习 / OPD】OpenClaw-RL 源码阅读笔记 --- (1)---基础](#【Agentic RL / 强化学习 / OPD】OpenClaw-RL 源码阅读笔记 --- (1)---基础)
- [0x00 概要](#0x00 概要)
- [0x01 背景知识](#0x01 背景知识)
- [1.1 Agentic RL 的核心难点](#1.1 Agentic RL 的核心难点)
- 难点总览
- 难点详解
- [难点1:奖励信号稀疏 & 延迟](#难点1:奖励信号稀疏 & 延迟)
- [难点2:长序列下的 Credit Assignment](#难点2:长序列下的 Credit Assignment)
- 难点3:探索效率
- 难点4:环境多样性与泛化
- 难点5:安全性与不可逆操作
- [1.2 本项目难点](#1.2 本项目难点)
- 两种范式下的对比
- [OpenClaw-RL 特殊定位](#OpenClaw-RL 特殊定位)
- [1.2 胶水代码](#1.2 胶水代码)
- 解决的核心问题
- [OpenClaw-RL vs 标准 RL infra](#OpenClaw-RL vs 标准 RL infra)
- [1.1 Agentic RL 的核心难点](#1.1 Agentic RL 的核心难点)
- [0x02 论文基础](#0x02 论文基础)
- [2.1 核心问题](#2.1 核心问题)
- [2.2 如何解决](#2.2 如何解决)
- [Binary RL(二元强化学习)](#Binary RL(二元强化学习))
- [Hindsight-Guided On-Policy Distillation (OPD)](#Hindsight-Guided On-Policy Distillation (OPD))
- [Binary RL + OPD 联合训练](#Binary RL + OPD 联合训练)
- 三种优化方法的信号对比
- [0x03 Roadmap](#0x03 Roadmap)
- [3.1 优化分类](#3.1 优化分类)
- [Track 1](#Track 1)
- [Track 2](#Track 2)
- 对比总结
- [3.2 实际场景示意](#3.2 实际场景示意)
- [3.1 优化分类](#3.1 优化分类)
- [0xEE 广告](#0xEE 广告)
- 购买链接
- [0xFF 参考](#0xFF 参考)
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
现有 AI Agent 系统存在一个核心问题:被浪费的"下一状态信号"。每次 Agent 执行动作后收到的下一状态(用户回复、工具输出、终端状态变化、GUI 界面更新等),仅被用作生成下一轮对话的上下文,信息被提取后随即被丢弃,并未转化为实时训练模型的宝贵数据资源。
而 OpenClaw-RL 的核心理念正是将每一次交互都转化为学习机会。通过统一的技术框架和巧妙的方法设计,它把 OPD(On-Policy Distillation)变成一种在线的 next-state 学习机制,让 AI Agent 能够在持续服务用户的同时,从实时交互中自动学习和改进------无需人工标注,也无需停机重训。具体贡献如下:
- 首次将下一状态信号作为实时在线学习源:识别并系统性地回收了评估性和指导性两类信号,让 Agent 在真实交互中持续进化。
- 首个统一的异步 Agent RL 基础设施:支持个人对话、终端、GUI、SWE 和工具调用五种场景的统一训练,实现了策略服务、环境托管、PRM 评判和策略训练的完全解耦,确保服务零中断。
- Token 级方向性监督(OPD):不同于标量奖励将所有 Token 推向同一方向,OPD 提供每个 Token 的独立监督,因此响应内部不同 Token 可能被强化或抑制。
- 过程奖励与结果奖励的有机结合:借鉴 RLAnything 的洞察,在长视野 Agent 任务中证明过程奖励的不可或缺性。
0x01 背景知识
1.1 Agentic RL 的核心难点
我们回头再看看 Agentic RL 的核心难点。
LLM-RL 架构就是一个"带私教的模拟考试"系统------把 LM 当成一个大 policy,每次行动就是"生成一整个回答",然后根据这次回答的评分整体推一下参数。
而 Agentic RL 则是在"状态→动作→环境反馈"这个闭环上做 RL,LLM 只是这个闭环里实现策略的一部分。对"数据 Agent/工具 Agent"来说,真正重要的是"每一步选的工具和操作是否对任务有贡献"------在这个粒度上,单纯对最终回答打个分再 PPO 一下,是很难学到东西的。
一句话总结:LLM-RL 优化的是"回答好不好";而 Agentic RL 优化的是"整个系统做事情做得好不好"。
难点总览
Agentic RL ≠ Chat RL,原因是:Agent 在真实环境中行动,环境是动态的、不可逆的、部分可观测的。Agentic RL 面对的核心挑战维度如下:
- 奖励信号:稀疏、延迟、噪声、误导
- 状态空间:高维、连续、非结构化(屏幕像素、文件系统、代码库)
- 动作空间:离散但巨大(自然语言 token 序列)
- 时间跨度:单步 → 多步 → 长程多轮
- 环境非静态:环境随 agent 的行动改变
- 安全性:错误动作不可逆(删文件、发邮件)
难点详解
难点1:奖励信号稀疏 & 延迟
问题:很多 Agent 任务只有最终结果可以评分。
- 写代码:只有代码能运行才是 +1
- GUI 操作:只有最终界面状态正确才是 +1
- 中间步骤无法评分 → 梯度无法有效传播
业界解法:
| 方法 | 代表工作 | 思路 |
|---|---|---|
| 结果验证 (RLVR) | DeepSeek-R1, QwQ | 可验证的任务(数学、代码)用 ground truth 打分 |
| LLM-as-Judge | Self-Rewarding LLM | 用大模型对中间步骤打分(本项目的 PRM 方案) |
| Process Reward Model | Let's Verify, ORM vs PRM | 训练专用的步骤评分模型 |
| Hindsight Labeling | HER, OpenClaw OPD | 用未来信息倒推当前步骤的质量 |
| 环境信号 | ALFWorld, WebArena | 把环境的 success/failure/error 作为自然奖励 |
难点2:长序列下的 Credit Assignment
问题:100 步任务,第 3 步的错误导致第 97 步失败,如何归因?
- 传统 RL:Monte Carlo returns(高方差)或 GAE(需要 Critic,贵)
- LLM RL:GRPO 直接广播 scalar reward → credit assignment 完全忽略 → 模型不知道"是哪个 token/step 导致失败"
业界解法:
| 方法 | 思路 |
|---|---|
| Step-Wise Reward | 对每步动作单独打分,映射到 token 跨度 |
| Advantage Decomposition | 把 Q(s,a) 分解为步骤级别 |
| Process Supervision | 每步要求模型写出中间推理,单独评分 |
| LLM Critic | 让另一个 LLM 估计 V(s)(但训练稳定性差) |
| OPD/Hindsight (本项目) | 用 teacher per-token log-probs 提供密集信号 |
难点3:探索效率
问题:LLM 的动作空间是整个 token 词表的指数序列,随机探索几乎不可能找到好的轨迹。
典型失败模式:Agent 尝试写代码 → 99% 时间生成语法错误 → reward = -1 → 永远无法采样到正确的轨迹来学习。
业界解法:
| 方法 | 思路 |
|---|---|
| 课程学习 | 从简单任务开始,逐步增加难度 |
| 树搜索 (MCTS + LLM) | 显式探索,保留有前景的状态节点 |
| 拒绝采样 | 只用成功轨迹训练(pass@k 筛选) |
| DAgger / Imitation + RL | 先 SFT 专家轨迹,再 RL 微调 |
| OPD (本项目) | 教师提供 hindsight hint,引导探索方向 |
难点4:环境多样性与泛化
问题:在一个环境(VSCode)中训练的 Agent 无法泛化到另一个环境(Vim)。
业界解法:
| 方法 | 代表工作 | 思路 |
|---|---|---|
| 大规模多样化环境 | WebArena, OSWorld | 覆盖大量不同 GUI/Web 场景 |
| 环境域随机化 | Robotics RL | 随机化物理参数 |
| 元学习 | MAML | 快速适应新环境 |
| 世界模型 | Dreamer V3 | 学习环境动力学,在模拟中训练 |
难点5:安全性与不可逆操作
问题:Agent 训练时犯错,可能删库、发邮件、支付费用。
业界解法:
| 方法 | 思路 |
|---|---|
| 沙箱环境 | Docker/VM 隔离,训练时用虚拟环境(本项目的 terminal-rl 用沙箱) |
| 人工审批环节 | 高风险操作需要确认(安全 overhead 大) |
| 保守策略约束 | KL 散度约束,限制 policy 偏离 ref model 太远 |
| 模拟器优先 | 先在模拟器中充分训练,再谨慎迁移到真实环境 |
1.2 本项目难点
如果按照解决难度来排(从易到难),业界图景中的定位大致如下:
python
数学 RL → 代码 RL → 工具调用 RL → SWE RL → GUI RL → 真实对话 RL
[✓] [✓] [✓] [◑] [◑] ↑ OpenClaw-RL
(有 GT) (有 GT) (部分 GT) (弱 GT) (环境反馈) (行为信号)
本项目的独特定位在于:
- 大多数工作在"有 ground truth"的任务上(数学对错、代码跑通/不通);
- OpenClaw-RL 面对的是"真实用户对话"------没有 ground truth,只有行为信号(用户的下一步操作)。长程多轮真实对话 RL 的难度非常大;
- OpenClaw-RL 处于难度谱的最困难端,其 Hindsight OPD 方法是对"无 ground truth 的真实任务"的一种创新性应答。
两种范式下的对比
结构上的根本差异如下。
单轮 RL:
python
π : Input (s) ---→ Output (a) ---→ Reward (r)
(一次映射) (一条回复) (一个分数)
Agentic RL:
python
π : S₀ ---a₀---→ S₁ ---a₁---→ S₂ ---a₂---→ ... ---aₙ---→ r
(循环映射) (状态转移由环境决定) (episode 结束才有分)
核心差异是时间维度:单轮 RL 没有时间,Agentic RL 的每个动作都发生在特定的时刻,其结果塑造了未来的状态。
OpenClaw-RL 特殊定位
python
纯单轮 RL OpenClaw 纯 Agentic RL
(InstructGPT) (多轮对话) (Web Agent)
| | |
1 轮 = 1 样本 每轮 = 1 样本(中间状态) T 轮 = 1 样本(episode)
dense reward dense but noisy sparse reward
无时间依赖 弱时间依赖 强时间依赖(状态转移)
OpenClaw 通过 next_state 机制,把多轮对话拆解成多个独立的单轮 RL 问题,从而回避了 Agentic RL 最难的两个问题:稀疏梯度和长 episode off-policy gap。但代价是:失去了 episode 级别的信息------对话整体质量无法被单个 turn 的 reward 完整捕捉。
1.2 胶水代码
看到一个搞 RL Infra 同学的一种说法:RL Infra 是"胶水代码"。我们以 OpenClaw-RL 为例来审视这个说法------确实,大多数开源组件不需要修改,因此在某种程度上,RL Infra 是"胶水代码"。
python
组件 来源 OpenClaw-RL 的工作
─────────────────────────────────────────────────────────────────────────
SGLang 推理服务 开源项目 (SGLang) ← 直接用,不改
Megatron 训练 开源项目 (Megatron-LM) ← 直接用,不改
Slime 框架 开源项目 (slime) ← 直接用,不改
Qwen3 模型 HuggingFace 下载 ← 直接用
OpenClaw App 项目的 TypeScript 侧 ← 已有,不改
真正新写的代码 (openclaw-rl/opd/combine) :
┌──────────────────────────────────────────────────────────┐
│ ~2660 行 Python (精确统计) │
│ 分布在 8 个 .py 文件中: │
│ │
│ openclaw-rl/openclaw_api_server.py 730 行 │
│ openclaw-rl/openclaw_rollout.py 152 行 │
│ openclaw-opd/openclaw_opd_api_server.py 1001 行 │
│ openclaw-opd/openclaw_opd_rollout.py 158 行 │
│ openclaw-opd/topk_distillation_loss.py 120 行 │
│ openclaw-combine/combine_loss.py 140 行 │
│ openclaw-combine/openclaw_combine_api_ 205 行 │
│ server.py │
│ openclaw-combine/openclaw_combine_rollout.py 155 行 │
│ │
│ ───────────────────────────────────────── │
│ 合计: 2661 行 │
└──────────────────────────────────────────────────────────┘
然而,胶水是有极高技术含量的。 胶水要处理异步状态管理、跨组件协调协议、框架接口适配这几个非平凡问题------这就是为什么代码量虽然不大,但设计密度相当高。
解决的核心问题
纯粹的"胶水"只是把 A 的输出接到 B 的输入。但 RL infra 要解决的问题更复杂。接下来,我们借助OpenClaw-RL来逐项拆解 RL infra 面对的几个核心问题,看看对"胶水"的高技术要求。
① 异步时序问题
推理发生在 turn t,但 reward 来自 turn t+1(next_state)。这意味着我们无法在 turn t 结束时立刻打分,需要一个有状态的异步状态机来桥接这个时间差。
具体的实现方案是双缓冲设计:
_pending_turn_data:dict[str, dict[int, dict]]------ 按 session → turn 维度暂存 turn 数据,等待 PRM 评分完成后再提交为 training sample。_pending_records:dict[str, dict]------ 按 session 维度暂存 JSON 记录,等待 next_state 到达后写入 record file 并触发 PRM 评分。
工作流程是:
turn N 到达 → 数据存入 _pending_turn_data 和 _pending_records → turn N+1 到达 → _flush_pending_record 弹出 _pending_records 中的记录并触发 _fire_prm_scoring→ PRM 异步完成后回调 _maybe_submit_ready_samples → 从 _pending_turn_data 取出数据提交 sample。
这不是简单的 pipeline,而是有状态的双缓冲异步状态机。OPD 服务器使用了相同的双缓冲设计。
② 训练与服务的权重同步问题
Megatron 更新参数后需要同步到 SGLang 推理引擎。同步期间 SGLang 不能服务请求(权重不一致),需要一套协调机制来避免推理出"半新半旧"的权重。
解法是通过 threading.Event 实现暂停/恢复信号:
generate_rollout_openclaw调用resume_submission()→ 收集完 batch 后调用pause_submission()- API 层在处理请求时检查
submission_enabled.is_set(),若为 False 则返回 HTTP 503 - 这个 503 是一个优雅的"稍后再试"信号,用户无感知,OpenClaw 客户端会自动重试
③ 奖励信号的延迟问题
PRM 打分是异步的------我们需要并行查询 m 次再做多数投票。这意味着训练不能立即可用数据,需要任务编排。
具体实现:
asyncio.gather并行发起 m 次 PRM 查询(_query_prm_once)asyncio.create_task创建后台评分任务task.add_done_callback注册两个回调:_task_done_cb(错误日志)和_maybe_submit_ready_samples(就绪检查 → 提交)
这个设计意味着:PRM 评分和用户请求处理是完全并行的,评分延迟不会阻塞用户的下一轮对话。
④ 被动 Rollout 的适配问题
Slime 默认期望一个"主动发 prompt"的 rollout 函数(即训练框架驱动数据生成),但 OpenClaw 的 rollout 是"等用户来驱动"------数据由真实的用户对话产生,而非训练脚本采样。
因此需要 generate_rollout_openclaw实现被动等待语义:
- 恢复 submission → 从 output_queue 中排空已收集的 sample → 暂停 submission → 返回给 trainer
- 这个函数是 Slime 框架要求的
--rollout-function-path自定义入口,属于对框架接口的非标准使用,需要对 Slime 的接口语义有精确理解
OpenClaw-RL vs 标准 RL infra
OpenClaw-RL 又与标准 RL infra 有所不同,我们来对比一下:
-
标准 RL infra(如 OpenRLHF):
prompt_batch → generate → score → train → loop- 数据流是单向的,时序是同步的
-
OpenClaw-RL:
用户行为驱动 → 异步打分 → 被动收集 → 异步训练- 数据流是反向的,时序是异步的。这个反转需要对每个组件的接口语义有深入理解,才能把"被动接收对话"适配进"主动采样"框架
一个直觉上的类比如下:
| 维度 | 标准 RL infra | OpenClaw-RL |
|---|---|---|
| 类比 | "工厂流水线"------原材料(prompt)进来,产品(trained model)出去,每道工序按顺序推进 | "餐厅后厨"------顾客点菜(用户发消息)是随机的、异步的;厨师(推理服务)响应;服务员(API proxy)收集反馈;大厨(训练)在后台利用空隙持续学习 |
| 数据驱动方 | 训练框架主动采样 | 用户行为驱动 |
| 时序特征 | 同步,单向 | 异步,反向 |
胶水代码负责让这个"餐厅"正常运转:确保厨师学到的菜谱及时更新,确保反馈被正确归因到正确的菜品,确保后厨繁忙时前台能优雅地暂停取菜。
0x02 论文基础
论文题目是:OpenClaw-RL: Train Any Agent Simply by Talking
论文主要贡献点分析:
- 主要创新点:首次提出将所有异构的交互信号(用户聊天、终端报错、GUI 界面变化)统一转化为实时的在线强化学习训练源。
- 关键技术与方法:设计了 OpenClaw-RL 异步解耦架构(推理、环境、裁判、训练四个循环互不阻塞);提出了两种互补的信号恢复方法,即二元强化学习(Binary RL)用于提取标量奖励,以及后见之明引导的同策略蒸馏(OPD / On-Policy Distillation)用于提取 Token 级别的方向性监督。
- 显著性结果与意义:不仅让个人专属 Agent 能通过日常聊天不断进化,还证明了这套架构能完美扩展到通用 Agent(如终端、GUI、软件工程、工具调用),在长逻辑链任务中取得了 SOTA 级别的提升。
2.1 核心问题
现有的 AI Agent 系统存在一个问题:每次 Agent 执行动作后收到的"下一状态信号"(用户回复、工具输出、终端状态变化、GUI 界面更新等),仅被用作生成下一轮对话的上下文,信息被提取后随即被丢弃,并未转化为实时训练模型的宝贵数据资源。这种"数据浪费"体现在两个层面:
- 评估信号浪费:下一状态信号隐含着对前一动作的评价(用户重新提问表示不满,测试通过表示成功,错误日志表示失败),这本是天然的过程奖励,但现有系统要么忽略,要么仅用于离线训练。
- 指导信号浪费:下一状态信号中往往包含具体的改进方向(如用户说"你应该先检查文件",或详细的 SWE 报错信息),但现有方法要么只能使用"对/错"这样的标量奖励,要么依赖预先准备好的反馈-响应配对,未能利用好实时、具体的指导性反馈。
现有方法的局限性
论文系统梳理了现有方法的不足:传统 RL for LLM 依赖集中式批量训练,需要预先收集数据集,无法个性化、实时优化,具体如下:
- RLHF/DPO:依赖离线偏好数据或成对比较,需要人工标注,无法从实时交互中学习
- 标准强化学习:使用标量奖励,无法将文本指导信息转化为策略梯度
- 蒸馏方法:依赖预策划的反馈-响应配对,而非实时信号
- 并发工作:虽然尝试在线利用下一状态信息,但纠错提示仍是隐式的
核心洞察
论文的核心观察是:下一状态信号是通用的,策略可以同时从所有类型的信号中学习。 个人对话、终端执行、GUI 交互、SWE 任务和工具调用轨迹不再是各自独立的训练问题,而是可以在同一循环中用于训练同一策略的交互流。基于这一观察,研究团队提出了 OpenClaw-RL------一个让 AI Agent"边用边学"的统一强化学习框架。
接下来,我们思考一个关键问题:为什么过程奖励对智能体任务至关重要?
在长视野的智能体任务中,仅有结果的奖励只在最终步骤提供梯度信号,而绝大多数轮次缺乏监督。PRM 根据下一状态信号为每轮分配奖励,在整个轨迹中提供密集的信用分配。近期的工作为此提供了强有力的实证证据------RLAnything 证明,将逐步的 PRM 信号与结果奖励整合,在 GUI 智能体、文本游戏智能体和编码任务中的表现始终优于仅使用结果的训练。
OpenClaw-RL 直接建立在这一洞察之上:它的 PRM 将实时的下一状态信号作为证据来评判每个轮次,并在实证部分证明这种密集的信号对长视野 RL 设置是有帮助的。
解法核心思想为:把用户日常对话本身变成训练信号,用"下一状态"(next state)作为天然的奖励来源------不需要人工标注,不需要中断使用体验。
2.2 如何解决
OpenClaw-RL 的个性化目标(通过 RL 优化策略权重),在本质上是"把用户偏好/对话经验写入模型权重",这是一种 Memory Consolidation(记忆固化)------推理时无需额外系统,知识被"内化"进参数。
OpenClaw-RL 主要采用三种学习方法。
这三种方法的关系如下:
- Binary RL (
openclaw-rl/):基础方法,PRM ±1 评分 + GRPO - OPD (
openclaw-opd/):独立实现的 Teacher 模型,通过 hint judge 生成 hint + teacher log-probs 蒸馏 - Combined (
openclaw-combine/):继承自 OPD(class OpenClawCombineAPIServer(OpenClawOPDAPIServer)),同时使用 RL Reward 和 OPD teacher signal
需要特别指出的是,Binary RL 和 OPD 是两套独立的实现,并非继承关系。从代码中可以清晰看到:
OpenClawAPIServer是独立类OpenClawOPDAPIServer是独立类- 只有
OpenClawCombineAPIServer继承自OpenClawOPDAPIServer
之所以这样设计,是因为 RL 和 OPD 的核心机制差异较大------RL 侧重 PRM 打分 + GRPO,OPD 侧重 hint 提取 + teacher log-probs 蒸馏------各自独立实现反而更清晰,而 Combine 复用 OPD 的 hint judge 基础设施再叠加 RL reward。
Binary RL(二元强化学习)
目标:将评估性下一状态信号转化为标量过程奖励。
PRM 根据用户的下一条回复或环境的执行结果,将 Agent 上一轮动作评为 +1(好)、-1(坏)或 0(中性),并通过 m 次独立评判后的多数投票获得稳定的标量奖励,训练采用 PPO 风格的 clip。
从源码来看,PRM 的评分 prompt 设计得非常精巧。核心逻辑是:
- 区分 next_state 的 role :
role='user'(用户自然语言反馈)和role='tool'(工具返回值)被明确区分,且 tool 返回值的前置说明是"这个内容在助手动作之前是不可用的------它存在是因为助手调用了工具",避免 PRM 误判; - 明确负面信号特征:用户要求"重做/重试/重复"("do it again", "try again")、请求"纠正/修改"("change X to Y", "no, I meant...")、或"改述/重申"同一请求("rephrases or restates"),这三类行为信号被明确标为 -1 的触发条件;
- 多数投票消噪 :单次 PRM 查询可能不稳定,因此查询 m 次(参数
PRM_M),取多数结果,平票则返回 0。
具体到训练层面,_submit_turn_sample 中还有一个"至少一个有效样本"的兜底保证:如果某个 session 迄今没有产生任何有效样本(_session_effective[session_id] == 0),即使当前 turn 的 PRM 分数为 0,也会被提升为有效样本(loss_mask = [1] 而非 [0])。这保证了每个 session 至少有一个 turn 参与训练,避免"全零 session"浪费数据。值得注意的是,这个兜底机制只在 RL server 中存在,OPD server 没有实现------因为 OPD 的样本有效性由 hint judge 是否接受来控制。
Hindsight-Guided On-Policy Distillation (OPD)
OpenClaw-RL 使用 Hindsight-Guided On-Policy Distillation(OPD)。
这样,OPD 让 AI 能从错误中学习,而且有超级老师指导,所以学得特别快!
- "后见之明" = 从错误中学到的有用提示
- "同策略蒸馏" = 学生 AI 向更厉害的教师 AI 学习
- "在线" = 边用边学,不用停下来专门训练
我们来看一个生动对比。
-
普通 RL 就像学骑自行车时,爸爸只在后面喊:"歪了!""又歪了!""还是歪了!"------你自己要想:到底是往左歪还是往右歪?该往哪边调整?
-
OPD 就像学骑自行车时,爸爸不仅扶着你,还说:"现在往右歪了,把手往左转一点""对!就是这样保持平衡""前面有石头,慢一点"------你立刻就知道:哦!原来这样调整就能保持平衡!
核心公式如下:
从源码来看,OPD 的实现比 RL 复杂得多。关键流程如下:
第一步:Hint Judge 并行查询 。Hint judge 的 prompt 不同于 PRM------不是打分,而是判断"下一状态是否包含能改进上一轮回复的有用信息",如果有则提取 1-3 句的具体提示,用 [HINT_START]...[HINT_END] 包裹。
第二步:选取最佳 hint 。从 m 次投票中筛出 score=1 且 hint 长度超过 10 字符的结果,选取 hint 最长的那条(max(good, key=lambda v: len(v["hint"].strip())))------因为更长的 hint 通常包含更多具体指导信息。
第三步:Teacher log-probs 计算。将 hint 追加到原 prompt 末尾,形成 enhanced prompt → 送到 teacher 模型(可以是更强的模型,也可以是同一模型的 teacher 推理模式)→ 在 student 生成的每个 response token 位置上查询 teacher 的 log-probability。
第四步:Token-level advantage 。A_t = logπ_teacher(a_t | s+hint) - logπ_student(a_t | s),逐 token 计算。与 RL 的全回答统一标量 reward 不同,这个信号是方向性的、逐 token 的。
OPD 的完整数据流如下图所示。
python
1.学生模型rollout → 生成agent对话(含tool calls + results)
↓
2.找到 (assistant_turn,next_state)对
例如:assistant写了有bug的代码 → tool返回pytest失败信息
↓
3.LLM Judge 从 next_state 提取 hint
例如:"应该用dict而不是list来存储映射关系"
↓
4.构建enhanced prompt=原始上下文+hint
↓
5.关键步骤:用VLLM的get_logprobs()计算:
- 输入:enhanced_prompt+学生原始回复的tokens
- 输出:模型在"知道hint"的条件下,对学生每个token的top-k logprobs
↓
6.得到 distill_token_ids[pos][k] 和 distill_logprobs[pos][k]
这就是 "teacher distribution"---------带有后验知识的概率分布
↓
7.Trainer计算逐token优势:
A_t = teacher_logprob(token_t) - student_logprob(token_t)
正值→teacher认可这个token→上调权重
负值→teacher不认可→下调权重
Binary RL + OPD 联合训练
OpenClaw-RL 的另一个关键设计是,它并不把 Binary RL 和 OPD 看成互相替代的两条路线,而是明确把它们设计成互补关系:
- Binary RL 的优点 是覆盖面广:几乎所有 turn 只要能从 next-state 判断出大致好坏,就能转成一个简单的 {+1, -1, 0} reward,因此它适合吃掉那些模糊、隐式、但普遍存在的 evaluative signal;缺点则是监督太粗,通常只能把整步动作往同一个方向推。
- OPD 则刚好相反:它要求 next-state 中存在足够明确、能被抽成 hint 的 directive information,覆盖率更低,但一旦样本成立,就能提供逐 token、带方向的细粒度纠偏。
因此前者是**"高覆盖、低分辨率"** ,后者是**"低覆盖、高分辨率"**。
OpenClaw-RL 的做法不是在两者间二选一,而是直接把它们合并在同一个 PPO 更新里:
\(A_t = w_{\text{binary}} r_t + w_{\text{opd}}\left(\log \pi_{\text{teacher}}(a_t\mid s_t^{\text{enhanced}}) - \log \pi_{\theta}(a_t\mid s_t)\right)\)
其中默认 \(w_{\text{binary}} = w_{\text{opd}} = 1\),通过环境变量 OPENCLAW_COMBINE_W_RL 和 OPENCLAW_COMBINE_W_OPD 控制。
这个式子的直觉也很清楚:binary RL 提供的是"这一步总体对不对"的全局方向,OPD 提供的是"具体哪些 token 应该增、哪些应该减"的局部修正。二者通过简单的加权和合并为一个统一的 advantage,然后走标准的 PPO clipped surrogate loss。论文里的实验现象也和这个分工一致:单独 binary RL 的提升比较有限,单独 OPD 提升更强但见效偏慢,而把两者结合起来效果最好。
从 combine_loss.py可以看到,这个联合 loss 的实现非常简洁------OPD 样本的 reward=0 所以 GRPO advantage=0,RL 样本的 teacher_log_probs ≈ rollout_log_probs 所以 teacher advantage ≈ 0,两个分支自然解耦,各自主导自己类型的样本。
Combine server 的调度逻辑决定了每个 turn 产生什么类型的样本:
| hint accepted? | eval ±1? | 样本类型 |
|---|---|---|
| yes | yes | OPD+RL combined |
| yes | no | OPD only |
| no | yes | RL only |
| no | no | 丢弃 |
三种优化方法的信号对比
| Binary RL (GRPO) | OPD (On-Policy Distill) | Combined (= RL + OPD) | |
|---|---|---|---|
| 信号来源 | next_state 隐式 | next_state 显式指令 | 两者皆有 |
| 优势计算 | A_t = scalar(全 response 统一) | A_t=logπ_teacher−logπ_student(per-token 粒度) |
A_t=w_rl⋅r+w_opd⋅(teacher−student) |
| 覆盖率 | 所有评分 turn | 只有 hint 被接受的 turn | 所有 turn |
| 训练样本数 | 多 | 少但质量高 | 最多 |
| 适用场景 | 隐式反馈(👍/👎) | 显式纠正("你应该...") | 混合场景(推荐) |
0x03 Roadmap
README.md 介绍了 Roadmap:
markdown
Our long-term goal is to **advance personalized, practically useful agents
with reinforcement learning**. The roadmap has two tracks:
#### Track 1 --- [Personal Agent Optimization](#personalagent)
✅ **Release Track 1:** Fully async OpenClaw-RL framework
with Binary RL + OPD
✅ Best recipe discovery via demonstration experiments
✅ Support LoRA Training
✅ Deploy training on [Tinker](https://thinkingmachines.ai/tinker/)
⬜ Support low-precision training/inference
⬜ Beyond the policy: extend learning to skills and memory
#### Track 2 --- [General Agents Optimization](#generalagent)
✅ **Release Track 2:** Scalable agentic RL infra for general agents
⬜ Support more cloud services
3.1 优化分类
个性化代理优化(Track 1):
- 日常对话:从用户的自然对话中学习个性化偏好
- 持续优化:在不中断使用的情况下持续改进代理能力
- 隐私保护:所有数据本地处理,无需上传敏感信息
通用代理强化学习(Track 2):
- 复杂任务:支持终端、GUI、软件工程等复杂操作任务
- 零标注学习:完全从环境反馈中学习,无需人工标注
- 多模态支持:处理文本、图像、工具调用等多种输入输出
Track 1
Track 1 用于 Personal Agent(openclaw-rl/opd/combine),其奖励来源:PRM(主)+ 环境信号(辅)。其中,环境信号(tool return)作为 next_state 的输入,由 PRM(LLM judge)解读后给出最终 reward。PRM 是必须的,环境信号是 PRM 的"证据"。
python
Turn N:助手回复
↓
Turn N+1 到达(next_state)
│
├─ 若 turn_type = "user" → 用户自然语言反馈
│ e.g. "再做一遍" → PRM → score=-1
│ "谢谢" → PRM → score=+1
└─ 若 turn_type = "tool" → 工具/环境返回值
e.g. Python 执行报错 → PRM → score=-1
工具成功返回 → PRM → score=+1
PRM 的 prompt 直接来自源码,关键节选如下:
python
# openclaw_api_server.py:83-87
"role='tool': The return value of a tool the assistant invoked. "
"This content was NOT available before the assistant's action --- "
"it exists BECAUSE the assistant called the tool. "
"A successful, non-error tool output means the assistant's action "
"worked correctly and should be scored positively."
这个设计很精妙:它让 PRM 理解了一个关键事实------tool 的输出是 agent 动作的结果 而非前置信息,因此成功输出 → 动作有效 → 正向奖励。如果 PRM 不理解这一点,可能会把 tool 返回的超长 JSON 当作"噪声输入"而给出错误的评分。
Track 2
Track 2 用于 General Agents(terminal-rl / toolcall-rl / swe-rl / gui-rl),其奖励来源:环境(主)+ PRM(可选增强)。
python
Terminal RL:
Agent 执行 bash 命令 → exit_code / stdout / stderr
→ 直接计算 reward(是否完成任务)
→ PRM 可选(PRM_ENABLE=1)用于 per-step 细粒度评分
(terminal-rl/generate.py:286)
Tool-call RL(ReTool):
模型调用代码解释器求解数学题 → 答案是否正确(可验证)
→ 直接计算 binary reward(correct/incorrect)
→ PRM 可选,用于 step-wise advantage 提升训练效率
对比总结
我们思考一下:为什么 Track 1 不直接用环境信号?因为个人助理场景的反馈是模糊自然语言("你理解错了"、"再说一遍"),没有程序化的 true/false。PRM 充当"理解人类意图的翻译器",把模糊反馈转化为可训练的标量 reward。
Track 2 则相反------exit code 和测试用例是天然的二值信号,不需要额外的 LLM 来"翻译"。
对比总结如下:
| Track 1 Personal Agent | Track 2 General Agents | |
|---|---|---|
| 主要 reward | PRM(LLM judge 解读 next_state) | 环境直接返回(exit code / 答案正确性) |
| 环境信号角色 | PRM 的输入证据 | 直接 reward 来源 |
| PRM 角色 | 核心必需组件 | 可选增强(per-step 细化) |
| 适用原因 | 用户对话反馈难以自动解析 | 任务结果可程序化验证 |
3.2 实际场景示意
python
用户: "帮我写个排序算法"
Assistant: "好的, 这是冒泡排序..." [turn N]
用户: "不对, 我需要快速排序" [next_state, role=user]
↓ 分类: (b) 修正请求 → \boxed{-1}
↓ score=-1.0 → loss_mask=[1] → reward=-1(惩罚错误响应)
用户: "帮我写个排序算法"
Assistant: "好的, 这是快速排序..." [turn N]
用户: "很好! 现在帮我优化一下" [next_state, role=user]
↓ 分类: (a) 正面推进 → \boxed{1}
↓ score=+1.0 → loss_mask=[1] → reward=+1(奖励正确响应)
0xEE 广告
继续给第二本书打广告。
购买链接
0xFF 参考
Agentic RL 训练:它不是单一 RL 算法,而是一整套环境建模、学习信号、异步数据流、策略优化和基础设施的协同系统
OpenClaw-RL: Train Any Agent Simply by Talking