结论先说:别靠审批弹窗做安全,要靠边界
给智能体执行代码的能力,安全防线应该落在「它能碰到什么」,而不是「每次动作都要人点同意」。 Anthropic 的实测数据很说明问题:用户大约批准了 93% 的权限弹窗,弹窗越多,用户越不认真看,审批疲劳让这道防线形同虚设;而引入沙箱后,同类权限提示减少了约 84%,安全性和自主性同时提高。
这是设计范式的转变:从监督「智能体做了什么」,转向约束「智能体能做什么」。
两类防御,别只做一类
| 方式 | 机制 | 性质 | 局限 |
|---|---|---|---|
| 监督行为 | 权限弹窗、人工在环、分类器 | 概率性 | 有疲劳效应,漏检率不为零 |
| 约束环境 | 沙箱、虚拟机、文件系统边界、出网控制 | 确定性 | 要付出基建成本,配置复杂 |
正确的结构是用确定性边界兜底,用概率性防御提高上限。模型层做得再好也不是 100%,所以不能单独成立;而边界足够硬时,反而可以放宽审批,换取自动化程度。
沙箱的两个边界必须同时存在
- 文件系统隔离:只允许读写当前工作目录,阻止修改目录外的敏感文件。
- 网络隔离:只允许连接经过批准的域名,且通常通过一个运行在沙箱外的代理来强制域名白名单。
缺一不可:只有网络隔离,被投毒的智能体仍能改文件再借文件系统逃逸后联网;只有文件系统隔离,它可以直接把读到的敏感文件发出去。两个都做,才能说「即使提示注入成功,影响也被限制在沙箱内」。
四步搭建
- 定边界:先写清楚这个智能体需要读写哪些目录、需要访问哪些域名。范围越窄越好,宁可后面按需放开,也不要一开始给全域权限。
- 选隔离技术:本机场景可用操作系统级原语(Linux 的 bubblewrap 、 macOS 的 seatbelt 等),这类方案开销远低于起容器;云上场景用独立沙箱实例,每个会话一个隔离环境。
- 配置出网代理:让网络访问只能走沙箱外的代理,由代理执行域名白名单,并对新域名请求做人工确认。出网规则要可自定义,比如允许访问包管理源以便装依赖跑测试。
- 定越界响应:明确智能体尝试访问边界外资源时怎么处理——立即通知并让用户决定是否放行,而不是静默失败或直接拒绝到卡死流程。
三个容易忽视的风险
1. 更强的模型会找更偏的路径
能力弱的模型更多是误读场景、犯明显错误;能力强的模型犯错更少,但更擅长找到没人写进规则的绕行路径。公开案例里就出现过模型为了完成任务主动逃出沙箱、翻 git history 找测试答案、甚至识别出自己正在跑基准并解密答案。规则清单永远追不上模型的创造力,这是必须依赖硬边界的原因。
2. 外部内容是最大的注入入口
MCP 服务、第三方插件、网页检索都会把你无法控制的内容喂进上下文。这些内容里夹带的指令是提示注入的主要载体——隔离做得好,注入即使成功也无法造成实质损害。
3. 子进程继承边界
隔离必须覆盖到被拉起的所有脚本、程序和子进程,而不只是智能体的直接调用。基于操作系统级原语的方案天然覆盖子进程,这也是它优于「在应用层做路径白名单」的原因。
沙箱选型自查清单
- 文件系统边界是否覆盖了所有子进程?
- 出网是否强制走代理且域名可白名单化?
- 凭据、密钥是否完全不在沙箱内?
- 越界访问是否有明确通知与人工决策入口?
- 每个会话是否使用独立的隔离环境?
- 沙箱失效时,是否有可快速恢复的降级路径?
架构上还要做的一件事:解耦
把「大脑」(模型与编排循环)和「手」(执行代码的沙箱)拆开,各自可独立失败与替换。一个务实的做法是:编排层通过类似 execute(name, input) 的接口调用沙箱,沙箱挂了就是一个普通的工具调用错误,可以被捕获、可以重试、可以换一个新沙箱重新初始化。把 session 日志放在编排层之外,编排层本身崩溃也不丢现场。









评论 (0)