跳到主要内容

文档索引

在以下地址获取完整的文档索引:https://docs.langchain.org.cn/llms.txt

在进一步探索之前,请使用此文件发现所有可用页面。

智能体生成代码、与文件系统交互并运行 shell 命令。由于我们无法预测智能体可能做什么,因此其环境的隔离至关重要,这样它就无法访问凭据、文件或网络。沙盒通过在智能体的执行环境和主机系统之间创建边界来提供这种隔离。 在 Deep Agents 中,沙盒是后端,用于定义智能体的操作环境。与其他只暴露文件操作的后端(状态、文件系统、存储)不同,沙盒后端还为智能体提供了一个 execute 工具来运行 shell 命令。当你配置沙盒后端时,智能体将获得:
  • 所有标准文件系统工具(lsread_filewrite_fileedit_fileglobgrep
  • 用于在沙盒中运行任意 shell 命令的 execute 工具
  • 一个保护主机系统的安全边界

为什么要使用沙盒?

沙盒用于安全目的。它们允许智能体执行任意代码、访问文件和使用网络,而不会危及你的凭据、本地文件或主机系统。当智能体自主运行时,这种隔离至关重要。 沙盒特别适用于:
  • 编程智能体:自主运行的智能体可以使用 shell、git、克隆存储库(许多提供商提供原生 git API,例如 Daytona 的 git 操作),并运行 Docker-in-Docker 以进行构建和测试管道
  • 数据分析智能体:在安全、隔离的环境中加载文件、安装数据分析库(pandas、numpy 等)、运行统计计算,并创建 PowerPoint 演示文稿等输出
使用 Deep Agents CLI?CLI 通过 --sandbox 标志内置沙盒支持。请参阅使用远程沙盒,了解 CLI 特定的设置、标志(--sandbox-id--sandbox-setup)和示例。

基本用法

这些示例假设您已使用提供商的 SDK 创建了沙盒/开发盒,并已设置凭据。有关注册、身份验证和提供商特定的生命周期详细信息,请参阅可用提供商

可用提供商

有关提供商特定的设置、身份验证和生命周期详细信息,请参阅沙盒集成 没有看到您的提供商?您可以实现自己的沙盒后端。请参阅贡献沙盒集成

生命周期和作用域

沙盒会消耗资源,并且在关闭之前会产生费用。如何管理它们的生命周期取决于您的应用程序。 选择沙盒生命周期如何映射到您的应用程序资源。有关此决定的更多信息,请参阅投入生产

线程作用域(默认)

每个对话都有自己的沙盒。沙盒在首次运行开始时创建,并在同一线程上的后续消息中重复使用。当线程被清理(或沙盒 TTL 过期)时,沙盒将被销毁。这对于大多数智能体来说是正确的默认设置。 示例:一个数据分析机器人,每个对话都从一个干净的环境开始。

助手作用域 (Assistant-scoped)

给定助手的所有线程共享一个沙盒。沙盒 ID 存储在助手的配置中,因此每个对话都返回到相同的环境。文件、已安装的包和克隆的存储库在对话之间持续存在。当智能体维护一个长期运行的工作区时使用此模式。 示例:一个编程助手,在对话之间维护一个克隆的存储库和已安装的依赖项。
助手作用域的沙盒会随着时间累积文件、已安装的包和其他沙盒内状态。请与您的沙盒提供商配置 TTL,定期使用快照进行重置,或实施清理逻辑以防止沙盒的磁盘和内存无限增长。线程作用域的沙盒通过每次对话都重新开始来避免这种情况。

基本生命周期

from daytona import Daytona

from langchain_daytona import DaytonaSandbox

sandbox = Daytona().create()
backend = DaytonaSandbox(sandbox=sandbox)

result = backend.execute("echo hello")
# ... use sandbox
sandbox.stop()

按对话划分的生命周期

在聊天应用程序中,对话通常由 thread_id 表示。通常,每个 thread_id 都应该使用自己唯一的沙盒。 如果沙盒提供商允许将元数据附加到沙盒,请在您的应用程序中或与沙盒一起存储沙盒 ID 和 thread_id 之间的映射。
聊天应用程序的 TTL。当用户在空闲一段时间后可以重新参与时,您通常不知道他们是否或何时会回来。在沙盒上配置一个生存时间 (TTL) — 例如,归档 TTL 或删除 TTL — 以便提供商自动清理空闲沙盒。许多沙盒提供商都支持此功能。
以下示例展示了使用 Daytona 的获取或创建模式。对于其他提供商,请查阅沙盒提供商 API 以获取等效的标签、元数据和 TTL 选项。
from langchain_core.utils.uuid import uuid7

from daytona import CreateSandboxFromSnapshotParams, Daytona
from deepagents import create_deep_agent
from langchain_daytona import DaytonaSandbox

client = Daytona()
thread_id = str(uuid7())

# Get or create sandbox by thread_id
try:
    sandbox = client.find_one(labels={"thread_id": thread_id})
except Exception:
    params = CreateSandboxFromSnapshotParams(
        labels={"thread_id": thread_id},
        # Add TTL so the sandbox is cleaned up when idle
        auto_delete_interval=3600,
    )
    sandbox = client.create(params)

backend = DaytonaSandbox(sandbox=sandbox)
agent = create_deep_agent(
    model="google_genai:gemini-3.1-pro-preview",
    backend=backend,
    system_prompt="You are a coding assistant with sandbox access. You can create and run code in the sandbox.",
)

try:
    result = agent.invoke(
        {
            "messages": [
                {
                    "role": "user",
                    "content": "Create a hello world Python script and run it",
                }
            ]
        },
        config={
            "configurable": {
                "thread_id": thread_id,
            }
        },
    )
    print(result["messages"][-1].content)
except Exception:
    # Optional: delete the sandbox proactively on an exception
    client.delete(sandbox)
    raise

集成模式

根据智能体运行的位置,存在两种将智能体与沙盒集成的架构模式。

沙盒内智能体模式

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

沙盒作为工具模式

智能体在您的机器或服务器上运行。当它需要执行代码时,它会调用沙盒工具(例如 executeread_filewrite_file),这些工具会调用提供商的 API 以在远程沙盒中运行操作。 优点:
  • ✅ 无需重建镜像即可即时更新智能体代码。
  • ✅ 智能体状态和执行之间更清晰的分离。
    • API 密钥保留在沙盒外部。
    • 沙盒故障不会丢失智能体状态。
    • 可以选择在多个沙盒中并行运行任务。
  • ✅ 只按执行时间付费。
权衡
  • 🔴 每次执行调用都有网络延迟。
示例
from daytona import Daytona
from deepagents import create_deep_agent
from dotenv import load_dotenv
from langchain_daytona import DaytonaSandbox


load_dotenv()

# Can also do this with AgentCore, E2B, Runloop, Modal
sandbox = Daytona().create()
backend = DaytonaSandbox(sandbox=sandbox)

agent = create_deep_agent(
    model="google_genai:gemini-3.1-pro-preview",
    backend=backend,
    system_prompt="You are a coding assistant with sandbox access. You can create and run code in the sandbox.",
)

try:
    result = agent.invoke(
        {
            "messages": [
                {
                    "role": "user",
                    "content": "Create a hello world Python script and run it",
                }
            ]
        }
    )
    print(result["messages"][-1].content)
except Exception:
    # Optional: delete the sandbox proactively on an exception
    sandbox.stop()
    raise
本文档中的示例使用沙盒作为工具模式。当您的提供商 SDK 处理通信层并且您希望生产环境与本地开发保持一致时,请选择沙盒内智能体模式。当您需要快速迭代智能体逻辑、将 API 密钥保留在沙盒外部或更喜欢更清晰的职责分离时,请选择沙盒作为工具模式。

沙盒工作原理

隔离边界

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

execute 方法

沙盒后端具有简单的架构:提供商必须实现的唯一方法是 execute(),它运行 shell 命令并返回其输出。所有其他文件系统操作(readwriteeditlsglobgrep)都是由BaseSandbox基类在 execute() 之上构建的,该基类通过 execute() 在沙盒内部构建并运行脚本。 这种设计意味着
  • 添加新的提供商很简单。实现 execute() — 基类处理所有其他事情。
  • execute 工具是条件可用的。在每次模型调用时,调度器会检查后端是否实现了SandboxBackendProtocol。如果没有,该工具将被过滤掉,智能体将永远不会看到它。
当智能体调用 execute 工具时,它会提供一个 command 字符串,并返回组合的 stdout/stderr、退出代码,以及在输出过大时的一个截断通知。 您也可以直接在应用程序代码中调用后端 execute() 方法。
pip install langchain-daytona
from daytona import Daytona

from langchain_daytona import DaytonaSandbox

sandbox = Daytona().create()
backend = DaytonaSandbox(sandbox=sandbox)

result = backend.execute("python --version")
print(result.output)
例如:
4
[Command succeeded with exit code 0]
bash: foobar: command not found
[Command failed with exit code 127]
如果命令产生非常大的输出,结果会自动保存到文件中,并且智能体被指示使用 read_file 逐步访问它。这可以防止上下文窗口溢出。

两种文件访问方式

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

处理文件

deepagents 沙盒后端支持文件传输 API,用于在您的应用程序和沙盒之间移动文件。

初始化沙盒

在智能体运行之前,使用 upload_files() 来填充沙盒。路径必须是绝对路径,并且内容是 bytes
pip install langchain-daytona
from daytona import Daytona

from langchain_daytona import DaytonaSandbox

sandbox = Daytona().create()
backend = DaytonaSandbox(sandbox=sandbox)

backend.upload_files(
    [
        ("/src/index.py", b"print('Hello')\n"),
        ("/pyproject.toml", b"[project]\nname = 'my-app'\n"),
    ]
)

检索工件

在智能体完成后,使用 download_files() 从沙盒中检索文件。
pip install langchain-daytona
from daytona import Daytona

from langchain_daytona import DaytonaSandbox

sandbox = Daytona().create()
backend = DaytonaSandbox(sandbox=sandbox)

results = backend.download_files(["/src/index.py", "/output.txt"])
for result in results:
    if result.content is not None:
        print(f"{result.path}: {result.content.decode()}")
    else:
        print(f"Failed to download {result.path}: {result.error}")
在沙盒内部,智能体使用文件系统工具(read_filewrite_file)。upload_filesdownload_files 方法用于您的应用程序代码在主机和沙盒之间移动文件。

安全注意事项

沙盒将代码执行与您的主机系统隔离,但它们不能防止上下文注入。控制智能体部分输入的攻击者可以指示它从沙盒内部读取文件、运行命令或窃取数据。这使得沙盒内部的凭据特别危险。
切勿将密钥放入沙盒。通过上下文注入的智能体可以读取和窃取注入沙盒的 API 密钥、令牌、数据库凭据和其他秘密(通过环境变量、挂载文件或 secrets 选项)。即使是短期或作用域受限的凭据也适用此规则——如果智能体可以访问它们,攻击者也可以。

安全处理密钥

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

一般最佳实践

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

© . This site is unofficial and not affiliated with LangChain, Inc.