Google Cloud 于 2026-09-30 发布 GKE 沙箱新版,启动从 44 至 85 秒降到 1.1 至 8.8 秒,尾部延迟降 45 倍。 这条经验复盘落在「前置部署」Forward Deployed Engineer(FDE)的基础设施交付段:智能体与强化学习跑批用的「沙箱池」正是「前置部署」Forward Deployed Engineer(FDE)进客户现场后要亲手调的平台底座,客户最先追问的永远是加速器空转,而这份复盘给的不是平台能力宣传,是一套「先量基线、再把瓶颈回灌改原语」的可复制流程。「前置部署」Forward Deployed Engineer(FDE)真正该抄走的只有两个数:沙箱「时间到首命令」的均值与尾部最大值,以及控制平面的 Pod 创建量。 先把原来的做法讲清楚。改动前就是原始 Kubernetes 调度:每一条回放轨迹都新建一个 Pod,镜像冷了要现场拉,脚本跑完再把 Pod 删掉。测试环境是一台 10 节点的 gVisor「沙箱池」,开了 GKE 镜像流式 GKE Image Streaming、装了 Agent Sandbox 控制器,再加一个集群内的 SDK driver 去认领热 Pod。负载有两种:500 张镜像的 SWE-bench 环境,和更狠的 4578 张镜像的 R2E-Gym 语料,后者连本地磁盘都放不下。 在文档规模下会撞上三个瓶颈,出处在原文里写得很直白。第一个是加速器空转,也就是「时间到首命令」TTFC 与尾部延迟陷阱:强化学习是同步跑批,整批必须等最慢的那个沙箱就绪,沙箱要花几分钟去供给、拉镜像、跑初始化脚本,昂贵的加速器就只能干等。第二个是「镜像基数」:标准容器缓存假设只有几张静态基础镜像,而智能体强化学习里每一个任务(比如 SWE-bench 里成千上万个 GitHub 仓库)往往对应一张完全独立的 OCI 镜像,一轮跑下来就是上千张体积超过 1.2GB 的镜像,拉取立刻成为瓶颈。第三个是控制平面饱和:一次跑批就是一波突发,原文举的例子是 4578 张 R2E 镜像、每张假设 4 次回放,也就是 18312 个任务需要同时存在 18312 个沙箱;每分钟数十万个临时 Pod 的翻转让 API server 排长队、Pod 状态报错,还会误触发节点健康驱逐。对「前置部署」Forward Deployed Engineer(FDE)来说,这三个瓶颈正好对应客户现场最常被投诉的三件事:慢、排队、抖动,FDE 接手 GPU 集群调优时应当逐条对照,而不是先动模型层。 新做法是把 Kubernetes 自己放进自动研究与验证回路。原文明确写:团队没有去猜强化学习研究者要什么,而是用 SWE-bench 这类重负载基准故意压垮自家集群,把每一个冒出来的瓶颈(etcd 超时、GPU 空转尖峰)都回灌进开发周期去改 GKE 核心原语。对「前置部署」Forward Deployed Engineer(FDE)来说,这一步的价值在于它把「平台要改什么」从需求讨论变成了一组可复现的实验结果;调参开关、基准测试框架和压测负载都随 agent-sandbox-rl 示例一起开源,输出人类可读报告与 JSON 报告,可以在自己的集群上把同一组对比重跑一遍。原文由 Google Cloud 产品经理 Tinsley Shi 与 staff software engineer Tomer Glottmann 联名发布,两人都在平台侧,这也是它能给出压测细节的原因。 对「前置部署」Forward Deployed Engineer(FDE)来说,这张表里的每一行都应该能在自己的集群上复现,否则不能写进交付报告。改动前后的数字是这条复盘最硬的部分,按原文的表格逐条列清,并标明测试口径。「时间到首命令」TTFC 均值:改动前 44 至 85 秒(原文写 44s – 85s),改动后 1.1 至 8.8 秒,官方标注提速 10x,来源是同一批 10 节点 gVisor 沙箱池上的固定预算对比。尾部延迟,也就是最坏情况的最大 TTFC:改动前 7.5 分钟,原文括号里给出 450 秒,改动后严格低于 10 秒,官方标注提速 45x。并发量从 500 个同时任务一路拉到 18312(4578 张 R2E 镜像 × 4 次回放),官方称增益在每一种配置下都成立。这里必须点明一个常见误读:45x 说的是尾部最大值,均值只有 10x,两者不能互换着引用。 第二个指标是控制平面与 Pod 生命周期抖动,这一项决定集群在高并发下会不会自己抖散。同样一轮 4578 张镜像 × 4 次回放的负载,改动前原始 Kubernetes 要创建 18312 个 Pod,改动后 GKE Agent Sandbox SDK 只创建 5869 个,官方标注抖动降低 3.1x。原因在机制上:原始 Kubernetes 为每一步轨迹重建 Pod,而 SDK 的复用策略让 Pod 活着,在两次回放之间在 Pod 内部做 git reset 与仓库 checkout。原文还写了一个在压力测试里才暴露的后果:18312 个任务的规模下,原始路径触发了无界的垃圾回收循环。这条对「前置部署」Forward Deployed Engineer(FDE)的意义是:交付报告里必须同时给 Pod 创建量与失败沙箱计数,只给成功率不算证据。 原文把增益归因到两处改动,这两处才是可以照搬的做法。 第一处是把镜像水化 hydration 移出关键路径。高基数语料远超本地磁盘,训练中途去拉冷镜像会造成 I/O 争用和数分钟级的尾部延迟;SDK 负责把镜像「镜像放置」规划到不同节点,GKE 镜像流式 GKE Image Streaming 与提前预热池负责其余部分,结果是水化在回放真正开口要沙箱之前就已经完成。第二处是给控制平面限速。高并发回放会触发 API server 的惊群 thundering herd,Agent Sandbox 控制器加入速率控制,约束「预热池」的补充速度,让 etcd 与 API server 在突发下保持稳定。 还有一条容易被忽略的工程细节:SDK 会把每一个失败的沙箱计数并标记为可重试 retriable,而不是静默丢弃。原文的解释是,一次没有被记录的丢弃不只是少了一条回放,而是会让训练信号产生「奖励偏差」 reward bias。对「前置部署」Forward Deployed Engineer(FDE)来说,这句话可以直接翻译成一条验收条款:沙箱失效率与 silent drop 计数必须可查,不能只看最终成功率。 把博客正文和同仓库的 release notes 对照读,会发现一处版本归属的差异,这一点决定你部署时该锁哪个版本。博客把限速归给 Agent Sandbox Controller v1.0.0;而 kubernetes-sigs/agent-sandbox 仓库里,v1.0.0 于 2026-08-28 发布,它的 release notes 写的是另一批数字:去掉一次多余的元数据 patch 之后,单个 Sandbox 的平均 reconcile 延迟下降 55%(2.2x 提速),并优先处理大规模突发分配下的 claim p99 启动延迟,把预热候选的轮询间隔从 500ms 调到 100ms;与补充速率限制相关的 flags 是到 v1.0.2(2026-09-11)才在 release notes 里被文档化的,CRD 名此时写作 sandboxwarmpools.extensions.agents.x-k8s.io。更晚的 v1.0.4(2026-09-24)又加了 FleetConfig.run_isolation 的 names 与 namespace 两种模式,以及 shutdownAfterSeconds,用来隔离同一命名空间里并发的训练任务。结论很实用:想拿到博客里那套限速行为,别只锁 v1.0.0,直接上 v1.0.4 更稳。 原文给了唯一一个生产用户的口径。前沿实验室 Mistral AI 的 research engineer Jean-Malo Delignon 在原文中说,他们跨集群编排数十万个安全环境,单集群要扛住超过 30000 个沙箱的尖峰。这是厂商博客里引用的客户引语,不是独立第三方实测,但它至少说明这套「并发回放」的规模量级已经有公司在生产里跑。FDE 引用这条规模时必须注明它是厂商博客里的客户引语,不是第三方实测,也不能当成承诺指标。 作者与官方自己承认的局限、以及公开材料留下的空白,必须写全,这几条决定上面的数字能用到什么程度。 第一条,全部数字是厂商自测,没有第三方复核,也没有客户侧的改动前后对照。测试固定在一台 10 节点的 gVisor 沙箱池上,换机器规格、换镜像分布,增益都会变。 第二条,最关键的缺失是钱。原文只给秒数与 Pod 数,没有给加速器空转的绝对成本、GPU 小时数或账单金额,所以这套改动到底省多少钱,读者算不出来,只能自己按本集群的加速器单价折算。 第三条,预热不是免费的,这是官方自己写的权衡。提前把环境暖起来要花掉便宜的 CPU 与后台集群时间,让镜像流式与「就绪探测」不再落在关键路径上;原文的判断是「加速器空转才是贵的资源」,但并没有给出预热这部分的开销数字。 第四条,Pod 复用会在两次回放之间保留状态,官方只说了靠 Pod 内的 git reset 与仓库 checkout 来清理,没有公布清理失败的检测方式,也没有公开跨租户或跨任务的隔离测试结果。原文里提到的 LLM 生成代码场景,恰恰是残留状态最危险的地方。 第五条,版本归属不一致已经在上面写明。博客说限速来自 v1.0.0,仓库 release notes 里补速率限制的 flags 到 v1.0.2 才出现,两边口径不同,部署前必须在自己集群上按实际版本核对。 第六条,未覆盖的场景要主动点名。官方只测了两种代码执行负载(500 张 SWE-bench 镜像与 4578 张 R2E 镜像),浏览器类、数据库类、非代码类智能体的沙箱没有任何数据;安全侧只说明沙箱跑在 gVisor 隔离里,在 18312 并发这个量级上没有公开逃逸测试或 CVE 数据;集成侧目前只覆盖 Gymnasium、NVIDIA NeMo Gym 与 OpenHands 三家,仓库里另有 openclaw-fleet-gke 这类参考架构,但其余 harness 需要自己写适配器。 该行动的是两类人,动作可以立刻做,不必等这类平台进自己的客户现场。 第一类是在客户现场调 GPU 集群、被追问加速器空转的「前置部署」Forward Deployed Engineer(FDE);第二类是负责智能体评估与强化学习跑批的平台团队。两类人面对的是同一个问题:沙箱启动到底是加速器空转的主因,还是被误判成了主因。 具体做法五步。第一步,先量基线再动手:在目标集群上原样跑 agent-sandbox-rl 示例里的基准框架(仓库路径 kubernetes-sigs/agent-sandbox 下的 examples/agent-sandbox-rl),它输出人类可读报告与 JSON 报告,先用原始 Kubernetes 路径跑一遍,把 TTFC 均值与尾部最大值记下来,这两个数就是验收基线。第二步,按回放并发量定预热池:并发量 = 镜像数 × 每个镜像的回放次数(本例是 4578 × 4 = 18312),把「镜像放置」交给 SDK 规划,不要手工钉死节点选择器。第三步,把镜像水化移出关键路径:打开 GKE 镜像流式 GKE Image Streaming 并提前预热;当单张镜像大于 1.2GB、镜像种类上千时,这一步是必选项而不是优化项。第四步,控制器版本直接上 v1.0.4,并显式设置 FleetConfig.run_isolation;只按博客描述的 v1.0.0 部署,限速相关 flags 可能根本不存在。第五步,验收三项指标:TTFC 均值与尾部最大值、Pod 创建量,以及 SDK 上报的失败沙箱计数——官方特意强调静默丢弃会造成奖励偏差 reward bias,所以这个计数必须是零丢失,而不是只看成功率。 适用条件是:这套做法只在「同步跑批、批内最慢者决定整批」的智能体强化学习与评估负载上成立。交互式低并发推理、单租户长期在线的服务用不上预热加复用的模型,强行套用只会多付预热成本。如果你的瓶颈是 GPU 数量不足而不是沙箱启动慢,这套改动能带来的提升接近零;镜像种类在几百张以内且单张远小于 1.2GB 时,镜像流式带来的收益也会明显缩小。FDE 在客户现场要先确认瓶颈归属,再决定是否引入这套预热与复用配置。 回滚与退出方式是两层,都不需要改业务代码。SDK 这一层:关掉预热池与 Pod 复用,退回每条轨迹新建 Pod 的原始模式,配置上把预热池规模设为 0 并停用复用策略。集群这一层:保留 Agent Sandbox 控制器但把预热池置零,把 FleetConfig.run_isolation 与限速参数回退到默认值。触发回滚的条件有三条:Pod 内状态清理不干净造成跨回放污染;限速参数把预热池补充压得过慢,导致 TTFC 尾部回弹超过 10 秒;或者 API server 在高并发下出现 429 与 etcd 延迟抬升。回滚之后要重跑一次同配置基准,确认确实回到了原始 Kubernetes 的那组基线数字,否则你无法判断问题出在平台还是在负载本身。FDE 在变更前就把基线数字与回滚阈值一起写进交付文档,这样回滚之后能立刻判断改动是否真的生效。 原始来源: - https://cloud.google.com/blog/products/containers-kubernetes/accelerate-agentic-rl-with-gke-agent-sandbox - https://github.com/kubernetes-sigs/agent-sandbox/releases/tag/v1.0.0 - https://github.com/kubernetes-sigs/agent-sandbox/tree/main/examples/agent-sandbox-rl