游乐游手机版
首页/AI教程/文章详情

OpenClaw-RL源码阅读笔记:第六节Rollout强化学习与OPD核心详解

时间:2026-06-19 14:01
OpenClaw-RL框架的Rollout环节是策略与环境的交互过程。与标准主动生成轨迹不同,OpenClaw被动等待真实用户发起对话,从队列收集完整样本,实现基于环境反馈的在线强化学习,支持多种训练模式。

【Agentic RL / 强化学习 / OPD】OpenClaw-RL 源码阅读笔记 --- (6)--- Rollout

我们先从核心概念说起。强化学习中有一个基础环节叫做“Rollout”。本文将重点探讨这一环节——在OpenClaw-RL框架中,Rollout是如何设计与实现的。当然,代码只是切入点,更重要的是借此理清强化学习的相关设计思路。

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

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

framework

一个标准的RL训练管道可以粗略划分为5个阶段(实际会有重叠,依系统而异),本阶段重点介绍第三阶段——Rollout。

Stage 1 Stage 2 Stage 3 Stage 4 Stage 5
─────────────────────────────────────────────
Prompt  Rollout Reward  Advantage  Gradient
Selection      Generation Scoring    Computation  Update
   "问什么"    "怎么答"    "打几分"    "好了多少"   "往哪走"

0x01 Rollout基础

所谓rollout,就是用当前策略在环境中运行一遍,生成一条完整的交互轨迹:τ = (s₀, a₀, r₀, ..., sₜ, aₜ, rₜ)。

1.1 概念

在RL框架的语境里,“rollout”这个词其实包含两个层面的含义:

  • 含义1(过程):“doing a rollout”指的是用策略在环境中生成轨迹的这一动作。
  • 含义2(结果):“the rollout”指的是生成出来的那条轨迹数据,包含了tokens、log_probs、reward、loss_mask等一系列信息。

在Slime的代码中,generate_rollout_openclaw()这个函数名使用的是含义1(执行rollout过程),它返回的RolloutFnTrainOutput(samples=...)则是含义2(rollout的结果数据)。

1.1.1 标准RL

在标准设置下,rollout就是在环境中执行策略,产生一条完整的交互轨迹(trajectory)。

形式化的定义如下:

给定策略 π 和环境 E,一次 rollout 产生一条轨迹 τ:
τ = (s₀, a₀, r₀, s₁, a₁, r₁, ..., sₜ, aₜ, rₜ)
其中:
  s₀ ~ ρ₀           (初始状态,从prompt分布采样)
  aₜ ~ π(·|sₜ)      (策略生成 action)
  s₊₁ ~ P(·|sₜ, aₜ) (环境状态转移)
  rₜ = R(sₜ, aₜ)     (环境给出奖励)
1.1.2 LLM RL

在LLM RL的语境下,一次rollout = 给定一个prompt,模型生成一个完整response + 记录log-probs + 打分。换个更简洁的描述:一次rollout = 给定一个prompt,模型生成一个完整response。

s₀ = prompt                (初始状态)
a₀, a₁, ..., aₜ = response 的每个 token(一系列 action)
r = 对整个 response 的打分(terminal reward)
轨迹 τ = (prompt, token₁, token₂, ..., tokenₜ, reward)

注意一个关键区别:LLM的rollout通常是single-step episode,一轮对话即结束,不像游戏环境那样有多步交互。

1.1.3 GRPO

一个GRPO的rollout batch,流程如下:

  • 采样B个prompt
  • 每个prompt生成N个response
  • 总共得到B × N条轨迹

每条轨迹包含的数据:

  • prompt(输入)
  • response tokens(actions)
  • log π_old (a_t | s_t)(旧策略的log-probs,用于后续PPO ratio计算)
  • reward(打分)
1.1.4 OpenClaw-RL

OpenClaw的rollout有一个非常鲜明的特点:不主动生成,而是等待用户发起对话,再从队列中收集。凑够rollout_batch_size个样本,就算完成一次“rollout”。

每条轨迹包含的信息:

  • prompt = 用户消息(s₀)
  • response = 模型回复(a₀...aₜ)
  • rollout_log_probs = SGLang生成时记录的log π_old(用于PPO ratio)
  • reward = PRM评分 {-1, 0, +1}
  • (OPD模式)teacher_log_probs = teacher模型的log-probs

主动和被动两种方式的对比,非常直观:

标准RL Rollout:
────────────────────────────────────────────────
dataset = load("math_data.jsonl")
for prompt in dataset.sample(batch_size):        ← 主动选题
    responses = model.generate(prompt, n=4)     ← 主动生成N个
    for resp in responses:
        score = reward_model(resp)
        submit(prompt, resp, score)

OpenClaw Rollout:
────────────────────────────────────────────────
@openclaw_rollout.py
def generate_rollout_openclaw(...):
    worker.resume_submission()                    ← 打开阀门
    while len(data) < rollout_batch_size:
        data += queue.get()                      ← 等!等用户发消息
        await asyncio.sleep(0.05)                ← 继续等...
    worker.pause_submission()                    ← 关阀门
    return data
    # 数据从哪来?从APIServer的请求处理流程来
    # rollout函数本身不生成任何数据!

总结成表格,差异更清楚:

标准RL OpenClaw
谁控制prompt? 训练系统 用户
谁控制N? 训练系统(n=4~16) 用户(永远n=1)
数据到达时间 确定的(GPU生成速度) 不确定的(等用户)
--disable-rollout-global-dataset 不需要 必须(没有dataset)

1.2 RL2 对比

拿RL2这个框架来做对比,看看它怎么做rollout,可以更好地理解OpenClaw的设计取舍。

RL2的架构核心是:在同一组GPU上交替做推理和训练。换句话说,RL2 = 一个on-policy RL循环,把LLM当policy network,把推理服务器当采样器。

6-RL2

展开核心数据流是这样的:

6-核心数据流

三个核心子系统及其职责:

  • Rollout = SGLang推理 + 环境交互 → 产出(token序列,reward)
  • Actor/Critic = FSDP分布式模型 → 计算logps/values → 反向传播
  • Environment = env_step(action) → reward(规则/外部API/LLM judge)

几点关键理解:

  1. Reward不是一个独立模块——它集成在env_step里,具体实现方式完全灵活(规则/外部服务/LLM judge都行)。
  2. PRM可以通过多轮环境来实现——每个step返回中间reward,累加到轨迹中。
  3. 整个Rollout是异步的——SampleGroup并发、env_step可以调外部网络、SGLang请求并发。
  4. 所有组件共享同一组GPU——通过offload + memory occupation管理实现时分复用。

0x02 OpenClaw-RL Rollout基础

在OpenClaw-RL里,Rollout本质上是Policy Serving和Environment这两者的交叉。

Rollout = 在环境中执行策略,生成完整轨迹的过程 = Policy的推理输出 × Environment的状态转移

它的完整循环大致如下:

Environment 提供 State(t)(用户消息)
       ↓
Policy Serving 执行推理 → Action(t)(模型回复)
       ↓
Environment 接收 Action(t) → Environment 提供 State(t+1)(用户下一条消息)
       ↓
重复,直到session结束

2.1 硬件架构

在OpenClaw-RL的硬件架构里,GPU 4-5标记的名称是“SGLang Rollout Engine”。但它实际负责的是rollout的Policy Serving侧:

  • 接收HTTP请求(用户消息)
  • 运行LLM推理,生成token
  • 返回模型回复

而rollout的Environment侧(用户行为)则在GPU之外:

  • 用户什么时候发消息? → 外部世界决定
  • 用户发什么内容? → 外部世界决定
  • 用户是否继续对话? → 外部世界决定
┌──────────────────────────────────────────────────────────────┐
│                     Rollout(概念上)                          │
│                                                              │
│  ┌─────────────────┐          ┌───────────────────────┐      │
│  │  Policy Serving │          │     Environment       │      │
│  │   GPU 4-5       │    +    │   真实用户(外部)     │      │
│  │  LLM推理生成回复 │          │   提供state、接收action│      │
│  └─────────────────┘          └───────────────────────┘      │
│                                                              │
└──────────────────────────────────────────────────────────────┘

2.2 总体模块交互架构图

OpenClaw-RL的整体模块交互架构图(以Combine方法为例)如下,可以从中清晰定位到Rollout相关内容。

6-模块交互架构图

2.3 Slime 的 RolloutFunction 封装

在代码层面,Slime用一个函数把rollout的所有逻辑都包裹起来:

# openclaw-rl/openclaw_rollout.py
def generate_rollout_openclaw(args, rollout_id, data_buffer, evaluation=False):
    """
    Slime的rollout function:

    标准rollout(主动生成):
        rollout_engine.generate(prompts) → 直接调LLM生成轨迹
        = Policy Serving(GPU 4-5)自己完成整个rollout
        Environment是静态的(题目数据集)

    OpenClaw的被动rollout:
        等待 _sample_queue.get() → 从真实用户对话中取已完成的轨迹
        = Policy Serving已经完成了(对话已结束)
        = Environment已经交互过了(用户消息已收到)
        = 这里只是"收集"已经发生的rollout
    """
    while len(samples) < batch_size:
        sample = _sample_queue.get(block=True)  # 被动等待
    return samples

--disable-rollout-global-dataset这个参数的含义,简单说就是:告诉Slime“不需要你主动用LLM生成rollout”,同时告诉它“我的rollout由真实用户+Policy Serving联合产生,你只管拿已完成的样本”。

具体流程如下图:

Slime训练框架调用:
generate_rollout_openclaw(args, rollout_id, data_buffer)
       │
       │  passive rollout:
       │  不主动生成,等待真实对话产生数据
       ▼
+---------------------------------------+
|  worker.resume_submission()           |  <- 开启 submission_enabled Event
|  _drain_output_queue()                |  <- 等待 rollout_batch_size=16 组
+---------------------------------------+
       │
       ▼
(数据由异步 FastAPI handler 填入)

2.4 被动Rollout

OpenClaw-RL的rollout是典型的被动rollout。generate_rollout_openclaw()等待真实用户发消息,而不是主动从prompt池中挑选问题来生成回答。这意味着系统对rollout allocation(选什么问题来训练)几乎没有控制权——全由用户说了算。

优势:

  • 训练数据就是真实用户对话,天然分布对齐,不存在train-deploy distribution gap。
  • 用户多样性天然提供了entropy保障和batch内的reward方差。
  • 无需维护prompt数据集。

劣势:

  • 无法做curriculum learning(由简到难的教学顺序)。
  • 无法增大group size G(每turn只有一条用户消息)。
  • 无法做dynamic sampling(不能要求用户“换个问题再问”)。
  • Rollout allocation几乎完全失控。

2.5 小结

  • 概念上:Rollout = Policy Serving + Environment两者的交互过程,不属于任何一方专有。
  • 架构上:GPU 4-5标记为“Rollout Engine”,但实际只承担了Policy Serving(推理)侧的工作。
  • 代码上generate_rollout_openclaw是一个被动的收集器,真正的rollout在FastAPI服务器处理用户请求时就已经完成了。

0x03 OpenClaw-RL Rollout 实现

3.1 Rollout 完整流程

6-Rollout完整流程

几个关键设计要点:

机制 实现方式
next_state 滞后 turn N的next_state = turn N+1请求里messages的最后一条
PRM 异步 asyncio.create_task + done_callback触发提交
at-least-one session全为score=0时,首个turn强制loss_mask=1
权重同步暂停 submission_enabled Event控制,同步中返回503

3.2 Session 生命周期

假设一个session含有三轮对话:

turn 1 → [buffered, waiting next_state]
turn 2 → flush turn1(next_state = turn2.messages[-1])→ PRM(turn1) fire
turn 3 → flush turn2(next_state = turn3.messages[-1])→ PRM(turn2) fire
session_done=True → flush last_turn(next_state=None)→ force_no_prm
3.2.1 示例

下图展示了rollout的一个3-turn示例。

6-3-turn示例

3.2.2 单个 Turn 的完整处理流程

6-单个Turn的完整处理流程

3.2.3 多个 Turn 的机制

关键时序在于next_state的“延迟到达”机制:

  • Turn 1发生时:用户发消息M1 → SGLang生成R1 → 返回给用户。但此时R1的next_state还没出现(用户还没回复),所以_pending_records[session_id] = {response_text: R1},等待Turn 2。

  • Turn 2发生时:用户发消息M2(即Turn 1的next_state)。_handle_request()被调用,messages[-1]=M2就是Turn 1的next_state——直到此刻才可用!然后_flush_pending_record(session_id, M2)被调用,_fire_prm_scoring(R1, next_state=M2)被异步触发。同时SGLang生成R2,返回给用户。_pending_records[session_id]={response_text:R2},等待Turn 3。

  • PRM评估R1的结果异步返回_submit_turn_sample(turn_data_1, prm_result_1)output_queue.put(Sample(loss_mask=..., reward=score_1))

这个设计的微妙之处在于:每个turn的reward,是在下一个HTTP请求到达的时刻才确定的,而不是在当前请求结束的时刻。这是OpenClaw Rollout中最独特的工程设计。

3.3 At-Least-One Guarantee

At-Least-One Guarantee的作用很简单:防止整个session贡献零梯度。确保即使最“平庸”的session,也至少有一个turn进入训练。可以理解为Reinforce-Ada“强制至少一个梯度”的session级版本。

它是最直接的零梯度修复方案。具体做法:第一个被PRM评过(has_next_state=True)但score=0的turn,强制将其loss_mask设为[1],让它参与训练。这样每个session至少贡献一个样本。

# _submit_turn_sample()中的核心逻辑:
exclude = not has_next_state or score == 0.0
# 正常情况下:score=0 → exclude=True → loss_mask=[0, 0, ..., 0]
# 但是!特殊保障:
if exclude and has_next_state and self._session_effective.get(session_id, 0) == 0:
    exclude = False  # ← 强制参与训练!
    # "at-least-one guarantee"
    # openclaw_api_server.py:615-622
    # 使用 _session_effective 计数器追踪每个 session 的有效样本数
    # 首个 has_next_state 但 score=0 的 turn → 强制 exclude=False
if exclude and has_next_state and self._session_effective.get(session_id, 0) == 0:
    exclude = False  # ← 强制参与训练!
    # "at-least-one guarantee"
    # 之后 self._session_effective[session_id] += 1
3.3.1 问题情景

设想一个极端场景:整个session的所有turn都score=0。

用户发了5条消息,但每次都是中性反馈(score=0)→ 所有turn的loss_mask=[0] → 这个session对训练没有任何贡献 → 分母增大但分子不变 → rollout_batch_size难以填满 → 训练停滞。

3.3.2 逻辑分析
  • 问题的逻辑:全部loss_mask=[0] → 整个session贡献零梯度。
  • At-Least-One触发records[0]["loss_mask"]=[1]强制打开第一个turn的门,但reward不变,还是0.0。
  • 此时的梯度情况
    • loss_mask=[1](门打开了)
    • reward=0.0 → advantage由GRPO的批内归一化决定
    • 在训练batch中,这个样本会与来自其他session的+1/-1样本一起归一化
    • 这个0.0 reward的样本advantage ≈ 0(在均值附近)
    • 贡献的梯度接近但不等于零
  • at-least-one的真正价值:确保Policy不会在这类对话上“完全不见光”。即使效果微弱,也让这种回复参与了分布的锚定,防止Policy在这类对话上悄悄退化。
3.3.3 直观类比
  • loss_mask = 考试是否交卷:0代表这次不参加考试(完全不影响成绩),1代表参加考试(成绩会影响最终评价)。
  • advantage = 这次考试得了多少分:正值是鼓励,负值是惩罚,接近0则基本没有反馈。
  • at-least-one = “就算这次内容不好,也必须交卷”:强制loss_mask=1,哪怕advantage≈0。至少这次答题留下了记录,不会被系统彻底忽视。
3.3.4 设计要点
为什么score=0用loss_mask=0而不是advantage=0?

两种方式理论上都产生零梯度(在kl-coef=0时)。但实践中loss_mask=0更优:

  • 效率:直接跳过这些token的梯度计算,节省计算资源。
  • 语义清晰:明确表达“这个turn没有学习价值,不参与训练”。
  • --kl-coef=0.0一致:如果有KL惩罚,advantage=0的token仍会通过KL term产生梯度,loss_mask=0则彻底排除,避免这种副作用。
为什么Binary RL需要at-least-one

Binary RL面临的具体问题是:训练饥饿(training starvation)。

设想一个极端场景:

Session A: turn1 → score=0, turn2 → score=0, turn3 → score=0
Session B: turn1 → score=0, turn2 → score=0
- → output_queue中全是 loss_mask=[0]*T 的样本
- → Slime收到 rollout_batch_size 个样本
- → 前向传播正常,但 ∂L/∂θ ≈ 0(所有token都被mask掉)
- → 实际上没有任何参数更新
- → 占用了一次完整的rollout+forward pass+backward pass,什么也没学到

at-least-one的修复:

# openclaw_api_server.py
if exclude and has_next_state and self._session_effective.get(session_id, 0) == 0:
    exclude = False  # 强制loss_mask=[1]
    # 但reward保持0.0!

注意:被promote的样本reward仍然是0.0,所以advantage ≈ 0,梯度实际上接近0。它解决的并不是“学到有用信号”的问题,而是确保:

  • output_queue里每个session至少有一个非ABORTED的样本(Slime的sample状态机有相关要求)。
  • 防止Slime内部因为全mask=0的batch触发边界异常。
为什么 OPD/Combine 不需要

根本原因在于两种“零贡献”的本质不同。关键区别在于:Binary RL的零贡献样本会“占据”批次槽位但静默无效;OPD/Combine则完全不产生这种样本。

Binary RL的零贡献路径score=0 → exclude=True → loss_mask=[0]*T → 样本进入output_queue,但不产生梯度。样本在批次中“占位”,Slime看得到,但无梯度流动。

OPD/Combine的零贡献路径hint被拒绝 & evl=0 → 样本根本不进入output_queue(直接丢弃)。样本对Slime来说就等于不存在。

OPD的信号结构:

情形 是否进入队列 advantage
hint 接受 teacher_lp - rollout_lp ≠ 0(几乎必然)
hint 拒绝 ×(丢弃) N/A

OPD样本要么有真实的per-token教师信号(即使reward=0,advantage也非零),要么根本不进队列。不存在“占位但无梯度”的中间状态。

Combine的信号结构:

情形 进队列? OPD项 RL项
OPD+RL ≠ 0 ≠ 0
OPD-only ≠ 0 = 0
RL-only = 0(数值对消) ≠ 0
丢弃 × N/A N/A

凡是进入队列的样本,至少有一个信号项非零——这是dispatch逻辑保证的。

这里有一个有趣的设计对称性:Binary RL存在“批次污染”问题,所以需要at-least-one作为“最低保证”;而OPD/Combine的dispatch逻辑本身就确保了“进队列=有信号”,问题从根源上被消除,at-least-one自然也就不再需要。

Binary RL的at-least-one是在loss_mask二元门控机制下的补丁,而OPD/Combine绕开了这个机制(始终loss_mask=[1],通过advantage对消来“关掉”不需要的信号),所以补丁也就不再需要。

0x04 AsyncRolloutWorker

AsyncRolloutWorker = 线程边界 + 开关 + 数据渡口。

4.1 功能

AsyncRolloutWorker是Slime(Policy Training)与FastAPI Server(Policy Serving)之间的线程边界管理器。它不做推理、不做打分,但它控制着Policy Serving的“营业时间”,控制着两侧的生命周期和数据流转。通过output_queue,它把FastAPI异步世界里生产的样本,安全地传递给Slime同步训练世界。

具体功能包括:

  • 启动和管理
  • API服务器管理:启动和管理OpenClawAPIServer实例,控制运行状态、资源分配,传递必要参数。
  • 样本队列管理:创建queue.Queue()作为样本传输通道,监控队列大小和积压情况,实现30秒无进展警告机制。
  • 训练批次收集/协调:等待足够数量的样本后触发训练,管理样本提交的暂停/恢复机制,显示收集的样本数量和耗时统计。
  • 提交控制(暂停/恢复)

4.2 示例图

6-示例图

4.3 三个核心职责

4.3.1 线程隔离:让FastAPI跑在独立asyncio事件循环里
  • Slime的主循环(训练)是同步代码。
  • FastAPI需要异步事件循环。
  • AsyncRolloutWorker把FastAPI server启动在独立的线程中,两侧互不阻塞。
# worker_thread_func 跑在独立线程
def worker_thread_func(self):
    asyncio.run(self.continuous_worker_loop())
    # asyncio.run() 创建独立事件循环
    # FastAPI/httpx 异步请求全在这个线程里

注意:continuous_worker_loop()本身只是一个sleep(1.0)的keepalive循环——真正的数据生产在FastAPI的request handler里,不在这里。

4.3.2 开关控制:submission_enabled 事件同步
def pause_submission(self):
    self._submission_enabled.clear()   # 关闸 → FastAPI返回503
    self._server.purge_record_files()  # 清理临时记录

def resume_submission(self):
    self._submission_enabled.set()     # 开闸 → FastAPI正常接受请求
  • threading.Event是跨线程安全的信号量。
  • Slime主线程通过这个事件控制FastAPI线程的“营业状态”。
  • weight sync期间 = paused = 503;rollout收集期间 = resumed = 正常。
4.3.3 数据渡口:output_queue 跨线程传递样本

queue.Queue是Python标准库中线程安全的FIFO,也是FastAPI线程和Slime主线程之间唯一的共享数据结构。

# FastAPI线程写入(async)
await asyncio.to_thread(self.output_queue.put, (sample.group_index, [sample]))

# Slime主线程读取(同步)
def get_completed_groups(self) -> list[tuple]:
    while True:
        completed.append(self.output_queue.get_nowait())

4.4 与 OpenClawAPIServer 的协作机制

AsyncRolloutWorker是OpenClaw-RL框架中的异步轨迹收集工作者,负责管理整个rollout数据收集流程的生命周期。

4.4.1 交互架构模式——生产者-消费者模式
  • OpenClawAPIServer:作为生产者,生成训练样本并放入队列。
  • AsyncRolloutWorker:作为消费者管理者,提供队列并协调消费过程。
  • Slime训练器:作为最终消费者,从队列中获取样本进行训练。
4.4.2 层次化控制结构
AsyncRolloutWorker(顶层控制)
    ↓ 创建并管理
OpenClawAPIServer(数据生产)
    ↓ 提交到
SampleQueue(数据传输)
    ↓ 消费于
SlimeTrainer(模型训练)
4.4.3 具体交互机制
队列传递机制
  • 队列创建:AsyncRolloutWorker在初始化时创建self.output_queue = queue.Queue()
  • 队列共享:将output_queue作为参数传递给OpenClawAPIServer。
  • 样本提交:OpenClawAPIServer调用self.output_queue.put((group_index, [sample]))
  • 队列消费:Slime训练器通过rollout_worker.get_output_queue()获取队列并消费。
状态同步机制
  • 提交开关:AsyncRolloutWorker维护_submission_enabled状态。
  • 暂停信号:训练开始前调用pause_submission()禁用提交。
  • 恢复信号:权重更新后调用resume_submission()启用提交。
  • API服务器响应:OpenClawAPIServer在提交前检查提交状态。
权重更新协调
  • 记录清理:AsyncRolloutWorker调用purge_record_files()清空记录文件。
  • 状态重置:确保新策略开始时的数据一致性。
  • API服务器配合:OpenClawAPIServer响应清理请求并重置内部状态。
4.4.4 两者配合的工作流程
初始化阶段

AsyncRolloutWorker初始化:创建输出队列,设置提交状态,初始化统计变量。

OpenClawAPIServer初始化:接收队列引用,初始化内部状态字典,启动FastAPI服务准备接收用户请求。

运行阶段

数据生产流程:用户请求到达 → OpenClawAPIServer处理请求并生成样本 → 调用_submit_turn_sample()创建Sample对象 → 执行self.output_queue.put(...) → AsyncRolloutWorker检测队列大小变化。

批次收集流程:AsyncRolloutWorker定期检查output_queue.qsize() → 当队列大小达到阈值时准备训练批次 → 调用pause_submission()防止新样本干扰 → 训练器从队列中提取完整批次。

训练阶段

权重更新协调:训练开始 → AsyncRolloutWorker暂停样本提交 → 调用purge_record_files() → 清空所有待处理的回合记录和状态 → 新策略模型加载到SGLang服务。

恢复运行:AsyncRolloutWorker调用resume_submission() → OpenClawAPIServer使用新策略处理后续请求 → 确保新旧策略数据不混合。

实际应用场景示例

正常对话流程
用户请求 → OpenClawAPIServer(生产样本)→ output_queue → AsyncRolloutWorker(监控队列)→ SlimeTrainer(消费训练)

权重更新流程
训练批次完成 → AsyncRolloutWorker.pause_submission() → purge_record_files() → 权重更新 → AsyncRolloutWorker.resume_submission() → 新策略生效

异常处理流程
队列积压警告 → AsyncRolloutWorker发出30秒超时警告 → 管理员介入或自动扩容 → 恢复正常处理

这种设计确保了OpenClaw-RL能够在保证用户体验的同时,高效地收集和处理强化学习训练数据,体现了解耦设计和异步处理的现代系统架构思想。

0xFF 参考

来源:https://juejin.cn/post/7652581847890346010
上一篇如何编写GitHub项目README.md文件 下一篇vibecoding最适配上古小黄鸭调试法
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
RAG四标融合企业知识资产体系四库协同GEO优化实践
AI教程 · 2026-07-01

RAG四标融合企业知识资产体系四库协同GEO优化实践

生成式AI正在彻底改写信息检索的底层逻辑。传统SEO依赖关键词堆砌和外链建设的策略,在大模型的内容采信规则下已经基本失效。取而代之的,是生成式引擎优化(GEO)。它不再关注外链数量,而是重点衡量你的知识是否结构化、证据链是否坚实、信源是否可靠——这些维度才是RAG(检索增强生成)架构真正看重的核心指

一个普通上班人分享WorkBuddy使用心得与真实体验
AI教程 · 2026-07-01

一个普通上班人分享WorkBuddy使用心得与真实体验

前言 最近我开始使用WorkBuddy——这是腾讯推出的一款AI办公工作台。差不多用了一周时间,趁印象还新鲜,把真实的使用感受记录下来,给还在犹豫的朋友做个参考。不吹不黑,只说实际体验。 初印象:不只是聊天机器人 之前用过不少AI工具,大多数就是个对话框,你问它答,答完就结束了。WorkBuddy不

AI幻觉变真功能实战教程:App Inventor 2视频录制拓展一周开发实录
AI教程 · 2026-07-01

AI幻觉变真功能实战教程:App Inventor 2视频录制拓展一周开发实录

先讲一个颇具戏剧性的开端。 这件事的开端颇显荒诞——有用户前来咨询,称AI Pro版的介绍中提到我们有一款“视频录制拓展”。团队全体成员都感到困惑,翻遍产品列表,发现根本不存在该组件。AI那种“一本正经胡说八道”的能力,这次确实让我们陷入尴尬。 按常理,此事到此便可结束——一句“抱歉,暂时没有这个拓

别再混淆OLAP和SQL-on-Hadoop两者查询本质不同
AI教程 · 2026-07-01

别再混淆OLAP和SQL-on-Hadoop两者查询本质不同

OLAP和SQL-on-Hadoop虽都使用SQL查询数据,但本质不同。SQL-on-Hadoop负责海量数据批量计算与ETL,查询速度秒级至分钟级;OLAP通过预聚合实现毫秒级多维分析,适合BI报表。两者在数据平台分工协作,前者是后厨加工,后者是前台快速服务。

GEO优化深度解析:AI偏好FAQ还是长文内容?
AI教程 · 2026-07-01

GEO优化深度解析:AI偏好FAQ还是长文内容?

在GEO优化中,AI对内容形式无统一偏好:FAQ在简单查询中引用率41%,长文在复杂查询中达58%。内容应基于用户意图选择形式,FAQ适配简单事实类问题,长文建立主题权威,两者互补而非替代。