跳转到内容

02 为什么需要沙箱

本章导读|预计 9 分钟

上一章说沙箱是「Agent 的手脚」。但服务器也能跑代码,为什么要专门造一个沙箱? 这一章回答:Agent 的执行需求,和传统后端程序到底差在哪——答案藏在那六个「刚需」里。

# 需求 具体表现 没有沙箱会怎样
1 执行不可信代码 LLM 会幻觉、写错、被注入 直接污染宿主环境
2 有状态 改文件 → 再跑 → 看结果 每步都从零开始,做不了多步任务
3 可回滚 出错就丢弃重来 环境被搞脏,无法恢复
4 可并行 多个子任务同时跑 串行慢,且互相干扰
5 可观测 看 stdout / 文件变化 / 耗时 出问题无从排查
6 可回收 用完即销毁 资源泄漏、成本失控、残留风险

这六条里,第 1 条是「安全」诉求,第 2–6 条是「功能」诉求。很多团队只盯着第 1 条,结果造出一个很安全、却做不了事的沙箱——这又回到了第 0 章那个「把沙箱只当牢房」的错误。

为什么这六条不能靠「本地进程 + 小心一点」解决?

  • 本地进程无法可靠地「用完即销毁」——改了的文件、装的包、写的缓存都留在机器上。
  • 本地进程无法低成本地「回滚」——除非你预先做了整机快照。
  • 本地进程无法强约束「可观测」——它可以直接绕开你的日志。
  • 最重要:让 LLM 生成的代码跑在宿主机上,等于把宿主机交给一个可能被操纵的模型。

看一个真实形态的任务,体会这六个需求是怎么同时出现的:

用户:帮我把 data.csv 清洗后算平均值,画个图
Agent:
1) 沙箱内写 clean.py
2) 运行 → 报错(缺 pandas)
3) pip install pandas ← 包管理 + 网络策略
4) 重跑 → 成功,生成 result.csv ← 有状态(上一步装的 pandas 还在)
5) 写 plot.py 画图 → 生成 chart.png
6) 把 chart.png 传出来给用户 ← 文件导出

逐步对照:

步骤 用到的刚需
1 文件系统写入(有状态)
2 执行 + 观测 stdout / 错误
3 包管理 + 出网策略(风险点)
4 有状态(环境要延续)
5 执行 + 文件产出
6 文件导出,且只能导出成果,不导出环境
全程 可观测、可回收

注意第 3 步:为了让它能 pip install,你必须开一点网络。这是 Agent 沙箱最典型的两难——开了怕外泄,不开干不了活。第 6 章的白名单代理就是为这个场景设计的。

2.3 对比:没有沙箱时 Agent 的处境

Section titled “2.3 对比:没有沙箱时 Agent 的处境”
场景 直接在本机跑 在沙箱里跑
代码删错文件 真删了 沙箱销毁,无事发生
装了个恶意包 宿主中招 隔离,销毁即清
死循环 / 占满内存 拖垮本机 触发限额,被 kill
并发跑 10 个任务 互相干扰 每任务独立环境
读到宿主的 API Key 直接拿到,可能被外泄 默认清空环境变量,读不到
被注入后访问内网 直通内网 / 云元数据 网络隔离,阻断 169.254.169.254

2.4 为什么是「特别」需要:三个 Agent 独有的变量

Section titled “2.4 为什么是「特别」需要:三个 Agent 独有的变量”

普通后端也会跑不可信代码(比如用户上传的脚本),但 Agent 让风险成倍放大:

  1. 执行频率高、粒度细:Agent 会一轮轮自主动作,每一次都可能执行一段新代码。传统「人工审核后执行」的模式失效。
  2. 执行内容由模型即时生成:代码不是在发布时审过、冻结的,而是运行时现写的,无法提前审计。
  3. 决策可能被外部输入操纵:一段恶意网页、一个恶意依赖的描述,就能诱导 Agent 执行任意命令(prompt injection)。这是传统程序没有的攻击面。

结论:Agent 不是「偶尔跑一下危险代码」,而是「持续地、自主地、在被操纵风险下执行新代码」。这三点叠加,使沙箱从「可选项」变成「基础设施」。

  1. Agent 对沙箱的需求是六个,不只是「安全」一个。
  2. 有状态 + 可观测是完成多步任务的前提;可回滚 + 可回收是控制风险与成本的前提。
  3. 包管理与网络是「功能」和「安全」的交叉点,也是设计难点。
  4. Agent 的执行频率、代码的即时生成、决策的可被操纵,三者叠加让沙箱成为必需。
  1. 列举一个你业务里的 Agent 任务,标注它需要上面六个刚需中的哪几个。
  2. 在你的任务里找出至少一个「既要用网络、又怕外泄」的具体动作,写出你打算怎么处理。