☰
OpenClaw-RL 源码阅读笔记(1)基础:Agentic RL 与 OPD 的配置骨架怎么搭
2026/9/26 15:33:23 网站建设 项目流程

1. 从一次跑不通的 OpenClaw-RL 说起

OpenClaw-RL 是一个面向 Agentic RL 的在线强化学习框架,核心思路是把 Agent 每次动作之后收到的「下一状态」——用户回复、工具输出、终端报错、GUI 变化——当成训练信号回收利用。它提供三种模式:openclaw-rl(Binary RL / GRPO)、openclaw-opd(Hindsight-Guided On-Policy Distillation)、openclaw-combine(两者联合)。适合谁?适合已经了解 PPO/GRPO 基本概念、想读源码但被一堆配置文件劝退的工程师,也适合想把 Agent 接进训练闭环、却卡在「入口在哪、Key 填哪」的实践者。

我第一次拉下仓库时,最直接的感受不是算法难,而是配置骨架散:settings.json、config.toml、环境变量、CC Switch、Cline 各管一段,谁先谁后没有一张图。结果就是openclaw-rl能起来,openclaw-opd报 401;或者 rollout 跑通了,PRM 评分一直 pending。这篇笔记只做一件事:把基础篇的配置骨架搭起来,让最小可运行环境先跑通,再谈读openclaw_api_server.py那 730 行。

我会按「问题场景 → TaoToken 前置 → 可复制配置 → 验证请求 → 错排查 → 下一步」的顺序走。所有 Key/API 通道统一走 TaoToken,这样 RL、OPD、Combine 三个 server 不用各配一套上游,省掉大量对不齐的麻烦。

2. TaoToken 前置:统一 Key 与 API 通道

OpenClaw-RL 的推理侧默认对接 SGLang,但 PRM 评分、Hint Judge、Teacher log-probs 这些环节都要调外部模型。如果每个组件各填一个 base_url 和 key,配置会迅速失控。我的做法是:所有模型调用统一走 TaoToken 的 API 通道,只维护一份 Key。

TaoToken 在这里扮演的是「统一入口」:你拿到一个 API Key,配一个 base_url,RL server、OPD server、Combine server 以及 Cline 这类编辑器插件都指向同一个地址。官网入口在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 基址是 https://taotoken.net/api (注意这个不带 UTM)。

具体要准备的东西:

  • 一个 API Key:在控制台创建,见 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite
  • Key 管理页:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite
  • 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite

注意:Key 只放在本地环境变量或.env,不要写进会提交到 git 的settings.json。我见过有人把 key 直接塞进 config 然后 push,后面只能全部轮换。

如果你只是想先验证模型通道是否通,不用急着配 RL,直接去模型对话页发一条消息即可:https://taotoken.net/model-chat?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite 。通道通了,再往下搭骨架。

3. 可复制配置:settings.json 与 config.toml 骨架

OpenClaw-RL 的配置分两层:应用层用settings.json(OpenClaw App 侧,TypeScript),训练/服务层用config.toml(Python 侧,Slime/Megatron 风格)。两者通过环境变量桥接。下面是我实测能跑通的最小骨架。

3.1 settings.json:应用侧入口

这个文件决定 OpenClaw App 把请求发到哪、用哪个模型。关键字段是baseUrl和apiKey,都指向 TaoToken。

{ "provider": "openai-compatible", "baseUrl": "https://taotoken.net/api", "apiKey": "${TAOTOKEN_API_KEY}", "model": "claude-sonnet-4-20250514", "timeoutMs": 120000, "retry": { "maxAttempts": 3, "backoffMs": 800 }, "rollout": { "endpoint": "http://127.0.0.1:8780", "sessionHeader": "X-OpenClaw-Session" } }

这里${TAOTOKEN_API_KEY}是占位,实际从环境变量注入。rollout.endpoint指向本地 RL server 的 API 端口,OpenClaw App 的每轮对话会打到这个端口,由 server 决定是否转成训练样本。

3.2 config.toml:训练与服务侧骨架

Python 侧的config.toml管三件事:推理服务(SGLang)、训练(Megatron)、以及 OpenClaw 特有的 PRM/OPD 参数。最小骨架如下:

[server] host = "0.0.0.0" port = 8780 mode = "openclaw-rl" # 可选 openclaw-rl / openclaw-opd / openclaw-combine [upstream] base_url = "https://taotoken.net/api" api_key_env = "TAOTOKEN_API_KEY" prm_model = "claude-sonnet-4-20250514" hint_model = "claude-sonnet-4-20250514" teacher_model = "claude-sonnet-4-20250514" [prm] enable = true votes = 3 # PRM_M,多数投票次数 timeout_s = 60 [opd] enable = false # openclaw-opd / combine 时置 true hint_min_len = 10 topk = 20 [combine] w_rl = 1.0 # OPENCLAW_COMBINE_W_RL w_opd = 1.0 # OPENCLAW_COMBINE_W_OPD [rollout] function_path = "openclaw_rollout.generate_rollout_openclaw" passive = true # 被动等待用户驱动

三个 mode 的差异只在[opd]和[combine]段是否启用。openclaw-rl只用 PRM;openclaw-opd关 PRM、开 OPD;openclaw-combine两个都开。

3.3 环境变量:把两层粘起来

export TAOTOKEN_API_KEY="sk-你的key" export OPENCLAW_MODE="openclaw-rl" export OPENCLAW_COMBINE_W_RL=1.0 export OPENCLAW_COMBINE_W_OPD=1.0 export PRM_M=3

提示:config.toml里的api_key_env只写变量名,不写值。这样同一份 config 可以在不同机器上复用,Key 走各自的 shell 环境。

3.4 CC Switch 与 Cline 的接入

CC Switch 用来在多个 provider 配置间切换。给它加一个 TaoToken profile:

{ "name": "taotoken", "baseUrl": "https://taotoken.net/api", "apiKeyEnv": "TAOTOKEN_API_KEY", "models": ["claude-sonnet-4-20250514", "gpt-4o"] }

Cline(VS Code 插件)里选 OpenAI Compatible,Base URL 填https://taotoken.net/api,API Key 填同一个。这样你在编辑器里调试 Agent 逻辑时,和 RL server 走的是同一条通道,行为一致,排查问题时不会因为「编辑器能通、server 不通」而绕弯。

4. 验证请求:从单轮到 PRM 评分

配置搭好后,别急着开训练。按下面三步验证,每步都有明确的成功标志。

4.1 第一步:验证模型通道

curl -s https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet-4-20250514", "messages": [{"role": "user", "content": "reply with OK"}] }' | head -c 300

返回里有choices[0].message.content就算通。这一步不通,后面全白搭。

4.2 第二步:启动 RL server 并打一轮

python -m openclaw_rl.openclaw_api_server --config config.toml

启动日志里应该能看到submission_enabled初始为 True、PRM votes=3。然后模拟一轮对话:

curl -s http://127.0.0.1:8780/v1/chat \ -H "Content-Type: application/json" \ -H "X-OpenClaw-Session: test-session-001" \ -d '{"messages":[{"role":"user","content":"写一个快速排序"}]}'

成功标志:返回 assistant 回复,同时 server 日志出现pending turn stored。此时数据进了_pending_turn_data,等下一轮触发 PRM。

4.3 第三步:触发 PRM 评分

再发一轮,模拟用户反馈:

curl -s http://127.0.0.1:8780/v1/chat \ -H "Content-Type: application/json" \ -H "X-OpenClaw-Session: test-session-001" \ -d '{"messages":[{"role":"user","content":"不对,我要的是归并排序"}]}'

成功标志:日志出现_flush_pending_record→_fire_prm_scoring→_maybe_submit_ready_samples,最终打印sample submitted, reward=-1。这说明「下一状态信号 → PRM 评分 → 训练样本」这条链路通了。

注意:PRM 是异步的,sample submitted可能比 HTTP 返回晚几秒。别看到 HTTP 200 就以为评分完成了,盯日志。

5. 本篇常见错排查

5.1 401 / 403:Key 没注入

最常见。config.toml里写了api_key_env = "TAOTOKEN_API_KEY",但 shell 里没 export,或者用了sudo导致环境变量丢失。检查:

echo $TAOTOKEN_API_KEY | head -c 8

输出为空就是没注入。另外确认 base_url 是https://taotoken.net/api,不要多加/v1后缀导致路径重复。

5.2 PRM 一直 pending,样本不提交

日志停在pending turn stored不动。原因通常是PRM_M次查询里有超时,asyncio.gather卡住。把[prm].timeout_s调大,或临时把votes降到 1 验证链路。还有一种情况:session id 没带,server 无法把两轮关联到同一 session,自然不触发 flush。检查请求头X-OpenClaw-Session。

5.3 OPD 模式报 hint 为空

openclaw-opd下日志出现no valid hint。这是正常的——OPD 只对「下一状态包含明确指导信息」的 turn 生效。如果用户回复是「谢谢」,hint judge 会拒绝,该 turn 不产生 OPD 样本。想验证 OPD 链路,用带具体纠正的回复,比如「你应该先检查文件是否存在」。

5.4 Combine 模式 advantage 全为 0

openclaw-combine下如果w_rl和w_opd都是 0,advantage 恒为 0,训练不动。检查环境变量OPENCLAW_COMBINE_W_RL/OPENCLAW_COMBINE_W_OPD是否被覆盖成 0。默认都是 1.0。

5.5 Cline 能通但 server 不通

两者 base_url 一样却结果不同,多半是 Cline 用了自己的代理设置或证书。对比两边的实际请求:Cline 侧看输出面板的 request log,server 侧加--log-level debug。差异通常在 header 或超时上。

6. 下一步:读源码与长期编码

骨架跑通后,读源码的顺序建议是:先openclaw_api_server.py的_flush_pending_record和_maybe_submit_ready_samples,理解双缓冲异步状态机;再看openclaw_opd_api_server.py的 hint judge 流程;最后看combine_loss.py那 140 行,理解 RL 和 OPD 如何在同一个 PPO 更新里解耦。

如果你打算长期在这套框架上做 Agent 编码实验,建议把 Key 和通道固定下来,用 Coding Plan 管理额度与模型切换:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。接入细节随时查文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。

我踩过的一个坑:一开始把 PRM 和 Hint Judge 配成不同 provider,结果两边的超时和重试策略不一致,排查异步问题时非常痛苦。统一走 TaoToken 之后,至少「通道」这个变量被消掉了,剩下的都是框架本身的问题,好定位得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询