代理生成代码、与文件系统交互并运行 Shell 命令。因为我们无法预测代理可能会做什么,所以其环境必须是隔离的,以防止其访问凭据、文件或网络,这一点至关重要。沙箱通过在代理的执行环境与您的主机系统之间创建边界来提供这种隔离。 在 Deep Agents 中,沙箱是 后端,它们定义了代理运行的环境。与其他仅暴露文件操作的后端(State、Filesystem、Store)不同,沙箱后端还为代理提供了一个用于运行 Shell 命令的 execute 工具。当您配置一个沙箱后端时,代理将获得:
  • 所有标准文件系统工具 (ls, read_file, write_file, edit_file, glob, grep)
  • 用于在沙箱中运行任意 Shell 命令的 execute 工具
  • 一个保护您主机系统的安全边界

为什么使用沙箱?

沙箱用于保障安全性。 它们允许代理执行任意代码、访问文件和使用网络,而不会危及您的凭据、本地文件或主机系统。 当代理自主运行时,这种隔离至关重要。 沙箱特别适用于:
  • 编程代理:自主运行的代理可以使用 Shell、Git、克隆仓库(许多提供商提供原生 Git API,例如 Daytona 的 Git 操作),并运行 Docker-in-Docker 以构建和测试流水线。
  • 数据分析代理— 在安全、隔离的环境中加载文件、安装数据分析库(pandas、numpy 等)、运行统计计算并创建如 PowerPoint 演示文稿等输出。
正在使用 Deep Agents Code? Deep Agents Code 通过 --sandbox 标志内置沙箱支持。有关 Deep Agents Code 的特定设置、标志(--sandbox-id, --sandbox-setup)和示例,请参阅 使用远程沙箱。
如果您在寻找 LangSmith 沙箱: LangSmith 提供您可以直接从 LangSmith UI 或 SDK 使用的第一方托管沙箱,无需第三方账户。有关托管沙箱资源、快照、服务 URL 和认证代理,请参阅 LangSmith 沙箱。

基本用法

这些示例假设您已经使用提供商的 SDK 创建了沙箱/devbox 并设置了凭据。有关注册、身份验证和提供商特定生命周期的详细信息,请参阅可用提供商。
LangSmith 跟踪显示哪些 Shell 命令在沙箱内运行以及代理如何使用文件系统工具。请按照可观测性快速入门进行设置。有关托管沙箱托管,请参阅 LangSmith 沙箱。我们建议您也设置 LangSmith Engine,它可以监控您的跟踪记录、检测问题并提出修复建议。

可用提供商

技能需要 deepagents>=1.7.0。
没看到您的提供商?您可以实现自己的沙箱后端。请参阅贡献沙箱集成。

生命周期和作用域

大多数应用程序选择每个会话一个沙箱(会话作用域)或同一个助手的所有会话共享一个沙箱(助手作用域)。 沙箱会消耗资源并产生成本,直到它们被关闭。请确保在不再使用沙箱时将其关闭。 有关完整的生命周期表、异步图工厂说明、TTL 行为、LangGraph Deployment 配线以及客户端示例,请参阅投产指南中的沙箱生命周期。

会话作用域(默认)

每个对话拥有自己的沙箱。首次运行时创建它;同一会话上的后续轮次会复用它。当会话结束或沙箱 TTL 到期时,环境将消失。如以下示例所示,使用沙箱名称或元数据存储映射,以便每次运行都解析到相同的沙箱。
当用户可能在空闲后返回时,请为沙箱配置 TTL,以便提供商自动删除或归档空闲环境。

助手作用域

同一助手上的每个会话都复用一个沙箱。文件、已安装的包和克隆的仓库会在对话之间持久存在。
助手作用域的沙箱会随时间在沙箱内累积状态。请与您的沙箱提供商配置 TTL,使用快照定期重置,或实现清理逻辑,以防止磁盘和内存无限增长。
有关在图工厂之外进行手动创建、执行和拆除,请参阅基本用法和沙箱集成以了解提供商特定的 API。

集成模式

根据代理运行的位置,有两种将代理与沙箱集成的架构模式。

代理在沙箱内模式

代理在沙箱内部运行,您通过网络与其通信。您构建一个预装了代理框架的 Docker 或 VM 镜像,在沙箱内运行它,并从外部连接以发送消息。 优点:
  • ✅ 与本地开发高度相似。
  • ✅ 代理与环境紧密耦合。
权衡:
  • 🔴 API 密钥必须存在于沙箱内部(安全风险)。
  • 🔴 更新需要重新构建镜像。
  • 🔴 需要通信基础设施(WebSocket 或 HTTP 层)。
要在沙箱中运行代理,请构建一个镜像并在其上安装 deepagents。
然后在沙箱内运行代理。 要在沙箱内使用代理,您必须添加额外的基础设施来处理应用程序与沙箱内代理之间的通信。

沙箱作为工具模式

代理在您的机器或服务器上运行。当需要执行代码时,它调用沙箱工具(如 execute、read_file 或 write_file),这些工具调用提供商的 API 在远程沙箱中运行操作。 优点:
  • ✅ 无需重新构建镜像即可即时更新代理代码。
  • ✅ 代理状态与执行更清晰地分离。
    • API 密钥保留在沙箱外部。
    • 沙箱故障不会丢失代理状态。
    • 可以选择在多个沙箱中并行运行任务。
  • ✅ 仅为执行时间付费。
权衡:
  • 🔴 每次执行调用都有网络延迟。
本文档中的示例使用沙箱作为工具模式。 当您的提供商 SDK 处理通信层且您希望生产环境与本地开发保持一致时,请选择代理在沙箱内模式。 当您需要快速迭代代理逻辑、将 API 密钥保留在沙箱之外或更喜欢关注点分离时,请选择沙箱作为工具模式。

沙箱工作原理

隔离边界

所有沙箱提供商都保护您的主机系统免受代理的文件系统和 Shell 操作的影响。代理无法读取您的本地文件、访问您机器上的环境变量或干扰其他进程。然而,沙箱本身不能防止:
  • 上下文注入:控制代理部分输入的攻击者可以指示其在沙箱内运行任意命令。沙箱是隔离的,但代理在其中有完全控制权。
  • 网络数据渗出:除非网络访问被阻止,否则上下文注入的代理可以通过 HTTP 或 DNS 从沙箱发送数据。一些提供商支持阻止网络访问(例如 Modal 上的 blockNetwork: true)。
有关如何处理机密和缓解这些风险的信息,请参阅安全注意事项。

execute 方法

沙箱后端架构简单:提供商唯一必须实现的方法是 execute(),它运行 Shell 命令并返回其输出。 所有其他文件系统操作(read, write, edit, ls, glob, grep)都由 BaseSandbox 基类在 execute() 之上构建,该基类构造脚本并通过 execute() 在沙箱内运行它们。 这种设计意味着:
  • 添加新提供商很简单。 只需实现 execute()——基类会处理其他所有事情。
  • execute 工具是条件可用的。 在每次模型调用时,工具箱会检查后端是否实现了 SandboxBackendProtocol。如果没有,则该工具会被过滤掉,代理永远不会看到它。
当代理调用 execute 工具时,它提供一个 command 字符串并返回合并的 stdout/stderr、退出代码,如果输出过大则返回截断通知。 您也可以在应用程序代码中直接调用后端 execute() 方法。 例如:
如果命令产生非常大的输出,结果会自动保存到文件中,并指示代理使用 read_file 增量访问它。这可以防止上下文窗口溢出。

文件访问的两个层面

文件进出沙箱有两种截然不同的方式,了解何时使用每种方式很重要: 代理文件系统工具:read_file, write_file, edit_file, ls, glob, grep, execute 是 LLM 在执行期间调用的工具。这些工具通过沙箱内的 execute() 执行。代理使用它们来读取代码、写入文件和运行命令作为其任务的一部分。 文件传输 API:您的应用程序代码调用的 uploadFiles() 和 downloadFiles() 方法。这些方法使用提供商的原生文件传输 API(而非 Shell 命令),旨在在主机环境和沙箱之间移动文件。使用这些方法可以:
  • 在代理运行前用源代码、配置或数据填充沙箱
  • 在代理完成后检索工件(生成的代码、构建输出、报告)
  • 预填充代理将需要的依赖项

处理文件

填充沙箱

在代理运行之前,使用 uploadFiles() 来填充沙箱。文件内容以 Uint8Array 形式提供:

检索工件

在代理完成后,使用 downloadFiles() 从沙箱检索文件:
在沙箱内部,代理使用自己的文件系统工具 (read_file, write_file):而不是 uploadFiles 或 downloadFiles。这些方法是供您的应用程序代码在主机和沙箱之间移动文件的。

安全注意事项

沙箱将代码执行与您的主机系统隔离,但它们无法防止上下文注入。控制代理部分输入的攻击者可以指示其读取文件、运行命令或从沙箱内渗出数据。这使得沙箱内的凭据尤其危险。
切勿将机密信息放入沙箱内。 API 密钥、令牌、数据库凭据和其他通过环境变量、挂载文件或 secrets 选项注入沙箱的机密信息,都可以被上下文注入的代理读取和渗出。这甚至适用于短期或范围受限的凭据——如果代理可以访问它们,那么攻击者也可以。

安全处理机密信息

如果您的代理需要调用经过身份验证的 API 或访问受保护的资源,您有两个选择:
  1. 将机密信息保留在沙箱外的工具中。 定义在主机环境(而非沙箱内部)运行的工具,并在其中处理身份验证。代理通过名称调用这些工具,但永远不会看到凭据。这是推荐的方法。
  2. 使用注入凭据的网络代理。 一些沙箱提供商支持代理,这些代理拦截来自沙箱的传出 HTTP 请求,并在转发之前附加凭据(例如 Authorization 头)。代理永远不会看到机密信息——它只是向 URL 发出普通请求。此方法尚未在所有提供商中广泛提供。
如果您必须将机密信息注入沙箱(不推荐),请采取以下预防措施:
  • 对所有工具调用启用人在回路审批,而不仅仅是敏感调用
  • 阻止或限制沙箱的网络访问以限制渗出路径
  • 使用尽可能窄的凭据范围和尽可能短的生命周期
  • 监控沙箱网络流量以发现意外的出站请求
即使有这些保障措施,这仍然是一个不安全的解决方法。一个足够有创意的上下文注入攻击可以绕过输出过滤和 HITL 审查。

通用最佳实践

  • 在应用程序中对沙箱输出采取行动之前先进行审查
  • 在不需要时阻止沙箱网络访问
  • 使用中间件过滤或编辑工具输出中的敏感模式
  • 将沙箱内产生的一切都视为不受信任的输入