如果你在任何真实规模下运行编程智能体 (coding agents),你就拥有一支临时虚拟机舰队。你可能并没有主动申请这样做。但在你决定(且正确地决定)不信任的、由模型生成的代码绝不应该在应用程序的信任边界内执行的那一刻,这一切就发生了。每个任务都有自己的沙箱,每个沙箱都是一个微型虚拟机 (microVM) 或硬化容器。突然间,那个自以为在构建“智能体产品”的平台团队,实际上正在运营一些看起来非常像微型 AWS Lambda 的东西:池预热 (pool warming)、快照流水线、装箱调度器 (bin-packing schedulers),以及一个针对无人认领环境的清理进程 (reaper process)。
陷阱在于假设你的容器编排直觉可以无缝迁移。有些确实可以。但 Kubernetes 是为了调度长周期的、同质化的服务而设计的,而智能体沙箱恰恰相反:生命周期短、极度异构,且创建速度之快让部署滚动更新 (rollout) 看起来像是在悠闲散步。那些挣扎的团队往往将沙箱基础设施仅仅视为“步骤更多的容器”。有趣的工程挑战——以及几乎所有的成本——都集中在四个问题上:冷启动、文件系统状态、装箱密度和弃置。
为什么每个任务都拥有专属机器
“按任务隔离”模型之所以胜出,原因很简单:智能体是一个连接到执行循环的不受信任的代码生成器。OpenAI 的 Codex 在其专属云容器中运行每个任务,预装好代码库,任务完成后即销毁,且默认关闭网络访问。Anthropic 的云服务以及所有主流沙箱供应商——E2B、Daytona、Modal、Fly.io——都趋向于同一种形态:会话作用域、隔离、可丢弃。
共享环境会同时在两个方向上失败。安全性:模型生成的代码可能会执行 rm -rf、窃取凭据或破坏后续任务依赖的状态。正确性:两个智能体在共享环境中安装冲突的依赖版本,会产生无人能复现的故障。按任务隔离从结构上消除了这两类问题,这也是为什么现在没有严肃的开发者再对此表示异议。
但这将成本转移到了其他地方。一个每天处理 10,000 个智能体任务的服务,现在每天需要启动 10,000 台机器。这支舰队的单位经济效益——机器启动速度、每台机器闲置时的内存占用、装箱密度——都变成了产品层面的关注点。一个需要 30 秒才能完成配置的沙箱,是对每个任务征收的 30 秒“税收”,而那些为单个工具调用就启动沙箱的智能体循环,在每个会话中要支付几十次这种开销。
冷启动:资源池是对流量的赌注
原始数据解释了整个预热池行业的兴起。Firecracker microVM 的冷启动——包括最小内核、用户空间初始化、网络设置——中位数大约在 110–200ms 左右,p99 超过 300ms。这还没算上克隆代码库、安装依赖或启动语言服务器的时间。一个从零开始构建的、现实中的“冷”智能体环境需要数十秒。而从内存快照恢复相同的环境,虚拟机本身只需要个位数的毫秒;Lambda SnapStart 的生产环境数据在 p50 左右约为 3ms。供应商提供的端到端数据如 Daytona 从预热池创建沙箱不到 90ms,以及 Fly.io 对其智能体专用机器提供的约 300ms 检查点/恢复 (checkpoint/restore)。
这就是“完全冷启动”和“从快照恢复”之间三个数量级的差距,而预热池就是你购买“极速体验”的方式。你预先启动 N 个环境到某个检查点——操作系统就绪、运行时已安装、常用依赖存在——然后要么让它们保持运行(支付闲置内存费用),要么创建快照并停放它们(支付存储费用和恢复延迟代价)。
规模估算问题才是最有趣的地方,因为这是在对你无法控制的流量下注:
规模太小 :突发流量会掉进冷启动路径。冷启动延迟在并发下会产生叠加效应——一堆任务每个都在等待 30 秒,这就不再是延迟问题,而是宕机事故。
规模太大 :你将全天候为闲置内存付费。与 CPU 不同,内存无法优雅地超卖;一个预热但闲置的资源池几乎是纯粹的成本。
太通用 :预热起不到作用。一个预置的 Ubuntu 镜像能帮你省下 200ms 的内核启动时间,但省不掉主导实际启动时间的 40 秒 npm install。
最后一点是很多团队容易忽略的。有价值的快照不是“一个已启动的虚拟机”,而是“一个已启动且已经安装了该仓库 依赖树的虚拟机”。这意味着你的预热池不是一个池,而是一个以环境指纹为键的缓存,这带来了所有缓存管理难题:当 lockfile 更改时的失效机制、基于流行度的保留策略,以及大量永远不值得预热的长尾环境。挂起/恢复 (Suspend/resume) 计费模型——即停放的机器按存储而非计算计费,如 Fly 的挂起机器——之所以存在,正是为了让一个巨大的、大部分闲置的缓存变得经济适用。
文件系统状态:写时复制 (Copy-on-Write) 是核心所在
第二个成本中心是将工作树导入沙箱。朴素的方法是:针对每个任务都执行 git clone 加上依赖安装。对于大型单体仓库 (monorepo) 来说,这需要花费数分钟,而且这是数分钟的无效工作,因为每天 10,000 个任务生成的几乎是完全相同的文件系统。
每一个生产级沙箱平台最终都会得出相同的答案:写时复制 (copy-on-write) 分层。一个只读的基础镜像包含操作系统、工具链和依赖树;每个沙箱获得一个薄薄的可写覆盖层 (overlay),仅捕获该任务所做的更改。OverlayFS 是其中的主力——曾有厂商记录显示,通过在同一主机上的沙箱之间共享只读基础层,将每个沙箱的内存占用了削减了 75%,因为共享层的页面缓存 (page cache) 只需支付一次成本,而不是按虚拟机支付。块级方法(ZFS 或 device-mapper 快照)在更低的一层实现了同样的效果:无论代码库规模如何,“检出” (checkout) 都变成了一个以毫秒计的元数据操作。
这也是快照分类比厂商营销更重要的地方。仅文件系统快照(Daytona 的模型)能立即恢复你的文件,但需要重建进程状态——你的语言服务器会重新索引,你的 REPL 会重启,你运行到一半的测试也消失了。内存加文件系统快照(E2B、Modal、Together 的方法)则会同时恢复正在运行的进程,这便是“智能体环境回来了”与“智能体环境从未察觉到它被暂停过”之间的区别。对于具有昂贵内存状态的数小时智能体任务,这一区别决定了平台的选择。
微妙的失效模式:恢复内存快照会克隆 所有内容 ,包括必须唯一的东西——随机种子、TLS 会话状态、机器 ID、缓存的时间戳。从一个快照恢复的两个沙箱就像连体双胞胎,在某些方面可能会破坏加密,并使任何假设唯一性的组件感到困惑。Firecracker 文档对此直言不讳;平台通过恢复后的重新播种钩子 (re-seeding hooks) 来处理它,如果你构建自己的快照流水线,你也将继承这一清单。
当任务时长从几秒到几小时不等时的装箱问题 在理论上,密度是微型虚拟机 (microVMs) 的优势所在:Firecracker 的开销在每个虚拟机 5MiB 以下,主机理论上可以运行数千个。在实践中,束缚因素是访客内存 (guest memory),而调度问题比任何 Kubernetes 装箱 (bin-packing) 指南所准备的都要棘手。
容器装箱的经验法则是假设服务:长寿命、可预测的资源曲线、已知的副本数量。你将它们紧密压缩,减少节点数量,节省 30–50%——这是标准操作手册。而智能体任务逐一打破了这些假设:
持续时间是双峰分布且在准入时未知。 一个任务可能是一个 5 秒的代码检查 (lint),也可能是一个 3 小时的迁移。你无法要求调度器围绕一个没人知道的时长进行规划,而落在同一主机上的长任务会产生短任务无法回填的搁置容量。
资源使用是突发且自发的。 一个决定运行完整测试套件的智能体,会从接近空闲状态瞬间转为占满四个核心。相关的突发情况——同一主机上的多个智能体同时进行编译——会击败那些在不相关的 Web 流量下表现良好的超配 (oversubscription) 计算公式。
没有优雅驱逐。 Kubernetes 可以重新调度一个无状态 Pod 来整理节点碎片。但在任务中途杀死智能体的沙箱会丢弃可能价值数小时的已支付模型 Token。每个沙箱实际上都是一个带有“禁止驱逐”注解的 Pod——而这正是装箱文献中指出的破坏装箱效率的配置。
从容器时代传承下来的经验包括:请求/限制 (request/limit) 纪律、优先级层级,以及“装箱是一个预测问题”的观察。误导性的则是:任何假设你可以在放置后移动工作的策略。实际的集群往往会收敛于按预期持续时间进行隔离——交互式短任务放在紧密压缩、超配的主机上,哪怕严重的突发也只是短暂影响;长运行任务放在保守压缩的主机上,在那里,容量搁置比密度更重要——加上对 CPU 的激进超配(反正智能体大部分时间都在等待模型响应)和对内存的诚实置备。
收割者:遗弃是常态,而非例外 最后一个问题是起初没人会设计的问题:大多数沙箱并非正常结束,而是被遗弃。用户关闭了标签页。编排器崩溃了。智能体完成了工作,但“完成”信号丢失了。重试派生了第二个沙箱,而第一个仍在运行。如果没有积极的回收策略,你的集群会单调增长出一层僵尸机器,持续计费直到有人注意到发票。
对于智能体工作负载,空闲检测确实很难,因为看起来空闲的沙箱往往只是在等待模型响应,而一次漫长的推理调用看起来完全就像是被遗弃了。朴素的基于 CPU 的空闲超时会在智能体思考中途杀死沙箱。可行的收割者 (reapers) 结合了多种信号:没有连接的客户端,并且 没有正在进行的模型调用,并且 N 分钟内没有文件系统写入——并采用“优先挂起”而非“优先杀死”的策略,这样误报的代价只是恢复成本(毫秒级,廉价),而不是丢失工作成果(数小时的 Token,昂贵)。
这也是计费模型反哺架构的地方。按秒计费加上自动挂起——这是整个厂商领域的发展方向——让收割者的工作变得宽容:尽早停放,经常停放,按需恢复。虚拟机式的持续计费让收割者的每一次漏报都变成真金白银的流失。如果你正在评估平台,“对于没人管的沙箱会发生什么”是一个比任何基准测试都更能说明问题的切入点。
你现在是在运行一个云平台——像云服务商一样规划预算 坦白说:单任务隔离(per-task isolation)是正确的选择,无论你的组织架构如何定义,它都会让每个智能体(agent)平台实质上变成一个微型云服务商。这其中有四个核心问题:作为流量对赌的温池(warm pools)、作为文件系统策略的写时复制(copy-on-write)、感知执行时长的装箱(duration-aware packing),以及作为一等公民子系统的资源回收(reaping)——这些正是该云平台真正的产品核心。各大供应商(E2B、Daytona、Modal、Fly)的竞争焦点正是在于他们能为你分担多少这些复杂性,而它们之间的每 CPU 秒价格差异高达 50 倍。因此,“自研还是外购”的权衡值得深思熟虑,而非盲目默认。
如果你选择自研,请毫不犹豫地向 Serverless 时代“偷师”——借鉴 Firecracker 快照、SnapStart 的恢复准则以及 Lambda 的池管理模式。在调度方面,请不要迷信你对容器的固有直觉。如果你选择购买服务,请从这些看似枯燥的维度进行评估:快照类型(内存或仅文件系统)、挂起(suspend)定价、高并发下的恢复延迟以及回收器(reaper)的行为逻辑。无论哪种方式,沙箱集群(sandbox fleet)都不再仅仅是一个实现细节。对于智能体(agent)产品而言,它 就是 你的基础设施账单。只有那些能够尽早核算成本的团队,才能在业务量增长 10 倍时依然保持高效交付。
会员专享
余下内容仅对会员开放。 会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。
— 完整文章,包含未公开存档的部分 — 可落地的工作框架,附带权衡与决策依据 — 新文章抢先看,先于公开发布 登录以继续阅读→ 随时取消 · 一次订阅,畅读全部