跳转到内容

沙盒客户端

使用本页选择沙盒工作应在何处运行。大多数情况下,SandboxAgent 定义保持不变,只需更改 sandbox 运行选项中的沙盒客户端及其特定选项。

目标建议起点原因
在 macOS 或 Linux 上实现最快的本地迭代UnixLocalSandboxClient无额外服务依赖,并提供简单的本地文件系统工作流。
基础容器隔离DockerSandboxClient使用指定镜像在 Docker 内运行工作。
托管执行或生产环境风格的隔离托管沙盒客户端将工作区边界移至由供应商管理的环境。

对于大多数用户,建议从以下两个沙盒客户端之一开始:

客户端安装要求适用场景
UnixLocalSandboxClient在 macOS 或 Linux 上实现最快的本地迭代。适合作为本地开发的默认选项。
DockerSandboxClient本地可使用 Docker CLI需要容器隔离,或需要通过指定镜像与本地环境保持一致。

Unix-local 是开始针对本地文件系统进行开发的最简单方式。当您需要更强的环境隔离或与生产环境保持一致时,请迁移到 Docker 或托管供应商。

要从 Unix-local 切换到 Docker,请保持智能体定义不变,只更改客户端:

使用 Docker
import { run } from '@openai/agents';
import { SandboxAgent } from '@openai/agents/sandbox';
import { DockerSandboxClient } from '@openai/agents/sandbox/local';
const agent = new SandboxAgent({
name: 'Workspace reviewer',
model: 'gpt-5.6-sol',
instructions: 'Inspect the sandbox workspace before answering.',
});
const result = await run(agent, 'Inspect the workspace.', {
sandbox: {
client: new DockerSandboxClient({ image: 'node:22-bookworm-slim' }),
},
});
console.log(result.finalOutput);

同一个智能体通常可以使用任一本地客户端运行:

在本地客户端之间切换
import {
DockerSandboxClient,
UnixLocalSandboxClient,
} from '@openai/agents/sandbox/local';
const client = process.env.USE_DOCKER
? new DockerSandboxClient({ image: 'node:22-bookworm-slim' })
: new UnixLocalSandboxClient();

除非在客户端构造函数或每次运行的 sandbox.options 中设置 networkMode: 'none',否则 DockerSandboxClient 将使用 Docker 的默认网络。'none' 模式会在禁用网络的情况下启动容器。该模式不能与 exposedPorts 结合使用;SDK 会在创建或恢复容器之前拒绝此配置。目前不支持其他显式 networkMode 值。

会话生命周期有两种管理方式。

方式传入内容关闭会话的一方适用场景
SDK 所有sandbox: { client }运行器沙盒只需在一次运行期间存续。
开发者所有sandbox: { session }您的代码需要在运行后检查文件、复用同一个活动会话,或协调多次运行。

正常完成或失败时,运行器会关闭 SDK 所有的会话。当运行因审批中断而暂停,或未完成的流式运行被取消时,运行器会改为将其拥有的沙盒状态保留在 RunState 中,以便继续同一次运行。

自行创建会话时,也应自行关闭:

管理沙盒会话生命周期
import { run } from '@openai/agents';
import { Manifest, SandboxAgent } from '@openai/agents/sandbox';
import { UnixLocalSandboxClient } from '@openai/agents/sandbox/local';
const manifest = new Manifest();
const agent = new SandboxAgent({
name: 'Workspace reviewer',
model: 'gpt-5.6-sol',
instructions: 'Inspect the sandbox workspace before answering.',
});
const client = new UnixLocalSandboxClient();
const session = await client.create({ manifest });
try {
await run(agent, 'First pass.', { sandbox: { session } });
await run(agent, 'Follow-up pass.', { sandbox: { session } });
} finally {
await session.close?.();
}

沙盒状态和对话状态彼此独立:

  • SDK 对话状态存储在 result.history、SDK SessionconversationIdpreviousResponseId 中。
  • 沙盒状态存储在活动沙盒会话、序列化的 sessionStateRunState 沙盒载荷或快照中。

如果希望通过沙盒客户端重新连接到同一个后端会话,请使用 sessionState。如果希望创建一个以已保存工作区内容为初始状态的新会话,请使用快照。

序列化并恢复沙盒状态
import { Manifest } from '@openai/agents/sandbox';
import { UnixLocalSandboxClient } from '@openai/agents/sandbox/local';
const manifest = new Manifest();
const client = new UnixLocalSandboxClient({
snapshot: { type: 'local', baseDir: '/tmp/my-sandbox-snapshots' },
});
const session = await client.create({ manifest });
const state = await client.serializeSessionState?.(session.state);
await session.close?.();
if (state) {
const restored = await client.resume?.(
await client.deserializeSessionState!(state),
);
await restored?.close?.();
}

暂停或恢复更大的工作流时,RunState 也可以保留由运行器管理的沙盒状态。如果沙盒生命周期在序列化运行之外管理,请使用显式 sessionState

对于 Docker,仅当 SDK 验证活动容器的身份,并重新验证当前清单、环境和路径授权后,恢复同一个内存中的 RunState 才能复用该容器。如果无法复用活动容器或复用请求被拒绝,Docker 会回退到可恢复的快照。通过 RunState.fromString(...) 序列化并重建的 RunState 不携带受信任的活动容器权限,因此 Docker 也会从快照恢复,而不会连接到已序列化的容器 ID。如果未配置可恢复的快照,恢复将失败,而不会连接到未经验证的容器。

对于未显式设置 baseDir 的本地快照,请设置 OPENAI_AGENTS_SANDBOX_SNAPSHOT_DIR 以覆盖存储目录。否则,SDK 在 macOS 上使用 ~/Library/Application Support/openai-agents-js/sandbox-snapshots,在 Windows 上使用 %LOCALAPPDATA%\openai-agents-js\sandbox-snapshots,在其他平台上使用 $XDG_STATE_HOME/openai-agents-js/sandbox-snapshots;如果这些位置不可用,则回退到主目录或临时目录。

清单条目会在智能体运行前准备就绪。您可以为每次运行或每次客户端创建调用调整物化并发数:

调整清单物化并发数
import { run } from '@openai/agents';
import { SandboxAgent } from '@openai/agents/sandbox';
import { UnixLocalSandboxClient } from '@openai/agents/sandbox/local';
const agent = new SandboxAgent({
name: 'Repository inspector',
model: 'gpt-5.6-sol',
instructions: 'Inspect the repository before answering.',
});
await run(agent, 'Inspect the repo.', {
sandbox: {
client: new UnixLocalSandboxClient(),
concurrencyLimits: {
manifestEntries: 4,
localDirFiles: 16,
},
},
});

manifestEntries 限制并行处理的顶层条目数量。localDirFiles 限制 localDir() 条目内的文件复制并发数。

当会话实现 pathExists() 时,false 表示后端已确认该路径不存在。权限错误、I/O 故障和供应商探测失败会以供应商错误的形式拒绝,而不会被视为路径不存在。这样可以防止编辑器、清单和记忆流程覆盖或替换可能存在但无法访问的路径。

挂载条目描述要暴露哪些存储,挂载策略则描述沙盒后端如何连接这些存储。请从 @openai/agents/sandbox 导入内置挂载条目和通用策略。

常用挂载选项:

  • mountPath:存储在沙盒中出现的位置。相对路径基于清单根目录解析;绝对路径按原样使用。
  • readOnly:当沙盒不应向挂载的存储写回数据时设置此选项。
  • mountStrategy:使用同时匹配挂载条目和沙盒后端的策略。

挂载会被视为临时工作区条目。快照和持久化流程会分离或跳过已挂载路径,而不会将挂载的远程存储复制到已保存的工作区中。

通用本地/容器策略:

策略或模式适用场景说明
inContainerMountStrategy(...)沙盒镜像可以运行 rclonemount-s3blobfuse2 等挂载命令。可作为通用策略使用;是否支持取决于后端。
dockerVolumeMountStrategy(...)Docker 应在容器启动前连接由卷驱动支持的挂载。仅限 Docker。
localBindMountStrategy()本地后端应将绝对本地路径绑定到工作区中。在允许的情况下,受本地工作区物化机制支持。

后端支持范围有明确限制:

后端挂载说明
UnixLocalSandboxClient通过本地工作区模型支持本地绑定式挂载。
DockerSandboxClient支持本地绑定挂载,以及 Docker 可以连接存储时的 Docker 卷式策略。
托管供应商供应商特定策略由各供应商实现提供。请查阅该供应商的文档,了解支持的挂载及所需设置。

不要假设某个挂载条目适用于所有后端。如果客户端无法强制执行清单元数据、身份或挂载行为,应尽早失败,而不是静默忽略清单的相关部分。

需要托管环境时,通常可以沿用同一个 SandboxAgent 定义,只需更改 sandbox 运行选项中的沙盒客户端。

托管供应商实现可从 @openai/agents-extensions 的供应商子路径导入。请查阅供应商文档,了解确切的环境变量、可运行代码示例、端口行为、PTY 支持、快照行为和清理行为。

安装 @openai/agents-extensions 并满足其包级对等依赖。每个供应商可能还要求安装供应商 SDK 包或完成后端设置:

客户端导入路径供应商要求
BlaxelSandboxClient@openai/agents-extensions/sandbox/blaxelnpm 对等依赖:@blaxel/core
CloudflareSandboxClient@openai/agents-extensions/sandbox/cloudflareCloudflare Sandbox 桥接 Worker URL 和 Worker 身份验证
DaytonaSandboxClient@openai/agents-extensions/sandbox/daytonanpm 对等依赖:@daytonaio/sdk
E2BSandboxClient@openai/agents-extensions/sandbox/e2bnpm 对等依赖:e2b@e2b/code-interpreter
ModalSandboxClient@openai/agents-extensions/sandbox/modalnpm 对等依赖:modal
RunloopSandboxClient@openai/agents-extensions/sandbox/runloopnpm 对等依赖:@runloop/api-client
VercelSandboxClient@openai/agents-extensions/sandbox/vercelnpm 对等依赖:@vercel/sandbox

ModalSandboxClient 创建沙盒时,使用 cpumemoryMiB 请求 CPU 和内存预留。使用 cpuLimitmemoryLimitMiB 设置上限。您可以在客户端构造函数或每次运行的 sandbox.options 中设置这些选项;每次运行的值会覆盖构造函数的默认值。每个值都必须是有限的正数。cpuLimit 要求同时设置 cpu,且不能小于它;memoryLimitMiB 要求同时设置 memoryMiB,且不能小于它。

CloudflareSandboxClient 不会导入 Cloudflare npm SDK,而是通过 HTTP 与已部署的 Cloudflare Sandbox 桥接 Worker 通信。

VercelSandboxClient 按以下优先级解析各个 PAT 凭据字段:每次创建的选项、构造函数选项,然后是 VERCEL_PROJECT_IDVERCEL_TEAM_IDVERCEL_TOKEN。只有当最终得到的 projectIdteamIdtoken 均非空时,才会转发凭据。否则,它会省略全部三个字段,并让 @vercel/sandbox 解析身份验证,包括平台 OIDC 或本地供应商凭据。会话序列化和恢复时,会保留完整的已解析凭据。序列化凭据会被视为一个完整的三字段组合,不会与当前选项或环境变量混合;不完整的序列化凭据会被丢弃,随后回退到解析当前配置。由于令牌仍存在于序列化会话状态中,请安全存储该状态。

托管沙盒客户端会暴露供应商特定的挂载策略。请选择最适合您存储供应商的后端和挂载策略:

默认情况下,系统会拒绝在沙盒内部运行辅助程序的凭据挂载,因为模型控制的代码可以访问该辅助程序的进程凭据。这包括通过受支持挂载字段提供的凭据、环境中的 AWS 或 GCP 环境变量、RCLONE_CONFIG_* 值,以及工作负载身份或托管身份发现。无凭据的 rclone 和 mountpoint 辅助程序会禁用环境或元数据身份验证,并在后端支持时使用匿名访问。建议优先使用外部或供应商原生策略,例如 Docker 卷、Modal 云存储桶或 Cloudflare 存储桶挂载。

如果必须使用沙盒内辅助程序,请在应用程序创建的清单中确认每个受信任的有效挂载路径。对于通过类型化挂载字段直接提供的挂载范围凭据,请使用 manifest.withInContainerMountCredentialExposureAcknowledged('mounted/path') 返回的清单。对于环境凭据、工作负载身份或托管身份,以及外部凭据或配置文件,请使用 manifest.withInContainerMountBroadCredentialExposureAcknowledged('mounted/path') 返回的清单。同时使用这两类权限的挂载需要两种确认。这些精确路径确认仅在运行时有效,绝不接受来自清单初始化对象或序列化清单数据的确认。它们允许所选辅助程序接收凭据,但不会将这些凭据限制在挂载路径内,因此同一沙盒中其他由模型控制的代码仍可能获取这些凭据。请使用沙盒范围内、短期有效且遵循最小权限原则的凭据。

挂载引用的凭据文件不能直接或通过符号链接解析到可序列化的清单条目。动态清单变更会按会话进行序列化;如果特权挂载转换或替换过程中的卸载操作在供应商侧影响可能已开始后失败,SDK 将使该会话失效并终止它,而不会复用或持久化状态不明确的会话。

序列化沙盒状态会省略挂载凭据,包括沙盒内挂载辅助程序选用的环境凭据。任何持久化的挂载拓扑都要求在恢复前提供当前受信任的清单。对于可恢复的外部或供应商原生挂载,只有在不含凭据的当前挂载拓扑与持久化挂载拓扑匹配后,SDK 才会恢复凭据。仅当未脱敏的活动权限仍与当前受信任清单匹配时,显式 sessionState 才能重新连接现有的供应商原生挂载;如果权限已脱敏、轮换或移除,则需要创建新沙盒。无法将无凭据拓扑分离出来的不透明配置无法恢复。当 Runner 恢复使用了沙盒内挂载辅助程序的序列化 RunState 条目时,它会丢弃已存储的会话,并使用当前受信任配置创建新沙盒。调用方提供的显式 sessionState 和直接供应商恢复操作则会拒绝容器内挂载状态;请显式启动新沙盒。对于容器内挂载,系统会拒绝通过不透明 secretRefs 提供的 Runloop 凭据文件变量;请通过 managedSecrets 提供当前受信任路径,以便 SDK 在挂载前验证其有效路径。

后端挂载说明
Docker支持结合 inContainerMountStrategy()dockerVolumeMountStrategy() 等本地策略使用 s3Mount()gcsMount()r2Mount()azureBlobMount()boxMount()s3FilesMount()
ModalSandboxClient支持通过 ModalCloudBucketMountStrategy 挂载 S3、R2 和使用 HMAC 身份验证的 GCS 挂载条目。
CloudflareSandboxClient支持通过 CloudflareBucketMountStrategy 挂载 S3、R2 和使用 HMAC 身份验证的 GCS 挂载条目。
BlaxelSandboxClient支持通过 BlaxelCloudBucketMountStrategy 挂载 S3、R2 和 GCS 挂载条目。包含凭据的云挂载要求使用 SDK 所有的沙盒;复用的非自有命名沙盒可以使用无凭据云挂载,或结合 BlaxelDriveMountBlaxelDriveMountStrategy 使用持久化 Blaxel Drive。
DaytonaSandboxClient支持通过 DaytonaCloudBucketMountStrategy 挂载基于 rclone 的 S3、GCS、R2、Azure Blob 和 Box 挂载条目。
E2BSandboxClient支持通过 E2BCloudBucketMountStrategy 挂载基于 rclone 的 S3、GCS、R2、Azure Blob 和 Box 挂载条目。
RunloopSandboxClient支持通过 RunloopCloudBucketMountStrategy 挂载基于 rclone 的 S3、GCS、R2、Azure Blob 和 Box 挂载条目。
VercelSandboxClient支持通过 VercelCloudBucketMountStrategy 在创建时挂载 S3。对于新代码,请针对每个精确挂载路径使用 withInContainerMountCredentialExposureAcknowledged() 确认内联凭据。已弃用的 allowS3CredentialExposure: true 选项仍可用于兼容已发布的内联 S3 凭据配置,但它不会授权环境凭据或其他广泛权限。请复用已挂载的活动会话,因为序列化挂载状态无法直接恢复。

对于 E2B 和 Runloop 基于 rclone 的挂载,SDK 会优先使用现有的 rclone 二进制文件。如果不存在,则仅在验证 SHA-256 校验和后安装由 SDK 固定版本的 Linux 归档文件;不受支持的架构和校验和验证失败都会中止挂载。

下表汇总了各后端可以直接挂载的远程存储条目:

后端AWS S3Cloudflare R2GCSAzure Blob StorageBoxS3 Files
Docker
ModalSandboxClient
CloudflareSandboxClient
BlaxelSandboxClient
DaytonaSandboxClient
E2BSandboxClient
RunloopSandboxClient
VercelSandboxClient

“是”表示后端可以执行该类型的存储挂载,但不会绕过上述凭据边界。Docker 的 dockerVolumeMountStrategy()、Modal 云存储桶挂载和 Cloudflare 存储桶挂载会将挂载凭据保留在模型控制的沙盒之外。Docker 的 inContainerMountStrategy() 以及 Daytona、E2B 和 Runloop 的 rclone 策略在接收凭据时,需要针对精确路径进行确认。Box 挂载要求身份验证,因此应根据 Box 权限是通过类型化挂载字段提供,还是通过外部凭据或配置文件提供,选择相应的确认方式。Docker S3 Files 挂载使用广泛的工作负载身份,因此需要调用 withInContainerMountBroadCredentialExposureAcknowledged()

当后端支持时,沙盒客户端可以通过 resolveExposedPort(port) 暴露端点。

客户端行为
UnixLocalSandboxClient将已配置的端口解析到 127.0.0.1
DockerSandboxClient发布已配置的容器端口,并解析其主机端点。

当需要后端强制执行允许列表时,请在客户端选项中声明端口:

暴露端口
import { DockerSandboxClient } from '@openai/agents/sandbox/local';
const client = new DockerSandboxClient({
image: 'node:22-bookworm-slim',
exposedPorts: [3000],
});
功能Unix-localDocker
exec_command支持支持
PTY write_stdin支持支持
apply_patch支持通过工作区文件 API 支持
view_image支持通过工作区文件 API 支持
命令的 runAs当主机可以解析并切换到指定用户时支持受容器/用户设置限制
本地快照支持支持
本地/Docker 挂载支持本地绑定式挂载支持绑定式和 Docker 卷式挂载

本地 PTY 支持通过 SDK 进程中的一个小型 Python 3 桥接程序实现。该桥接程序仅用于 tty: true 会话,因为 Node.js 未提供内置 PTY API,而 SDK 需要标准 POSIX PTY 行为来处理交互式标准输入、信号和退出状态报告。请在运行 SDK 代码的环境中安装 python3,或将 OPENAI_AGENTS_PYTHON 设置为 Python 3 可执行文件。这与 Docker 沙盒镜像内安装的 Python 版本(如果有)无关。

托管供应商支持的功能因供应商而异。请查阅供应商特定文档,了解确切的选项、环境变量、端口行为、PTY 支持、快照行为和清理行为。