论文:OpenForge RL: Train Harness-native Agents in Any Environment 作者:Xiao Yu, Baolin Peng, Ruize Xu, Hao Zou, Qianhui Wu, Hao Cheng, Wenlin Yao, Nikhil Singh, Zhou Yu, Jianfeng Gao(Columbia / Dartmouth / Microsoft Research) arXiv:2607.21557(2026-07,ICLR 2027 under review) PDF:
content/uploads/papers/openforge-rl.pdfGitHub:MSR-Orchard/OpenForge-RL 环境层:microsoft/Orchard
1. 在部署 Harness 中生成训练轨迹
简化 rollout 与真实部署的失配,当代 SOTA Agent 的能力越来越来自 inference harness——Claude Code、Codex、OpenClaw、ZeroClaw 等 orchestration 层管理多轮交互、工具调用、上下文与 MCP 接入。然而开源 SFT/RL 栈通常假设简化的单进程 rollout:固定 chat template、无子 agent、无 harness 特有控制流。
这造成 train–deploy mismatch(训练–部署失配):在简化环境里训出的 policy,部署到真实 harness 时,工具 schema、上下文管理、子 agent 路由、错误恢复语义都可能不同——Orchard 论文已展示:OpenSWE-32B 换到从未见过的 Kimi-CLI harness 时 SWE-bench Verified 从 45.0 崩到 3.6。OpenForge RL 的核心问题是:能否在 Agent 实际部署的 harness 里做端到端 RL,且与任意 RL 训练后端(如 veRL)解耦?
Proxy 与 K8s Orchestrator,OpenForge RL 由两个正交组件构成:
1.1. Lightweight Proxy:轻量代理
- 插入 harness 与推理服务之间,Serving harness 发起的全部 LLM/VLM 调用。
- 将请求路由到 RL 框架的 inference engine(训练中的 policy)。
- 记录 io-pair,在 rollout 结束后重建为
(s₀,a₀,r₀, …, s_T,a_T,r_T)轨迹,供 veRL / slime 等标准 RL codebase 消费。 - 关键性质:不修改 harness 内部逻辑——换 harness 只改 sandbox 镜像/启动命令,不改 trainer。
K8s Rollout Orchestrator 的编排职责包括:
- 每个 rollout 在独立远程容器中运行(与 Orchard Env 集成)。
- 容器预装目标 harness(OpenClaw、ZeroClaw、Codex、Claude、Pi、OpenCode、Hermes 等)及任务环境(Terminal、Web、Computer Use)。
- 训练与 rollout 物理解耦:rollout 占 CPU 容器,policy 更新占 GPU 节点——可 scale 0 → 数千并行 sandbox。
整体数据流:
Trainer (veRL, GPU) ←── trajectories ── Proxy (intercept & collect)
│ ↑
└── generation requests ──────────────┘
│
Orchestrator → Sandbox Pod × N
(真实 Harness + Environment)
数据合成(Claude Agent SDK + Opus 4.6) 五阶段 pipeline:Propose → Refine → Implement → Verify → Package,并行生成 Claw / GUI 域任务;SFT pool 经 benchmark 去重与流行网站过滤。
仓库提供两条 Recipe:
| Recipe | Backbone | 训练数据 | 评测 harness |
|---|---|---|---|
| OpenForge-Claw | Qwen3-30B-A3B-Thinking | ~0.2K–2.6K 合成 Claw 任务 | ZeroClaw / OpenClaw / Codex / ReACT |
| OpenForge-GUI | Qwen3-VL-8B | SFT + RL(~2.5K 任务) | 纯 screenshot 输入的 computer-use |
Claw、GUI 与跨 Harness 结果,OpenForge-Claw(30B-A3B) — ClawEval / QwenClawBench / MCPAtlas:
| 阶段 | ClawEval pass@3 | QwenClawBench | MCPAtlas |
|---|---|---|---|
| Qwen3-30B-A3B-Thinking 基线 | 39.8 | 21.8 | 12.4 |
| OpenForge-Claw (SFT) | 52.1 | 32.1 | 23.6 |
| OpenForge-Claw (SFT+RL) | 55.9 | 33.7 | 28.1 |
对比同量级开源:Qwen3-32B pass@3 31.7 / MCPAtlas 22.5;LLaMA-4-Scout pass@3 16.8。距 Claude Opus 4.6(ClawEval pass@3 80.8)仍有巨大 gap,但 SFT+RL 一致提升。
Harness 迁移(ClawEval pass@1) — 训练多 harness vs 单 harness:
| 模型 | ReACT* | ZeroClaw | OpenClaw | Codex |
|---|---|---|---|---|
| Qwen3-30B-A3B 基线 | 26.1 | 32.5 | 11.4 | 12.2 |
| OpenForge-Claw (SFT+RL, 三 harness 训练) | 45.1 | 48.5 | 20.9 | 32.5 |
单 harness 训练已泛化到未见 harness(ZeroClaw-only → OpenClaw +3.3、Codex +4.6);三 harness 联合训练全面最优,复杂 harness(OpenClaw、Codex)增益最大。
OpenForge-GUI(8B) — pass@1:
| 阶段 | OSWorld-Verified | Online-Mind2Web | WebVoyager |
|---|---|---|---|
| Qwen3-VL-8B | 29.4 | 38.7 | 49.2 |
| OpenForge-GUI (SFT) | 34.4 | 57.4 | 61.5 |
| OpenForge-GUI (SFT+RL) | 37.7 | 63.0 | 72.3 |
亮点:仅 2.5K 任务训练,Online-Mind2Web 63.0 超过 MolmoWeb-8B(35.3,200K+ 任务);WebVoyager 72.3 接近 UI-TARS-1.5-7B(66.4)。论文强调:在真实 deployment harness 里训练,样本效率显著高于简化栈上的大规模 SFT。
RL 行为分析(ClawEval):SFT→RL 后,generic shell 工具调用占比下降(22.6% → 13.9%),转向专用 service tools;self-verification、format robustness、tool coverage、step efficiency 等行为维度 SFT+RL 全面高于 SFT;error recovery 仍弱——RL 主要提升 reliability,非全能。
训练资源:Claw RL ~48H(8×B200 policy + Azure rollout VM);GUI browser-use ~32–36H。
Discussion 三章结论(Section 5) 对 harness 研究有直接指导意义:
- Q1:哪个 harness 更难学? Codex / OpenClaw 等多进程、强工具编排的 harness 显著难于 ReACT* 简化栈——同样的 SFT+RL 预算下,复杂 harness 上的绝对分更低,但 RL 相对增益更大。
- Q2:跨 harness 迁移? 在 ZeroClaw 上训练已能提升未见 OpenClaw / Codex 表现;三 harness 联合训练是 Pareto 最优——说明 policy 学到的是 partially harness-agnostic 的 agentic skill,而非 memorizing 单一 CLI 语法。
- Q3:RL 加了什么? 主要是 reliability(self-verification、专用工具覆盖、步数效率),而非 error recovery——后者在 SFT+RL 后仍接近随机,暗示需要 failure-centric curriculum 或显式 recovery reward。
Claw 域 RL 超参(Table A1 摘要):lr 1e-6、batch 8、group 8、KL 0.001、max rollout 900s/step、100 training steps;GUI browser-use lr 1e-6、group 5、KL 0、entropy 0.001。Rollout pod 2–4 CPU / 2–6 GiB RAM——刻意 Small footprint 以提高并发。
1.2. 复现成本与适用边界
- 完整复现门槛高:核心实现虽已公开,训练仍依赖 Orchard Env、Kubernetes、veRL 与成规模的推理资源,单机很难复现论文吞吐。
- 任务规模小:Claw ~2.6K、GUI ~2.5K,泛化边界未充分探索。
- Proxy 假设:要求 harness 所有 LLM 调用走可拦截 API;本地嵌入式模型或硬编码路径可能漏采。
- Error recovery 瓶颈:RL 后仍弱,可能需要 dedicated failure-centric 数据。
- 闭源 SOTA gap:距 GPT-5.4 / Claude Opus 4.6 在 OSWorld(75.0 / 72.7)仍差一个数量级。
- 成本结构:每 rollout 一容器,虽比 managed sandbox 便宜(Orchard Env spot 约 0.10×),但 RL 需要海量 rollout,总成本仍可观。
OpenForge RL 在 Orchard 三层栈中位于 Recipe 层,依赖 Orchard Env 提供环境基础设施。数据按下面的方向流动:
| 层 | 组件 | 职责 |
|---|---|---|
| Recipe | OpenForge RL | Proxy + 数据合成 + veRL 训练循环 |
| Foundation | Orchard Env | K8s sandbox REST API、in-pod agent、网络隔离 |
| Trainer | veRL / slime | Policy 优化、inference engine |
Rollout 生命周期,1. Orchestrator 按任务 spec 启动 sandbox Pod(2 CPU / 2–6 GiB,任务 Dockerfile + harness 预装)。 2. Harness 在 sandbox 内驱动多轮 agent↔environment 交互;每次 LLM 调用经 Proxy 转发到 trainer 的 inference server。 3. Proxy 记录 (prompt, response, metadata);episode 结束信号触发 trajectory reconstruction。 4. Trainer 消费轨迹做 PPO/GRPO 等更新;新 policy 权重同步回 inference server,进入下一批 rollout。
与 Orchard 原有三 Recipe 关系:Orchard-SWE/GUI/Claw 是「Env + 简化/固定 harness」路线;OpenForge RL 是后续工作,把 harness 本身换成部署态真实栈(ZeroClaw、OpenClaw、Codex),专门消除 mismatch。
2. 可启动的环境规范
OpenForge RL 的数据合成流水线产出一份可以启动的环境规范,自然语言题目只是其中一项。对每个任务,至少需要固定以下对象:
- 初始状态:sandbox 镜像、目录内容、账户或页面状态、依赖版本和预置服务;
- 动作空间:Harness 能暴露给 policy 的 shell、文件、浏览器、MCP 与领域工具,以及各工具的参数 schema;
- 目标描述:Agent 可以看到的任务文本和不能泄漏给它的隐藏验收条件;
- 终止规则:成功提交、达到时间或步数预算、Harness 主动停止、环境崩溃分别怎样编码;
- 验证器:从最终环境读取什么事实,怎样区分成功、任务失败和基础设施异常。
初始状态必须可重建。若任务要求修复仓库,镜像摘要、代码 commit 和依赖锁文件应一起记录;若任务发生在网页,登录态、页面版本和后端数据也属于状态。只保存一段 prompt,几周后重新运行时得到的已经可能是另一道题。环境生成阶段的 Verify 因而有两层含义:它既要确认任务可完成,也要确认验证器能从干净初态判失败、从参考完成态判成功。
动作空间同样影响任务难度。给 Agent 一个领域专用工具,与只给通用 shell 后让它自行调用 API,并不是同一实验。Proxy 虽然能够看到 LLM 请求和响应,却未必自动掌握 Harness 内部的所有确定性动作。因此轨迹清单需要标出:哪些动作由 policy 直接生成,哪些由 Harness 按规则插入,哪些环境变化来自外部事件。缺少这层区分时,训练器可能把 Harness 的固定行为误算成模型 action。
从 Harness 日志重建可训练轨迹,一次真实 Harness rollout 可能包含多轮 LLM 调用、子进程、上下文压缩和工具返回。Proxy 记录的基本单元是调用时模型真正看到的输入 与生成的输出 。训练轨迹还需要把它们与环境观察和 episode 身份对齐:
其中 是 rollout 标识, 是逻辑顺序, 是动作后的环境观察, 保存 Harness、工具和截断等元数据。多进程 Harness 不能只依赖日志到达时间排序,因为并发请求可能交错;重建器需要稳定的 episode、parent call 和 sequence 标识,才能恢复每条分支实际看到的历史。
训练时还要明确 logits mask。系统消息、用户任务和工具返回构成 state,只为模型生成的 token 计算 policy loss;Harness 自动拼接的模板或确定性路由不应被当成模型选择。若消息经过上下文压缩,Proxy 应记录压缩后的真实输入,同时保留压缩器版本。否则训练数据声称模型根据完整历史做出动作,实际部署时它看到的却是另一份摘要。
轨迹终点需要绑定验证证据。Harness 退出和模型输出「完成」都只能标记执行流程结束;reward 由验证器重新读取环境后给出,例如执行测试、查询后端状态或检查目标页面。episode 最终可被标成 success、task_failure、timeout、environment_error 和 verifier_error。后两类通常不应直接作为 policy 的负样本,因为模型未必有机会影响它们。
最终奖励、过程进度与一个小型手算,OpenForge RL 强调 task-native verifier。最干净的终局奖励可以写成:
它回答的是最终任务有没有完成。过程进度则描述中间状态离验收条件还有多远,例如通过了多少个独立测试、是否建立了正确资源、是否完成必要的自检。过程进度适合诊断和构造辅助信号,却不能自动冒充最终奖励:通过四个测试中的三个,不一定代表任务完成了四分之三,其中一个失败可能正好暴露核心功能缺失。
考虑同一任务采样四条轨迹,最终验证结果为 。组内平均奖励为
若使用最简单的组内中心化优势,四条轨迹得到
成功轨迹中的 policy action 被提高概率,失败轨迹中的 action 被降低概率。现在假设第二条轨迹已经通过三个过程检查,但最终验证失败;它的终局奖励仍是 ,优势仍为 。这三个检查可以作为分析字段,也可以在经过论证后加入 shaped reward,例如 。然而只要 ,优化目标就改变了:policy 可能学会积累容易通过的中间项,却不完成收尾阶段的关键条件。
再看第四条轨迹。Sandbox 在验证前崩溃,这属于 environment_error;若仍记成 ,它同样得到 ,模型会为系统故障受到惩罚。该样本应从有效 reward 组中剔除或重新 rollout。剩下三条有效轨迹的均值变为 ,相应优势也要按实际采用的归一化规则重新计算。这个小例子说明:奖励计算之前,先把终局事实、过程进度和系统异常分开。
若 reward 只在终点出现,长轨迹仍有 credit assignment 困难。给整条 response 序列分配同一个 episode advantage 是常见近似,但它无法指出某次工具选择究竟好在哪里。OpenForge 的行为分析表明 RL 提升了 self-verification、工具覆盖和步数效率,却没有同等解决 error recovery。这与终局奖励的性质一致:成功样本能强化一整套可靠行为,稀少的失败恢复片段却难以得到清晰、稳定的局部信号。
2.1. RL 更新与异步 rollout 的边界
在一次训练迭代中,trainer 固定 policy 版本,Orchestrator 启动一批 sandbox,Harness 经 Proxy 请求生成,验证器给出 episode reward,随后 trainer 才用这些轨迹更新参数。无论底层采用 PPO、GRPO 还是其他 on-policy 变体,都需要知道每条 action 是由哪个 policy checkpoint 生成的。若 rollout 持续时间差异很大,而新旧 policy 的轨迹混入同一 batch,重要性比率和组内比较的含义都会变得含糊。
因此,轨迹元数据至少要含 policy_version、采样参数、Harness 版本、任务版本和 reward 版本。异步系统可以容忍不同 episode 在墙钟时间上交错,但不能让样本来源不可追踪。训练器也要分别统计有效轨迹率、环境失败率和验证器失败率;只报告 GPU 利用率或总 rollout 数量,会掩盖大量不能用于更新的坏样本。
真实 Harness 训练还有一个选择性偏差:特别长或频繁失败的 episode 更容易超时,最终进入 batch 的可能主要是短轨迹。如果不报告长度分布和截断原因,policy 看起来在改善,实际上训练数据可能逐渐偏向简单任务。对长任务而言,max rollout 是实验条件,也是改变数据分布的过滤器。
泄漏、不可复现与判定器错误,合成任务最直接的泄漏来自 benchmark 本身。若生成模型能看到评测任务、参考实现或隐藏测试,再通过改写进入训练池,最终分数无法说明泛化。论文的数据流水线包含 benchmark 去重;复现时还应在任务文本、代码片段、网站目标和验证逻辑多个层面检查近重复,不能只比较标题字符串。验证器源代码若直接暴露在 Agent 可读目录里,也可能诱导 policy 针对检查条件投机,而不是完成真实目标。
不可复现通常来自环境漂移。容器标签指向了新镜像、网站内容更新、MCP server 升级、依赖下载到不同版本,都会改变状态转移。每个任务包应记录内容寻址的镜像摘要、资源校验和、网络策略、Harness commit、工具 schema 与验证器 commit。若必须依赖实时服务,至少要记录执行时间和关键响应,并把服务不可用单独计数。
判定器也会犯错。假阳性把未完成任务判成功,会直接奖励投机行为;假阴性把正确的等价解法判失败,会压低合理策略。发布 benchmark 前,可以让参考解、已知错误解和一组扰动解共同经过 verifier:参考解应稳定通过,缺关键功能的扰动解应稳定失败,重复执行不应因残留状态改变结果。对 GUI 任务,只看最终截图往往不够,后端状态或可访问性属性能提供更稳定的事实。
一套可执行的评测协议,要验证「Harness-native 训练」而不是其他变量带来的提升,可以按以下协议组织实验:
- 冻结任务包:给每个任务固定初始快照、动作权限、终止条件和 verifier 版本,并清理与训练池的近重复项。
- 固定 policy 条件:比较系统使用同一 backbone、checkpoint、采样参数和上下文预算;若训练后模型不同,则另设推理 Harness 消融。
- 建立 Harness 矩阵:至少包含训练中出现的 Harness 和未见 Harness;记录各自工具 schema、上下文策略和自动重试行为。
- 隔离 rollout:每次从干净 sandbox 启动,保存 policy、任务、镜像、Harness 和 reward 的版本标识,禁止上一条轨迹残留状态。
- 运行外部验证:Harness 退出后由独立 verifier 检查环境;将任务失败、超时、环境错误和 verifier 错误分开。
- 报告共同预算:除 pass rate 外,同时报告有效 episode 数、墙钟时间、token、工具步数、截断比例和每个成功任务的成本。
- 检查恢复能力:单列需要从失败中恢复的任务,不用总体成功率代替;OpenForge 的分析已经提示这一维仍弱。
- 保存可复算产物:保存任务清单、去重方法、轨迹 schema、版本 manifest 和逐任务验证结果;公开代码仍不足以替代论文未提供的完整训练资源与运行记录。
这套协议不要求所有系统内部实现相同。它要求共同控制的变量真正一致,并把无法控制的差异完整报告。只有这样,三 Harness 联合训练的收益、未见 Harness 迁移和 RL 带来的可靠性变化,才能与额外预算、环境差异或判定器偏差区分开。
2.2. Train-deploy mismatch 是怎样产生的
真实 Harness 会改写模型实际面对的决策过程。它决定 system prompt 怎样拼接、工具如何命名、历史何时压缩、错误会不会自动重试,也决定一次模型输出之后环境返回什么。训练时若用一个简化 ReAct loop,部署时换成 Codex 或 OpenClaw,表面上仍是同一个模型,状态空间与动作空间却都变了。
可将部署 Harness 诱导出的轨迹分布记为 ,训练 Harness 的分布记为 。某个策略在训练分布上的期望回报为:
部署时真正关心的是 。两者差异来自 Harness 对状态、动作与转移的共同改写,不能只用「prompt 有点不同」概括。举个具体例子:训练 loop 把工具错误原样返回,部署 Harness 却会自动重试两次再压缩错误;模型在训练中学到的恢复动作,部署时可能接收到另一种观察,甚至没有机会看到第一次失败。
动作 schema 也会制造错位。训练环境把写文件表示为 write(path, content),部署环境可能要求 patch、基线哈希和权限确认。策略即使理解任务,也可能因格式不适配而无法行动。OpenForgeRL 让真实 Harness 自己构造上下文并解析调用,Proxy 只拦截它原本就会发出的模型请求,这才保留了部署时的接口语义。
多 Harness 训练可以看成在多个分布上共同优化:
其中 控制各 Harness 的采样比例。若简单 Harness 便宜、成功率高,它可能占据大部分有效轨迹,策略随后偏向容易解析的工具格式。训练调度器需要同时观察任务域、Harness 与结果分桶,避免总样本数很大,复杂 Harness 却几乎没有产生可用更新。
Proxy 拦截面与轨迹忠实度,官方仓库把 recording proxy 放在 Harness 与 OpenAI-compatible endpoint 之间,这个位置能看到每次模型请求与响应,却看不到所有环境变化。Harness 可能在两次模型调用之间自动裁剪历史、执行确定性重试、启动子进程,甚至按规则补上一条工具消息。轨迹重建器必须明确哪些事件来自 policy,哪些来自 Harness。
一条可训练记录至少需要如下标识:
episode_id / parent_call_id / sequence_id
policy_version / harness_version / task_version
messages_seen_by_model / sampled_tokens / sampling_config
tool_call / tool_result / termination_reason
reward_version / verifier_result / infrastructure_status
messages_seen_by_model 应保存请求发出时的真实消息,而非事后从完整日志推测。若 Harness 在请求前做过 compaction,训练就应使用压缩后的输入;把被删历史重新塞回样本,会让优化器学习一个部署时不存在的条件分布。sampled_tokens 还要配套 logits mask,只给 policy 真正生成的 token 计算损失,不能把 Harness 模板和工具返回当成模型答案。
多进程 Harness 对顺序提出了更高要求。日志到达 Proxy 的墙钟顺序不一定等于因果顺序;两个子进程可能并行请求,各自依赖不同父调用。只靠时间戳拼接,会产生一条现实中从未出现过的对话。parent_call_id 与局部序号用于恢复调用树,训练器随后选择保留分支结构,或按清楚定义的规则切成多条样本。
轨迹忠实度可以用三项检查:请求重放后消息哈希一致;动作在相同 checkpoint 上能复现相同工具调用;终局 reward 能由独立 verifier 重算。三项分别覆盖输入、转移和结果。任一项失真,RL 都可能稳定优化错误的数据。
Rollout 吞吐如何手算,远程 sandbox 把 CPU 侧执行与 GPU 侧更新解耦,但 GPU 不会因此自动满载。设平均一条轨迹有 次模型调用,每次生成占用 GPU 时间 ,环境与工具等待为 ,sandbox 启动为 。单条轨迹墙钟时间约为:
若并发 sandbox 数为 ,理想吞吐接近 ;实际还受 Proxy 排队、推理动态批处理与长尾任务影响。假设 ,,,,单条轨迹约需 。100 个 sandbox 的理想吞吐约为每分钟 42.9 条。若环境等待翻倍,吞吐降到约每分钟 23.1 条,GPU 可能在两轮请求之间空转。
扩大 也有上限。推理服务饱和后,排队时间进入 ;Kubernetes 启动大量 Pod 会争抢镜像、CPU 和网络;某些实时网站还会限流。工程上应同时观测 sandbox 启动 P50/P99、Proxy 队列深度、有效轨迹率、GPU token 吞吐和环境错误率。只有 GPU 利用率很高而有效轨迹率很低,意味着算力正在认真学习一堆坏 episode。
长尾决定训练同步点。若 trainer 等整批 rollout 全部返回,最慢的少数任务会阻塞更新;若提前截断,又会系统性丢掉复杂长任务。可以采用有界异步窗口:每个样本携带 policy_version,只接受落后不超过阈值的轨迹;超出阈值则重新采样或使用明确的 off-policy 修正。阈值越宽,硬件越忙,数据与当前策略的偏差也越大。
3. Harness 选择与课程设计
论文显示 Codex、OpenClaw 一类复杂 Harness 更难学,RL 的相对增益又更明显。这提示课程不能只按任务难度排序,还要按 Harness 难度分层。一个任务在 ReAct* 下可能很简单,换到包含上下文管理、专用工具和多进程路由的 Harness 后,失败点已经变化。
训练初期可以让策略先学会稳定格式和基本工具闭环,再增加长轨迹、错误恢复与复杂 Harness;但不能长期停留在简化 loop,否则错位会被重新带回来。更可靠的课程单位是 (task, harness, failure_mode):同一任务分别在工具缺失、响应超时、局部成功和验证失败下采样,明确观察策略能否把失败转成下一步动作。
error recovery 仍弱,也说明成功轨迹不够。终局奖励能强化顺利完成的行为,却很少告诉模型如何从半途故障回来。可以从真实失败 episode 截取「故障出现到恢复完成」的片段,构造带初始 checkpoint 的 recovery task;也可以让环境确定性注入超时、旧文件和工具返回畸形。验证仍以最终环境为准,不能奖励模型写出一段漂亮的反思。
多 Harness 课程还要防止表面迁移。策略可能只是记住多套工具别名,并没有学到共享能力。未见 Harness 评测应选接口、上下文策略和自动恢复机制都不同的系统,同时报告格式错误、工具选择、计划完成和错误恢复等细分行为。若只在工具名称相近的 Harness 上得分提升,泛化结论要收窄。
Reward 管线的失败模式,Reward 从 verifier 到 trainer 之间还有一条数据管线。Reward 一旦绑定到错误 episode,训练会在没有报错、损失正常下降的表象下学习随机标签。episode_id 复用、超时回执晚到或任务重试覆盖旧记录,都可能让一个成功结果落到另一条轨迹上。
因此 reward 记录应同时绑定 episode、任务版本、初始 checkpoint、最终状态哈希和 verifier 版本。Trainer 消费前再检查这些字段,与轨迹 manifest 不一致的样本进入隔离队列。二元成功率之外,还要统计 task_failure、timeout、environment_error、verifier_error 与 invalid_trace,只有确实反映 policy 行为的结果才能参与优势计算。
判定器投机同样会在 RL 中被放大。只检查文件存在,策略会学会创建空文件;只检查页面出现某段文本,策略可能把文本写进无关区域。对每个 verifier,可以准备参考解、缺关键步骤的错误解和扰动解,验证它能区分三者。训练过程中还应抽样人工复核高奖励轨迹,尤其关注回报突然上升而外部质量没有同步改善的阶段。
过程奖励需要克制。若一条任务含五个检查,四个容易、一个决定成败,按通过比例给 reward 会鼓励策略反复收割容易项。更稳妥的方式是把过程信号用于课程采样与诊断,终局硬条件仍决定成功;确需 shaping 时,权重、上限和消融结果都应报告,使读者能判断增益来自完成任务,还是改变了评测目标。
从研究数字到部署决策,OpenForgeRL 的结果证明真实 Harness 可以进入开放训练栈,也显示数千任务已经能带来明显提升,但它没有替团队回答「该训练哪一个 Harness」。部署选择要看现有工具生态、权限模型、可观测性和维护成本。一个基准分稍高却无法稳定记录轨迹的 Harness,可能不适合持续训练;一个较简单但接口稳定、验证充分的 Harness,反而更容易形成数据飞轮。
部署前可以做四格实验:基座模型在旧/新 Harness 上各跑一次,训练后模型再在两种 Harness 上各跑一次。四个结果能够粗分模型增益、Harness 增益与二者交互。若训练后只在训练 Harness 上提高,说明适配性很强;若在未见 Harness 上也提高,才有较强证据支持共享 agentic skill。
成本也应按成功任务计算。设一次训练周期总成本为 ,评测或生产中每个 episode 成本为 ,成功率为 ,那么忽略重试差异时,每个成功任务的运行成本约为 。训练价值来自 的提高、 的下降,或者减少人工接管。若成功率提升很小而 rollout 成本翻倍,技术上有效,业务上仍可能不划算。
OpenForgeRL 把真实 Harness 纳入可记录、可训练、可比较的实验对象。模型、Harness、环境和 verifier 可以分别版本化,训练结果也由此能够追问:能力究竟长在 policy 里,还是来自部署栈替它做了更多工作。
把系统拆开看,一条训练样本从任务入队到进入 loss,至少经过八个阶段:选择任务、启动 sandbox、加载 Harness、请求 policy、执行工具、终局验证、重建轨迹、训练消费。任何阶段失败,都不该笼统记成 reward 0。
task@v3
→ sandbox(image@sha256)
→ harness@commit
→ proxy(policy@step-120)
→ environment actions
→ verifier@v7
→ trajectory manifest
→ trainer batch@121
假设 Harness 在第六次模型调用后超时,但环境里的目标已经完成。Orchestrator 记录的是 harness_timeout,verifier 却可能返回 success。是否把这条样本用于训练,要看终止语义:若生产系统允许超时后的外部验收,成功信号仍有意义;若产品要求 Harness 必须在预算内主动提交,超时就是失败。这个决定属于任务定义,不能由训练脚本临时猜。
再假设 verifier 成功,轨迹重建却发现第三次调用缺少工具返回。此时 reward 没问题,样本却不完整。把它送进 trainer 会让某个 action 缺少真实条件,应标为 invalid_trace。相反,轨迹完整而 verifier 服务宕机,动作数据仍可用于 SFT 或离线分析,却不适合直接生成 RL 优势。将阶段状态分开保存,才能让不同数据用途各取所需。
3.1. 数据选择会改变学到的行为
只保留成功轨迹做 SFT,模型会看到大量顺利路径,却很少看到失败后的处理;把所有失败轨迹用于 RL,又可能混入环境故障和验证器错误。数据清理不能只按最终 reward 切一刀。
可以按转移片段标注四类行为:有效推进、无效探索、从失败恢复、产生不可逆错误。有效推进适合监督学习;恢复片段即使整条 episode 最终失败,也可能包含有价值动作;环境故障附近的片段通常需要剔除;不可逆错误则适合安全训练与动作门控。OpenForgeRL 观察到 RL 对 self-verification 和 tool coverage 有帮助,而 error recovery 仍弱,这也提示数据池需要主动寻找恢复片段。
任务采样还会影响成功率表象。若当前策略在简单任务上容易成功,在线采样会迅速积累这些任务的数据,随后进一步优化简单任务。困难任务因为持续得 0,既缺少正样本,也难产生可区分的组内优势。Balanced rollout 或基于成功率的课程可以提高临界难度任务的采样权重,但采样规则本身必须进入实验记录,否则最终成绩无法复算。
去重不能只看 prompt。两个任务的文字不同,底层仓库、隐藏测试或目标网站可能相同;反过来,同一句目标在不同初始状态下又可能是两道真正不同的题。任务指纹可组合文本嵌入、代码与资源哈希、验证器结构和初始状态摘要。评测集污染检查也沿用同一套多层指纹,而非只比标题。
版本矩阵与回归定位,一次实验至少涉及 policy、Harness、环境镜像、任务、Proxy 重建器和 verifier 六个版本。只记模型 checkpoint,几个月后很难解释同一权重为何复跑得到不同结果。可以把一次 run 的身份写成:
其中六个字母分别对应上述组件。成绩表中的每个数字都应能落到一组 和逐任务结果。
当成功率下降时,版本矩阵可以做最小二分。先固定旧 policy,只升级 Harness;若下降复现,问题来自接口或控制流。再固定 Harness,只升级环境与 verifier;若结果变化,检查任务漂移。收尾阶段才比较新旧 policy。一次同时升级所有组件,只能得到「新系统变差了」,无法指导修复。
真实 Harness 往往快速迭代,训练数据也会跨版本。旧轨迹是否还能使用,取决于消息模板、工具 schema 与动作语义是否兼容。若只是增加无关日志,可继续使用;若工具参数或自动重试逻辑改变,旧轨迹代表的 policy 条件分布已经变化,应分桶训练或降权,而非全量混合。
安全边界进入训练环,远程 sandbox 限制了单条 rollout 的破坏范围,但训练会反复运行成千上万条轨迹,小概率事故会被放大。环境默认禁用宿主机挂载,网络访问使用 allowlist,凭证按任务发放短期 token,资源配额限制进程、磁盘与调用次数。Harness 的权限也应与生产目标一致;训练时给无限权限、部署时再收紧,依然是一种 train-deploy mismatch。
外部网站和 API 还涉及真实副作用。用于训练的环境最好提供镜像、模拟服务或专用测试账户。确需访问实时服务时,写操作进入隔离租户,并设置总预算与速率限制。Verifer 读取的凭证与 Agent 使用的凭证分离,防止 policy 直接修改验收数据。
训练日志可能包含仓库代码、页面内容和工具响应。Proxy 位于所有模型调用的汇合点,天然也是敏感数据的汇合点。记录前要按消息字段脱敏,原始 trace 设置访问与保留周期,发布数据集再做许可证和隐私检查。一个能训练真实 Harness 的系统,也更容易收集真实环境里的秘密,这部分不能留给上线前补救。
4. 复现实验时应保存什么
论文数字要能复算,至少保存任务清单与版本、容器镜像摘要、Harness 启动参数、模型采样参数、每条轨迹的终止原因、verifier 输出和汇总脚本。模型训练还需记录 optimizer、batch、group size、KL/entropy 系数、最大 rollout 时间、有效样本数与 policy 版本推进规则。
只发布平均分不够。逐任务结果能够检查任务子集变化,失败类别能够区分 policy 与基础设施问题,长度分布能够发现超时带来的选择偏差。对于有随机性的 Agent,报告采样次数、pass@k 或 pass^k 的明确定义,并保留随机种子与原始 episode;否则相同的百分比可能对应完全不同的统计量。
OpenForgeRL 官方仓库已经公开核心 rollout engine、环境实现、veRL 示例与推理脚本,Kubernetes 编排依赖 Orchard Env。复现顺序宜从单任务单 sandbox 开始,确认 Proxy 能重建完整轨迹与 verifier 能复算结果,再扩到并发 rollout,收尾阶段接入参数更新。直接从大集群起跑,任何一个版本或路由错误都会被吞进海量日志里。
训练轨迹必须满足的约束,1. Harness-native rollout:训练轨迹必须来自真实 harness 控制流,非 reimplementation。 2. Train–inference 解耦:Proxy 是唯耦点;trainer 与 sandbox 可异构部署。 3. Trajectory fidelity:Proxy 记录的 io-pair 必须能重建 harness 实际看到的 state–action 序列。 4. Environment portability:换环境只改 sandbox 镜像;换 harness 只改启动命令与 Proxy 路由。 5. Reward 仍 task-native:ClawEval / OSWorld / WebVoyager 等官方 verifier,非 LLM judge。
要把 Harness 写进受控决策过程,普通 MDP 的粒度还不够。人们常把状态写成 、动作写成 ,再把工具执行理解为环境转移 ;这对固定的 ReAct 循环勉强够用,对真实 Harness 却过于粗糙。模型并不直接接触环境状态,它看到的是 Harness 经过选择、排序、裁剪和格式化之后生成的消息;模型输出也不一定直接成为环境动作,还可能先经过语法解析、权限检查、参数补全、自动重试与路由。更贴近实际的分解是:
其中 是外部环境的真实状态, 是 Harness 自己维护的记忆与控制状态, 决定模型看见什么, 把模型生成内容解释成可执行动作。工具返回之后,Harness 还会更新自己的状态:
这组式子解释了为什么换 Harness 并非只换一段 system prompt。上下文压缩改变 ,工具参数修复改变 ,自动重试和子代理调度改变 ;三者都会改变策略实际面对的条件分布。即便底座权重、任务和外部环境完全相同,轨迹分布仍可能明显不同。
这里还有一层容易被忽略的部分可观测性。模型只看到 ,不知道 Kubernetes Pod 的剩余寿命、后台进程是否仍在运行、网页服务是否刚刚发生瞬时故障,也未必知道 Harness 已替它重试过几次。若这些隐藏变量会影响下一步结果,模型面对的其实是 POMDP。Harness 的历史整理机制承担了近似信念状态的角色:它把哪些失败、文件变化和工具结果保留下来,决定模型能否推断当前处境。压缩器若删除了「第一次写入失败但产生了半成品文件」这条信息,模型下一轮可能重复执行破坏性动作;保留全部原始日志又可能挤掉任务目标。所谓 Harness 能力,很大一部分正是在有限上下文中维护足够的信念状态。
因此,训练数据中的一条消息不能脱离产生它的控制状态来解释。相同的 permission denied,可能是模型首次越权,可能是 Harness 降权后重放旧命令,也可能是沙箱策略临时加载失败。三者对应的责任归因不同。Proxy 能保存模型真正看到的消息,却无法仅凭消息还原全部 。若研究目标涉及自动重试、压缩、并行分支或审批门控,就要由 Harness 额外输出结构化控制事件,并让这些事件与 LLM 调用共享 episode 与父子调用标识。
两种接入模式由此有了明确差别。DirectEnvInstanceConfig 让训练引擎驱动外层循环,状态更新和 token mask 较容易掌握,代价是部署 Harness 的 可能被简化。PipelineEnvInstanceConfig 让环境拥有整个黑盒 episode,能够保留真实控制流,代价是训练器只能通过记录与重建理解发生了什么。前者适合研究模型在规范工具循环里的学习规律,后者适合研究部署系统中的真实行为;把前者的结论直接外推到后者,需要额外的跨 Harness 验证。