OpenAI Agents SDK 沙箱如何挂载 S3 等远程存储
【免费下载链接】openai-agents-pythonA lightweight, powerful framework for multi-agent workflows项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-python
如果你的 Sandbox Agent 需要读写存放在 S3、GCS、R2 等对象存储里的数据,而不是每次都在本地临时文件里折腾,OpenAI Agents SDK 的沙箱支持把这些远程存储挂载到沙箱工作区内:Agent 用普通的文件工具和 shell 命令访问挂载目录,数据实际留在远程桶里。本文以 Docker 沙箱后端挂载 S3 桶为主线,给出仓库中现成的可运行示例、验证方式,以及 S3 承载跨沙箱记忆的可选玩法。沙箱(Sandbox agents)目前是 beta 功能,API、默认值和支持能力在 GA 前可能变化。
先理解两个概念:Mount 条目与挂载策略
SDK 把挂载拆成两层(见 docs/sandbox/clients.md 的 "Mounts and remote storage" 一节):
- Mount 条目(如
S3Mount、GCSMount、R2Mount、AzureBlobMount、BoxMount、S3FilesMount)描述"暴露什么存储",作为Manifest的 entries 写入; - 挂载策略(如
DockerVolumeMountStrategy、InContainerMountStrategy)描述"沙箱后端如何把存储挂上",必须同时匹配条目类型和沙箱后端。
写在条目上的通用选项:
mount_path:存储出现在沙箱里的位置。Manifest 条目路径是 workspace 相对路径时,在 manifest root 下解析;绝对路径原样使用。read_only:默认True。只有当沙箱需要把写回落到远程存储时才设False。mount_strategy:必填,选一个与条目和后端都匹配的策略。
一个重要的行为边界:挂载被视为 ephemeral workspace 条目。快照(snapshot)和persist_workspace()流程会跳过或断开挂载路径,而不是把远程存储复制进保存的工作区——也就是说数据本来就留在 S3 里,这正是挂载的意义。
准备条件
按 docs/sandbox_agents.md 的快速开始部分:
pip install "openai-agents[docker]"前置条件:
- Python 3.10 或更高;
- 宿主机运行 Docker(示例用
docker.from_env()连接 Docker daemon); - 一个可运行的模型。示例默认模型为
gpt-5.6-sol,可通过环境变量OPENAI_MODEL覆盖。
S3 侧需要的环境变量(取自 examples/sandbox/memory_s3.py 与 examples/sandbox/docker/mounts/s3_mount_read_write.py)。下面示例值均为占位,请替换为你自己的桶名与凭据:
export S3_MOUNT_BUCKET="my-bucket" # 桶名,必填(memory_s3.py 也认 S3_BUCKET) export AWS_ACCESS_KEY_ID="..." # 你的 S3 Access Key export AWS_SECRET_ACCESS_KEY="..." # 你的 S3 Secret Key # 可选: export AWS_SESSION_TOKEN="..." # 临时凭据时的会话 token export AWS_REGION="us-east-1" # 或 AWS_DEFAULT_REGION export S3_ENDPOINT_URL="..." # 仅 S3 兼容端点(非 AWS 官方 S3)时需要 export S3_MOUNT_PREFIX="some/prefix/" # 仅挂载桶内某个前缀时需要两个运行前提需要注意:
- 镜像:示例脚本
ensure_mount_image()会检查本地是否存在agents-sandbox-docker-mount-example:latest,缺失时基于 examples/sandbox/docker/Dockerfile.mount 构建。该镜像在 ubuntu:22.04 上安装 fuse3、固定版本 rclone(1.74.4)、mount-s3、blobfuse2 和 mount.s3files,覆盖容器内各挂载工具的路径。 - rclone 卷驱动:走
DockerVolumeMountStrategy(driver="rclone")时,Docker 在容器启动前通过名为rclone的卷插件挂卷,因此宿主机必须已安装 rclone Docker 卷插件。缺失时创建会话会抛出plugin "rclone" not found,冒烟示例会直接退出并提示 "rclone Docker volume plugin not found"。
主路径:在 Docker 沙箱里挂载 S3 桶
核心代码就三件事:用S3Mount声明挂载、给DockerSandboxClient指定镜像、用Runner跑起来。S3Mount的字段(见 src/agents/sandbox/entries/mounts/providers/s3.py):
| 字段 | 说明 |
|---|---|
bucket | 必填,桶名 |
prefix | 只挂载桶内某个前缀 |
region | 区域;access_key_id/secret_access_key/session_token为内联凭据 |
endpoint_url | S3 兼容服务的端点地址 |
s3_provider | 默认"AWS" |
最小可用写法(与仓库示例同构):
from agents import Runner from agents.run import RunConfig from agents.sandbox import Manifest, SandboxRunConfig from agents.sandbox.capabilities import Filesystem, Shell from agents.sandbox.entries import DockerVolumeMountStrategy, S3Mount from agents.sandbox.sandboxes.docker import ( DockerSandboxClient, DockerSandboxClientOptions, ) manifest = Manifest( entries={ # 条目键即挂载路径(workspace 相对) "data": S3Mount( bucket="my-bucket", # 读者自己的桶名 access_key_id="...", secret_access_key="...", region="us-east-1", prefix="some/prefix/", mount_strategy=DockerVolumeMountStrategy(driver="rclone"), read_only=False, # 需要 Agent 写回远程桶时设为 False ), } ) client = DockerSandboxClient(docker_from_env()) # docker 库的 from_env() sandbox = await client.create( manifest=manifest, options=DockerSandboxClientOptions(image="agents-sandbox-docker-mount-example:latest"), ) async with sandbox: result = await Runner.run( agent, # 你的 SandboxAgent "检查 data/ 目录并列出内容。", run_config=RunConfig(sandbox=SandboxRunConfig(session=sandbox)), ) print(result.final_output) await client.delete(sandbox)仓库里有一个完整可跑的示例 examples/sandbox/docker/mounts/s3_mount_read_write.py,它使用上面同样的S3Mount+DockerVolumeMountStrategy(driver="rclone")+read_only=False组合,挂载目录为s3-docker-volume-rclone。设置好环境变量后直接运行:
python examples/sandbox/docker/mounts/s3_mount_read_write.py验证挂载是否真的可用
验证逻辑在公共支撑模块 examples/sandbox/docker/mounts/mount_smoke.py 中,流程是:
- 构建一个 shell-only 的
SandboxAgent,要求它把一段指定内容用printf %s写到挂载目录下的文件里,再用cat读回; - 宿主机侧通过
sandbox.read(path)直接读该文件,断言读回内容与写入内容完全一致; - 全部通过则打印验证结果。
运行成功时终端输出(由代码逻辑决定):
done docker_volume/rclone: ok其中done是 Agent 按指令回复的内容,docker_volume/rclone: ok表示"Agent 写入 → 宿主机读回 → 内容一致"这一读写闭环校验通过。
失败时的两个明确信号:
- 创建会话阶段报
plugin "rclone" not found:宿主机缺 rclone Docker 卷插件(见"准备条件"); - 容器内挂载路径在
sandbox.start()阶段抛MountCommandError,示例会把exc.context里的command与stderr打印出来,方便定位容器内挂载命令的失败原因。
可选分支:用 S3 承载跨沙箱的记忆
如果你的目标是"多个全新沙箱之间共享 Agent 记忆",仓库提供了 examples/sandbox/memory_s3.py:把Memorycapability 的 layout 指到 S3 挂载目录里,让记忆产物直接落在远程存储。
它的做法(默认挂载目录为persistent):
Memory( layout=MemoryLayoutConfig( memories_dir="persistent/memories", sessions_dir="persistent/sessions", ), generate=MemoryGenerateConfig(extra_prompt=MEMORY_EXTRA_PROMPT), )示例流程是跑两个全新的 Docker 沙箱:第一个沙箱修一个 bug,会话关闭时记忆生成把memory_summary.md等产物写进 S3 挂载目录;第二个沙箱挂载同一个桶前缀后,先断言persistent/memories/memory_summary.md非空(证明 S3 里的记忆真的被新沙箱读到了),再基于记忆执行后续任务。最后脚本打印 S3 里各记忆产物(persistent/sessions、MEMORY.md、memory_summary.md、raw_memories、rollout_summaries)的树状清单,并输出S3 prefix: {prefix}。
运行方式(S3_BUCKET与 S3 凭据环境变量同上):
python examples/sandbox/memory_s3.py --model gpt-5.6-sol --prefix my-persistent-prefix--prefix不传时默认生成sandbox-memory-example/<uuid>形式的唯一前缀。关于 Memory 机制本身(读/生成的默认行为、layout 隔离等)见 docs/sandbox/memory.md。注意按该文档说明,全新空沙箱的记忆是空的——跨沙箱复用记忆的前提正是把memories/目录放在可持久化的地方(这里是 S3 挂载)。
其他远程存储与后端支持
"等远程存储"的支持矩阵以 docs/sandbox/clients.md 的表格为准。各后端可直接挂载的远程存储类型:
| 后端 | AWS S3 | Cloudflare R2 | GCS | Azure Blob Storage | Box | S3 Files |
|---|---|---|---|---|---|---|
| Docker | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
ModalSandboxClient | ✓ | ✓ | ✓ | - | - | - |
CloudflareSandboxClient | ✓ | ✓ | ✓ | - | - | - |
BlaxelSandboxClient | ✓ | ✓ | ✓ | - | - | - |
DaytonaSandboxClient | ✓ | ✓ | ✓ | ✓ | ✓ | - |
E2BSandboxClient | ✓ | ✓ | ✓ | ✓ | ✓ | - |
RunloopSandboxClient | ✓ | ✓ | ✓ | ✓ | ✓ | - |
VercelSandboxClient | ✓(仅创建时挂载) | - | - | - | - | - |
Docker 后端的四类策略(通用,与具体桶类型配合使用):
InContainerMountStrategy(pattern=RcloneMountPattern(...)):镜像内能跑rclone时使用,支持 S3、GCS、R2、Azure Blob、Box,可走fuse或nfs模式;InContainerMountStrategy(pattern=MountpointMountPattern(...)):镜像内有mount-s3,Mountpoint 风格的 S3 / S3 兼容访问,支持S3Mount和GCSMount;InContainerMountStrategy(pattern=FuseMountPattern(...)):镜像内有blobfuse2和 FUSE 支持,支持AzureBlobMount;InContainerMountStrategy(pattern=S3FilesMountPattern(...)):镜像内有mount.s3files且能访问现有 S3 Files 挂载目标;DockerVolumeMountStrategy(driver=...):Docker 专用,容器启动前挂卷驱动;S3、GCS、R2、Azure Blob、Box 可经rclone驱动挂载,S3 和 GCS 还可经mountpoint驱动。
容器内策略要求镜像自带对应 CLI——Dockerfile.mount里安装的 rclone、mount-s3、blobfuse2、mount.s3files 正是为此准备的,agents-sandbox-docker-mount-example:latest这个示例镜像覆盖了上述全部容器内路径。换用 hosted 后端时,SandboxAgent定义基本不变,只改SandboxRunConfig里的 client 和对应的 provider 挂载策略;各 provider 的安装 extras 与示例入口见 examples/sandbox/extensions/。
凭据边界与限制
这部分来自 clients.md 的说明,直接关系到你能不能把内联凭据塞进挂载条目:
- SDK 对"需要受保护权限"的容器内挂载采取拒绝式边界:除非受信应用代码显式确认暴露范围,否则在启动沙箱或挂载助手之前就会拒绝该挂载。确认方式是对 manifest 调用(以挂载条目名为参数):
manifest.with_in_container_mount_credential_exposure_acknowledged("data")——挂载级凭据(如内联 access key);manifest.with_in_container_mount_broad_credential_exposure_acknowledged("data")——更宽的权限来源(托管/工作负载身份、外部凭据文件等)。 两者同时需要时都要调用;确认是运行期语义、不会被序列化。文档建议优先外部/provider 原生策略,否则使用沙箱级、短生命周期、最小权限的凭据。
- 无凭据的
rclone挂载仅支持 S3、GCS、R2、Azure Blob;FuseMountPattern(blobfuse2 会发现环境中的 Azure 凭据)与S3FilesMountPattern(使用环境 IAM 权限)需要宽范围确认。 VercelSandboxClient的 S3 挂载只能在创建时配置,挂载中的会话不能 resume;内联凭据需allow_s3_credential_exposure=True。- 会话状态序列化会移除云挂载凭据和确认标记。对支持恢复挂载会话的后端,恢复时要通过
SandboxRunConfig.manifest或agent.default_manifest提供当前受信的 manifest,且挂载拓扑必须与持久化状态一致,否则恢复在沙箱启动前失败。 - 挂载是 ephemeral 条目:快照、
persist_workspace()都不会把挂载的远程存储复制进工作区;注入的 live 会话也不能通过 manifest 覆盖新增或修改挂载条目。
继续深入
- 客户端选型与挂载策略全表:docs/sandbox/clients.md
- Manifest、capability 与生命周期概念:docs/sandbox/guide.md
- 更多可运行示例:examples/sandbox/(含
unix_local_runner.py、docker/docker_runner.py等入口)
【免费下载链接】openai-agents-pythonA lightweight, powerful framework for multi-agent workflows项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-python
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考