OpenAI Agents API ↗ 在 OpenAI 运行 Codex Agent 循环。使用自托管环境时,Codex 会改为在你的 Cloudflare 账户中运行命令并编辑文件。Cloudflare 模板会将每个 session 的 Codex executor 运行在自己的 Linux sandbox 中:由一个 Durable Object 为该 session 启动的 Container。
模板 ↗ 包含本指南部署的 Worker 和 container 镜像。
当 session 启动、需要环境、正在工作以及进入空闲时,OpenAI 会向你账户中的 Worker 发送已签名的 webhook。Worker 验证每个 webhook,从 OpenAI 检索 session,并将其传给以该 session 命名的 Durable Object。Durable Object 启动运行 codex exec-server 的 container。executor 使用受限 API key 主动连接到 OpenAI。它会针对 /workspace 中的文件运行来自 Agent 的命令,这些文件留在你的 Cloudflare 账户中。
你需要:
- 可访问 Containers 的 Cloudflare Workers 付费计划账户
- OpenAI Agents API 访问权限和 OpenAI API key
curl- 手动部署时需要 Node.js 24 ↗ 或更高版本,以及正在运行的 Docker ↗ daemon
你还需要一个供 codex exec-server 使用的受限 OpenAI API key,本指南称之为 executor key。它需要 api.model.read 和 api.agents.environments.connect 权限。Worker 使用的 OpenAI API key 需要 api.agents.read。这两个 key 必须属于同一个组织、项目和所有者,无论该所有者是用户还是服务账户。
这些步骤会创建一个 OpenAI agent,使用 Deploy to Cloudflare 按钮部署 Worker 及其 container,注册 webhook,并在 /workspace 中运行测试任务。
- 设置你的 OpenAI API key,然后创建一个 agent:
export OPENAI_API_KEY="<OPENAI_API_KEY>"curl "https://api.openai.com/v1/agents" \
--request POST \
--header "OpenAI-Beta: agents=v1" \
--header "Authorization: Bearer $OPENAI_API_KEY" \
--json '{
"name": "sandbox-demo",
"model": "gpt-5.6-sol"
}'从响应中复制 id 字段并保存为 agent ID:
export OPENAI_AGENT_ID="agent_..."-
为 container 清理端点生成共享 secret 并保存:
openssl rand -hex 32选择 Deploy to Cloudflare:
提示时输入这些值:
变量 值 OPENAI_API_KEY用于检索 session 状态的 OpenAI key OPENAI_EXECUTOR_API_KEY受限的 executor key OPENAI_AGENT_ID第 1 步中的 agent ID OPENAI_WEBHOOK_SECRET首次部署使用 pending-webhook-registrationEXECUTOR_CLIENT_SECRET本步骤生成的共享 secret 保存已部署的 Worker URL:
export WORKER_URL="https://<YOUR_WORKER>.workers.dev"模板会在 OpenAI 创建 session 后立即启动 container,并在 session 进入空闲时对 container 做 snapshot。空闲 session 会将其 container 保留
EXECUTOR_KEEP_ALIVE_SECONDS时间,模板中的wrangler.jsonc将其设为 30 秒。 -
在 OpenAI 项目 webhook 设置 ↗ 中,注册
https://<YOUR_WORKER>.workers.dev/webhook。OpenAI 必须能访问此 URL。订阅这些事件:
agent.session.createdagent.session.action_requiredagent.session.in_progressagent.session.idleagent.session.failed
复制 OpenAI 返回的签名 secret。在 Worker 的 Settings > Variables and Secrets 中,将
OPENAI_WEBHOOK_SECRET替换为它,然后选择 Deploy。如果是手动部署,请改为在templates/openai-agents-api目录中运行此命令:npx wrangler secret put OPENAI_WEBHOOK_SECRET检查设置:
curl --fail-with-body "$WORKER_URL/health"当响应包含
"configured": true和"webhook_configured": true时,Worker 已就绪。 -
创建自托管 session:
curl https://api.openai.com/v1/agents/sessions \
--request POST \
--header "OpenAI-Beta: agents=v1" \
--header "Authorization: Bearer $OPENAI_API_KEY" \
--json '{"agent_id": "'"$OPENAI_AGENT_ID"'", "environment": {"type": "self_hosted", "workspace_directory": "/workspace"}}'从响应中复制 id 字段并保存为 session ID:
export SESSION_ID="sess_..."在一个终端中打开 session 事件流:
curl --no-buffer \
"https://api.openai.com/v1/agents/sessions/$SESSION_ID/events" \
--header "OpenAI-Beta: agents=v1" \
--header "Authorization: Bearer $OPENAI_API_KEY" \
--header "Accept: text/event-stream"流保持打开时,请从另一个终端提交任务。先在该终端导出 OPENAI_API_KEY 和 SESSION_ID:
curl "https://api.openai.com/v1/agents/sessions/$SESSION_ID/events" \
--request POST \
--header "OpenAI-Beta: agents=v1" \
--header "Authorization: Bearer $OPENAI_API_KEY" \
--json '{
"events": [
{
"type": "session.input.message",
"input": [
{
"role": "user",
"content": [
{
"type": "input_text",
"text": "Use the shell to write hello to /workspace/hello.txt, then read it."
}
]
}
]
}
]
}'事件流会显示 Agent 的进度及其回复。
手动部署
若要从终端部署,而不是使用第 2 步中的按钮:
-
克隆模板仓库,安装依赖,并登录 Cloudflare:
git clone https://github.com/cloudflare/sandbox-sdk.git cd sandbox-sdk/templates/openai-agents-api npm install npx wrangler login -
为 container 清理端点生成共享 secret 并保存:
openssl rand -hex 32 -
存储 Worker secrets。提示时输入你的 OpenAI API key、executor key、agent ID 和共享 secret:
npx wrangler secret put OPENAI_API_KEY npx wrangler secret put OPENAI_EXECUTOR_API_KEY npx wrangler secret put OPENAI_AGENT_ID npx wrangler secret put EXECUTOR_CLIENT_SECRET -
部署 Worker 及其 container:
npm run deploy
要更改 keep-alive、预热和 snapshot 设置,请编辑 wrangler.jsonc 中的 EXECUTOR_KEEP_ALIVE_SECONDS、EXECUTOR_PREWARM_ENABLED 和 EXECUTOR_SNAPSHOTS_ENABLED,然后再次运行 npm run deploy。
保存已部署的 Worker URL,然后继续第 3 步。
重新连接现有 session
再次打开 session 事件流,然后发送更多输入:
curl "https://api.openai.com/v1/agents/sessions/$SESSION_ID/events" \
--request POST \
--header "OpenAI-Beta: agents=v1" \
--header "Authorization: Bearer $OPENAI_API_KEY" \
--json '{
"events": [
{
"type": "session.input.message",
"input": [
{
"role": "user",
"content": [
{
"type": "input_text",
"text": "Read /workspace/hello.txt again."
}
]
}
]
}
]
}'模板中的 基础示例 ↗ 是一个使用 OpenAI Agents API TypeScript SDK 的 TypeScript 应用。它会创建在 executor Worker 上运行的自托管 session。其 HTTP 端点用于发送首次输入、发送后续输入以及清理。POST /demo 端点会运行整个工作流:创建 session、在 container 中写入并读取文件、发送后续消息,然后删除 OpenAI session 及其 executor。
删除 OpenAI session:
curl "https://api.openai.com/v1/agents/sessions/$SESSION_ID" \
--request DELETE \
--header "OpenAI-Beta: agents=v1" \
--header "Authorization: Bearer $OPENAI_API_KEY"要立即停止某个 session 的 container,请使用部署时的共享 secret 调用清理端点:
export WORKER_URL="https://<YOUR_WORKER>.workers.dev"
export EXECUTOR_CLIENT_SECRET="<EXECUTOR_CLIENT_SECRET>"
curl --fail-with-body \
--request DELETE \
--header "Authorization: Bearer $EXECUTOR_CLIENT_SECRET" \
"$WORKER_URL/executors/$SESSION_ID"删除 OpenAI session 不会向 Worker 发送 webhook。当 Worker 收到 agent.session.failed webhook、session 查询返回 404 Not Found,或你调用清理端点时,Worker 会停止 container 并删除其对 container snapshot 的记录。仍然存在的空闲 session 会为其下一次环境连接保留 snapshot。
-
应用创建或检索 OpenAI session,并通过 Agents API 发送输入。
-
当
EXECUTOR_PREWARM_ENABLED为true(如模板中那样)时,agent.session.createdwebhook 会让 Worker 检索 session,并使用该 session 的环境 ID 和远程 URL 启动其 container。 -
agent.session.action_requiredwebhook 会让 Worker 检索 session,确认由已配置的 agent 拥有它,并读取该 session 需要的环境 ID 和远程 URL。 -
以该 session 命名的 Durable Object 使用这些连接详情和 executor key 启动 container。
codex exec-server会主动连接到 OpenAI。 -
每次 container 启动、环境连接以及
agent.session.in_progresswebhook 都会重置EXECUTOR_KEEP_ALIVE_SECONDS截止时间。截止时间过后,Worker 会检索 session。如果 session 仍处于活动状态,Worker 会设置新的截止时间。 -
agent.session.idlewebhook 会让 Worker 对 container 做 snapshot 并重置截止时间。截止时间过后,Worker 会停止 container 并保留 snapshot。 -
新输入会发送另一个
agent.session.action_requiredwebhook。Worker 会为相同环境 ID 复用正在运行的 container,或从已保存的 snapshot 启动下一个环境。
当 session 进入空闲时,Worker 会在停止 container 之前对其文件系统做 snapshot。下一次环境连接会从该 snapshot 启动,因此 /workspace 中的文件会回来。正在运行的进程和内存不会回来。如果 snapshot 失败,Worker 会让 container 继续运行,并安排另一次生命周期检查。更多信息请参阅 Sandbox 生命周期。
session 仅在其持续期间使用其 snapshot。当 session 失败、后续查询发现 session 已不存在,或你调用清理端点时,Worker 会删除该 session 的 snapshot 记录。下一个 session 随后从镜像启动。Worker 不会删除 snapshot 本身。
将 EXECUTOR_SNAPSHOTS_ENABLED 设为 false 时,每个新 executor 都会以空的 /workspace 启动。要在 session 结束后保留文件,请将它们存储到其他位置,例如 R2 bucket。更多信息请参阅 挂载 R2 bucket。
模板中的 templates/openai-agents-api/Dockerfile 文件定义了 executor 镜像。将 Debian 软件包添加到其 apt-get install 命令。例如,添加 jq 和 Python:
RUN apt-get update \
&& apt-get install --yes --no-install-recommends \
ca-certificates \
curl \
git \
jq \
python3 \
ripgrep \
&& rm -rf /var/lib/apt/lists/*你也可以在镜像中安装语言工具,例如全局 npm 软件包。不要将 API key 或其他 secrets 放入 Dockerfile。通过 Worker secrets 和 container 环境变量在运行时传入它们。
要构建并部署新镜像,请在 templates/openai-agents-api 目录中运行 npm run deploy。新 container 会从它启动。从 snapshot 启动的 session 会保留其旧镜像的文件系统,因此不会获得新软件包。
该模板是最小示例。在将其用于生产之前,请检查这些默认设置:
- 你的 OpenAI API key、webhook secret 和
EXECUTOR_CLIENT_SECRET保留在 Worker secrets 中。executor key 会作为CODEX_API_KEY进入 container,container 中的每个进程都可以读取它。请仅向 executor key 授予它需要的两项权限。 - container 具有互联网访问,以便
codex exec-server可以访问 OpenAI。Agent 运行的每条命令都具有相同访问权限。要限制目标或从 Worker 向请求添加凭据,请参阅 出站流量。 - OpenAI 必须能在没有交互式 Access 登录的情况下访问
/webhook。Worker 会检查每个 webhook 的签名,清理端点需要EXECUTOR_CLIENT_SECRET。如果你用 Cloudflare Access 保护其他路由,请使用 按路径的策略,让/webhook保持可访问。
关于 sandbox 向其中代码暴露的内容,请参阅 Sandbox 安全。