AI代理的两种沙盒架构
AI 沙盒正成为新的基础设施,但如何有效使用它们仍然是一个关键问题!
随着越来越多的 AI 代理需要执行代码、安装包和访问文件,它们需要专用的、必须与主机系统隔离的工作空间,以防止对凭据、文件或网络资源的未授权访问。沙盒正是提供了这种隔离。
LangChain 创始人 Harrison Chase 最近分析了将 AI 代理与沙盒集成的架构挑战,确定了两种主要模式:在沙盒内运行代理,或在将沙盒作为工具时外部运行代理。
1、模式 1:代理在沙盒内运行
代理完全在沙盒环境中运行,外部通信通过网络进行。
实现方法:构建预装代理框架的 Docker 或 VM 镜像,在沙盒内运行,并通过外部消息传递连接。代理暴露 API 端点(通常是 HTTP 或 WebSocket),使应用程序能够跨越沙盒边界进行通信。
优势:
- 镜像本地开发环境——如果你在本地运行深度代理,你将在沙盒中运行相同的命令
- 代理可以直接访问文件系统并修改环境
- 当代理与执行环境紧密耦合时很有用,例如在与特定库交互或维护复杂的环境状态时
挑战:
- 跨沙盒通信需要基础设施支持。一些提供商如 E2B 在其 SDK 中处理这个问题;否则,你需要自己构建 WebSocket 或 HTTP 层,包括会话管理和错误处理
- API 密钥必须存储在沙盒内以允许代理进行推理调用,如果沙盒被泄露会造成安全风险。像 E2B 和 Runloop 这样的提供商正在开发密钥库功能来解决这个问题
- 更新需要重建容器镜像并重新部署,减慢开发迭代周期
- 在代理激活之前必须恢复沙盒,通常需要额外的逻辑
- 对于关心保护代理知识产权的团队,代码和提示在代理在沙盒内运行时更加脆弱
来自 Witan Labs 的 Nuno Campos 强调了另一个安全顾虑:"代理的任何部分都不应该具有比 bash 工具更多的权限。例如,如果你想要一个同时具有 bash 和网络搜索工具的代理,所有 LLM 生成的代码都可能拥有不受限制的网络访问,这是一个重大安全风险。使用模式 2,你可以给工具比 LLM 生成的代码更多的权限,因为安全边界围绕着 bash 工具,而不是整个代理。"
2、模式 2:沙盒作为工具
代理在本地或服务器上运行,当需要代码执行时通过 API 调用远程沙盒。
实现方法:代理在本地(或服务器)运行,当他们生成需要执行的代码时,调用沙盒提供商 API(如 E2B、Modal 或 Runloop)。提供商 SDK 从代理的角度处理所有通信细节——沙盒只是另一个工具。
优势:
- 无需重建容器镜像即可即时更新代理代码,加速开发迭代
- API 密钥保留在沙盒外——只有执行发生在隔离环境中
- 提供更清晰的关注点分离:代理状态(对话历史、推理链、内存)存在于代理运行的地方,与沙盒分离。这意味着沙盒故障不会丢失代理状态,并且你可以切换沙盒后端而不影响核心代理逻辑
E2B 的 Tomas Beran 强调了额外的优势:
能够在多个远程沙盒中并行运行任务——仅在代码执行期间支付沙盒时间,而不是整个进程运行时间
来自 Zo Computer 的 Ben Guo 补充道:"我们选择模式 2 考虑到未来需要在 GPU 机器上运行代理工具——持久化沙盒和推理工具通常有不同的环境要求。"
挑战:
- 网络延迟是主要缺点。每次执行调用都跨越网络边界,为许多小执行工作负载累积开销
- 许多沙盒提供商提供有状态会话,其中变量、文件和安装的包在同一会话中的调用之间持久化,通过减少所需的往返来缓解一些延迟问题
3、选择指南
当以下情况时选择模式 1:
- 代理与执行环境紧密耦合(例如,代理需要持久访问特定库或复杂的环境状态)
- 你希望生产环境紧密镜像本地开发
- 提供商 SDK 为你处理通信层
当以下情况时选择模式 2:
- 你需要在开发过程中快速迭代代理逻辑
- 你希望 API 密钥保持在沙盒外
- 你希望代理状态和执行环境之间有更清晰的分离
4、实现示例
以下是使用 deepagents 框架的特定示例:
模式 1:代理在沙盒内首先,构建预装代理的镜像:
FROM python:3.11
RUN pip install deepagents-cli
然后在沙盒内运行。完整实现需要额外的基础设施来处理应用程序和沙盒内代理之间的通信(WebSocket 或 HTTP 服务器、会话管理、错误处理)。
模式 2:沙盒作为工具
from daytona import Daytona
from langchain_anthropic import ChatAnthropic
from deepagents import create_deep_agent
from langchain_daytona import DaytonaSandbox
# 或者使用 E2B、Runloop、Modal
sandbox = Daytona().create()
backend = DaytonaSandbox(sandbox=sandbox)
agent = create_deep_agent(
model=ChatAnthropic(model="claude-sonnet-4-20250514"),
system_prompt="你是一个具有沙盒访问权限的 Python 编码助手。",
backend=backend,
)
result = agent.invoke({
"messages": [{
"role": "user",
"content": "运行一个小的 Python 脚本",
}]
})
sandbox.stop()
此代码遵循以下工作流程:
- 代理在你的机器上本地计划——生成 Python 代码解决问题
- 调用 Daytona API 在远程沙盒中执行代码
- 沙盒返回结果——代理看到输出并继续本地推理
5、社区讨论
这个话题引发了重大的社区讨论。
一些开发人员质疑模式 1 在生产环境中的可行性,引用"巨大的安全漏洞和各种极具挑战性的基础设施约束(沙盒可观察性、正常运行时间、扩展等)。"
Nico Ritschel 对一些缺点提供了不同的视角,提出了简单的实际解决方案:
- 代理推理调用和将密钥注入沙盒外部可以解决 API 密钥问题——对于知识产权保护,IP 可以存储在代理可访问的工具中
- Harrison Chase 回应关键代理还不是标准做法,尽管一些提供商正在添加这些功能。
原文链接: LangChain Founder Harrison Chase Explains Two Sandbox Architectures for AI Agents
汇智网翻译整理,转载请标明出处