作用 1:提供 Prompt(State)
谁提供真实用户通过手机 App怎么提供HTTP POST → /v1/chat/completions → body.messages特点完全不可控分布随用户群体变化openclaw_api_server.pyapp.post(“/v1/chat/completions”)async def chat_completions(request):body await request.json()messages body[“messages”] # → 这就是 environment 提供的 state3.2 作用 2给出 Reward谁打分PRMLLM JudgeGPU 6-7怎么打分构建评分 prompt → SGLang 生成 → 解析 \boxed{±1}特点有噪声majority vote m3 缓解score await self._prm_evaluate(session_id, turn_num, response_text, next_state)→ 内部调用 _majority_vote() 聚合返回 {-1, 0, 1}3.3 作用 3提供 Transition多轮场景谁驱动用户决定是否继续对话怎么转移用户发下一条消息 → 新的 state特点按单轮处理每个 turn 独立评分和训练实际使用 _pending_turn_data 字典存储待评分 turn 数据而非 sessions 容器。turn 在收到 next_state 后完成评分才提交为 training sample。self._pending_turn_data.setdefault(session_id, {})[turn_num] turn_data3.4 作用 4判断 Termination什么时候结束用户主动结束会话session_done 请求头为 true或 Session 超时由客户端/App 端决定非服务端主动判定if session_done:self._flush_pending_record(session_id, None)self._maybe_submit_ready_samples(session_id, force_no_prmTrue)# 随后清理 _session_effective 和 _turn_counts3.5 OpenClaw 环境的独特之处理解了四类作用后我们把 OpenClaw 的环境和标准 RL 做一个整体对比会发现几个关键差异标准 RL 环境: OpenClaw “环境”:env Gym(…) env 真实用户 × Nenv.reset() 不可重置env.step(action) 用户决定何时回复env.reward PRM 代理评分关键差异State 提供者 ≠ Reward 提供者State 由用户提供Reward 由 PRM 提供不是用户满意度。这一点是 OpenClaw 与传统 RL 最大的架构差异——传统 RL 中 reward 嵌在 env 规则里OpenClaw 把它解耦了。“环境是分布式的每个用户 一个独立环境实例环境总数 同时在线用户数动态变化。环境没有显式 API不是 env.step() → (obs, reward, done)而是 event-driven——HTTP 请求到来时才有数据。3.6 小结OpenClaw 的环境” 真实用户群体。用户提供 promptstatePRM 代替用户给出 reward。环境不可控、不可重置、不可预测——这是 OpenClaw 所有设计取舍的根源。也正因如此OpenClaw 无法用标准 env.step() 接口封装而必须采用 event-driven 的 FastAPI 处理——这就是下一章 0x04 要讨论的环境没有显式 API的根因。0x04 RewardReward到底属于 Environment还是Reward Judging答案: 两者都对, 取决于视角。4.1 视角差异这是一个 RL 理论和工程实践的视角差异:RL 理论视角: 工程实践视角:reward 是 environment 的输出 reward 是一个独立的评分模块env.step(a) → (s’, r, done) reward judge(prompt, response)r 是 env 的一部分 judge 是独立部署的服务为什么会有这个混淆?在传统 RL 中, reward 和 environment 绑定在一起:CartPole: env.step(push_left) → (new_angle, 1, False)↑reward 是 env 的一部分(杆没倒 → 1, 倒了 → 0)数学题: env 答案验证器reward (model_answer correct_answer) ? 1 : -1reward 内嵌在 environment 规则中但在 LLM RLHF/RL 中, environment 和 reward 被解耦了:LLM RL:environment (提供 prompt): 用户/dataset → promptreward judging (评分): RM / LLM judge / 人类标注两者独立部署、独立运行 → 形成了独立的 reward judging 阶段4.2 OpenClaw 中 Reward 的位置传统 RL 视角:Environment 用户(提供prompt) PRM(给reward) App(提供transition) → reward 属于 environmentOpenClaw 工程视角:用户提供 prompt ← 物理上在手机端PRM 评分 ← 物理上在 GPU 6-7两者毫无关系← 只是被 Proxy 串联在一起 → reward 属于独立的 “Reward Judging” 阶段OpenClaw 代码视角:prompt 来源: request.body.messages (HTTP 请求)reward 来源: _prm_evaluate() → _majority_vote() (异步评分)两者在同一个 API Server 中, 但执行时机完全不同:先收到用户消息 → 转发给 SGLang 生成回复 → 返回给用户之后异步调 PRM 评分 → 构建 Sample → 放入 queue正确的理解方式为Reward 理论上属于 environment 的一部分, 实践中是独立的 Reward Judging 阶段。两种说法都没错, 只是视角不同。在 OpenClaw 这种工程系统中, 把它看作独立阶段更有助于理解架构。Environment (广义)┌──────────────────┐ ┌─────────────────────────┐│ State 提供 │ │ Reward Judging ││ (用户App) │ │ (PRM, GPU 6-7) ││ │ │ ││ 功能: │ │ 功能: ││ 提供 prompt │ │ 评分 response ││ 提供 context │ │ majority vote │└──────────────────┘ └─────────────────────────┘理论上都属于 “environment”实践中 Reward Judging 是独立阶段4.3 Reward Judging 独立出来的好处传统 RL (reward 嵌入 env)┌─────────────────────────────────────────────────┐│ CartPole: reward 杆没倒 ││ → reward 规则写死在 env 代码里 ││ → 想改评分标准? 改 env 代码 → 重新编译 → 重新部署 ││ → reward 和 state transition 耦合 │└─────────────────────────────────────────────────┘LLM RLreward独立好处1可替换性今天用PRMLLMjudge→明天换trainedRM→后天用人类标注。只需换Stage 3其他阶段不动好处2可扩展性PRM独立部署在GPU6-7→可以独立扩容env用户和rewardPRM独立扩缩好处3异步解耦用户立即收到回复不等评分评分异步进行→不影响用户体验好处4多信号融合同时用PRM评分teacher log-probsOPD不同reward信号可以并行计算、按需组合好处5评分标准灵活修改评分prompt→改变评分行为不需要重新训练RM零成本调整4.4 可信度差异Environment Reward vs Judge Reward 的可信度差异8-可信度差异可信度光谱如下最可信 ←────────────────────────────────────────────────→ 最不可信数学验证 代码测试 Trained RM LLM Judge 用户点赞(√2证明) (单元测试) (偏好学习) (PRM) (拇指向上)确定性 确定性 高一致性 有噪声 极稀疏可验证 可验证 有偏可能 随机性 主观偏好窄领域 窄领域 中领域 广领域 广领域← OpenClaw 在这里: LLM Judge (PRM) →4.5 Judge Reward 的三种噪声来源噪声 1: 内在随机性 (temperature 0)同一个 (prompt, response) 调 3 次 → 可能得到 [1, 0, -1]缓解: majority vote (m3)残留风险: 2:1 的投票结果仍可能是错噪声 2: 系统偏好 (Systematic Bias)LLM judge 可能系统性偏好:更长的回答 (长度偏好)更自信的语气 (确定性偏好)特定格式 (列表偏好)缓解: 评分 prompt 工程残留风险: 很难完全消除噪声 3: 能力边界 (Capability Limitation)judge model 和 student model 同族 (都是 Qwen3)→ judge 可能在 student 擅长的领域给错分 → “以其昏昏使人昭昭”缓解: 用更大的 judge modelOpenClaw: judge 和 student 同大小 → 这个问题严重4.6 对训练的影响Environment Reward Judge Reward(如数学验证) (如 PRM)训练方向: ✅ 确定正确 ⚠️ 可能偏移收敛速度: ✅ 信号干净→快 ⚠️ 噪声→慢Reward hacking 风险: 低 (规则明确) 高 (judge 可被利用)适用范围: 窄 (需标准答案) 广 (任何对话)4.7 小结OpenClaw 选择了 Judge Reward (PRM) Reward Judging 独立的好处是可替换、可扩展、异步解耦。这换来了广适用性。代价是信号质量 → majority vote OPD dense signal 部分补偿质量损失即 Judge Reward 有三种噪声 (随机性、系统偏好、能力限制), 可信度远低于 Environment Reward (数学验证等)。0x05 Rollout Allocation在RL系统中的位置与职责Rollout Allocation 与 Environment 的三种关系如下5.1 情形A静态环境(数学代码题)EnvironmentVerifier(答案是否正确)→ 成本低(验证一次~0.1秒)→ 不保留状态(每次验证独立)Rollout Allocation 与 Environment 关系弱耦合—allocation只需要考虑哪些prompt有学习价值不用考虑environment状态因为environment每次都是空白的典型做法按历史pass rate过滤prompt(如GRPO的基础设置)VIP/Knapsack等根据学习价值动态分配rollout次数5.2 情形B有状态的动态环境(Web/ComputerUse/SWE)Environment 有状态的执行环境(浏览器/文件系统/代码沙箱)→ 成本高(重置环境可能需要几分钟)→ 保留状态(上一步的操作影响下一步的可选动作)Rollout Allocation 与Environment 强耦合耦合 1 重置成本影响分配环境A重置需要30秒→同样预算能跑更少rollout环境B重置需要5秒→同样预算能跑更多rollout分配必须考虑environment的cost差异耦合 2 环境反馈可以指导Early TerminationAgent在前5步完全没有进展→这条轨迹大概率全失败 → 提前终止这条rollout把预算给其他prompt→ RLAnything 的acc(a)a_low 判断就是这个逻辑耦合3 环境难度是动态的相同prompt不同初始环境状态→ 完全不同的难度同一个添加单元测试任务在干净仓库Vs复杂仓库里完全不一样因此→ Per-prompt allocation 不够需要 per-(promptenv_state) allocation5.3 情形C真实用户环境(OpenClaw-RL)Environment用户本人(外部不可控)→ 成本零(用户主动发消息无需主动触发)→ 状态用户的意图和上下文(完全外部决定)Rollout Allocation 与 Environment:完全被动一allocation不是系统做的是用户行为决定的用户发消息触发一个 rollout用户不发消息没有rollout分配发生在更下游哪些 turn 的 score ≠ 0 → 决定哪些 rollout 真正进入梯度 → 这是 Post-hoc filtering而非 Pre-allocation5.4 OpenClaw中的实际模块对应三个连接点① --disable-rollout-global-dataset 告诉Slime我不用你的PromptSampler(模块①) OpenClaw用真实用户替代了PromptSampler② openclaw_api_server.py 的/v1/chat/completions 模块② RolloutWorkers 的接口 但方向反了不是Workers 主动调 Environment而是Environment(用户)主动调Workers③_submit_pending_record() / _flush_pending_record() 模块③ Sample Filter 的逻辑 score0 的 turn → loss_mask0软过滤 at-least-one guarantee → 防止整个 session 被软过滤掉0x06 实现0x03 我们已经看了四类作用的代码位置。这一章我们回答一个更根本的问题为什么 OpenClaw 没有一个 environment.py 或 env.py 文件为什么没有把环境封装成一个 Environment 类6.1 标准 RL 的 Environment 接口在传统 RL 中环境是一个同步、可控、可重置的对象核心接口是 step(action) → (observation, reward, done)标准 RL如 Gymnasiumenv gym.make(“CartPole-v1”)obs env.reset()while not done:action policy(obs)obs, reward, done, info env.step(action) # ← 环境的核心接口标准 LLM RL 中环境通常不存在或非常简单数学题用答案验证器代码题用单元测试对话用下一个 prompt从 dataset 来。它们都满足可重复、可控制、无延迟的假设。6.2 OpenClaw 的 Environment无法封装的原因OpenClaw 的 environment 真实用户 OpenClaw App FastAPI Proxy 的组合它是异步、不可控、不可重置的“env” 是异步的、不可控的、不可重置的用户什么时候回复不知道用户回复什么不知道让用户重来不可能传统的 env.step() 接口根本不适用——因为调用方无法主动驱动环境只能被动等待用户发消息。所以 OpenClaw 没有封装成 Environment 类而是用 event-driven 的 FastAPI 处理HTTP 请求到来时才有数据每个请求触发一次完整的接收 obs → 执行 action → 计算 reward → 判断 done流程。