Tracks
OpenAI 较新的 Agents 沙盒工作流改变了代理执行的结构。框架不再把代理、文件、工具和运行时都塞进一个混乱的循环中,而是将可信的编排层与执行环境分离开来。
这意味着,您的应用可以负责代理逻辑、模型调用和决策,而实际工作发生在一个具备文件、命令和生成输出访问能力的沙盒化工作区内。
当您的代理需要做的不仅是基于提示上下文进行回答时,这种设置尤其有用。例如,它可以在受控环境中检查项目、编写或修改文件、运行代码、测试输出,并生成工件。
在本指南中,我们将学习如何把 OpenAI Agents 框架与 Modal Sandboxes 结合起来,构建一个实用的代理式应用。该代理能够在隔离的 Modal 环境中运行,安全地执行命令,处理文件,并将有用的输出返回给主应用。
若想先了解不使用沙盒的入门内容,推荐阅读我们的 OpenAI Agents SDK 教程。
OpenAI Agents SDK 有哪些新变化?
更新版的 OpenAI Agents SDK 提供了更清晰的方式来构建可与真实文件、工具和执行环境协作的代理。SDK 不再把一切都塞进同一个提示循环中,而是将代理编排层与实际工作的沙盒分离开来。
关键更新包括:
- 原生沙盒支持,可在隔离环境中运行代理
- Manifest,用于定义代理可访问的文件、文件夹和输出
- SandboxAgent,将代理连接到沙盒化的工作区
- SandboxRunConfig,控制沙盒运行的位置与方式
- 类 Codex 的工具,用于文件编辑、Shell 命令和项目检查
- MCP 支持,使代理能够连接外部工具与服务
- Skills 与 AGENTS.md 支持,为代理提供更清晰的项目指令
- 支持多个沙盒提供商,包括 Modal、E2B、Cloudflare、Daytona、Blaxel、Runloop 和 Vercel
这些更新结合在一起,使构建能够检查项目、运行代码、编辑文件,并从受控工作区返回生成输出的代理式应用变得更容易。
1. 项目搭建
在这个演示项目中,我们将使用 OpenAI Agents SDK 和 Modal Sandboxes 构建一个简单的工单分诊示例。应用会创建一个沙盒化工作区,向其中添加一些项目文件,然后让一个 GPT-5.4-mini 代理在回答前检查这些文件。
首先在您的环境中安装所需的包:
pip install "openai-agents[modal]" modal
在运行项目之前,您需要两个账号:
- OpenAI 账号:在 OpenAI Platform 创建账号,并用信用卡充值 API 额度。请确保您的账号已通过验证,以访问最新受支持的模型。
- Modal 账号:注册 Modal。免费套餐包含的月度额度足以完成本指南的测试。
接下来,将您的 OpenAI API 密钥添加到本地环境中。
- 在 macOS 或 Linux 上:
export OPENAI_API_KEY="your_openai_api_key" - 在 Windows PowerShell 上:
$env:OPENAI_API_KEY="your_openai_api_key"
然后在本地验证 Modal:
modal setup
这会打开浏览器并要求您登录 Modal。登录后,批准令牌生成请求。Modal 会自动将凭据添加到您的本地环境。
一切就绪后,您应在终端中看到成功消息,确认 Modal 认证完成。

2. 定义沙盒工作区
接下来,创建一个 Python 文件,例如 main.py,并加入所需的导入。这些导入会引入 OpenAI Agents SDK、沙盒配置类,以及 Modal 沙盒客户端。
import asyncio
from agents import ModelSettings, Runner
from agents.run import RunConfig
from agents.sandbox import Manifest, SandboxAgent, SandboxRunConfig
from agents.sandbox.entries import File
from agents.extensions.sandbox import ModalSandboxClient, ModalSandboxClientOptions
现在我们需要定义沙盒工作区。在本例中,工作区包含一个小型的工单分诊项目,带有 README.md、一个应用文件和一份发布核对清单。
manifest = Manifest(
entries={
"README.md": File(
content=(
b"# Support Ticket Triage\n\n"
b"Small service that labels customer tickets by urgency and team.\n"
)
),
"src/app.py": File(
content=(
b"def route_ticket(subject: str, customer_tier: str) -> dict:\n"
b" urgent = customer_tier == \"enterprise\" or \"outage\" in subject.lower()\n"
b" return {\n"
b" \"priority\": \"high\" if urgent else \"normal\",\n"
b" \"team\": \"support-ops\" if urgent else \"customer-care\",\n"
b" }\n"
)
),
"docs/release-checks.md": File(
content=(
b"# Release Checks\n\n"
b"- Confirm routing rules match the current support escalation policy.\n"
)
),
}
)
Manifest 告诉代理沙盒内有哪些文件。这样代理就能针对真实的项目结构进行检查、编辑和推理,而不必仅依赖提示中的文本。
在这里,代理将能够审查工单分流逻辑、检查文档,并在沙盒化工作区内进行修改。
3. 创建沙盒代理
定义好工作区后,创建基于沙盒的代理。SandboxAgent 专为与真实工作区协作而设计,这意味着它可以检查文件、理解项目结构,并基于沙盒内的实际内容作出回应。
agent = SandboxAgent(
name="Modal Sandbox Assistant",
model="gpt-5.4-mini",
instructions=(
"You are a coding assistant reviewing a small production service. "
"Inspect the sandbox workspace before answering. "
"Keep the answer short and practical."
),
default_manifest=manifest,
model_settings=ModelSettings(tool_choice="required"),
)
这里我们将代理命名为 Modal Sandbox Assistant,并使用 gpt-5.4-mini 模型以获得更快的响应。指令要求代理在回答前检查沙盒工作区,这在回答依赖于项目实际文件时至关重要。
default_manifest=manifest 将代理连接到我们先前创建的工作区。tool_choice="required" 设置鼓励代理使用可用的沙盒工具,而不是仅凭记忆或提示上下文作答。
4. 创建 Modal 沙盒客户端
接下来,创建 Modal 沙盒客户端。它负责连接 OpenAI Agents 的工作流与 Modal 沙盒,实际的文件与命令执行将在其中进行。
client = ModalSandboxClient()
options = ModalSandboxClientOptions(
app_name="openai-agents-modal-demo",
workspace_persistence="tar",
)
ModalSandboxClient() 指定使用 Modal 作为沙盒提供商。也就是说,代理会在隔离的 Modal 环境中运行,而不是直接在您的本地机器上运行。
ModalSandboxClientOptions 控制 Modal 沙盒的配置方式。此处,app_name 为 Modal 应用指定一个清晰的名称,而 workspace_persistence="tar" 指示 Modal 在运行期间如何打包和持久化工作区文件。
5. 启动沙盒会话
当客户端和选项都准备好后,根据 manifest 创建沙盒并启动会话。
sandbox = await client.create(
manifest=manifest,
options=options,
)
await sandbox.start()
client.create() 会使用我们在 Manifest 中定义的文件创建一个新的 Modal 沙盒。这意味着沙盒会带着相同的项目结构启动,包括 README.md、src/app.py 和 docs/release-checks.md。
然后,await sandbox.start() 会启动沙盒会话。此时,您已经在 Modal 上拥有一个在线的隔离工作区,可供代理检查文件、运行命令并处理项目。
6. 在沙盒中运行代理
沙盒激活后,通过 SandboxRunConfig 传入在线沙盒会话来运行代理。这会告诉 OpenAI Agents SDK,代理在运行期间应使用 Modal 的沙盒工作区。
result = await Runner.run(
agent,
(
"Explain what this service does and name one production check "
"before release. Keep it under 3 sentences."
),
run_config=RunConfig(
sandbox=SandboxRunConfig(session=sandbox),
workflow_name="Modal sandbox example",
),
)
print(result.final_output)
这一步将各个部分串联起来。模型负责推理,而沙盒为其提供访问真实工作区文件的能力。
在此示例中,代理可以检查工单分诊项目,理解服务的功能,查看发布说明,并基于 Modal 沙盒内的文件返回简短答案。
7. 清理沙盒
代理运行完成后,请删除沙盒,避免在 Modal 中留下未使用的会话。
await client.aclose(sandbox)
这会在工作完成后移除沙盒会话。养成这个习惯很好,因为沙盒会话在活动期间会占用算力资源。
在真实项目中,您应将其放入 finally 块中。这样即使代理调用失败或脚本出错,清理也会照常执行。
8. 完整代码示例
以下是完整脚本,一次性展示。它会创建工作区、启动 Modal 沙盒、在其中运行代理、打印最终输出,并清理沙盒会话。
import asyncio
from agents import ModelSettings, Runner
from agents.extensions.sandbox import ModalSandboxClient, ModalSandboxClientOptions
from agents.run import RunConfig
from agents.sandbox import Manifest, SandboxAgent, SandboxRunConfig
from agents.sandbox.entries import File
async def main():
manifest = Manifest(
entries={
"README.md": File(
content=(
b"# Support Ticket Triage\n\n"
b"Small service that labels customer tickets by urgency and team.\n"
)
),
"src/app.py": File(
content=(
b"def route_ticket(subject: str, customer_tier: str) -> dict:\n"
b" urgent = customer_tier == \"enterprise\" or \"outage\" in subject.lower()\n"
b" return {\n"
b" \"priority\": \"high\" if urgent else \"normal\",\n"
b" \"team\": \"support-ops\" if urgent else \"customer-care\",\n"
b" }\n"
)
),
"docs/release-checks.md": File(
content=(
b"# Release Checks\n\n"
b"- Confirm routing rules match the current support escalation policy.\n"
)
),
}
)
agent = SandboxAgent(
name="Modal Sandbox Assistant",
model="gpt-5.4-mini",
instructions=(
"You are a coding assistant reviewing a small production service. "
"Inspect the sandbox workspace before answering. "
"Keep the answer short and practical."
),
default_manifest=manifest,
model_settings=ModelSettings(tool_choice="required"),
)
client = ModalSandboxClient()
options = ModalSandboxClientOptions(
app_name="openai-agents-modal-demo",
workspace_persistence="tar",
)
sandbox = await client.create(
manifest=manifest,
options=options,
)
await sandbox.start()
try:
result = await Runner.run(
agent,
(
"Explain what this service does and name one production check "
"before release. Keep it under 3 sentences."
),
run_config=RunConfig(
sandbox=SandboxRunConfig(session=sandbox),
workflow_name="Modal sandbox example",
),
)
print(result.final_output)
finally:
await sandbox.aclose()
if __name__ == "__main__":
asyncio.run(main())
该脚本遵循当前 OpenAI 沙盒结构,并使用 Modal 作为执行后端。代理逻辑保留在您的 Python 应用中,而实际工作区在 Modal 沙盒中运行。
finally 块很重要,因为即使代理运行失败,它也会关闭并删除沙盒。这有助于保持您的 Modal 环境整洁,避免遗留未使用的会话。
9. 本地测试应用
脚本准备好后,在与 main.py 同一文件夹的终端中本地运行:
python main.py
如果配置正确,脚本会创建一个 Modal 沙盒,将清单加载进去,针对工作区运行 OpenAI 代理,打印响应,然后清理沙盒。
您应看到类似如下的输出:
This service triages customer support tickets by assigning urgency and routing them to the right team. One production check before release is to confirm the routing rules still match the current support escalation policy.
运行可能需要几秒钟。在运行期间,打开您的 Modal 控制台,点击 openai-agents-modal-demo 应用并查看日志。这有助于确认沙盒已创建、启动、被代理使用并成功清理。

10. 创建交互式 Web 应用
第一个脚本是静态的,只能发送一次请求、获得一次响应并结束。为便于使用,我们可以借助 Gradio 将其改造成交互式 Web 应用。这让我们可以与沙盒代理对话、追问、创建或编辑文件,并在简单的浏览器界面中运行测试。
首先,安装最新版 Gradio:
pip install gradio
然后创建一个名为 app.py 的新文件,并将 Gradio 应用代码(OpenAI-Agents-in-Modal/app.py)复制进去。该应用沿用相同的 OpenAI Agents 与 Modal 沙盒设置,但将其封装在聊天界面中。代码还会在可能的情况下复用沙盒会话,从而避免每条消息都从零创建一个全新的沙盒。
用以下命令运行应用:
python app.py
您应在终端中看到一个本地 URL:
* Running on local URL: http://127.0.0.1:7860
* To create a public link, set share=True in launch().
在浏览器中打开该本地 URL 以使用聊天应用。您可以让代理检查项目、解释服务功能、创建新辅助文件、编辑现有文件,或在 Modal 沙盒内运行测试。

例如,我先让它解释项目服务的作用,几秒内它就基于沙盒文件返回了详细的回答。

随后我让代理创建一个新的路由辅助文件。这个请求稍慢一些,因为代理需要修改沙盒工作区、添加测试,并运行测试套件。
代理创建了 src/routing_rules.py,在 tests/test_routing_rules.py 处新增了测试文件,并用 pytest 进行了验证。全部 6 项测试均通过,确认新辅助模块可正常工作且现有工单分流逻辑保持不变。

整体来看,这个 Gradio 应用为您提供了一个与 Modal 支持的 OpenAI 代理协作的简易前端。用户通过浏览器发送消息,应用将其传给 SandboxAgent,代理在 Modal 沙盒内工作,最终响应会显示在聊天界面中。
结语
借助 Modal Sandboxes 的 OpenAI Agents,为构建能够处理真实文件、运行命令,并从隔离环境返回有用输出的代理式应用提供了清晰的路径。
Modal 的搭建过程很顺畅,创建沙盒本身也相对直接。连接一切之后,代理能够检查项目、创建新的路由辅助文件、添加测试,并确认 6 项测试全部通过。
不过,构建交互式应用并配置模型比预期花费了更多精力。文件创建与测试步骤也更耗时,因为 Modal 沙盒有时会超时。我不得不将沙盒超时时间从 300 秒提高到 600 秒,给代理足够时间完成整个流程。
另一个痛点是日志与可观测性。在等待代理完成时,并不总能清楚了解 Agents SDK 在后台做什么。即使是 Modal 的日志,有时也不足以判断代理是在检查文件、编辑代码还是运行测试。
未来若能提供更详细的代理日志(类似于使用 Claude Code 等工具时的体验),就能更清晰地跟进每一步。
总体来说,这是一套构建沙盒化代理应用的强大工作流,尤其当您的代理需要处理文件、代码和生成输出时。您可以在 GitHub 上找到完整项目,克隆到本地自行运行:kingabzpro/OpenAI-Agents-in-Modal。
如果您想系统学习如何构建高级 AI 系统,推荐参加我们的 Building Scalable Agentic Systems 课程。
OpenAI Agents SDK 沙盒常见问答
代理编排层与沙盒执行环境有什么区别?
编排层位于您的 Python 应用中,负责代理逻辑、模型调用和决策。沙盒则是实际工作的隔离环境,例如文件读写、Shell 命令和代码执行。二者分离意味着不受信任或不可预测的代码在沙盒中运行,不会影响您的主应用。
我必须使用 Modal 吗?能否使用其他沙盒提供商?
Modal 只是多个受支持提供商之一。OpenAI Agents SDK 支持 Modal、E2B、Cloudflare、Daytona、Blaxel、Runloop 和 Vercel。您可以通过更换客户端类(例如使用 E2BSandboxClient 替代 ModalSandboxClient)来切换提供商,其余代理代码基本保持不变。
什么是 Manifest,代理为什么需要它?
Manifest 定义了沙盒工作区中存在的文件与文件夹结构。没有它,代理只能访问其提示上下文中的内容。通过传入 Manifest,您为代理提供了一个真实项目以供检查、编辑和推理,这比仅依赖文字描述能产出更扎实、准确的回应。
OpenAI Agents SDK 的沙盒更新是否等同于 ChatGPT 的 Code Interpreter 工具?
不是。Code Interpreter 工具是面向终端用户的 ChatGPT 内置功能。Agents SDK 的沙盒是面向开发者的框架,允许您自带执行环境(如 Modal 或 E2B),并连接到您自己构建和控制的代理。您自行管理工作区、文件以及沙盒会话的生命周期。