跳转到内容
搜索文档

使用 OpenAI Agents SDK 构建 AI 编程 Agent

最后更新 查看 MarkdownAgent 设置

OpenAI Agents SDK 是用于构建多智能体工作流的轻量级 Python 框架。开箱即用的 Cloudflare Sandbox 集成,使该 SDK 具备一流的 Cloudflare 后端,为 agent 提供隔离容器以运行代码、安装软件包和管理文件。

在本教程中,你将部署一个 sandbox bridge Worker,并构建一个 Python agent:接受编程任务,在 Cloudflare Sandbox 中执行,然后将输出文件复制到本地机器。

预计完成时间:20 分钟

前提条件

  1. 注册已启用 Containers / Sandbox beta 的 Cloudflare 账户
  2. 安装 Python 3.12+uv
  3. 获取 OpenAI API key

1. 部署 sandbox bridge

sandbox bridge 是一个 Cloudflare Worker,通过 HTTP 暴露 Sandbox API,使非 Worker 客户端(例如使用 OpenAI Agents SDK 的 Python 脚本)能够创建和控制 sandbox。

Sandbox 环境已预配置 Node.js 和 Python 开发环境,因此 agent 可以立即开始编写和运行代码。

将 bridge 部署到你的 Cloudflare 账户:

Deploy to Cloudflare

该按钮会部署 Worker 并生成用于身份验证的 SANDBOX_API_KEY secret。部署完成后,记下 Worker URL 和 API key——下一步会用到。

手动部署

如果你希望分步部署:

  1. 安装 Node.jsDocker

  2. 搭建 bridge 项目:

    npm create cloudflare sandbox-bridge --template=cloudflare/sandbox-sdk/bridge/worker
    cd sandbox-bridge
  3. 登录 Cloudflare:

    npx wrangler login
  4. 设置 API key secret:

    openssl rand -hex 32 | tee /dev/stderr | npx wrangler secret put SANDBOX_API_KEY

    密钥会打印到终端并传给 Wrangler。请妥善保存——后续需要用它验证 API 请求。

  5. 部署 Worker:

    npx wrangler deploy
  6. 验证部署:

    curl https://cloudflare-sandbox-bridge.<your-subdomain>.workers.dev/health

    你应看到 {"ok":true}

2. 设置 Python 项目

为 agent 创建新目录:

mkdir openai-sandbox-agent && cd openai-sandbox-agent

创建包含凭据的 .env 文件:

.envsh
OPENAI_API_KEY=sk-your-openai-key
CLOUDFLARE_SANDBOX_API_KEY=your-bridge-token
CLOUDFLARE_SANDBOX_WORKER_URL=https://cloudflare-sandbox-bridge.your-subdomain.workers.dev

3. 构建 agent

创建如下内容的 main.py。内联脚本元数据会告诉 uv 需要安装哪些依赖,因此所有内容都集中在一个文件中:

main.pypython
# /// script
# requires-python = ">=3.12"
# dependencies = ["openai-agents[cloudflare]"]
# ///
"""One-shot coding agent backed by a Cloudflare Sandbox."""

from __future__ import annotations

import asyncio
import os
import sys
from pathlib import Path

from agents import Runner
from agents.extensions.sandbox.cloudflare import (
    CloudflareSandboxClient,
    CloudflareSandboxClientOptions,
)
from agents.run import RunConfig
from agents.sandbox import SandboxAgent, SandboxRunConfig
from agents.sandbox.capabilities import Shell

MODEL = "gpt-5.4"

INSTRUCTIONS = """\
You are an expert developer working inside a sandbox.
The sandbox has bun, node, npm, and python available on the PATH.
Implement the user's task in /workspace, test it, then copy deliverable files to /workspace/output/.
""".strip()


async def copy_output(session, dest: Path) -> list[Path]:
    """Download files from /workspace/output/ in the sandbox to a local directory."""
    dest.mkdir(parents=True, exist_ok=True)
    ls = await session.exec("find", "/workspace/output", "-maxdepth", "1", "-type", "f", shell=False)
    if not ls.ok():
        return []
    copied: list[Path] = []
    for name in (l.strip() for l in ls.stdout.decode().splitlines() if l.strip()):
        handle = await session.read(Path(name))
        local = dest / Path(name).name
        payload = handle.read(); handle.close()
        local.write_bytes(payload if isinstance(payload, bytes) else payload.encode())
        copied.append(local)
    return copied


async def run(prompt: str, output_dir: Path) -> None:
    worker_url = os.environ.get("CLOUDFLARE_SANDBOX_WORKER_URL", "")
    if not worker_url:
        sys.exit("Error: CLOUDFLARE_SANDBOX_WORKER_URL is not set.")

    agent = SandboxAgent(
        name="Developer",
        model=MODEL,
        instructions=INSTRUCTIONS,
        capabilities=[Shell()],
    )

    client = CloudflareSandboxClient()
    options = CloudflareSandboxClientOptions(worker_url=worker_url)
    session = await client.create(manifest=agent.default_manifest, options=options)

    try:
        async with session:
            run_config = RunConfig(
                sandbox=SandboxRunConfig(session=session),
                tracing_disabled=True,
            )

            # Stream tool calls so the user can follow progress.
            result = Runner.run_streamed(agent, prompt, run_config=run_config)
            async for ev in result.stream_events():
                if ev.type == "run_item_stream_event" and ev.name == "tool_called":
                    print(f"  [tool] {getattr(ev.item.raw_item, 'name', '')}")
                elif ev.type == "run_item_stream_event" and ev.name == "tool_output":
                    print(f"  [output] {str(getattr(ev.item, 'output', ''))[:200]}")

            # Copy output files from the sandbox to the local machine.
            copied = await copy_output(session, output_dir)
            if copied:
                print(f"\nCopied {len(copied)} file(s) to {output_dir}:")
                for p in copied:
                    print(f"   {p}")
            else:
                print("\nAgent did not produce any output files.")
    finally:
        await client.delete(session)


if __name__ == "__main__":
    prompt = sys.argv[1] if len(sys.argv) > 1 else "Create a hello world HTTP server using Bun.serve"
    asyncio.run(run(prompt, Path("output")))

关键部分的作用如下:

组件 用途
SandboxAgent 接受 sandbox 特定配置(包括 capabilities)的 Agent 子类。
Shell() 向 LLM 暴露 shell 工具的能力,使其可在 sandbox 内运行命令。
CloudflareSandboxClient 通过 bridge Worker 创建并管理 sandbox 会话。从环境读取 CLOUDFLARE_SANDBOX_API_KEY 进行身份验证。
CloudflareSandboxClientOptions 将客户端指向你的 bridge Worker URL。
Runner.run_streamed() 执行 agent,并产出工具调用与文本输出的流式事件。
SandboxRunConfig 将活动的 sandbox 会话附加到运行,使 agent 的工具在容器内执行。

4. 运行 agent

uv run --env-file .env main.py "Create a hello world HTTP server using Bun.serve"

你应看到工具调用和输出流式打印到控制台:

Sending task to sandbox agent (gpt-5.4)...
  [tool] exec_command
  [output] exit_code=0 stdout: mkdir: created directory '/workspace/output'
  [tool] exec_command
  [output] exit_code=0 stdout: Listening on http://localhost:3000

Copied 1 file(s) to output:
   output/server.ts

agent 编写了代码,在 sandbox 中进行了测试,并将可交付文件复制到了本地机器。

你构建了什么

你构建了一个 Python 编程 agent,它能够:

  • 接受自然语言编程任务
  • 在隔离的 Cloudflare Sandbox 容器中执行代码
  • 安装软件包、运行测试,并迭代直至任务完成
  • 将可交付文件复制回本地机器

bridge Worker 的 Dockerfile 可按需完全自定义——安装额外语言、系统软件包或工具,以匹配你的用例。

Cloudflare Sandbox 还提供更多可集成到 agent 中的能力:

  • PTY 会话 — 通过 WebSocket 打开与 sandbox 的交互式终端会话,实现实时 I/O。
  • 存储桶挂载 — 将 R2 或兼容 S3 的存储桶挂载为 sandbox 内的本地目录,用于持久数据。
  • 工作区备份与恢复 — 使用 persist_workspace()hydrate_workspace() 持久化工作区状态,以便跨 sandbox 生命周期恢复工作。
  • 文件操作 — 在 sandbox 内以编程方式读取、写入和管理文件。

后续步骤

这篇文档对您有帮助吗?