乐于分享
好东西不私藏

AI-Native 软件工程(9):Execute Layer——AI 生成的代码如何安全执行

AI-Native 软件工程(9):Execute Layer——AI 生成的代码如何安全执行

上篇拆了 Verify Layer。验证通过之后,代码得跑起来。在哪跑、怎么跑才安全——这就是执行层。


三个星期前,我在一台开发机上跑 Agent 生成的 Python 脚本。脚本逻辑没问题,但内部有一行:subprocess.run("rm -rf /tmp/cache")——Agent “觉得”清理临时文件是个好习惯。

没有沙箱。脚本直接跑在宿主机。还好删的是 /tmp/cache 不是 /tmp,但我出了一身冷汗。

LLM 生成的代码不是恶意代码,但它是”未定义行为代码”——你不知道它会访问什么文件、发起什么网络请求、往 stdout 灌多少数据。在任何一个严肃的生产系统中,不能假设一段由概率模型吐出来的代码是安全的。

执行层的核心命题不是”怎么跑代码”——那个问题几十年前就解决了。真正的命题是:怎样在不可信代码和你的系统之间建一堵够坚固的隔离墙,同时不让这堵墙把开发体验一起隔死。


四个维度,同时优化

执行环境设计有四根柱子。它们不是四选一,是四个要同时优化的目标。每根柱子拉满都会撞到另外三根——这正是执行层有意思的地方。

隔离:一个光谱,不是开关

隔离不是”安全”或”不安全”。它是一个光谱,每一级隔离增加安全性,也增加延迟和复杂度:

       

         
           
           
         

隔离级别 技术栈 启动速度 安全等级 适用场景
进程级 subprocess + seccomp + Landlock < 10ms 受控开发环境
容器级 Docker / containerd + namespace + cgroup 2-5s CI/CD、内部工具
应用内核 gVisor (user-space kernel) 50-200ms 中高 多租户 SaaS
微虚拟机 Firecracker / Cloud Hypervisor 100-500ms 不可信代码、生产平台
WebAssembly WasmEdge / wasmtime < 5ms 中高 边缘函数、插件系统

       

     

Docker 不够吗?在大多数开发者场景下够。但对于”执行用户提交的任意代码”——不够。Docker 容器共享宿主内核,隔离半径依赖于 Linux namespace 和 cgroup。内核共享本身就是攻击面——历史上从容器逃逸到宿主机的大部分漏洞,都是因为共享内核。Northflank 的指南里有一句话我很认同:For truly untrusted AI-generated code, microVM isolation is recommended. 这不是 Docker 不安全,而是 Docker 的安全边界不是为”不可信代码执行”设计的。

gVisor 走了另一条路——它在用户态实现了一个精简内核,拦截应用的系统调用而不是直接传给宿主机内核。隔离强度介于容器和 VM 之间,启动速度远快于 VM。Google Cloud Run 和 App Engine 的后端就是 gVisor。

Firecracker 则更进一步——它是真的 VM,有独立的 Guest Kernel。但因为极度精简(只实现了云环境中真正需要的设备和驱动),启动速度可以压缩到 100 毫秒级。AWS Lambda 和 Fargate 的后端就是 Firecracker。


启动延迟:体验杀手

Agent 执行代码的典型工作流:生成代码 → 创建环境 → 安装依赖 → 执行 → 读输出 → 清理。

如果每次执行都启动 Docker 容器(2-5 秒),加依赖安装(5-30 秒),加清理(1-2 秒)——用户每次交互等 30 秒以上。这个延迟不是技术问题,是体验问题。用户不会说”沙箱启动慢了”,用户会说”这个 Agent 不好用”。

两种策略,各有利弊:

热池模式(Warm Pool)。提前启动一批沙箱实例,Agent 需要时直接分配。E2B、Daytona 都走这条路。E2B 把分配延迟压到了 200ms 以内。代价是预热池一直占用资源——假设你预热了 10 个 Firecracker VM,每个吃 128MB 内存、0.1 vCPU,那就是 1.28GB + 1 vCPU 在持续消耗。

快照模式(Snapshot)。Firecracker 支持内存快照——依赖安装完成后拍一个镜像,后续执行从快照恢复。启动从秒级降到毫秒级,比热池省资源。代价是快照管理本身的复杂度——快照过时了怎么办?多个快照之间怎么共享存储?你怎么知道哪个快照是”干净的”?

我的选择逻辑:个人开发 → 进程隔离(Claude Code sandbox-runtime,毫秒级启动,零维护成本)。团队共享的 Agent 平台 → 热池(启动延迟对多人并发场景影响最大)。多租户 SaaS → 快照 + 微 VM(快照解决冷启动,微 VM 解决安全)。


状态管理:无状态是理想,有状态是现实

你让 Agent 写数据清洗脚本。第一次运行——pandas 没装,报错。Agent 装了 pandas,重跑,成功。你说”再加可视化”——Agent 需要复用之前装好的 pandas 环境。

这种”多轮增量执行”意味着沙箱不能每次都是全新的。但状态持久化带来新问题:上次留下的临时文件、env 变量、甚至 /tmp 残留,可能被下次执行意外访问。

Claude Code 的做法值得细看:每次 bash 在同一个持久化工作区执行,但 seccomp + Landlock 在文件系统和网络层面卡死访问范围。它是一个”受信的工作区 + 不受信的代码”模型——工作区可以保留状态,代码能碰什么由策略文件决定。

E2B 的做法不同:每次执行从快照恢复一个干净的文件系统,然后把需要保留的文件通过 Filesystem API 写回来。更安全,但更慢,而且对”我需要保留 pip 安装的包”这种场景不够灵活。

这是执行层里最难设计的一环——状态管理没有通用最优解,只有”你的场景偏向哪边”。


可观测性:不能只靠”跑通了”

“代码在沙箱里跑了”不等于”代码做的事是对的”。

我们团队之前踩过坑:Agent 脚本在沙箱里执行成功,stdout 也正常,但数据库里的数据没变。查了两小时——Agent 连的是测试库,不是生产库。沙箱本身没报错,网络策略也没拦,但目标地址错了。

生产级的执行层需要的不是”执行成功/失败”的二元反馈。你需要:

  • • syscall 级别的审计日志——什么 syscall 被调了、哪个被 seccomp 拦了
  • • 文件系统追踪——读了什么、写了什么、删了什么
  • • 网络追踪——源 IP、目标 IP、端口、协议、传输字节数
  • • 资源监控——CPU、内存、磁盘 IO 的时间序列

当 Agent 生成了不该执行的命令——比如那个 rm -rf /tmp/cache——你需要的不只是”执行失败了”。你需要的是:”拦截了 47 个文件删除操作,目标路径匹配 /tmp/cache/*,操作被 Landlock write 策略拒绝。”


四种落地模式

以下四套架构不是我推演的,是从现有产品和开源项目中抽象出来的。它们各自已经在生产环境里跑了。

四种沙箱架构模式对比

模式 A:进程内隔离(Claude Code sandbox-runtime)

Anthropic 开源的 sandbox-runtime(Rust,Apache 2.0)选择了进程级隔离。不需要 Docker,不需要 VM,直接在 Linux 内核安全机制上做文章。

隔离级别光谱:从进程级 seccomp 到微虚拟机 Firecracker

这个方案最让我认同的是它的设计哲学:个人开发场景下,便利性优先于绝对安全。sandbox-runtime 是客户端工具,安全边界由你自己定义(”我允许这个目录的读写”),不是由平台管理员定义。

局限也明显:仅限 Linux;隔离强度低于 VM;不适合多租户。你在做一个让别人上传代码并运行的 SaaS 平台?这个方案不够。


模式 B:微虚拟机池(E2B / Firecracker)

E2B 在 Firecracker 上跑了完整的执行平台,三层结构:

E2B / Firecracker 微虚拟机池架构

三个核心组件:

一是预热池。始终保持 N 个就绪 VM。Agent 要执行代码时直接拿一个,200ms 内分配到。跑完不是销毁而是重置回干净状态——比每次都 cold start 省钱。

二是模板快照。不同语言和框架组合预构建为文件系统镜像。Python 3.12 + common data science 依赖是一个模板,Node 22 + TypeScript 是另一个。Agent 按需选择。

三是 Filesystem API。REST 接口在 VM 内外传文件。Agent 可以写文件进沙箱、从沙箱读执行结果。

这个方案适合多租户 SaaS 场景——硬件虚拟化隔离,租户间的数据不会因为一个内核漏洞全暴露。代价:比进程级方案重(50-200ms 冷启动)、需要专门基础设施、调试体验不如本地——你不能直接 SSH 进沙箱,得通过 API 和日志推断。


模式 C:边缘运行时(Cloudflare Sandbox SDK)

Cloudflare 把执行推到了边缘。每个执行实例是 V8 Isolate——比容器更轻两个数量级,跑在 Cloudflare 全球网络上,就近执行。

延迟是所有方案里最低的。弹性伸缩自动的。你不管基础设施。

硬伤:只支持 JavaScript / WebAssembly。Python 生态完全不在支持范围。如果你的 Agent 主要写脚本,这条路走不通。供应商锁定是长线风险——你的执行层深度绑定 Cloudflare API,以后想迁会非常痛。

适合轻量函数执行场景:数据格式转换、API 调用编排、简单的代码沙箱。不适合需要完整语言生态的执行环境。


模式 D:沙箱平台(阿里 OpenSandbox)

GitHub 10.6k stars,Apache 2.0,2026 年 5 月首发,已经进了 CNCF Landscape。OpenSandbox 走了一条跟前面三个都不一样的技术路线。

OpenSandbox 平台架构:Sandbox Protocol → 可插拔运行时 → 核心组件层

它的核心思路:不绑定某一种隔离技术,而是用一个统一协议(Sandbox Protocol,OpenAPI 规范)把 Docker、gVisor、Kata Containers、Firecracker 全部接进来。 本地开发用 Docker(快速启动),生产环境切 Firecracker(强隔离),切换只改配置。Kubernetes 集群用 Kata Containers,云上自动伸缩。

三个设计决策值得拆开看:

协议先行。不是先有实现再抽象协议,而是先定义 Sandbox Protocol,然后所有 SDK(Python / Java / TypeScript / Go / C#)基于同一个 OpenAPI 规范实现。这意味着不管你用什么语言写 Agent,调用沙箱的方式完全相同。执行层的 API 就是你的可移植性边界。

运行时可插拔。不同场景对”安全 vs 延迟 vs 成本”的权重完全不同。OpenSandbox 把它做成了一个参数选择而不是架构选择——Docker 是 dev default,gVisor 是 staging,Firecracker 是 production。这个设计比你想象的要实用得多。

MCP 原生集成。内置 MCP Server,Claude Code / Gemini CLI / Qwen Code 可以直接通过 MCP 协议发现沙箱能力。Agent 不需要”知道”沙箱的存在——对它来说,只是多了一个 execute_code 工具。对执行层来说,每个调用都被透明地做了沙箱隔离。

劣势:需要自建基础设施(不是 SaaS)、5 月首发(生产级打磨还不够)、生态早期(第三方 runtime plugin 几乎没有)。

信号价值大于实用价值:10.6k stars + CNCF 收录 + Apache 2.0,说明阿里在这个赛道下的是重注——争夺”AI Agent 时代的容器运行时标准”,就像 Docker 当年定义了云原生时代的容器标准一样。


选择框架:四档决策

我把这四个模式整理成一个决策框架。注意这不是技术选型推荐——不同场景适合不同方案,不存在”最好”只有一个:

个人开发、单用户 Agent:进程级隔离。Claude Code sandbox-runtime。毫秒级启动,零运维成本。你信任自己写的代码,只需要防止意外——不是防恶意。

团队协作、内部 Agent 平台:容器 + 沙箱平台。关注 OpenSandbox。从 Docker 起步,需要更强隔离时切 gVisor,一个配置的事。多语言 SDK 是加分项——你的团队可能用 Python 写 Agent、用 TypeScript 写工具链。

多租户 SaaS、不可信代码执行:微虚拟机是底线。Firecracker 或 gVisor,不是 Docker。内核 namespace 挡不住租户间数据泄露——你隔壁租户可能在跑 fuzz 测试,不能让他通过内核漏洞读到你的数据。

边缘 / 轻量函数:Cloudflare Sandbox 或 WebAssembly。延迟最低,弹性最好。语言生态受限——如果你确认只需要跑 JS/TS,这是最优解。


系列下一站

执行层解决了”代码在哪跑”。但如果执行结果本身是错的——Agent 脚本连了测试库而不是生产库,沙箱没报任何错——怎么办?

下一篇聊 Feedback Layer:执行结果如何形成闭环,Agent 如何从自己的错误中学习。


延伸阅读

  • • Anthropic: Making Claude Code More Secure and Autonomous[1] — sandbox-runtime 设计哲学与架构
  • • Northflank: How to Sandbox AI Agents in 2026[2] — 完整隔离方案对比(Firecracker / gVisor / Docker / Wasm)
  • • Docker: Comparing Sandboxing Approaches for AI Agents[3] — Docker 官方视角的沙箱方案对比
  • • OpenSandbox[4] — 阿里开源通用沙箱平台,可插拔运行时 + MCP 集成,Apache 2.0,10.6k stars

引用链接

[1] Anthropic: Making Claude Code More Secure and Autonomous: https://www.anthropic.com/engineering/claude-code-sandboxing
[2] Northflank: How to Sandbox AI Agents in 2026: https://northflank.com/blog/how-to-sandbox-ai-agents
[3] Docker: Comparing Sandboxing Approaches for AI Agents: https://www.docker.com/blog/comparing-sandboxing-approaches-ai-agents/
[4] OpenSandbox: https://github.com/alibaba/OpenSandbox