Agent Sandbox 搭建指南:安全运行 AI 代码的完整方案
2025 年春天,安全研究人员做了一件事——他们把 YCombinator Spring 批次的 16 个公开 AI Agent 全部测试了一遍。结果呢?7 个被攻破。有的泄露用户数据,有的被远程执行代码,还有个直接把数据库给删了。
这就是让 AI Agent 执行代码的代价。你给它自由,它给你挖坑。
我们都在用 AI 写代码、跑脚本、处理数据。但说真的,你有没有想过——那些由大模型生成的代码,你敢直接在服务器上跑吗?万一它来个 rm -rf /,或者偷偷把你的 AWS 密钥发到外部服务器,你连哭的地方都没有。
这就是 Agent Sandbox 存在的意义。
为什么 AI Agent 需要沙盒环境
说实话,AI Agent 和传统应用最大的区别在哪?不是它能对话,不是它能理解指令,而是它能自己写代码并执行。
想象一下这个场景:你让数据分析 Agent 帮你处理一份 1GB 的销售数据,它写了一段 Python 代码去读取、分析、生成图表。这段代码完全是大模型自动生成的,你根本没审过。然后呢?它跑起来了。
这里面有几个要命的风险:
任意代码执行。大模型不懂安全边界。os.system()、subprocess.run() 这些函数,它该用就用,根本不会考虑后果。一个精心设计的 prompt,就能让它执行任意系统命令。
资源耗尽攻击。Agent 写的代码没有资源意识。一个死循环就能把 CPU 吃满,一个无限递归能把内存撑爆。你的服务器直接瘫痪。
文件系统越权。如果你没有限制文件访问路径,它能读遍你的整个磁盘,写任意文件。配置文件、密钥、用户数据,全在它手里。
网络数据外泄。代码里偷偷藏一个 HTTP 请求,把敏感数据发到攻击者的服务器,你根本发现不了。
OWASP 在 2025 年发布了 AI Agent 安全威胁 Top 10,排名第一的就是「Agent 工具交互操纵」。简单说,就是攻击者可以通过 prompt 注入或者其他手段,让 Agent 调用工具的方式偏离你的预期。
已经有真实的攻击案例了:
- Langflow RCE 漏洞:Horizon3 发现的远程代码执行漏洞,攻击者可以通过恶意输入在服务器上执行任意代码。
- Cursor 自动执行漏洞:有研究者发现 Cursor 会自动执行某些 MCP 命令,攻击者可以构造恶意 prompt 触发。
- Replit 数据库擦除:AI 生成的代码意外删除了整个数据库。
沙盒不是可选项。它是 AI Agent 应用的基础设施,就像你不会在不装防火墙的情况下把服务器暴露在公网上一样,你也不应该在没有沙盒的情况下让 AI 执行代码。
沙盒的核心价值就三点:隔离——把风险代码关在笼子里;限制——给 CPU、内存、网络、文件访问设上限;审计——记录它干了什么,出了事能追查。
主流沙盒技术方案对比
好了,既然知道需要沙盒,那用什么呢?现在市面上主要有三种技术路线:容器(Docker)、gVisor、Firecracker 微虚拟机。
先给你一张对比表,心里有个数:
| 方案 | 安全隔离 | 启动速度 | 资源开销 | 适用场景 |
|---|---|---|---|---|
| Docker 容器 | ★★☆☆☆ | ★★★★★ | ★★★★★ | 开发测试、低风险代码 |
| gVisor | ★★★★☆ | ★★★★☆ | ★★★☆☆ | 生产环境、中等风险 |
| Firecracker | ★★★★★ | ★★★★☆ | ★★★☆☆ | 高安全要求、生产部署 |
Docker 容器:快但不够安全
Docker 是最常见的选择。启动快、资源消耗低、生态成熟。但问题是,Docker 容器和宿主机共享内核。
什么意思?容器里的进程虽然被 namespace 隔离了,但如果攻击者利用内核漏洞,就能突破容器边界,拿到宿主机的 root 权限。
2024 年就有好几个容器逃逸漏洞被披露。对于 AI 生成的不可信代码,Docker 的安全边界是不够的。
gVisor:在用户空间造一个”假内核”
gVisor 是 Google 开源的项目,思路很有意思——不直接用宿主机内核,而是在用户空间实现一个”假内核”(叫做 Sentry)。
容器里的程序发起系统调用时,gVisor 会拦截这些调用,由 Sentry 来处理。Sentry 只允许安全的操作,危险的操作会被拒绝。这样一来,即使代码想搞破坏,也接触不到真正的内核。
gVisor 的优势是兼容性好,大部分 Docker 镜像都能直接跑。缺点是有一定的性能损耗(大概 10-20%),而且对于一些特殊的系统调用可能不支持。
GKE(Google Kubernetes Engine)原生支持 gVisor,只需要在 Pod 配置里加一行 runtimeClassName: gvisor 就能用。
Firecracker:真正的硬件级隔离
Firecracker 是 AWS 开源的微虚拟机技术。每个沙盒都是一个小型的虚拟机,有自己独立的内核。
这意味着什么?就算攻击者拿到了沙盒里的 root 权限,利用了内核漏洞,他也只是在一个虚拟机里折腾,完全影响不到宿主机。
Firecracker 的启动速度能做到 100-800 毫秒,资源开销比传统虚拟机小得多(一个虚拟机最小只需要 128MB 内存)。
E2B、AWS Bedrock AgentCore 这些专业的 AI 代码沙盒服务,底层都是用的 Firecracker。
选型决策框架
怎么选?给你一个简单的决策树:
- 只是本地开发测试?用 Docker 就够了,方便快捷。
- 要部署到生产环境?
- 安全要求中等、追求性能 → gVisor
- 安全要求高、要符合合规要求 → Firecracker
- 不想自己运维基础设施?直接用托管服务(E2B、Bedrock AgentCore)
实战:搭建本地开发沙盒
说了这么多理论,来动手搭一个。方案是:FastAPI + Jupyter Kernel + gVisor 容器。
为什么这么组合?
- FastAPI 提供简洁的 HTTP 接口,AI Agent 可以通过 REST API 提交代码执行请求
- Jupyter Kernel 提供交互式的 Python 执行环境,支持变量持久化
- gVisor 容器提供安全隔离,防止恶意代码影响宿主机
步骤 1:编写 FastAPI 服务
创建一个 main.py 文件:
# main.py
import asyncio
from contextlib import asynccontextmanager
from fastapi import FastAPI, HTTPException
from jupyter_client.manager import AsyncKernelManager
from pydantic import BaseModel
app = FastAPI()
class CodeRequest(BaseModel):
code: str
class ExecutionResult(BaseModel):
output: str
@asynccontextmanager
async def kernel_client():
"""管理 Jupyter Kernel 的生命周期"""
km = AsyncKernelManager(kernel_name="python3")
await km.start_kernel()
kc = km.client()
kc.start_channels()
await kc.wait_for_ready()
try:
yield kc
finally:
kc.stop_channels()
await km.shutdown_kernel()
async def execute_code(code: str, timeout: int = 30) -> str:
"""执行代码并返回结果"""
async with kernel_client() as kc:
msg_id = kc.execute(code)
try:
while True:
reply = await asyncio.wait_for(
kc.get_iopub_msg(),
timeout=timeout
)
if reply["parent_header"]["msg_id"] != msg_id:
continue
msg_type = reply["msg_type"]
if msg_type == "stream":
return reply["content"]["text"]
elif msg_type == "error":
return f"Error: {reply['content']['evalue']}"
elif msg_type == "status" and reply["content"]["execution_state"] == "idle":
break
except asyncio.TimeoutError:
return "Error: Execution timed out"
return ""
@app.post("/execute", response_model=ExecutionResult)
async def execute(request: CodeRequest):
"""代码执行接口"""
try:
output = await execute_code(request.code)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
return ExecutionResult(output=output)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
这段代码的核心逻辑是:每次收到执行请求,启动一个独立的 Jupyter Kernel,执行代码,返回结果,然后销毁 Kernel。
步骤 2:编写 Dockerfile
FROM jupyter/base-notebook:latest
WORKDIR /app
COPY main.py /app/main.py
COPY requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
# 使用非 root 用户(安全最佳实践)
USER jovyan
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
注意那个 USER jovyan,这是安全实践。用非 root 用户运行容器,就算代码逃逸了,拿到的权限也有限。
步骤 3:部署到 GKE(启用 gVisor)
如果你用的是 GKE,只需要在 Pod 配置里加一行:
apiVersion: apps/v1
kind: Deployment
metadata:
name: agent-sandbox
spec:
template:
spec:
runtimeClassName: gvisor # 关键:启用 gVisor
containers:
- name: sandbox
image: your-registry/agent-sandbox:latest
ports:
- containerPort: 8000
resources:
limits:
memory: "512Mi"
cpu: "500m"
就这样,你的代码执行环境已经跑在 gVisor 沙盒里了。
步骤 4:添加安全限制
上面的配置还不够完善。生产环境至少还要加这些限制:
# 网络策略:限制只能访问必要的 API
# 文件系统只读
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
# 设置执行超时
# 在 FastAPI 代码里已经加了 timeout 参数
进阶:Kubernetes 集群部署
如果你的 AI Agent 应用需要大规模部署,单个容器就不够用了。这时候可以用 Kubernetes 的 Agent Sandbox 控制器。
Google 在 2025 年开源了一个 Agent Sandbox 项目,提供了声明式的沙盒管理 API。
Sandbox CRD 核心概念
Agent Sandbox 定义了几个自定义资源:
- Sandbox:单个沙盒实例,有稳定身份、持久存储、生命周期管理
- SandboxTemplate:沙盒模板,定义标准化配置
- SandboxClaim:按需申请沙盒实例
一个简单的 Sandbox 配置示例:
apiVersion: sandbox.k8s.io/v1alpha1
kind: Sandbox
metadata:
name: my-agent-sandbox
spec:
template:
spec:
runtimeClassName: gvisor
containers:
- name: executor
image: python:3.11-slim
command: ["sleep", "infinity"]
# 持久存储
volumes:
- name: workspace
emptyDir: {}
# 资源限制
resources:
limits:
memory: "1Gi"
cpu: "1"
生命周期管理
Agent Sandbox 的一个亮点是支持暂停/恢复:
# 暂停沙盒(释放 CPU 和大部分内存)
kubectl patch sandbox my-agent-sandbox --type=merge -p '{"spec":{"paused":true}}'
# 恢复沙盒
kubectl patch sandbox my-agent-sandbox --type=merge -p '{"spec":{"paused":false}}'
这对于间歇性执行的 AI Agent 特别有用——没任务的时候暂停,几乎不占资源;有任务了秒级恢复。
预热池(Pool)
为了进一步减少启动延迟,Agent Sandbox 支持”预热池”——预先创建一批处于暂停状态的沙盒,需要时直接激活。
这招能把沙盒的”冷启动”时间从秒级降到毫秒级。
托管服务选型建议
如果你不想自己折腾基础设施,托管服务是个好选择。目前主流的有这几家:
E2B:开源 + 云托管双模式
E2B 是专门为 AI Agent 设计的代码沙盒服务。它有两个版本:
- E2B Cloud:直接用他们的云服务,按量付费
- E2B on AWS:把开源版本部署到你自己的 AWS 账户
E2B 底层用的是 Firecracker,安全性有保障。它的 SDK 很简洁:
from e2b import Sandbox
# 创建沙盒
sandbox = Sandbox()
# 执行代码
result = sandbox.run_code("print('Hello, World!')")
# 关闭沙盒
sandbox.close()
E2B on AWS 特别适合对数据主权有要求的企业——所有数据都在你自己账户里,不用担心第三方。
AWS Bedrock AgentCore
AWS 在 2025 年推出了 Bedrock AgentCore,专门为 AI Agent 提供代码执行和浏览器操作能力。
Code Interpreter 提供 Python/JavaScript/TypeScript 运行时,每个会话在独立的微虚拟机里执行,支持最大 5GB 的文件处理。
Browser Tool 让 AI Agent 能操作浏览器——打开网页、填表单、点击按钮。这对于需要爬取网页、操作 SaaS 应用的 Agent 特别有用。
计费模式也挺合理:按 vCPU 和内存的实际使用时间计费,不是按实例运行时间。代码执行完资源就释放,不会浪费钱。
选型建议
| 场景 | 推荐方案 |
|---|---|
| 快速验证、小规模应用 | E2B Cloud |
| 企业级、需要数据本地化 | E2B on AWS 或 Bedrock AgentCore |
| 已深度使用 AWS 生态 | Bedrock AgentCore |
| 需要浏览器自动化 | Bedrock AgentCore Browser Tool |
| 完全自主控制、有运维能力 | 自建 Kubernetes + Agent Sandbox |
结论
说了这么多,其实核心就一句话:安全不是可选项,而是 AI Agent 应用的基础设施。
从技术选型来说:
- 小团队、快速验证,用 Docker 或 gVisor 就够了
- 企业级应用、高安全要求,用 Firecracker 或托管服务
- 已经在用 Kubernetes,直接上 Agent Sandbox 控制器
不管你选哪个,先从本地测试开始。写一个最简单的 FastAPI + Docker 配置,跑起来,然后再考虑安全加固和生产部署。
记住:沙盒越早加越好。别等到出了安全事故再来补救,那时候成本就高多了。
搭建 AI Agent 沙盒环境
从零开始搭建安全的 AI 代码执行环境
⏱️ 预计耗时: 60 分钟
- 1
步骤1: 创建 FastAPI 服务
编写 main.py 文件,实现代码执行接口:
• 使用 AsyncKernelManager 管理 Jupyter Kernel
• 设置执行超时(默认 30 秒)
• 返回执行结果或错误信息 - 2
步骤2: 编写 Dockerfile
基于 jupyter/base-notebook 镜像构建:
• 安装依赖(FastAPI、uvicorn)
• 使用非 root 用户(jovyan)运行
• 暴露 8000 端口 - 3
步骤3: 部署到 Kubernetes
配置 Pod 启用 gVisor:
• 设置 runtimeClassName: gvisor
• 配置资源限制(CPU/内存)
• 添加安全上下文(只读文件系统) - 4
步骤4: 验证沙盒隔离
测试安全边界:
• 尝试访问宿主机文件系统(应被拒绝)
• 执行资源密集型代码(应被限制)
• 检查网络隔离是否生效
常见问题
Docker 容器和 gVisor 有什么区别?
什么时候应该用 Firecracker 而不是 gVisor?
• 需要硬件级隔离(如金融、医疗数据)
• 必须符合严格的合规要求
• 处理完全不可信的第三方代码
gVisor 性能损耗较小(10-20%),适合大多数生产场景。
E2B 和 AWS Bedrock AgentCore 怎么选?
• 小规模应用先用 E2B Cloud
• 需要数据本地化用 E2B on AWS
Bedrock AgentCore 适合 AWS 生态深度用户:
• 已用 AWS 服务,集成更方便
• 需要浏览器自动化选 Browser Tool
沙盒会影响代码执行性能吗?
本地开发如何快速搭建沙盒?
11 分钟阅读 · 发布于: 2026年3月23日 · 修改于: 2026年3月23日

评论
使用 GitHub 账号登录后即可评论