第 04 章

安全执行 ① · Sandboxing 与执行环境

给 agent 那双手套上手套。工具一旦执行,跑的就是模型生成的代码,而模型会出错。怎么按威胁模型选一档隔离、设全五维权限(文件 / 网络 / 执行 / 资源 / 凭证)、决定沙盒在本地还是上云,以及为什么连前沿实验室都在网络出口上栽过跟头。前置:Ch2、Ch3。

约 2.5 小时
开篇 · 给 agent 那双手套上手套

这是 Agent 工程路书的第 4 章,约 2.5 小时,纯 Mode A。上一章你给 agent 接上了能改文件、跑命令、动数据库的工具。这一章面对接上工具之后立刻冒出来的问题:这些工具一旦执行,跑的就是模型生成的代码,而模型会犯错。怎么把这段代码可能造成的破坏关在一个可控的范围里,就是这一章。

读完后,你能根据威胁模型选一档隔离机制(从轻量的进程隔离到独立内核的微虚拟机),能设全五个维度的权限策略(文件、网络、执行、资源、凭证),知道沙盒该在本地跑还是上云、规模化时怎么把冷启动藏掉,并且理解一件让前沿实验室都栽过跟头的事:网络出口管控为什么这么难。

7 节:0 agent 会自己动手了 · 1 第一性原理(两个正交的问题)· 2 隔离机制阶梯 · 3 权限策略的五个维度(含网络出口这座桥)· 4 沙盒在哪跑(本地→云→舰队)· 5 当沙盒装的是一个桌面 · 6 审批与权限模型 · 7 可复现、重置、与训练环境。

边界 hard line:这一章只管向内的威胁,也就是模型自己出错、把环境搞坏。攻击者用注入的内容劫持 agent、让它在完美的沙盒里照样外泄数据,那是向外的威胁,归下一章 Ch5 对抗安全,这里只在网络出口那一节埋一座桥。底层的容器编排、K8s、调度这些通用基础设施怎么造,归系统设计路书,这里只讲作为 harness 工程师怎么选、怎么配、怎么接。

0. agent 会自己动手了

先把这一章存在的理由说清楚。上一章结束时,你给 agent 接上了真正能干活的工具,其中最有代表性的一类是 bash 工具:模型生成一条命令,你的代码把它执行掉。这一步跨过去之后,有件事的性质悄悄变了。在 Ch3 之前,模型的输出是文字,最坏不过是说错话;接上能执行的工具之后,模型的输出变成了会改变你这台机器的真实动作。一条 rm -rf 跑下去,删掉的是真文件;一段装依赖的脚本跑下去,改的是真环境。模型从一个会说话的东西,变成了一个会动手的东西。

这里要立刻校正一个直觉,它是这一章的第一刀。你可能觉得,要担心模型干坏事,是因为怕有坏人。不是的。就算这世界上一个攻击者都没有,模型生成的代码也不可信,原因很朴素:模型会犯错、会幻觉出危险命令、会被任务诱导着做出破坏性操作。它可能为了"清理一下"就把不该删的目录删了,可能在调试时把整个数据库 drop 了。Anthropic 在安全部署文档里把这件事的措辞分得很精确,模型出错(model error)和被攻击者注入(prompt injection)是两层不同的威胁,前者就算没有任何攻击者也存在。这一章只处理前一层,也就是向内的威胁:怎么在模型自己会出错的前提下,把它动手造成的破坏关在一个可控范围里。攻击者那一层,即向外的威胁,是下一章的事。

把这件事翻译成一个工程原则,就是这一章的总纲:模型生成的代码,要当作 semi-trusted code(半可信代码)来容纳。Anthropic 的原话是,跑任何半可信代码该用的那套原则在这里同样适用,即隔离、最小权限、纵深防御。沙盒(sandbox)就是这套原则的载体,它的核心目标只有一个,把模型这段代码万一出错时的爆炸半径(blast radius)限制住。这件事的 why-now 也很清楚:沙盒从一个可选项变成 agent 工程的标配,正是 2024 年之后的事,当 Computer Use 和 bash 工具让 agent 开始大规模地真动手,执行隔离就从"锦上添花"变成了"不做不行"。接下来七节,就是把这层手套一个手指一个手指地戴上。

1. 第一性原理:两个正交的问题

1.1 模型生成的代码是 semi-trusted code

在动手选任何具体技术之前,先要想清楚我们到底在防什么。把模型生成的代码当作半可信代码,意思是它介于两个极端之间:它不是你自己写的、审过的可信代码,也不一定是敌人写的恶意代码,它是一段大概率没问题、但你没法保证一定没问题的代码。对待这种代码的成熟做法,软件工程几十年前就总结出来了,就是那三件套:隔离它(让它跑在一个受限的环境里)、给它最小权限(只给它完成任务必需的能力)、做纵深防御(假设任何一层都可能失守,所以多设几道)。这一章后面所有具体机制,本质上都是这三个词的展开。

这套思路之所以重要,是因为它把"安全"从一个模糊的焦虑,变成了一个可以工程化的设计问题。你不需要预判模型具体会犯什么错,那是预判不完的;你只需要假设它会犯某种错,然后把环境设计成即使它犯了错、后果也被框在一个你能接受的范围里。这就是 blast radius 这个词的全部含义,你设计的不是"让模型不犯错",而是"模型犯错时最多炸掉多大一块"。想清楚这一点,你看任何沙盒方案的眼光都会变,你会本能地问:如果这里面跑的代码彻底失控,最坏会发生什么?这个问题的答案,决定了你该选多强的隔离。

1.2 两个正交的旋钮:approval ⊥ sandbox

带着 blast radius 这个视角,你会发现关于 agent 安全执行,其实有两个完全不同的问题被很多人混在一起谈,而把它们拆开是这一章最重要的地基。第一个问题是:这个动作要不要先问人?这是自主性(autonomy)的问题,落到工程上就是审批(approval)。第二个问题是:这个动作即使跑了,能造成多大破坏?这是容纳(containment)的问题,落到工程上就是隔离(sandbox)。这两个问题听起来像一回事,其实是两根独立的轴。

最干净的证据来自 Codex 的实现。它把这两件事做成了两个互不相干的命令行开关,一个叫 --ask-for-approval(管审批),一个叫 --sandbox(管隔离),官方文档明说前者和所有 --sandbox 模式都能组合。这意味着你可以要任意一种搭配:高隔离加低审批,也就是把 agent 关进一个强沙盒里、然后放手让它自己折腾,因为就算它瞎搞也跑不出沙盒;也可以低隔离加高审批,也就是让它在一个几乎没防护的环境里跑、但每一步危险操作都停下来问你。这两种搭配的安全感来源完全不同:前者靠的是墙够厚,后者靠的是人盯得紧。

autonomy 自主性(审批越宽松)→containment 隔离强度 →每步问人全自动裸跑强沙盒强沙盒 + 每步问最稳,但最慢强沙盒 + 放手跑生产理想态裸跑 + 每步问靠人兜底,累裸跑 + 全自动危险区 ⚠两轴独立 · 高隔离允许更高自主(沙盒兜底)· 低隔离时只能靠多问人兜底
Figure · 审批(autonomy 轴:要不要先问人)与 隔离(containment 轴:跑了能炸多大)是两个正交旋钮 —— Codex 的 --ask-for-approval 与 --sandbox 是两个独立 flag,可任意组合 · 看清这层正交是整章地基 · 对应正文 第 1.2 节

把这层正交性记牢,后面就不会乱。它给你的判断是:隔离和审批不是二选一,而是两个要分别拨的旋钮。一个设计得好的 agent 系统,往往是用强隔离换来更高的自主度,因为有沙盒兜底,你才敢让它少问几次、跑得更顺;反过来,当你不得不在一个隔离很弱的环境里跑时,就只能靠多问人来兜底,代价是又慢又累。这一章接下来主要讲容纳这根轴,也就是怎么把沙盒做强;审批那根轴的具体模型留到 第 6 节 专门讲,但你心里要始终清楚它们是两件事。

agent 安全执行有两个正交的问题:要不要先问人(autonomy),和跑了能炸多大(containment)。沙盒解决的是后者 —— 把模型出错时的爆炸半径关住。

2. 隔离机制阶梯

2.1 一个根本张力:强隔离 = 慢启动

把代码关起来,不是一个开关,而是一条从弱到强的强度阶梯。每往上爬一级,你都在四个维度上做权衡:隔离强度(被关的代码能造成多大破坏)、启动延迟(开一个这样的环境要多久)、syscall 兼容性(里面能不能正常跑各种程序)、运维复杂度(你自己维护它有多累)。这四个维度里,前两个的关系最值得先记住,因为它是贯穿整条阶梯的根本张力:隔离越强,启动通常越慢。一个轻量的进程隔离几乎瞬间就起来,而一个独立内核的虚拟机要花上百毫秒甚至几秒才能 ready。理解了这个张力,你才能理解后面所有机制为什么存在,它们本质上都是在这条张力曲线上找一个新的平衡点。

2.2 走一遍阶梯

让我们从最弱的一头一级一级往上爬,每一级你只要抓住它比上一级强在哪、又付出了什么代价。

最底下是裸进程加一点资源限制(rlimits)或者改一下根目录(chroot)。它和宿主共享一切,几乎没有真正的边界,启动零开销、兼容性百分百。这一级在实战里几乎从不单独用,它的教学价值是让你看清"什么都不做有多危险"。

往上一级,是 Linux 的那套原生隔离原语组合:用命名空间(namespaces)给进程一个隔离的视图,用控制组(cgroups)限制它用多少资源,用 seccomp 过滤它能发哪些系统调用,再用 Landlock 限制它能碰哪些文件和网络。这一级仍然和宿主共享内核,但攻击面已经收窄了很多,而且启动依然很轻。它是 Codex CLI 和 Claude Code 在本地默认用的底座。这里有个特别容易讲错的细节值得点一句:seccomp 和 Landlock 不是二选一的关系,而是互补叠加。seccomp 过滤的是系统调用本身及其参数,Landlock 是一个内核安全模块,管的是对文件、目录、网络端口这些内核对象的访问,而且它有一个很妙的性质,一个没有特权的进程可以用它给自己加限制。两者一个管"能调什么系统调用",一个管"能碰什么资源",叠在一起才完整。

再往上,在 macOS 上对应的是 Seatbelt(命令是 sandbox-exec),它用一份默认全拒绝、再选择性放行的配置来限制进程,Codex、Claude Code、Gemini CLI 在 mac 上都用它。然后是 Docker 这类容器,它把上面那套 Linux 原语产品化了,是大多数人想到隔离时的标准选择,启动也就亚秒级。但容器有个绕不过去的天花板:它和宿主共享同一个内核,所以一旦内核本身有漏洞,被关的代码理论上能逃出来。对于跑你自己信得过的代码,这没问题;但要在一台机器上跑多个互不信任的租户的代码,容器就不够了。

跨过容器,隔离强度有一次质的跃升,而代价就是启动变慢。gVisor 的思路是用一个跑在用户态的程序去重新实现大部分 Linux 系统调用,这样被关的代码发出的系统调用不会直接打到宿主内核上,宿主内核的攻击面被大幅收窄。代价是它没实现全部系统调用,有些冷门程序会跑不起来,而且开销上来了。Modal 这类平台选的就是它。再往上是真正的分水岭:Kata、Firecracker 这一类,给每一份被关的代码配一个独立的内核,跑在硬件虚拟化的边界里,内核漏洞也跨不过去。其中 Firecracker 特别值得记,它是一个极简的微虚拟机(microVM),只仿真五个设备,官方数据大约 125 毫秒就能起一个、每个只占不到 5 MiB 内存,所以它成了"在一台机器上跑完全不可信代码"的事实标准,e2b、Vercel Sandbox 用的都是它。最强的一头是完整的虚拟机,隔离最彻底但启动最慢,实战里因为开得太慢,反而排在 Firecracker 后面。

阶梯之外还有一个不太一样的物种,WASM。它不靠内核隔离,而是靠一个能力模型:被关的代码跑在一块线性内存里,想用任何能力都必须显式地被授予,默认什么都干不了,也没有指针能直接戳到宿主内存。它的启动是微秒级的,比容器快上百倍,内存也省上百倍,隔离还很强。听起来像银弹,但它有个硬伤,兼容性低,你的代码得能编译成 wasm 才行,移植成本不小。所以它适合跑那些你能控制、能重新编译的代码片段,不适合直接丢一个任意的 Linux 程序进去。

启动延迟 / 运维开销 →隔离强度 ↑强隔离 = 慢启动进程+rlimitsnamespaces+seccomp+LandlockDocker(rootless)gVisorFirecrackerKata全 VMWASM/WASI极快但兼容性低共享宿主内核(逃逸=波及宿主)独立内核(硬件边界)能力模型(WASM)第一分水岭 = 内核是否共享:决定「被攻破最坏后果」是只伤本任务还是波及宿主
Figure · 隔离机制阶梯 · 横轴启动延迟/运维开销,纵轴隔离强度 · 主趋势「强隔离 = 慢启动」(进程→Docker→gVisor→Kata→VM 一路上行右移)· 蓝点=独立内核(硬件边界,逃逸跨不过),灰点=共享宿主内核(内核漏洞理论可逃)· Firecracker / WASM 是打破张力的甜点(强隔离却快)· 示意位置,具体开销按 workload 自测 · 对应正文 第 2 节

2.3 三条横切素养

走完这条阶梯,有三条横切的判断比记住每个机制的名字更值钱。

第一条,也是最重要的一条:共享内核还是独立内核,是隔离强度的第一分水岭。进程、命名空间、Docker、gVisor 都和宿主共享内核,意味着内核一旦被攻破,理论上能波及整台宿主;而 Kata、Firecracker、完整虚拟机给每份代码独立的内核,有硬件边界兜底。这条分水岭直接对应一道判断题,它也是你选隔离档位时该问自己的核心问题:如果这个沙盒被攻破,最坏后果是什么?如果只影响当前这个任务,容器就够了;如果可能波及同一台宿主上其他用户的数据,那就必须上微虚拟机。第二条前面说过了,强隔离等于慢启动,这条张力会一直跟着你,后面 第 4 节 讲舰队供给时,核心工程就是怎么把这个慢启动藏起来。第三条是那个最容易混的细节,Landlock 不等于 seccomp,它们是互补叠加而不是替代关系,这一点上面已经展开过,这里再强调一次是因为它是"机制"层面最常被讲错的地方。

2.4 决策框架

把这些收口成一个能直接用的决策框架。Anthropic 在安全部署文档里给了一张四档表,它是 agent 语境下最权威的浓缩,建议你直接拿它当主轴,再用上面那条完整阶梯去展开细节。下面这张表是 narrative 之后的收口,不是用来代替理解的。

机制隔离强度性能开销运维复杂度选它的场景
OS 原语沙盒(seccomp/Landlock/Seatbelt)好(安全的默认值)极低本地、信得过的代码、要轻量
容器(Docker)取决于配置标准选择、低威胁、共享内核可接受
gVisor优(配置正确时)中到高多租户不可信代码,但不想管虚拟机
虚拟机(Firecracker / QEMU)优(配置正确时)中到高跑完全不可信代码的多租户事实标准

要补充一句关于那些开销百分比的诚实标注:同一个机制,开销随负载波动极大。拿 gVisor 举例,官方自己分档说,纯计算型的负载几乎没有开销,因为它根本不拦系统调用;但频繁开关文件这类重 I/O 的负载,开销可能高达几十甚至上百倍。所以任何一个写死的开销数字你都别当真,真实数字一定要按你自己的负载实测。

3. 权限策略的五个维度

3.1 选好机制只是"用什么关",还得决定"关到什么程度"

选定了隔离机制,只解决了"用什么关"的问题。接下来还要决定"关到什么程度",这就是权限策略。很多人讲沙盒只讲到文件和网络两条边界,但真实的策略面是五个正交的维度,Anthropic 官方那张最小权限表恰好印证了这一点。这五个维度是:文件系统(能读写哪些目录)、网络出口(能连出去哪些地方)、进程执行(能跑哪些命令)、资源限制(能用多少 CPU、内存、时间)、凭证暴露(能看到哪些密钥)。这一节一个个过,其中网络出口那一维最关键,因为它是这一章和下一章之间唯一的桥,我把它单独放到最后重点讲。

3.2 文件系统、执行、资源

文件系统这一维,核心是划清可读写的边界。成熟做法是默认只读,只把任务真正需要写的工作目录挂成可写,而且这个可写区最好是临时的(ephemeral),用内存盘(tmpfs)实现,容器一停就自动清空。这里有两个具体的坑。一是即便在可写的工作根目录里,有些东西也得强制只读,比如 Codex 就把 .git 目录在可写根内仍然锁成只读,防止 agent 改掉自己的版本历史、把搞砸的痕迹也一并提交了。二是只读挂载代码目录并不等于安全,因为代码目录里常常藏着 .env~/.aws/credentials~/.ssh、各种 *.pem 这类敏感文件,只读照样能被读出来外泄,所以这些得显式排除或脱敏。

执行这一维,管的是哪些命令能跑、哪些要先批。Codex 用一个叫 execpolicy 的引擎,把已知安全的只读命令放行、把会改变状态的命令拦下来要审批。Claude Code 的做法更细,它把命令先解析成抽象语法树(AST)再去匹配权限规则,而且只要解析得不干净、或者出现了 eval 这种能动态拼命令的构造,就一律强制审批。但这里有个必须诚实标注的局限,Anthropic 官方自己就明说,基于命令参数的字符串匹配很脆弱、不是一道安全边界。一条看起来限制了的规则,比如只允许访问某个域名的 curl,很容易被换个选项顺序或者协议变体绕过去。所以这一层要记住一个区分,后面 第 6 节 还会再用:审批规则决定的是"问没问",它是一道权限闸门,不是真正的隔离;真正的隔离是底下那层操作系统强制的沙盒,决定的是"能不能"。

资源这一维最直接,限制 CPU、内存、磁盘、时间、进程数。Anthropic 的硬化范式会显式地限制内存、CPU 核数、还有进程数(--pids-limit,专门防 fork bomb 那种疯狂自我复制的攻击),WASM 那边则用一个叫 fuel 的机制给执行时间封顶。这里有个很值得点出来的教学连接:资源和时间限制,本质上就是 agent 循环的"步数预算、时长预算"在系统层的落地。你在 Ch2 那一节把预算变成可执法的护栏 里学的是在 harness 代码层设预算,这里是同一件事在操作系统层再设一道,两层叠起来才是纵深防御。

3.3 凭证:让 agent 永远看不到真密钥

凭证这一维有一个堪称黄金范式的做法,值得单独讲,因为它把一个很难的问题解得特别漂亮。问题是这样的:agent 干活常常需要调用带鉴权的 API,那它就得拿到 token,可一旦 token 进了沙盒,模型出错或被诱导时就可能把它打印出来、外泄出去。黄金范式的解法是凭证代理注入:让 agent 发出不带任何凭证的请求,这个请求先到一个跑在沙盒外面的代理(proxy),由代理把真凭证注入进去再转发出去。这样一来,真凭证从头到尾都在沙盒外,agent 永远看不到它。这个设计的好处不止于此,凭证集中存在代理这一处便于管理,代理还能顺手记录所有流量、强制只能连白名单上的端点。落地上,可以用环境变量把模型的请求指到一个代理基地址,或者设一个全局的 HTTP_PROXY,也可以让 MCP 工具把鉴权请求发到沙盒边界之外去处理。

3.4 网络出口:Ch4 与 Ch5 唯一的桥

现在讲那个最关键的维度,网络出口管控(egress control)。它之所以特殊,是因为它有两副面孔。在这一章,它是"资源边界"的一维,管的是 agent 能往外连哪里;到了下一章,它会变成防数据外泄的关键防线,因为一条能往外通信的通道,就是攻击者把你私有数据偷运出去的出口。这一章先讲机制,也就是怎么做一道靠得住的出口管控;下一章再讲它为什么是对抗安全的命门。

机制上,靠得住的出口管控都遵循一个默认全拒绝(deny-by-default)的架构,而且层层递进。最干净的一种,以 Claude Code 的沙盒运行时为代表,是这样的:容器本身用 --network none 起,也就是压根没有任何网络接口;它唯一的出口是一条挂载进去的 Unix socket,这条 socket 连到宿主上、沙盒外的一个代理;由这个代理来强制域名白名单、注入凭证、记录全量流量,然后才真正放行到公网。微虚拟机版本里,这条 socket 换成 vsock,思路一样。Codex Cloud 的做法是另一种风味,agent 阶段默认禁网,只在装依赖的 setup 阶段开网,而且可以按环境配域名白名单加上 HTTP 方法白名单,比如只允许 GET、HEAD,把会写数据的 POST、PUT、DELETE 全挡掉。

沙盒 · --network noneagent模型生成的代码无任何网络接口Unix socket唯一出口proxy · 沙盒外(宿主上)① 域名 allowlist② 注入凭证(agent 看不到)③ 记全量流量(审计)凭证集中存一处 · 强制 endpoint 白名单公网固有极限(正引出 Ch5):· proxy 不解密 TLS,只按 client 给的 hostname 放行 → 沙盒内可用 domain fronting 绕到白名单外· 可信域名(api.anthropic.com)本身就是 exfiltration 通道 → 把数据外泄到它难挡 · egress 只是 defense-in-depth
Figure · deny-by-default egress:沙盒 --network none(无网络接口)→ 唯一出口走一条 Unix socket → 宿主外的 proxy 做域名 allowlist + 注入凭证(agent 永远看不到真凭证)+ 记全量流量 → 才出公网 · 固有极限:proxy 不解密 TLS,可信域名(如 api.anthropic.com)本身就是 exfiltration 通道 —— 这正是 Ch5 对抗安全要拆的那条腿 · 对应正文 第 3 节

但这里必须诚实地讲清楚出口管控的固有极限,因为正是这个极限引出了下一章。第一,代理通常不解密 TLS,它只能按客户端给它的域名做白名单,看不到加密流量里到底装了什么,所以沙盒内的代码可以用域名前置(domain fronting)这类手法绕到白名单外的主机。第二,也是更扎心的一点,可信域名本身就是一条外泄通道。你的白名单上多半放着 api.anthropic.com 这种 agent 真要用的域名,那攻击者就可以把偷到的数据伪装成正常请求发到这个可信域名去,你几乎挡不住。所以业界的共识很清醒:把厂商提供的沙盒出口管控当成纵深防御的一层就好,别把它当成一道硬的网络边界,真要安全,得在操作系统、容器、防火墙等好几层独立地再各设一道。

3.5 真实案例:Claude Code 的两个 egress CVE

要让你真正记住"出口管控很难"这句话,没有什么比一个真实案例更有说服力,而且这个案例的主角是前沿实验室自己。Claude Code 的沙盒运行时,架构就是上面讲的那套教科书式设计,--network none 加 Unix socket 加沙盒外代理,看起来无懈可击。但它的出口白名单在五个月里被绕过了两次。

第一个漏洞编号 CVE-2025-66479,出在一个配置语义的 bug 上。用户如果把允许的域名配成空列表,本意是最严格、什么都不让连,但代码里一个判断写错了,把"空列表"判成了"关掉整个白名单检查",结果是出站流量全部放行,跟没设白名单一样。第二个漏洞更阴,攻击者在域名里插入一个空字节,利用主机名解析的差异,截断掉真实域名,从而绕过通配符白名单连到攻击者自己的主机。这两个漏洞合起来,跨越了大约 130 个版本、五个月时间都可以被绕过,而一旦绕过,沙盒里那些本该被保护的凭证(~/.aws 里的密钥、GitHub token、云服务器的元数据)就能被外泄出去。更值得玩味的一个细节是,这道出口边界的关键一环,当时压在一个只有十来个 star 的第三方小包上。

这个案例的教学价值极高,它把两件抽象的事砸实了。一是前面说的那句话,沙盒是纵深防御不是硬边界,连把这套架构设计得最规范的团队都会在实现细节上栽跟头。二是出口管控的真实攻击面,恰恰藏在那些看起来无关紧要的实现细节里:一个空集合该怎么解释、一个主机名该怎么解析,这些地方一旦错了,整道边界就形同虚设。记住这个案例,你以后审任何沙盒方案,都会多问一句:这道边界的实现,经得起这种细节级的推敲吗?

4. 沙盒在哪跑:本地、云、舰队

4.1 本地:用操作系统原语就地隔离

知道了用什么机制关、关到什么程度,下一个工程问题是:这个沙盒在哪跑?最简单的形态是本地。Codex CLI 和 Claude Code 就在开发者自己的机器上,用前面讲的那些操作系统原语(mac 上的 Seatbelt、Linux 上的 bubblewrap 加 seccomp 加 Landlock)就地把每条 bash 命令隔离起来。它零额外基础设施、延迟最低,适合一个你信得过的 agent 在一份你熟悉的代码库上干活。

4.2 云:2026 已成型的一个基础设施品类

但本地形态有天花板:你只有一台机器,跑不了大规模并发,也没法让 agent 在你关掉电脑后继续在后台干活。于是沙盒上了云,而且到 2026 年,"给 AI agent 跑代码的沙盒平台"已经成长为一个成型的基础设施品类,有一批专门的厂商在做。这里要先划一条边界:沙盒即服务这一层本身属于 Agent 工程(#8),因为它是 agent 专用的执行环境;但它底下的 K8s、调度这些通用编排基础设施,归系统设计路书(#2)。这一章只站在 harness 工程师的角度,讲怎么从这些服务里选一个、怎么接。

下面这张表是这个品类在 2026 年的全景,贯穿全表的核心张力是:隔离强度、冷启动速度、状态能不能持久、有没有 GPU、支持哪些语言生态。要提醒的是,这些厂商对比里有不少是竞品自己写的软文,冷启动毫秒数和价格也跨源波动很大,所以下表的结论你当个起点,具体一定要自己测。

平台隔离冷启动状态定位 / 备注
e2bFirecracker 微虚拟机~150ms(快照恢复)可暂停/恢复,会话最长 24hAI 代码执行事实标准;Manus 用它给 agent 当虚拟电脑;有开源自托管
ModalgVisor(Kata 可选)快照式,默认 5min 可配 24hPython 优先,有广泛 GPU;贵(约普通 serverless 的 3 倍)
DaytonaDocker 默认(Kata/Sysbox 可选)亚 90ms(部分 27ms)持久工作区支持 Linux/Win/macOS 虚拟桌面做 computer-use
Cloudflare SandboxesLinux 容器亚 50ms闲置重置边缘原生,TS 优先,Beta
Fly.io SpritesFirecracker / 持久 VM1-2s 创建,~300ms 恢复整个 VM 跨会话持久为"跨会话维护长项目"的 agent
Codex Cloud后台容器缓存容器使新任务中位时长降约 90%容器态缓存 12hOpenAI 自营,后台/并行跑任务,可按环境配网
GKE Agent SandboxgVisor + Kata(2026 新增)warm pool 亚秒Pod 快照暂停/恢复K8s 原生,底座属 #2、agent-sandbox 抽象属 #8

4.3 舰队供给:把冷启动藏掉

云沙盒在生产规模上跑,核心工程不是选哪个隔离原语,而是怎么在每秒成百上千个请求来的时候,快速地给每个请求供一个干净的沙盒。这就回到了 第 2.1 节 那个根本张力:强隔离等于慢启动。如果每来一个请求都冷启一个微虚拟机,延迟没法接受。解法是几种"把冷启动藏掉"的供给策略。一种是温池(warm pool),预先热好一批 ready 的沙盒,请求来了直接发,GKE 报的数字是每秒能供三百个、九成在两百毫秒内。一种是快照恢复,把一个虚拟机起到 ready 状态后拍一张内存快照,新请求从快照恢复而不是从头冷启内核,这正是 e2b 那 150 毫秒的关键。还有一种是一次性的会话级环境,每个 agent 任务配一个独立环境,状态写到沙盒外面的对象存储或数据库里,任务结束就干净地销毁,这么做除了好回收,还有个安全理由,持久共享的环境会跨会话累积状态,早期一个恶意或畸形的运行可能影响后面的任务。

这里有一条该对你坦白的运维真相:选哪个隔离原语,只是这座冰山的一角。真正把一个生产级的沙盒舰队跑起来,你还得自己扛镜像分发和缓存、虚拟网络、编排、温池、自动伸缩、可观测性、回收悬挂资源、按环境配网络策略这一大堆事。实战中,延迟到底是多少,更多取决于你的镜像分发和温池策略,而不是你选了哪个隔离机制本身。所以当你评估上不上云沙盒、自建还是买服务时,要把这座冰山的水下部分算进去。

4.4 边界:沙盒服务属 #8,底层编排属 #2

边界 · harness 工程师选用沙盒服务,系统工程师造编排基础设施

Agent 工程路书(#8)教的是:作为 harness 工程师,怎么根据威胁模型选隔离档位、怎么设五维权限、怎么接沙盒即服务、怎么把执行环境做成能被训练循环复用的东西。也就是站在使用方的角度做选型和集成。

底层那套通用的容器编排、调度、服务网格、K8s 控制面本身怎么实现,归系统设计路书(#2)。一句话分工:#8 教怎么用沙盒服务让 agent 安全地动手,#2 教沙盒服务底下的分布式编排基础设施怎么造。像 GKE Agent Sandbox 这种,它的 K8s 底座属 #2,但它对外暴露的那层 agent-sandbox 抽象(怎么用 Claim 模型申请一个沙盒)属 #8。

5. 当沙盒装的是一个桌面

到目前为止,沙盒里关的都是代码执行。但还有一类 agent,它操作的不是命令行而是图形界面,它需要的沙盒也就不一样。这件事上一章已经埋过引子,你在 Ch3 那一节当工具是一个图形界面 里见过,GUI agent 通过看截图、输出点击和键入来操作软件。这种 agent 要跑在哪?答案是一个沙盒化的桌面,而它和代码执行的沙盒不是一回事:代码执行沙盒隔离的是一段代码,桌面沙盒隔离的是一整个图形会话,里面有虚拟显示、窗口管理、真实安装的应用。

2026 年有两种范式。一种是开发者自管,以 Anthropic 的 Computer Use 参考实现为代表,它就是一个 Docker 容器里装上虚拟的 X11 显示、窗口管理器、还有 Firefox 和 LibreOffice 这些真应用,Claude 通过截图"看"、用模拟的鼠标键盘"动",安全边界由开发者自己负责。另一种是托管,以 OpenAI 的 Operator 为代表,用户通过一个远程浏览器来操作,隔离和浏览器生命周期由 OpenAI 管,遇到登录这种敏感动作会暂停交还给用户,避免密码被截进图里。

桌面 agent 有一个值得专门点出的独特风险。浏览器 agent 跑在一个相对受限的网页环境里,而桌面 agent 直接接触整个文件系统、已经装好的应用、整个计算环境,它能跑 bash、能装软件、能改系统配置。这意味着前面几节讲的那套隔离纪律,对桌面 agent 不是可选项而是硬要求,它必须跑在一个沙盒化的桌面或虚拟机里。至于模型怎么从屏幕像素里看懂界面、准确定位那个按钮在哪,那是视觉理解的问题,归多模态路书,不在这一章。这一章只关心那个图形会话该怎么被安全地关起来。

6. 审批与权限模型

回到 第 1.2 节 立下的那根审批轴。前面讲了一整章的容纳(怎么把沙盒做强),这一节补上自主(要不要先问人)那根轴的具体模型,用两家的实现做对照,因为它们代表了两种不同的设计思路。

Codex 的模型最能体现两根轴的正交。它把沙盒和审批做成两组独立的档位,你做笛卡尔积式的组合。沙盒有三档能力:read-only(只读)、workspace-write(项目目录内可写)、danger-full-access(完全放开)。审批有四档自主度:从只让已知安全的读操作自动跑,到只在要逃出沙盒或要联网时才问,到只在失败时问,再到完全不问。三档隔离乘四档审批,就是 harness 设计的核心旋钮盘,你按任务的风险和信任度去拨。

Claude Code 的模型则是权限规则加操作系统沙盒的双层结构。上层是权限规则,按"拒绝、询问、允许"的顺序求值,第一条匹配上的规则胜出,规则可以用通配符写得很细。但关键在于下层:开启沙盒后,每一条 bash 命令都会被放进一个操作系统级的沙盒里(Linux 上是 bubblewrap、mac 上是 Seatbelt),即使上层权限规则放行了,操作系统这层照样限制它能碰的文件和网络。这一层带来一个很实在的好处,Anthropic 报告说开启沙盒后审批弹窗减少了大约 84%,因为有了操作系统兜底,很多本来要逐条问的 bash 命令现在可以安全地自动批准了。这正好印证了 第 1.2 节 那句话:强隔离换来更高的自主度。这里要再强调一遍那个区分,它是这一节的核心:权限规则是一道权限闸门,靠解析命令来决定"问没问",它本身可以被绕过,不是安全边界;底下那层操作系统沙盒才是真正决定"能不能"的强制隔离。两者缺一不可,但作用不同。

最后提一句人在环路(human-in-the-loop)。在危险动作前弹一个确认框让人来批,是审批落地的主要手段,但它有一个已知的失效模式,值得你现在就警惕:用户会盲目地点确认。当确认框弹得太频繁,人就会条件反射地一路点过去,审批就形同虚设了。这个失效模式怎么被攻击者利用,是下一章对抗安全的内容,这里先埋下:审批不是设了就万事大吉,设计得让人疲劳的审批,等于没有审批。

7. 可复现、重置、与训练环境

最后一节,把沙盒这件事和一个你可能没想到的方向连起来:模型训练。前面讲一次性会话级环境时提过,任务结束就把环境干净地重置掉。这个"重置"的能力,不只是为了卫生,它接通了一个更大的命题。

一个能被反复使用的执行环境,有三个性质:隔离(每次运行互不干扰)、有状态重置(一轮跑完能回到一个已知的基线状态)、可复现(同样的初始状态加同样的动作序列,得到同样的结果)。你回头看会发现,这三个性质恰恰就是强化学习训练环境需要的三个性质,几乎逐字对应。训练一个 agent 时,你要让它在一个环境里反复试错,每次试错要互相隔离、结束要能重置回基线、还要能复现以便调试和比较策略。于是有一个等式成立了:一个训练环境,等于沙盒(提供隔离和重置)加上奖励(一个可验证的信号,比如单元测试通过没有)加上重置(回到基线)。这也是为什么 2026 年这些执行环境正在变成一种托管服务,它们既服务于生产时跑 agent,也服务于训练时跑 agent。

这里要严守一条边界,它是 #8 和 #6 之间的精妙分工。训练环境里那个数据集怎么构造、怎么标注、怎么形成数据飞轮,以及强化学习的算法本身,归数据工程路书(#3)和后训练路书(#6)。Agent 工程这一章只教一件事:作为 harness 工程师,怎么把你的执行沙盒做成一个能被训练循环复用的东西,也就是把隔离、重置、可复现、快速开启这几件事做好。换句话说,#8 提供沙盒这个载体,#6 往里面填奖励和算法。这条线也是一个前向引用,等你走到 Ch12 讲训练环境工程时,会看到 harness 工程师在训练侧到底扮演什么角色。

综合 · 你给 agent 的手戴上了手套

回头看你这一章拿到了什么。你先立住了整章的地基,agent 安全执行有两个正交的问题,审批管自主、沙盒管容纳,而这一章专攻容纳,目标是把模型出错时的爆炸半径关住。你走了一遍隔离机制的强度阶梯,从几乎没边界的裸进程,到共享内核的容器,跨过共享内核与独立内核的第一分水岭,到独立内核的微虚拟机,知道了强隔离等于慢启动这条贯穿张力,也知道了该用"被攻破最坏后果是什么"这个问题去选档位。你拿到了权限策略的五个维度,文件、执行、资源、凭证、以及最关键的网络出口,还从前沿实验室自己的两个 CVE 里看清了出口管控为什么是纵深防御而不是硬边界。你知道了沙盒可以在本地、云、舰队三种形态下跑,规模化的核心工程是把冷启动藏掉。你看了图形界面 agent 需要的桌面沙盒,补全了审批那根轴的两家模型,最后把沙盒和训练环境接上了头。

把这些和前三章合起来,你脑子里那台 harness 又长出了一层。中间是会转的循环(Ch2),外面包着一套能用对、能治理的工具(Ch3),现在又给这双能动手的手戴上了一副手套,让它就算出错也炸不出可控的范围。你给 agent 的手,从能动,变成了能安全地动。

但这副手套只防得住一种威胁,就是模型自己出错。它防不住一件更阴的事:有人故意往模型读到的内容里塞指令,劫持它,让它在这个完美的沙盒里、用着你给的合法权限,亲手把你的私有数据外泄出去。这一章我们反复在网络出口那里埋的那座桥,下一章就要走过去。合上书,去动手:给你前几章那个 agent 接一个真沙盒,用 --network none 把它的网断掉,再配一个只放行特定域名的代理,然后故意让 agent 去访问一个白名单外的地址,看它怎么被挡住;再回头想想,如果要外泄的数据是发往白名单内的可信域名,你这道墙还挡得住吗?带着这个问题进 Ch5。

本章术语速查

下面按本章顺序复习。加粗是术语,后面是一句话解释;带链接的词可点进术语表看更完整的解释。

地基与隔离机制

  • 沙盒(sandbox) 把模型生成代码当 semi-trusted code 容纳,限制它出错时的爆炸半径
  • approval ⊥ sandbox 正交 审批=自主性轴(要不要先问人)、隔离=容纳轴(炸多大),两个独立旋钮
  • seccomp 过滤进程能发的系统调用及参数
  • Landlock 内核安全模块,在文件/端口等内核对象层做访问控制;无特权可自限;与 seccomp 互补叠加,不是二选一
  • gVisor 用户态重实现系统调用的 userspace kernel,收窄宿主内核攻击面;但系统调用不全
  • Firecracker(微虚拟机) 极简 microVM,每份代码独立内核、~125ms 启动,跑不可信代码的事实标准
  • 共享内核 vs 独立内核 隔离强度第一分水岭:决定被攻破时只伤本任务还是波及宿主

权限策略五维

部署与训练

  • 本地 / 云 / 舰队 沙盒的三种部署形态;舰队级核心工程是用温池/快照把冷启动藏掉
  • 训练环境(training environment) = 沙盒(隔离+重置)+ 奖励 + 重置;#8 做沙盒载体,数据/算法归 #3/#6

进阶词汇(对抗安全 / lethal trifecta / context engineering 等)归后续章节,完整术语见术语表 /glossary

参考文献

Mode A · 引用出处(正文 inline,集中列在此)

深 dive 资源(可选 · 想往下走再看)

  • Agent Sandbox on GKE(Google · 2026)· 第 4.3 节 舰队供给工业范本(温池 300/s · Pod 快照 · Claim 模型 · Kata)· 注意 #8(agent-sandbox 抽象)vs #2(K8s 底座)边界
  • e2b / Modal / Daytona / Cloudflare / Fly / Vercel Sandbox 官方文档 · 第 4.2 节 云沙盒全景一手(隔离 × 冷启动 × 状态 · 厂商对比数字按 workload 自测)
  • A Taxonomy of RL Environments for LLM Agents(2026)· 第 7 节 训练环境三性质(隔离/重置/复现)+ "训练环境 = 沙盒 + 奖励 + 重置" · 深入归 #3/#6

说明:Agent 工程领域目前没有合格的人讲解系统教学视频,所以本章是纯 Mode A,由原创讲解 + 一手文档/源码/安全披露扛起。本章涉及的开销百分比、冷启动毫秒数、价格多为厂商发布时点值或竞品对比,会随版本和 workload 大幅波动,引用前务必按当前文档与你自己的负载复核。

下一章

下一章(Ch5)进入第二站的最后一块 · 安全执行 ② · Agent 对抗安全。这一章你把模型出错的爆炸半径关住了,但你在网络出口那里反复看到一件事:一个完美的沙盒,挡得住模型把自己搞坏,却挡不住有人从外部劫持它。Ch5 会讲那条最危险的攻击链(私有数据、不可信内容、外泄通道三者同时具备的致命三连),会讲为什么 prompt injection 连续两版被 OWASP 列为大模型应用头号风险,以及在"约束而非过滤"的思路下,有哪些架构级的防御能真正拦住它。