AI沙箱指南:代码隔离、技术选型与成本实测

AI沙箱通过隔离限制智能体代码的访问边界,但凭证、网络与生命周期管理仍需应用层把关。
AI 沙箱为智能体执行代码提供隔离环境,核心目标是限制其能触碰的范围——宿主机、其他用户数据、凭证和外部服务。文章梳理了从隔离原理到运行时选型、安全边界和成本测算的完整框架:Docker 依赖 namespace 与 cgroup 共享宿主内核,gVisor 用用户态内核拦截系统调用,Firecracker 则以独立 guest 内核提供最强隔离;但隔离本身只限制影响范围,凭证管理、出站网络控制和输出校验仍需应用层实现。成本方面,沙箱按运行时间(含空闲)计费,显式的生命周期管理与清理机制对总成本的影响可能远超每小时费率的差异。选型应以真实用户任务测试为准,关注启动时间、失败率和完整工作负载成本。
AI智能体正在从对话走向执行——写代码、装依赖、跑测试、开服务。但把模型生成的代码直接跑在你的服务器上,等于把门钥匙交给陌生人。AI沙箱(AI Sandbox)正是为了解决这个问题而存在:它提供一个隔离环境,让智能体能够执行代码,同时限制它能触碰到的边界——宿主机、其他用户的数据、凭证以及外部服务。
本文基于 Lizard 团队发布的 AI 沙箱技术指南,从隔离原理、运行时选型、安全边界到成本测算,给出一份可落地的参考框架。

什么是AI沙箱
在智能体应用中,模型负责提出动作建议,应用程序决定在哪里、以何种方式执行这个动作。沙箱就是为需要代码执行的动作提供的那台「计算机」。模型可能写一段 Python 脚本、编辑一个代码仓库、或者启动一个 Web 应用——这些操作都在沙箱中完成。
沙箱的设计要求远不止「给每个用户一个文件夹」。一个实用的沙箱运行时需要做到:进程隔离、文件隔离、CPU 和内存上限、以及给应用程序一个随时中止任务的手段。凭证管理、网络访问和持久化存储各自需要独立的规则。
一个典型的例子:智能体需要分析用户上传的 CSV 文件时,它应该只拿到那个文件和足够的计算资源来处理它。它没有任何理由去读取 Web 服务器的环境变量,或者另一个客户上传的文件。
沙箱的执行流程
一个完整的沙箱请求通常遵循以下路径:
- 后端接收任务,请求模型生成代码或工具调用
- 后端创建沙箱,将任务所需的文件复制进去
- 沙箱执行代码,后端收集 stdout、stderr、文件和退出码
- 后端校验结果,再决定是否展示给用户或传递给其他服务
- 后端保存所需输出,停止沙箱
这个流程中最容易出错的地方是密钥管理。模型提供商的 API Key 和沙箱管理密钥必须保留在后端,绝不能传入沙箱。如果让生成的代码拿到管理密钥,它就可以用你的账户申请更多资源。
编程会话通常需要同一个沙箱跨多轮对话保持存活,而一次性计算则可以为每个任务创建全新沙箱。在引入沙箱复用之前,先确定状态的保留时长和归属用户。
Docker、gVisor与Firecracker的隔离边界对比
选择沙箱运行时,核心问题是隔离边界在哪里。三种主流方案代表了不同的安全模型:
| 方案 | 隔离边界 | 需要重点检查的内容 |
|---|---|---|
| 标准 Docker 容器 | Linux namespace 和资源控制分隔进程;容器共享宿主内核 | 能力配置、特权模式、宿主挂载、守护进程访问、宿主补丁 |
| gVisor | 用户态应用内核处理系统调用,减少对宿主内核的直接暴露 | 系统调用兼容性和工作负载性能 |
| Firecracker microVM | 虚拟机拥有独立 guest 内核,通过 KVM 实现硬件虚拟化 | Guest 和宿主补丁、网络策略、挂载数据、生命周期控制 |
Docker 适合信任级别已知、宿主配置经过严格审查的工作负载。它的安全性取决于你的运行方式——暴露 Docker socket 或大范围挂载宿主目录会彻底改变工作负载的控制范围。
gVisor 增加了一层用户态内核边界,代价是系统调用兼容性方面的取舍。Firecracker 使用小型虚拟机监视器和受限设备模型来提供更强的隔离。无论哪种方案,都不能替代对密钥的保护和对敏感服务的访问限制。
说个细节,Lizard Sandboxes 默认使用 Firecracker,但旧卷或快照、以及 Firecracker 启动失败后的回退场景,可能使用容器运行时。如果应用要求必须是 microVM,需要检查 getInfo().runtime 来确认实际运行时类型。
Linux namespace 与容器隔离:Docker 依赖的两大 Linux 内核机制是 namespace 和 cgroup。Namespace 负责「看得见什么」——PID namespace 让容器内的进程只看到自己的进程树,mount namespace 隔离文件系统挂载点,network namespace 隔离网络接口,user namespace 则可以把容器内的 root 映射成宿主上的普通用户。Cgroup 负责「用得了多少」——限制 CPU 配额、内存上限和 I/O 带宽。关键在于,这些机制都由宿主内核统一提供,容器内的进程发起系统调用时,最终仍由同一个宿主内核处理。因此一旦内核本身存在漏洞,或者容器被赋予了 --privileged、--cap-add 等额外能力,隔离边界就可能被穿透。这也是 gVisor 和 Firecracker 出现的根本原因:前者用用户态实现拦截系统调用,后者用硬件虚拟化让 guest 拥有独立内核。
系统调用兼容性(syscall compatibility):gVisor 的工作方式是在用户态重新实现一套「应用内核」来响应容器发出的系统调用,而不是让它们直接进入宿主内核。这带来更强隔离的同时,也意味着并非所有系统调用都能被完整、正确地模拟。Linux 的系统调用有数百个,语义各异,冷门调用、新引入的调用以及依赖特定内核行为的程序,都可能在 gVisor 下出现异常或性能下降。实践中受影响的典型场景包括:重度依赖 io_uring 的高性能 I/O、部分 ptrace 调试功能、以及某些需要精细内核特性的容器运行时。因此在选型时,不能只看「gVisor 更安全」这一条,而应该用真实工作负载跑一遍,观察是否有系统调用被拒绝、延迟是否可接受,再决定是否值得为隔离强度付出兼容性代价。
隔离能保护什么、不能保护什么
沙箱限制了代码执行的影响范围,但应用程序本身仍然需要决定用户或智能体可以执行哪些动作。
凭证与网络访问
任何复制进沙箱的内容,都会以你赋予的权限对工作负载可见。不要复制整个 .env 文件、SSH 目录或云服务凭证。如果任务需要调用外部 API,给它一个短时效、窄权限的凭证,或者通过后端工具代理每次请求并逐条校验。
隔离并不意味着网络被封锁。如果代码能读取密钥并发起外部请求,它就可能把密钥发送到别处。需要选择满足出站网络要求的方案和配置,不要假设网络白名单一定存在。
最小权限凭证(least-privilege credential):给沙箱的凭证应当满足三个约束——作用范围尽可能窄、有效期尽可能短、可被单独撤销。具体做法包括:不使用账户级或项目级的长期 API Key,而是为该任务签发一个只允许访问特定资源的临时令牌;在云环境中优先使用 STS 或短期会话凭证而非永久 Access Key;把密钥通过注入的环境变量或短暂挂载传递,而不是写进会被持久化的文件。更彻底的做法是完全不把凭证交给沙箱——让沙箱把外部请求发回后端,由后端持有凭证代为调用,并逐条校验请求的合法性。这样即使沙箱内的代码被恶意代码劫持,它也无法直接盗用凭证,因为它从来没见过凭证本身。
出站网络控制(egress control):控制出站流量是防止数据外泄的关键一环,但它的有效性取决于实现层次。应用层白名单(如仅允许访问特定域名)依赖 DNS 解析和代理配置,容易被绕过;网络层防火墙或安全组规则拦截在更底层,更难规避。需要注意的是,很多沙箱方案默认并不限制出站流量——代码可以直接连接任意外部地址。因此如果任务涉及敏感数据,应当在沙箱基础设施层面配置显式的出站规则,只放行任务必需的端点,并对 DNS 查询、非标准端口和 IP 直连保持警惕。
用户与存储文件
每个沙箱都应该绑定到经过认证的用户或任务。每次执行代码、下载文件或重新打开会话时,都要检查归属关系。一个被猜到的沙箱 ID 不应该授予任何访问权限。
持久化文件同样需要按用户隔离。即使每次执行都使用全新的虚拟机,如果可写工作区在不同的客户之间复用,数据仍然可能泄露。
超时限制与返回输出
设置执行超时和沙箱生命周期是两个独立的控制点。客户端超时只是停止等待,并不会停止远端进程。服务端的过期策略和清理机制才能应对不同的故障场景。
返回的文件和文本应当被视为不可信输入。对 JSON 要按应用程序期望的结构进行校验,渲染文本时进行转义,避免将生成的 HTML 与账户面板部署在同一域名下。
对于跳过交互式审批的智能体工作流,这些控制措施必须在第一条命令执行之前就位。
实战:在沙箱中运行Python任务
Lizard 的示例使用 Node.js 作为后端控制器,在沙箱内运行 Python。以下是一个最小可运行示例,执行固定计算以验证执行路径,不调用 LLM。
需要 Node.js 22 或更高版本、一个 Lizard 项目以及 API Key。在后端环境中设置 LIZARD_API_KEY 和 LIZARD_PROJECT_ID,两者都不能出现在浏览器代码中。
核心逻辑如下:创建沙箱 → 检查运行时确认为 Firecracker → 写入 Python 脚本 → 以指定用户身份执行 → 校验退出码和输出大小 → 解析并验证 JSON 结构 → 在 finally 块中清理沙箱。
Lizard 团队在 2026 年 10 月 17 日使用 codex 模板和 Node.js 22.23.2 实际运行了这个脚本:从 base 模板创建了一个 Small Firecracker 沙箱,以 user 身份运行 Python,输出了 { total: 25 },清理完成后退出码为 0。API Key 始终在后端控制器的环境中读取,没有传入执行 Python 的沙箱。
示例中有几个值得注意的设计决策:使用参数数组执行 Python 避免了 shell 插值;30 秒的命令超时限制客户端等待时间;两分钟的沙箱生命周期是独立的过期控制;finally 块确保即使输出校验失败也会请求清理。
要把这个示例变成智能体工具,只需将固定脚本替换为模型返回的代码,并为该任务定义结果 schema。授权、资源限制和输出校验保持在后台。一个成功的退出码并不能证明答案是正确的。
典型应用场景
数据分析:处理用户上传文件,运行 Python,返回图表或小型 JSON 结果。限制文件大小和执行时间,只保留用户需要的输出。
编程智能体:检出任务专属的代码仓库副本,编辑文件并运行测试。在单独的流程合并或部署变更之前,审查差异和测试结果。
应用构建器:安装依赖、启动开发服务器、提供私有预览。预览环境需要与你的面板域名和认证体系保持隔离。
浏览器智能体:当任务需要 UI 交互时,使用带浏览器和桌面环境的运行时。任何已登录的会话都应被视为拥有该账户访问权限的凭证。
成本结构与测算
AI 沙箱的成本计算起点是总运行时间——包括命令之间的空闲时间。然后加上存储、模型调用和其他服务费用。
Lizard 的公开定价(截至 2026 年 10 月 17 日)按秒计费,沙箱运行期间包括空闲时间都在计费。Small 规格(2 vCPU / 4 GB)每小时 $0.0162,Medium(4 vCPU / 8 GB)每小时 $0.0324,Large(8 vCPU / 16 GB)每小时 $0.0648。Pro 订阅 $19/月,包含 $19 使用额度,超出部分按量付费。持久化卷 $0.14/GB/月。
一个直观的测算:1,000 个 Small 任务,每个沙箱运行 5 分钟,计算费用为 1,000 × (5/60) × $0.0162 = $1.35。这个数字本身看起来很低,但如果每个任务结束后沙箱多运行一小时才被清理,额外费用会达到 $16.20——是正常用量的 12 倍。
这个对比揭示了一个被低估的事实:显式的生命周期管理和可靠的清理机制,对成本的影响可能远大于每小时费率的微小差异。
选型清单
在确定沙箱方案之前,用真实用户任务进行测试。一条简单的 shell 命令无法反映仓库构建或浏览器会话的表现。记录启动时间、依赖安装时间、总任务时间、失败次数和总运行秒数,同时关注中位数和最慢请求。
以下问题可以作为选型框架:
- 不同客户的代码和文件之间靠什么隔离?
- 生成的代码能触及哪些密钥和外部服务?
- 运行时是否支持任务所需的语言、包和浏览器工具?
- 控制器崩溃或连接断开时会发生什么?
- 哪些文件在关闭后仍然保留,如何备份?
- 加上空闲时间、存储和模型调用后,完整工作负载的成本是多少?
建议从单一任务、临时沙箱和经过校验的小型结果开始。衡量这个流程的实际表现后,再根据应用需求逐步引入持久化或更长的会话。
相关推荐

AGENTS.md 实战指南:让编程 Agent 真正好用
AGENTS.md 和 CLAUDE.md 能显著提升编程 Agent 表现,但研究发现用错反而让成本上升 20%。本文详解该写什么、该删什么、200 行与 32KB 的硬边界、Monorepo 嵌套规则及安全提醒。

花旗AI编程代理Devon:年省30%技术外包费,1.4万工程师已使用
花旗集团利用AI编程代理Devon,一年内削减30%技术供应商费用,1.4万工程师使用,产品发布提速30%-40%。本文分析其对IT外包行业的冲击及未来人机协作模式。

从生日派对到千亿AI帝国:新一代PayPal黑帮崛起
2015年一张生日派对合影,十年后催生Scale AI、Cognition AI等千亿估值AI公司。解析新一代PayPal黑帮的创业路径、互相投资生态,以及Peter Thiel的Founders Fund如何完成代际传承。