Browse this library

Chinese source article

4.2.2 · 快照分支与训练边界

从热路径、快照分支和容量模型讨论状态价值估计、跨 Harness 泛化与算法边界。

View original Markdown ↗

1. 热路径优化的排队模型

绕过 Kubernetes API 的 exec 热路径降低单次服务时间,也会改变系统可承载到达率。把 exec 请求近似看成到达率 λ\lambda、平均服务率 μ\mu 的队列,利用率为 ρ=λ/μ\rho=\lambda/\mu。即使平均服务时间很低,当 ρ\rho 接近一时,排队延迟仍会急剧上升。简单 M/M/1 近似给出

W=1μ−λ.W=\frac{1}{\mu-\lambda}.

它不精确描述多 Pod 和长尾命令,却说明平均 0.28 秒不能保证 P99。短 echo、大型测试、文件传输共用连接池时,少数长请求会阻塞短请求。按操作类型设置独立并发限制,或让 exec 只建立控制连接、长命令在 Pod 内异步运行,可以减少头阻塞。

直连 Pod IP 还把部分可靠性责任从 Kubernetes API 转到服务自身。Pod 重建后 IP 变化,orchestrator 的缓存必须失效;网络策略刚更新时连接可能短暂失败;跨节点路由和服务网格也会增加尾延迟。每个请求应解析 sandbox 当前 generation 与 endpoint,响应再带 generation。若执行期间 Pod 被替换,客户端能识别这次结果属于旧实例,避免把新 Pod 的空状态接在旧轨迹后面。

文件传输与命令执行的负载形态不同。一个 500 MB 文件会长期占用带宽和内存,若与小 health check 共用同一 worker pool,健康检查超时可能触发错误删除。限流要同时考虑请求数、字节数和执行时间。每个 sandbox、用户和集群设置分层配额,既防止单个异常轨迹拖垮服务,也避免大量小请求绕过单次大小限制。

吞吐优化最终看有效轨迹,而非 API QPS。设一小时完成 NN 条 episode,其中环境错误 NeN_e、重建失败 NrN_r、验证异常 NvN_v,有效率为

η=N−Ne−Nr−NvN.\eta=\frac{N-N_e-N_r-N_v}{N}.

环境提速 20% 却让错误率从 2% 升到 15%,有效样本吞吐可能下降。压力测试应跑完整生命周期并执行真实大小分布,而非只对短命令打点;同时报告 QPS、P50/P99、有效率和每条有效轨迹成本。

Stateful sandbox 的核心难题是定义「恢复到同一状态」。文件哈希一致是必要条件之一,远远不够。两个环境的进程、端口、数据库事务、随机数生成器、内核资源和外部服务会话可能不同。对任务 xx,更有用的定义是行为等价:对一组允许的后续动作 Ax\mathcal A_x,恢复状态 E\tilde E 与原状态 EE 产生相同或容许误差内的观察分布。

E≃xE~⟺P(o∣E,a)≈P(o∣E~,a),  ∀a∈Ax.E\simeq_x\tilde E \quad\Longleftrightarrow\quad P(o\mid E,a)\approx P(o\mid\tilde E,a),\;\forall a\in\mathcal A_x.

这个定义与任务相关。软件修复可能只关心仓库、依赖和测试进程,GUI 任务还关心浏览器 profile、页面 DOM、服务端账户与时间。无法对所有未来动作证明等价时,可以选一组 probe:读取关键文件、查询进程、检查端口、执行只读数据库查询、捕获页面状态。恢复前后 probe 一致,才允许分支 rollout 进入价值估计。

文件系统快照适合静态资产,却不能自动捕获进程内存。使用 CRIU 一类进程 checkpoint 仍会受内核版本、打开连接和设备限制。更可控的路线是让环境把可变服务状态外置到可快照存储,并设计明确的 quiesce 协议:暂停新请求、等待进行中操作结束、刷写缓存、记录版本,再创建快照。恢复时按相反顺序加载,并在开放流量前运行健康检查。

外部系统通常无法回滚。Agent 在真实网站创建订单后,本地 Pod 快照不能删除订单;两个 continuation 从同一快照出发,会共享并竞争外部账户。可以使用 mock service、每分支独立租户或带命名空间的测试资源。若只能访问共享服务,分支实验要限制为只读或可补偿动作,并把外部状态 ID 写入 manifest。所谓 branching 的成本优势只对可复制状态成立,不能无条件外推到整个互联网。

随机性也会破坏分支比较。两个 continuation 若使用不同模型采样种子,这是希望研究的策略随机性;环境中的数据库随机排序、时间和网络抖动则是干扰。快照应保存显式 RNG 状态,时钟可使用可控虚拟时间,外部响应可在允许情况下录制重放。仍无法控制的因素通过多次重复与配对设计估计方差。否则某个分支胜出,可能只因为页面加载更快。

状态快照本身有成本。设创建快照成本 CsC_s,恢复一次成本 CrC_r,重跑前缀成本 CpC_p,计划分叉 KK 次。使用快照节约的条件近似为

Cs+KCr<KCp.C_s+KC_r<KC_p.

若前缀很短或快照巨大,重跑更便宜;若前缀包含长编译、下载和多轮交互,快照优势明显。调度器可以根据实测 Cp,Cs,CrC_p,C_s,C_r 决定在哪些节点保存,而非每一步都 checkpoint。还要计入存储与清理成本,过期快照同样会成为资源泄漏。

分支价值估计必须确认各分支从同一策略条件出发。若快照中包含 Harness 已压缩的历史,而不同分支恢复时重新压缩,模型输入会变化;若模型服务在等待期间升级,policy 版本也变了。Checkpoint manifest 因而同时记录环境与认知状态:消息历史、压缩结果、工具 schema、Harness 控制状态、模型版本和采样参数。只恢复 Pod 而重建一份不同上下文,比较的就不再是同一 sts_t。

Orchard-SWE 保留 unresolved 轨迹,这一点比只收成功数据更重要。失败 episode 并非一整块负例:它可能正确定位问题、修复一半测试,收尾阶段因时间耗尽或一个边界条件未处理而失败。把全轨迹作为负样本会压低有效前缀,把它完全丢弃又浪费了最接近成功边界的数据。Credit-assignment SFT 试图从中找出 productive rise segment,本质是在缺少逐步真值时估计局部进展。

设终局验证由 MM 个测试组成,在第 tt 步后的通过向量为 vt∈{0,1}Mv_t\in{0,1}^M。最简单的进展分数是 gt=∑jvt,jg_t=\sum_jv_{t,j},片段收益为 gt2−gt1g_{t_2}-g_{t_1}。它能识别新增通过测试,却有两个盲区:测试重要性不同,且通过集合可能先缩小再扩大。修复根因时暂时破坏一个脆弱测试,最终换来多个关键测试通过,局部差分会误判中间动作。更稳妥的表示保留逐测试向量、依赖关系和最终状态,而非只留总数。

价值模型可以根据状态摘要估计完成概率 Vϕ(st)V_\phi(s_t),将上升片段定义为 Vϕ(st2)−Vϕ(st1)>δV_\phi(s_{t_2})-V_\phi(s_{t_1})>\delta。但训练价值模型的标签仍来自终局 reward,它可能把与成功相关却没有因果作用的特征当作进展。例如成功轨迹通常在后期运行完整测试,模型便可能给「运行测试」很高价值,即使代码尚未修好。要检查这种捷径,可以把同一状态配上不同无副作用命令,或在已知失败状态运行测试,看价值是否虚高。

Retrospective 估计还会利用未来信息。事后知道某文件最终被修改,容易把早期读取该文件标为关键;部署时 Agent 尚不知道它会成为答案。把这些片段用于 SFT 可以教会有效路径,却不能声称得到了在线可用的无偏优势。若把事后价值直接用于 RL,应明确它依赖完整轨迹,并检查是否把隐藏测试结果泄露进模型输入。

一种更强的证据来自干预。保存状态 sts_t,分别保留与删除候选片段造成的修改,再从两种状态采样 continuation。若保留片段后的成功率显著更高,才说明它具有实际贡献。设两组各 KK 次采样,估计差为

Δ^t=1K∑k=1KR(τk+)−1K∑k=1KR(τk−).\hat\Delta_t=\frac1K\sum_{k=1}^KR(\tau_k^+)- \frac1K\sum_{k=1}^KR(\tau_k^-).

这种成对反事实比单轨迹打分可靠,成本也高得多。Stateful branching 若实现,便能把它从少量离线实验扩展成系统化标注。当前没有完整分支能力时,可以在文件级任务上用补丁应用与撤销近似,仍要确认后台状态没有残留。

片段边界同样影响监督。把一次有效修改单独留下,却删除此前定位错误的观察,模型可能学会在没有证据时直接改文件;保留过长前缀又混入大量无效探索。一个片段应包含使首个动作可判断的最小上下文,以及能证明末端状态改善的验证结果。上下文选择可以通过删减测试:逐步移除早期消息,直到策略对首个动作的概率或后续成功率明显变化。

失败恢复片段值得单列。Agent 先执行错误补丁,随后读测试、回滚并改成正确方案,即使 episode 最终因另一个问题失败,回滚过程仍展示了检测和恢复。若只筛选价值单调上升片段,这类先降后升的轨迹可能被丢掉。可以以局部最低点为中心,保留「异常证据—诊断—恢复—重新验证」闭环,让模型学会在已经受损的状态里继续,而不只是模仿一路顺利的成功轨迹。

监督数据还应标明片段来源与置信度。隐藏测试差分、独立 verifier、价值模型和人工判断提供的证据强度不同。训练时可按置信度加权,评测时分别消融;若低置信片段贡献很小甚至有害,就不应靠扩大数量掩盖。数据卡报告保留率、各类证据比例、片段长度和原 episode 结果,才能让 107K rollouts 到最终 SFT token 的转换可核查。

Balanced Adaptive Rollout 的选择偏差。 稀疏奖励下,同一任务的组内样本全成或全败时,相对优势缺少区分。BAR 通过自适应采样提高含正负结果的组比例,训练效率由此上升。代价是训练任务不再按原始分布出现:成功率接近中间区间的任务被反复采样,过易与过难任务减少。

设目标任务分布为 p(x)p(x),调度后的分布为 q(x)q(x)。希望仍优化目标期望时,可对样本使用 p(x)/q(x)p(x)/q(x) 权重;但 q(x)q(x) 随策略成功率在线变化,估计噪声很大,极端任务的权重还会爆炸。实践中通常接受课程目标已经改变,再用固定、未重采样评测集衡量最终性能。关键在于不要把平衡池内 reward 当作部署成功率。

自适应难度估计也会滞后。模型更新后,昨天成功率 50% 的任务今天可能已变简单;若滑动窗口太长,调度器继续浪费采样,太短又会被随机波动驱动。可以为每个任务维护 Beta-Bernoulli 后验,成功 ss 次、失败 ff 次后均值为

p^x=s+α0s+f+α0+β0,\hat p_x=\frac{s+\alpha_0}{s+f+\alpha_0+\beta_0},

并用后验不确定性决定探索。采样很少的任务保留机会,证据充分的极易任务降低频率。模型大版本更新后应衰减旧统计,因为任务难度相对新策略已经变化。

全失败组还要区分过难与损坏。参考方案若也失败,优先检查环境和 verifier;强 teacher 能成功而当前 policy 全败,才是可用的困难任务;所有模型均失败且目标依赖缺失资源,则应隔离。BAR 若只根据当前 reward 加大采样,会把损坏任务当成最高难度,持续烧掉环境与模型预算。

全成功组也不一定无价值。它可以用于稳定 SFT、成本优化和安全检查:在都成功的轨迹中选择更短、更少风险动作或更低资源消耗的方案。若 reward 只有二元成功,组相对 RL 看不出差别;加入经过约束的次级成本,或把这些数据转到蒸馏阶段,能利用其信息。次级目标必须在成功条件下比较,防止模型用快速失败换低成本。

2. 跨 Harness 泛化的因果拆分

Orchard 论文强调同一环境可承载多种 Harness,并报告训练未见 Harness 上的结果。这里至少有三种可能的泛化:模型学会了任务语义,能在新接口下重新表达;两个 Harness 共享大量模板和工具语义,迁移主要是表面兼容;新 Harness 本身更强,通过规划、压缩或重试替模型完成更多工作。端到端分数无法自动区分三者。

设策略 π\pi、Harness HH、环境任务 xx 的成功率为 S(π,H,x)S(\pi,H,x)。训练前后策略为 π0,π1\pi_0,\pi_1,旧、新 Harness 为 HA,HBH_A,H_B。四格矩阵给出:

HAHBπ0S0AS0Bπ1S1AS1B\begin{array}{c|cc} & H_A&H_B\\\hline \pi_0&S_{0A}&S_{0B}\\ \pi_1&S_{1A}&S_{1B} \end{array}

S0B−S0AS_{0B}-S_{0A} 反映基础策略上的 Harness 差异,S1A−S0AS_{1A}-S_{0A} 是训练内接口增益,S1B−S0BS_{1B}-S_{0B} 才是新 Harness 上的策略增益。交互项

Δint=(S1B−S0B)−(S1A−S0A)\Delta_{int}=(S_{1B}-S_{0B})-(S_{1A}-S_{0A})

描述训练收益在 B 上被放大还是削弱。只报告 S1B>S1AS_{1B}>S_{1A},无法知道优势来自 policy 迁移还是 B 本身。

预算必须统一到任务级。Harness B 可能允许更多 token、更多工具调用或更长超时,成功率自然更高。可以同时给固定 token、固定墙钟、固定工具步数三种对照;现实部署再报告各自默认配置。若 B 用并行子代理,单看主线程步数会低估计算,应累计所有分支的模型 token 与环境动作。

观察空间也要对齐。一个 Harness 返回完整 stderr,另一个只写「失败」,前者提供更多信息;一个自动读取相关文件,另一个要求模型主动搜索,二者的任务已不等难。研究共享 policy 能力时,可以构造规范化 observation adapter;研究端到端产品时则保留原生能力,但把额外观察与自动动作列出。

新 Harness 的「未见」程度需要量化。仅换命令名、system prompt 或 JSON 字段属于低层接口变化;改变工具集合、历史压缩和错误恢复属于中层控制变化;从单 Agent 变成多 Agent、从终端变成 GUI 则改变了决策结构。迁移结论应标明变化层级。对低层变化有效,说明格式鲁棒;对中层变化有效,才更支持 Harness-agnostic 技能;跨模态迁移还需要额外证据。

轨迹数据若混合多个 Harness,可以帮助模型见到更多接口,也可能形成条件冲突。相同工具名在两套系统中语义不同,或相同错误字符串要求不同恢复动作,模型会收到矛盾监督。训练样本应包含稳定的 Harness 标识和 schema,必要时映射到统一中间动作;评测未见 Harness 时,则不给训练标识,观察模型能否通过工具描述快速适配。

Harness 切换后的提升还可能来自选择效应。强 Harness 使更多困难任务完成,成功样本分布随之变化;若只分析成功轨迹,会误以为模型在 B 中步骤更合理。失败与环境错误必须一起比较,并按同一任务配对。逐任务差值能指出收益集中在哪些类型:长上下文、工具故障、并行搜索,还是单纯格式修复。

一条 Agent 轨迹同时继承任务、环境、模型、Harness 与验证器五类来源。任一来源变化,样本语义都可能改变。适合长期保存的主键不应只是递增编号,而应由稳定标识组成:任务内容与初态摘要、镜像 digest、policy checkpoint、Harness commit、verifier commit、采样参数和 attempt。数据集发布时可以隐藏敏感路径,却要保留能判断两条轨迹是否同源的信息。

仓库任务尤其容易泄漏。同一个 issue 会被改写成多种描述,同一 bug 也可能出现在 fork、后续 commit 或相邻分支。按 prompt 哈希分割几乎没有作用。更可靠的分组键包括上游仓库、基线 commit、受影响文件、失败测试和补丁语义。补丁语义可以用修改函数、AST 差异和测试覆盖近似;无法确定时宁可把同一仓库集中到一个分区,牺牲部分覆盖换取清晰评测。

时间泄漏同样重要。训练轨迹使用 2026 年后的仓库状态,评测却声称模拟更早 issue,模型可能从后续代码看到修复。环境构建要固定基线 commit 和依赖快照,数据划分记录 issue 创建、修复合并与轨迹生成时间。实时网页任务则记录页面和后端状态的时间窗口;同一 URL 在不同日期可能已是完全不同的问题。

SWE 数据中的多个 rollout 共享任务初态。把它们随机分到训练与验证,会让验证测到对同一 bug 的再次采样,而非新任务泛化。即使消息轨迹不同,隐藏测试与修复目标仍相同。统计置信区间也要以任务为抽样单位;十条同任务 rollout 提供的是对该任务成功概率的估计,并非十个独立任务。

去重还要覆盖教师输出。两个 teacher 从同一参考补丁出发,生成文字不同但动作路径高度一致;直接当作多样样本会高估策略覆盖。可以把动作规范化为读取、搜索、修改、验证等事件序列,再比较文件与命令对象。语义去重不必删除全部近邻,可以保留少数代表,并把重复权重降下来,防止常见仓库模式占据训练池。

轨迹清洗应保持可逆血缘。原始事件层只追加,不直接覆盖;规范化层记录 parser 与 schema 版本;训练片段层保存来源区间、筛选理由和 reward;最终打包层记录 tokenizer 与 chat template。发现解析错误后,可以从原始事件重新生成,而不必猜测被清洗脚本改过什么。若为了隐私删除原始内容,也应保留删除清单、摘要与受影响字段,使后来者知道哪些分析无法进行。

数据集中的 unresolved 不是统一负类。至少可分为模型主动放弃、预算耗尽、测试失败、Harness 崩溃、环境失效和 verifier 不可用。只有前几类在环境健康时反映 policy 局限;其余属于数据质量问题。发布汇总时给出各类数量,训练脚本再按用途选择。将所有 unresolved 写成 reward 0,会让基础设施故障比例较高的仓库承受更多负更新。

截图与网页数据还含视觉近重复。相同页面在滚动、弹窗或时间变化后像素不同,感知哈希只能发现部分重复;DOM 结构、目标元素和任务后端 ID 能提供补充。GUI 轨迹若只发布 judge 通过的成功样本,读者无法估计 judge 的选择偏差。至少应给原始候选数、拒绝原因分布和人工抽查结果,即便失败截图因许可不能全部公开。

数据许可和敏感信息,Agent 轨迹比普通对话更容易夹带秘密:仓库中的配置、命令输出里的 token、网页账户信息、浏览器 cookie、文件路径中的用户名都可能进入模型上下文。采集端应在已知结构处先阻断,例如不给生产凭证、为测试账户发短期 token;存储端再按字段和内容双重扫描。仅在发布前做一次正则清洗,无法覆盖 base64、URL 参数、截图和模型复述。

脱敏会改变训练语义。把所有秘密替换为空字符串,工具调用可能失去必填参数;用统一 <SECRET> 又会让多个不同凭证看似相同。可使用带类型和作用域的占位符,如 <TOKEN:repo:episode>,并让模拟环境识别它。这样模型能学习凭证应放在哪里,却不能恢复真实值。原始与脱敏轨迹之间保留访问受控的映射审计,公开数据只含不可逆占位。

代码、网页和教师输出各自受许可约束。环境可执行不代表轨迹可以再发布,公开仓库也可能含限制性数据或个人信息。数据卡应说明来源、许可筛选、退出机制和删除传播:某条源数据撤回后,原始轨迹、派生片段、训练打包与缓存都能根据血缘定位。没有血缘图时,删除请求只能靠全库字符串搜索,容易漏掉改写内容。

2.1. 成本数字背后的容量规划

论文给出的 spot 与 on-demand 成本展示了自托管环境的潜在优势,但容量规划还要考虑利用率、运维和失败。购买 1000 个 Pod 的名义容量,若平均只有 40% 在执行有效 episode,其余时间等待模型或镜像,单位有效轨迹成本会明显升高。设集群每小时成本为 ChC_h,完成 episode 数为 NN,有效率为 η\eta,则

ceffective=ChNη.c_{effective}=\frac{C_h}{N\eta}.

提速和降价都可能被低 η\eta 抵消。spot 抢占若让长任务在末尾失败,损失的不只是环境分钟,还有此前模型 token。成本核算应把被丢弃 rollout 的推理费用算进去。

资源规格也会影响任务结果。给测试进程更少内存可能触发 OOM,CPU 限额太低会导致超时;这些失败若被当作 policy 失败,便改变训练。为了省成本动态缩小 Pod 时,必须在任务 manifest 中声明最低资源,并用参考方案在该规格上验收。跨系统成本比较需要对齐成功所需资源,不能让一方以更高失败率换低价格。

镜像缓存是吞吐的关键变量。大量异构 SWE 镜像首次拉取可能占用分钟和网络带宽,缓存命中后启动才很快。报告 Pod 创建时间时应分别给冷缓存与热缓存,并说明镜像大小分布。调度器可以把相同镜像任务聚到已有缓存的节点,但过度聚集会造成节点热点;还要防止恶意或错误镜像填满磁盘,把后续任务挤出缓存。

热池把冷启动换成闲置成本。设冷启动时间 TcT_c,任务服务时间 TsT_s,到达间隔随机。保留 KK 个预热 Pod 能降低等待,却在空闲时持续收费。适合固定镜像、任务到达稳定的 GUI 服务;SWE 镜像高度异构,通用热池只能预热基础 agent payload 和常见层。容量策略应根据镜像复用率、等待损失和闲置单价求平衡,而非把热池当作统一答案。

模型与环境容量要联调。若推理服务每秒只能处理 20 个调用,环境层把 exec 提升到每秒 150 个也不会线性提高 episode 吞吐;若模型生成很快而测试耗时长,则环境并发决定 GPU 是否有足够其他请求填充。可以用事件日志计算每条轨迹在 model、queue、environment、verifier 四类时间上的占比,再扩容占比高且排队明显的部分。

长尾决定同步训练的节奏。平均 episode 10 分钟,P99 可能超过一小时;等待完整 batch 会让大部分资源空闲,提前截断又丢失最难任务。按长度预测分桶、异步消费和软截止能缓解,但每种方案都会改变数据分布。成本报告应给完成时间分位数、截断率以及不同长度任务的成功率,避免平均值掩盖系统对长程任务不友好。

一个简单算例:500 个并发 Pod,每小时成本 100 美元,平均每条 12 分钟,理论每小时完成 2500 条。若启动失败 5%、运行故障 7%、verifier 异常 3%,近似有效率为 0.95×0.93×0.97=0.8570.95\times0.93\times0.97=0.857,每小时约 2143 条,环境成本约 0.047 美元一条。再考虑 10% 的策略过旧样本不能进入在线更新,用于 RL 的单位成本升到约 0.052 美元。若模型推理每条 0.20 美元,优化环境仍有价值,却不是总成本的主项;若任务本地模型推理很便宜,环境占比则会反过来升高。

托管服务与自托管的比较还包括工程人力、可用性和弹性。自托管在持续大负载下摊薄控制面成本,并能自定义镜像与网络;托管服务在突发、小规模任务上省去集群维护。论文的价格实验说明特定设置下的资源账单,不等于所有团队都应迁移。最有用的结论是把环境成本拆成可测组件,再根据自身任务分布复算。

默认 deny-egress 是良好起点,但 Kubernetes NetworkPolicy 的效果取决于 CNI、DNS 和规则组合。应从 Pod 内实际请求云元数据地址、集群 API、其他 namespace、允许域和随机公网域,验证每条路径。DNS 放行常被忽略:允许查询任意 DNS 可能形成低带宽外传通道;完全阻断又让域名 allowlist 无法工作。可使用受控解析器,只解析许可域并记录查询。

容器隔离也不等于强安全边界。内核漏洞、特权 capability、宿主机挂载和容器运行时配置都可能造成逃逸。任务镜像默认以非 root 用户运行,删除不需要的 capability,使用 seccomp/AppArmor 或等价策略,不挂载宿主机 socket。确需编译、浏览器 sandbox 或特殊内核能力的任务单独分级,放进更强隔离节点,不能为了兼容少数镜像给全部任务提权。

运行时注入 agent 要建立信任链。注入镜像按 digest 固定并签名,orchestrator 验证来源,Pod 内 agent 只暴露必要接口。若用户任务镜像能改写 agent 二进制或窃取其服务凭证,隔离层会被绕过。只读挂载、独立用户与短期双向认证可以缩小风险;协议仍要防命令注入、路径穿越和超大响应。

文件接口尤其要检查路径边界。客户端请求 /workspace/../etc/shadow、符号链接指向工作区外部、压缩包含 ../ 条目,都可能越过预期目录。若 API 设计为访问整个容器,就要明确这一权限;若只允许 workspace,则解析真实路径后再次验证前缀,并防止检查与使用之间被替换的竞态。Agent 本就可以执行 shell 时,文件 API 限制不会提供完整安全,但仍能保护控制面自身不被利用。

秘密分发遵循最小权限和最短寿命。每个 episode 使用独立凭证,权限限定资源与动作,结束后立即撤销;verifier 使用另一套只读或验收凭证,防止 policy 修改评分数据。Secret 不放进普通环境变量转储和轨迹日志,工具层以句柄引用。若任务需要模型填写 token,使用模拟值和测试服务,训练数据不接触生产秘密。

资源配额也是安全边界。fork bomb、无限日志、磁盘写满和高频网络请求既可能来自恶意任务,也可能是模型失误。CPU、内存、进程数、临时盘、输出大小、网络速率和总时长都要限制。达到配额时返回明确的 resource_exhausted,并记录是哪项资源,而不是让 Pod 无声消失。这样 Recipe 才能判断策略是否制造了问题。

清理验证要覆盖外部副作用。删除 Pod 后,临时云资源、测试账户记录、消息和对象存储文件可能仍在。环境 manifest 列出 episode 创建的外部资源,终止钩子逐项回收;清理失败进入独立队列并告警。对于无法真正删除的系统,使用带过期时间和命名空间的资源,至少避免长期污染下一次任务。

Orchard 同时报告环境微基准、数据规模和三个 Recipe 的模型结果,三类数字回答的问题不同。exec 延迟和千 Pod 创建成功率说明环境服务的性能与稳定性;107K 轨迹说明可收集的数据量;SWE、GUI、Claw 分数说明特定模型、训练配方与推理设置的端到端效果。环境更快能降低等待和成本,却不会在逻辑上推出模型分数更高;模型分数提高也不能证明每个环境组件都必要。

环境微基准需要明确分母。一次 exec 的延迟从客户端发请求开始,可能包含序列化、网络、Pod agent 调度和命令执行。若命令本身只有 echo,主要测框架开销;真实测试运行几十秒时,0.4 秒差异占比很小。可将延迟写成

Texec=Tclient+Tnetwork+Tagent+Tprocess+Tpayload,T_{exec}=T_{client}+T_{network}+T_{agent}+T_{process}+T_{payload},

并用空命令、不同输出大小和不同运行时长分别测量。对照系统若走不同区域、TLS 设置或并发限制,数字便不再只反映架构。

千 sandbox 26 秒端到端说明控制面能承受一次并发突发,仍需说明「成功」的判定:Pod 被 Kubernetes 接受、进入 Running、health check 通过,还是完成首条命令。训练真正需要的是 ready-to-exec。若前 900 个很快、收尾阶段 100 个因镜像或调度拖延,总时长由尾部决定;同时给 ready 曲线与 P50/P95/P99 比一个最大值更能解释扩展行为。

Terminal-Bench 从 direct Docker 迁到 Orchard 后分数无明显回归,为环境等价提供经验支持。分数略有上升不必解释成 Orchard 提升了模型能力,采样随机性、时间、依赖和运行噪声都可能造成差异。更直接的等价性证据是同一动作脚本在两环境的最终文件哈希、测试结果和错误类型;模型分数则作为综合回归,捕获脚本未覆盖的差别。

SWE 的 69.7% 与 reranking 后 73.0% 对应两套推理条件。Reranker 从多个候选中选择,会增加采样成本,效果依赖 value model 对候选排序的准确性。若每题产生 kk 条轨迹,73.0% 不应与其他系统的单次输出直接横比。至少报告每题候选数、总 token、环境时间和选择失败案例,才能判断提升来自 policy、本身的 pass@k 空间,还是更好的排序。

GUI 4B 模型超过 235B teacher 说明学生在给定评测上可以借助领域数据与 RL 达到更高成功率,无法推出小模型一般能力超过大模型。Teacher 负责生成数据时的采样 Harness、推理预算与训练后学生的评测 Harness可能不同;学生还见过目标域训练分布。公平解释应限定在 WebVoyager、Online-Mind2Web、DeepShop 的具体协议,并检查 judge 与网站漂移。

Claw 在切换 ZeroClaw 后提高,恰好展示 policy 与 Harness 交互。若训练时跨两个 Harness,模型可能学到一定接口鲁棒性;ZeroClaw 也可能拥有更强的工具和控制流。前述四格矩阵能拆分两者。pass@3 上升 14.3 点与 pass^3 上升 9.3 点说明至少一次成功和稳定成功都改善,但二者仍依赖逐任务三次采样的联合分布,不能用单次概率独立推导。

论文版本变化同样属于实验条件。v1、v2、v3 可能更新训练路线、模型与主表;引用数字时绑定 arXiv 版本与日期。仓库 main 在论文后继续演进,运行当前代码得到不同默认参数很正常。知识库同时给论文结论和当前代码状态时,应分别标注,避免读者把路线图实现或后续姊妹项目倒灌进原始实验。

结果归因的最小实验集,若要判断 Orchard Env 是否带来训练收益,至少需要三个层次的对照。第一层固定动作脚本,比 direct Docker 与 Orchard 的状态、延迟和错误;第二层固定 policy,比两环境中的轨迹与成功;第三层固定任务、token 和采样数,比使用 Orchard 数据训练前后的 policy。每一层只回答自己的因果问题。

Recipe 的数据贡献可通过等 token 消融。随机成功轨迹、只保留 resolved、加入 unresolved productive segment、再加入 RL,逐步比较。若每一步同时增加 token 数与数据质量,无法知道收益来自数量还是筛选。对失败片段,还应使用随机片段和相同长度的邻近片段作对照,确认 value-based 选择确实选中了更有用内容。

BAR 的贡献可在固定 rollout 预算下比较均匀采样与自适应采样,报告进入更新的非退化组比例、任务覆盖、梯度方差和最终固定集成绩。只报告训练 reward 会偏向 BAR,因为它主动改变了采样分布。还可以把 BAR 产生的数据交给相同优化器,排除 trainer 实现差异。

跨 Harness 泛化使用训练×评测矩阵,并增加原始基座。所有格子共享 checkpoint、任务、镜像、采样参数和预算;Harness 原生自动动作另行计费。按任务配对后,报告改善、退化与不变的任务数,避免平均分掩盖某一类任务大幅倒退。

环境可靠性要用故障注入验证。人为让 Pod 启动失败、exec 响应丢失、节点抢占、Redis 短暂不可用、verifier 超时,再检查错误分类、幂等重试和资源清理。系统在无故障压测中成功,无法证明异常路径不会产生重复动作、幽灵 Pod 或错误负奖励。注入率与恢复时间也要记录,使可靠性结论可复算。

2.2. Orchard 与训练算法的边界

Orchard Env 提供状态转移和观测,slime fork 与各 Recipe 决定怎样采样、构组、计算奖励和更新 policy。这个分层允许替换 PPO、GRPO、蒸馏或其他算法,也意味着论文某个训练技巧的效果不能自动归给 Env。公共环境降低了做受控比较的成本,最终比较是否公平仍取决于 Recipe。

On-policy 方法要求轨迹接近当前策略。环境执行时间长、队列积压或重试都会让样本变旧。Env 可以记录开始、结束和 policy 版本,trainer 才能决定丢弃、降权或继续使用。环境层若只返回最终消息而没有版本与时间,算法无法判断 policy lag;trainer 若忽略这些字段,再完整的记录也不会自动纠偏。

离线 SFT 对策略版本不敏感,却受行为覆盖限制。107K 轨迹展示教师和采样 Harness 到达过的状态,没出现的错误恢复路径无法从模仿中学到。加入 unresolved 能扩大失败状态覆盖,仍要通过筛选把环境故障与模型失误分开。SFT 学到的是数据条件分布,不能仅凭数据量推断在新状态上的恢复能力。

奖励由 Recipe 定义。SWE 隐藏测试、GUI judge、Claw verifier 的误差结构不同;Env 只保证它们能在对应状态运行。把多个域混合训练时,reward 数值尺度也未必可比。二元成功、分步 judge 和测试比例若直接相加,某个域会因密集反馈占据梯度。需要按域归一、分批或采用多目标权重,并在固定评测上验证权重选择。

轨迹中的工具动作是否参与 policy loss,也由训练层决定。Harness 自动插入的消息、环境返回和模板 token 应掩码;模型生成的工具 JSON、自然语言与代码可能采用不同权重。若重建器把自动修复后的动作当作模型输出,Env 执行成功会给不存在的序列正奖励。环境记录原始请求与执行请求,trainer 再明确选择,二者缺一不可。

价值模型 reranking 位于推理决策层。它可以利用多个完整候选的终态和轨迹特征,作用类似额外搜索。若把 reranked 成绩称为 policy 成绩,读者会低估推理预算与第二模型贡献。更清晰的报告同时列单样本、pass@k、oracle@k 与 value-rerank@k:oracle 上限展示候选池潜力,reranker 与 oracle 的差距展示选择误差。

算法替换还可能改变环境压力。更大的 group size 同时启动更多 sandbox,树搜索需要 snapshot 与分支,异步算法容忍长尾却增加策略滞后。Env 的性能不能脱离算法负载评估。一个在独立请求微基准中最快的实现,面对大量长连接、截图和分支恢复时未必仍领先。

Orchard 已给出可运行的开源环境、三条 Recipe、数据与论文实验,足以深入讨论环境服务、轨迹生成和训练接口。它当前不能回答所有长程 Agent 问题。Stateful pause、resume、branching 仍属于路线图,因此本章对快照价值估计的推导是基于该能力的研究方向与验收条件,不应冒充现有主表已经验证的机制。

论文覆盖 SWE、GUI 与 Claw,代表代码、网页和通用工具三类环境,仍没有覆盖真实长期团队协作、跨天任务、持续用户反馈与高风险外部操作。这些场景包含不可回滚的人类状态和制度约束,Pod 隔离只能管理其中一部分。将 Orchard 的沙箱结果外推到生产,需要重新定义权限、审批、隐私和用户满意度。

成本数字来自特定区域、时间和实例价格,会随云市场变化。本章保留计算结构与必要条件,不把美元数字视为长期常数。真正稳定的知识是如何计算 Pod 时间、有效率、重试损失和模型—环境联动;部署者应代入自己的价格与任务分布。

跨 Harness 结果支持在论文组合中的迁移,尚不足以宣称对任意未知 Harness 普遍泛化。工具语义相近、训练中见过多种接口与更强部署控制流,都可能贡献收益。要扩大结论,需要更多机制差异明显的 Harness、完整四格矩阵和统一预算。

数据公开让离线统计和训练更可行,完整 rollout 复现仍依赖原镜像、网站、teacher、verifier 与当时版本。缺少其中一项时,应明确复现层级。能够读数据集不等于重建环境,能够部署 Env 也不等于复算模型主表。

在这些边界内,Orchard 的贡献很清楚:它把过去各项目重复搭建的 sandbox 变成独立环境服务,使 distillation、RL 和 evaluation 能围绕同一状态转移接口组织;又用多个 Recipe 证明这层抽象并未局限在单一任务。后续工作要做的,是让状态可分支、证据可归因、故障可恢复,并把论文设置中的可用性扩展到更长、更开放的真实任务。

一条可复算的最小闭环,真正复现 Orchard 不必一开始就训练完整模型,可以先建立一条单任务闭环。第一步固定镜像 digest、任务初态与参考方案,在 direct Docker 中运行并保存最终状态。第二步把同一镜像交给 Orchard Env,使用相同用户、资源、网络和命令序列,比较文件哈希、退出码、测试与副作用。两者一致后,环境替换才算通过。

第三步接入一个固定 policy checkpoint 与固定 Harness,在 Orchard 中重复采样若干次。每条 episode 保存 policy、Harness、环境与 verifier 版本,分别统计任务失败和基础设施失败。若相同种子仍得到差异,沿请求、Pod generation、工具观察和终态逐层定位,而非先修改训练算法。

第四步把原始事件转换成训练样本。随机抽取调用,确认模型输入与采样时完全一致,模型 token 掩码正确,Harness 自动消息没有进入 loss;再从最终状态独立重跑 verifier,确认 reward 能按 episode 绑定。环境异常和轨迹不完整的样本进入隔离集合,不参与优势估计。

第五步只做一个很小的更新,并在固定锚点任务上比较更新前后。检查 loss、KL、梯度范数、动作格式和成功率,尤其确认没有因 parser 错位而训练模板 token。小闭环稳定后再增加并发、任务种类和训练步数。直接从千 Pod 开始,只会把一个可定位错误复制成海量坏轨迹。

这个闭环还应包含故障注入。让一次 exec 响应丢失,检查 operation ID 是否防止重复执行;让 verifier 超时,确认样本不会记成任务失败;让 worker 在命令结束后崩溃,确认终态和日志仍可回收;让 delete 失败,确认 TTL 与告警最终清理资源。四个测试覆盖控制面、数据面、奖励与生命周期的主要连接处。

收尾阶段再做吞吐扩展。并发从小到大递增,观察 ready 延迟、exec 尾延迟、Proxy 队列、模型利用率、环境错误率和有效轨迹吞吐。某个指标出现拐点时先扩容对应瓶颈;若错误率同时上升,就停止增加并发。目标是每小时得到更多可训练、可验证的 episode,而非在监控面板上堆出更多 Running Pod。

2.3. 状态、算法与系统边界

读到一个新的环境系统时,可以依次问五个问题。它是否定义了稳定状态与动作语义;它是否能把任务初态和终态复现;它能否区分 policy、Harness、环境与 verifier 的失败;它生成的轨迹能否重建模型当时的条件概率;它的性能数字是否换算成有效 episode 与统一预算。前四个决定结论是否可信,第五个决定方案是否值得规模化。

若状态语义含糊,训练公式再先进也可能吃到错误样本;若失败无法归因,reward 0 会混合模型与系统噪声;若轨迹无法重建,策略梯度对应的已是另一段历史;若只追 API QPS,系统可能更快地产生无效数据。Orchard 提供了回答这些问题的一套开源基础,但每个 Recipe 仍需把自己的任务、奖励和安全边界补完整。

因此,环境层的「薄」指职责清楚,不代表信息贫乏。它不替上层决定什么是好答案,却要完整记录动作怎样变成状态变化;它不选择 RL 算法,却要提供算法判断样本有效性所需的版本、时间与故障;它不承诺任何 Harness 都会泛化,却要让不同 Harness 在同一任务状态上可比较。守住这个边界,环境才能长期复用,研究结果也才能从一次演示变成可累积的证据。


产品落地对照见 ../../../essays/oasis-improvements-2026-08-harness-wave.md。