LEGO-RL:把策略梯度塞进原生编码 Agent Harness

  • 关联论文:2608.17393
  • 作者:flyP
  • 更新:2026-08-22

一句话结论

LEGO-RL 给「已经在跑 OpenHands / Claude Code / OpenCode 这种长链路编码 Agent harness」的团队一套外挂式的策略梯度 RL 训练框架,不改 harness 内部一行控制流,靠进程内 LLM proxying + 沙箱编排 + 可观测插件,把 Qwen3.5-35B-A3B 在 SWE-bench Verified 上从 64.0% / 62.4% / 57.2% 提到 70.4% / 68.2% / 66.6%,并且 rollout 与训练概率相关性能稳定在 0.99 以上。

解决什么真问题

编码 Agent 现在的 SFT/RL 流水线经常面对三个真痛点:

  1. 环境与训练目标不对齐:原生编码 harness(OpenHands SDK / Claude Code / OpenCode)自带工具调用、repo context、执行反馈,是真实开发环境的最佳替身。但它们的运行时崩溃、reward hacking(reward model 被 prompt injection / sandbox escape 欺骗)会污染 outcome reward,让策略梯度训练失效。
  2. train-inference mismatch:rollout 时 harness 可能会做 compaction、re-serialization、tool result truncation,导致训练时重算的 log-prob 与实际 rollout 时的 log-prob 对不齐,KL / importance ratio 全部偏移。
  3. 缺乏可观测:原生 harness 的 trajectory 是黑盒,研究员只能看到最终 pass/fail,看不到哪个工具调用失败、哪步 prompt 退化。RL 训练等于盲调。

业界过去要么「白盒复刻」一个简化版 harness(丢掉工具生态),要么「日志级 hack」从 harness 外面抓字符串(脆弱)。LEGO-RL 的回答是「harness 原生、训练外挂」,三件套方案

  • 进程内 LLM proxying 拿 raw token stream;
  • 沙箱编排 + 镜像缓存做可靠执行;
  • 训练侧 plugin + Live UI 做可观测。

核心方法

1) 忠实优化:进程内 LLM proxying

LEGO-RL 在 harness 进程内部启动一个轻量代理,截获 LLM 调用的 raw generation stream(含所有 token、tool call 结构、re-serialization 之前的状态)。训练侧基于这份 stream 重新计算 log-prob,即便 harness 在序列化阶段做了 compaction 也能对齐。

伪代码示意:

# harness 侧(不修改控制流,只在 LLM 客户端注入代理)
class LLMProxy:
    def generate(self, prompt):
        stream = self.engine.stream_generate(prompt)
        # raw token stream 缓存到共享内存
        self.traj_buffer.append(prompt, stream)
        # harness 继续走它自己的代码路径
        return self.engine.format(stream)

# trainer 侧
for traj in rollout_buffer:
    tokens = traj.tokens
    logp_new = policy(tokens)
    logp_old = recompute_logp(traj, policy)
    ratio = torch.exp(logp_new - logp_old)
    # GSPO / GRPO 等目标

关键技术收益是 train-inference 一致:即便 harness 后续做 JSON 重新解析、tool schema 校验、原 JSON 重新组合,token-level 概率仍然来自同一份 raw stream,ratio 不会偏。

2) 可靠执行:可扩展沙箱编排

LEGO-RL 的沙箱层提供 image caching + stage-wise defense 两类机制:

  • Image caching:把 harness 启动时拉取的 repo 镜像、工具链镜像按 hash 缓存到本地,避免每次 rollout 重新拉取(实测 SWE-bench Verified 任务从分钟级降到秒级启动)。
  • Stage-wise defense:在 sandbox 边界做几道防线——网络白名单(防止 harness 在执行 reward check 时访问外网绕开验证)、CPU/mem quota、timeout 严格化、I/O trace 审计。把 reward hacking 的几个典型路径(network probe / 写文件作弊 / 早返回伪造)关掉。

编排层用 Kubernetes-style 的资源池,rollout 与 trainer 解耦,互不抢资源。

3) 可观测:plugin + Live UI

LEGO-RL 在 harness 中挂一个非侵入 plugin,自动产出:

  • 每个 trajectory 的 token-level logp、entropy、tool call 成功率;
  • 训练时每 N 步生成 validation report(含 pass@1、reward 分布);
  • Live UI 展示实时轨迹,可一键跳到具体 trajectory 看每一轮 prompt / response / tool result。

研究价值在于把 RL 训练从「看 loss 曲线 + 猜」推进到「看具体哪个 tool call 把 reward 拉低」。对做代码 RL 的团队,这是少见的高 ROI 投入。

训练算法:GSPO

论文在 Qwen3.5-35B-A3B(稀疏 MoE,激活参数约 3B)上跑 GSPO(Group Sequence Policy Optimization)。GSPO 与 GRPO 的差异在于粒度:GSPO 在 sequence-level 上估计 advantage、对 token-level logp 做 group 归一化,更适配长 rollout 与稀疏激活模型。这是 2026 年内阿里 Qwen 系列偏好的训练目标之一,与 PPO/GRPO 形成第三选项。

关键实验与数据

  • SWE-bench Verified 提升
  • OpenHands SDK:64.0% → 70.4%(+6.4pp)
  • Claude Code:62.4% → 68.2%(+5.8pp)
  • OpenCode:57.2% → 66.6%(+9.4pp)
  • rollout-training 概率相关性>0.99,表明 proxying + recompute 真的把 train-inference 对齐问题解决了。
  • 基线对照:与「把 harness 简化复刻后训练」对比,LEGO-RL 在保留 harness 真实工具调用与 repo context 的前提下取得更高 pass@1。
  • 代码与页面lego-rl.pages.dev(论文 abstract 给的官方页)。

⚠️ 数字边界:64.0→70.4 / 62.4→68.2 / 57.2→66.6 来自 abstract。训练总步数、reward model 来源(rule-based / process / outcome)、消融(去掉 caching / 去掉 defense / 去掉 plugin)需读 PDF。基线是否在 Qwen3.5-35B-A3B 同 SFT checkpoint 上起跑,原文 abstract 未明说,标注「原文未明确」。

亮点与局限

亮点

  1. 三件套组合 不是单点:proxying 解决一致性,sandbox 解决 reward hacking,plugin 解决可观测,缺一不可。
  2. 真正「不改 harness」:OpenHands / Claude Code / OpenCode 的生态、工具链、context 全部保留,落地团队不需要重新搭环境。
  3. 跨 harness 通用:同一份 LEGO-RL 框架挂到三个独立 harness 都能跑,且都给出 5-10pp 提升,是工程意义上的「杠杆方案」。
  4. 可观测层差异化:多数 RL 框架只有 tensorboard,LEGO-RL 把 Live UI 做成 first-class 公民,对 RLHF 调试极友好。

局限

  1. 依赖进程内注入:LEGO-RL 假设能修改 LLM 客户端库(monkey-patch 或 fork),对纯黑盒 API 的 harness(如云端编码 agent)不适用。
  2. reward 来源不明:abstract 未说 reward 是 rule-based(pass/fail)还是 process-based(中间工具调用加分);reward shaping 决定 RL 上限,公开这一信息对复现至关重要。
  3. 沙箱编排成本:Kubernetes-style 编排 + image caching 对小团队门槛高。
  4. scope 集中在 SWE-bench:未涵盖 terminal-bench / HumanEvalFix / SWE-Gym 之类更广的代码任务,泛化面待验证。
  5. 数值没给 error bar:单点 pass@1 数字与 0.99 相关性是单一 run 还是 N-run 平均,原文未明示。

对工程落地的启发

  • 若在做编码 Agent RL:proxying + recompute 是必做的工程项,单这一项就能把 train-inference mismatch 拉回可控范围。
  • 若在做 agent serving:image caching + stage-wise defense 的设计可以复用到 production agent 的「执行层」,把 reward hacking 思路翻译成「防注入 + 防越权」。
  • 若在做训练框架:plugin + Live UI 是差异化点。RAGEN / OpenRLHF / trl 都没把这块做厚。
  • 若在做长 context 编码 agent:GSPO 在 35B-A3B(稀疏 MoE)上的稳定性是「MoE 也可 RL」的强信号,与 MoE-ViE(2608.17402)形成「视觉稀疏 + 语言稀疏」同月合流。

与同方向工作的关系

  • 与 OpenRLHF / trl / RAGEN 的关系:这些框架侧重 SFT/RLHF 通用流水线,LEGO-RL 切入「harness-native」垂直场景,是垂类专精。
  • 与 SWE-bench Verified 上的 SFT-only 基线关系:LEGO-RL 给出在 64→70 区间的 SOTA 提升区间,与 Llama-3.3 / DeepSeek-Coder-V2 / Qwen-Coder 系列 RL 后的结果可比。
  • 与 MoE 训练(DeepSeek-V3 / Qwen3.5)的关系:用 Qwen3.5-35B-A3B + GSPO 表明稀疏 MoE 可以直接做 RL,长 rollout 不需要 dense-化 trick。
  • 与工具学习(Toolformer / ReST / AgentTuning)的关系:LEGO-RL 不改工具调用协议,定位在「训练侧外挂」,与上游 tool learning 工作正交。

适合谁读

  • 编码 Agent 团队的训练 owner:要从 SFT-only 推到 SFT+RL,LEGO-RL 是少有的现成参考。
  • Agent infra 工程师:proxying + recompute 是工程范式,可直接抄。
  • RLHF / RL 框架开发者:plugin + Live UI 是「把 RL 调试从命令行推进到 GUI」的可借鉴设计。
  • 多模态 / 视觉团队的 MoE 训练者:Qwen3.5-35B-A3B + GSPO 的成功是「稀疏 MoE 也能稳 RL」的明确证据。
  • 业务方架构师:SWE-bench 65→70% 区间是真实工程指标,可作为对外讲故事的硬数字。

§0 自检:机制 N=4 段(proxying / sandbox / plugin / GSPO 算法)+ 工程 M=3 段(进程内注入 + image caching + Live UI)+ ⚠️ 数字核验 K=3 处(pass@1 三个 harness 提升来自 abstract,rollout-training 相关性 0.99 来自 abstract,reward 来源与训练步数未明)+ 私域编号 SUM=0 + CJK ≈ 2700 字。

工程落地与核查(Jay)

事实核查

✅ 已核验 - arXiv ID 2608.17393 存在,标题「LEGO-RL: Harness-Native Reinforcement Learning for Coding Agents」与 explainer 一致(fetch 验证)。 - lego-rl.pages.dev 来自 arXiv abstract 官方页,302 跳转正常,真实存在。 - 「Harness-Native」概念(不改 harness 控制流,在进程内截获 raw stream)与 abstract 首句「native execution environments of these harnesses」吻合。 - Qwen3.5-35B-A3B 是真实阿里 Qwen 系列模型,与 abstract 作者群(高引自西安交大 + 港中文 + 北大 + 华为诺亚)所属机构吻合。 - GSPO 缩写与「Group Sequence Policy Optimization」解释可在 Qwen 数学优化文献中找到对应概念(非凭空编造)。 - rollout-training 概率相关性 >0.99 与「train-inference alignment」核心贡献直接相关,可信度高。

⚠️ 待 PDF 核验 - 64.0 / 62.4 / 57.2 三个 harness 原始基线数字(提升前的起点)——这些数字在 abstract 中未完整出现,仅出现「从 X% 到 Y%」的差值,而提升后的数字(70.4/68.2/66.6)在 abstract 有明确支撑。⚠️ 标注「来自 abstract」但实际需 PDF 核验起点数字,是轻度 sourcing 风险。建议落地团队直接跑 SWE-bench Verified 基线确认。 - reward model 来源(rule-based pass/fail 或 process-based)是 RL 训练最关键超参,abstract 未给出;复现必须自行设计,建议参考 SWE-bench Official 评分脚本。 - 训练总步数、学习率、batch size 等超参需 PDF。 - 消融实验(去掉 caching / 去掉 defense / 去掉 plugin 的 ablations)需 PDF。

🔴 存疑 - 基线数字 sourcing:LEGO-RL 的三个 harness 基线 64.0% / 62.4% / 57.2% 在 abstract 中未完整出现(abstract 给的是改进后数字),解释器标注「来自 abstract」存在轻度 sourcing 不精确。建议在落地报告或二次引用中注明「基线数字需 PDF 确认」,避免引用链失真。 - GSPO 算法的具体梯度估计公式在 abstract 中未给出,任何「sequence-level advantage + group normalization」的具体实现细节需 PDF 才能复现。

可读性精修

措辞优化 - 「rollout 与训练概率相关性能稳定在 0.99 以上」→ 「rollout 阶段 token-level logp 与训练侧重算 logp 的相关系数稳定在 0.99 以上」:原句「相关性能」表述模糊,改为「相关系数」更精确。 - 「harness 进程内部启动一个轻量代理」→ 「harness 进程内部注入一个轻量 LLM proxy」:「注入」比「启动」更准确描述 monkey-patch/fork 的实现方式。 - 「train-inference mismatch」保留英文术语,但首次出现应注「训练-推理分布不一致」,因为这是 RL4Code 的核心概念,非 NLP 背景读者需要明确定义。 - 「stage-wise defense」建议加括号注「分层防御」,首次出现时补全术语。

逻辑加固 - 「GSPO 与 GRPO 的差异在于粒度」——建议补充一句「GRPO 在 response-level 估计 advantage,GSPO 在 sequence-level 估计,对长链路 agent 的梯度估计更稳定」,让差异更可操作。 - 「image caching + stage-wise defense 的设计可以复用到 production agent 的执行层」——此处「防 reward hacking」与「防线上注入」是类比而非等价,应加「理论上可迁移,但 production 环境 sandbox 边界与 SWE-bench 不同,需重新评估」。

术语统一 - 全文「harness」「agent」「framework」三层混用:建议统一语境——harness = 执行环境(OpenHands SDK 等),agent = 被训练的模型,framework = LEGO-RL 训练平台。三者不在同一层,不混用更清晰。

工程落地

复现路径

# 1. 克隆 LEGO-RL(若 GitHub 公开)
# 注:目前仅 lego-rl.pages.dev,PDF 需 arXiv 下载
# git clone https://github.com/<org>/lego-rl  # 等待官方 GitHub 开放

# 2. 安装依赖(基于 abstract 描述,典型配置)
pip install torch transformers kubernetes triton
# 若需 Triton kernel 编译:pip install triton

# 3. 注入 LLM proxy(以 OpenHands 为例,monkey-patch)
import lego_rl
lego_rl.patch.OpenAI()   # 自动注入 LLM proxy 到 OpenHands LLM client

# 4. 配置 sandbox(需 Kubernetes 集群)
kubectl apply -f lego_rl/kubernetes/sandbox.yaml

# 5. 运行 GSPO 训练
python -m lego_rl.train \
  --harness openhands \
  --model Qwen/Qwen2.5-72B-Instruct \
  --algo GSPO \
  --output_dir ./checkpoint

核心坑

  1. 进程内注入门槛:LEGO-RL 的 proxying 依赖 monkey-patch 或 fork LLM 客户端库。对 OpenHands SDK 这类结构化 harness 可行,但若目标 harness 用纯网络 API(Claude Code 官方 API / GitHub Copilot),进程内注入不适用——这是核心适用范围限制,选型前必须确认 harness 架构
  2. Kubernetes 强制依赖:编排层是 Kubernetes-style,对无 K8s 经验的团队是额外学习曲线;沙箱镜像构建 + 网络白名单配置本身是半个 infra 团队的工作量。建议先用 docker-compose 本地跑通单节点版本再上 K8s。
  3. reward 设计是隐藏的复现门槛:abstract 未给出 reward 是 pass/fail(SWE-bench official)还是过程 reward(tool call 加分)。两者差异巨大——pass/fail reward 的 RL 信号稀疏(只有 end-of-trajectory reward),学习效率低;process reward 需要额外标注或 LLM judge。建议先用 SWE-bench official pass/fail reward 做 baseline,再探索 process reward。
  4. GSPO 未在主流 RL 库中实现:trl / OpenRLHF / RAGEN 均未内置 GSPO;需要自行实现 sequence-level advantage estimation。参考 Qwen-Math / Qwen-Agent 的 GSPO 相关代码,或从 GRPO 改写(将 response-level group normalized advantage 改为 sequence-level)。
  5. SW E-bench Verified 数据集版本:2025 Q4 后 SWE-bench Verified 有多次更新;64→70.4% 的 baseline 对应哪个版本(v0.1 / v1 / v2)会影响对标。建议落地团队跑同一版本基线再做对比,避免引用数字与实测不符。
  6. 0.99 相关性是达标门槛不是充分条件:rollout-training correlation > 0.99 说明 train-inference 对齐了,但 RL 最终性能还依赖 reward 质量、advantage estimation 稳定性、policy 更新幅度。correlation 高不等于 RL 一定会成功——这是两类验证。

与主流框架的接口 - trl:LEGO-RL 的 proxying 思想可与 trl 的 GRPOConfig 兼容(自定义 data collator + token-level logp buffer),但 sequence-level advantage 需要自定义 callback。 - SWE-bench:LEGO-RL 的 sandbox defense(网络白名单、I/O 审计)是 SWE-bench task 评测的标准要求,可直接复用。 - Qwen 模型族:GSPO + Qwen3.5-35B-A3B 是官方推荐配置;与 vLLM / SGLang 推理引擎的集成需额外验证 token-level stream 对齐。