sandbox-sdk Skill:让 AI 用 Cloudflare 沙箱安全执行不可信代码

前言

给 AI Agent 接「跑代码」能力时,最先卡住的往往不是模型,而是执行环境。用户提交的脚本、LLM 临时生成的 Python、CI 里每次构建的测试命令,都不该直接落在 Worker 进程里跑。自己搭虚拟机或容器集群可以隔离,但成本高、接入重,和 Cloudflare Workers 这套边缘运行时也不在一条线上。

Cloudflare 为此提供了 Sandbox SDK:在 Workers 里用 TypeScript API 拉起隔离的 Linux 容器,执行命令、读写文件、跑代码解释器、对外暴露预览地址。配套的 Agent Skill 最初就叫 sandbox-sdk,用来把这套约定写进 Cursor、Claude Code、Codex 等编程助手,避免模型凭过期记忆乱写配置。

本文以 Cloudflare 官方文档、cloudflare/skills 仓库和 Skill 原文为准,说明这个 Skill 是什么、后来怎么拆分、怎么安装,以及用稳定版 SDK 搭一个最小可运行沙箱。

这是什么

sandbox-sdk 是 Cloudflare 维护的 Agent Skill,收录在 cloudflare/skills 仓库。它面向「要在 Cloudflare 上做隔离代码执行」的开发任务,覆盖沙箱生命周期、命令执行、文件操作、代码解释器和预览 URL。Skill 的 description 写明:在构建 AI 代码执行、代码解释器、CI/CD、交互式开发环境,或执行不可信代码时加载;并明确偏向从 Cloudflare 文档检索,而不是依赖模型预训练知识。

它教 Agent 使用的产品是 Sandbox SDK(npm 包 @cloudflare/sandbox,源码仓库 cloudflare/sandbox-sdk)。官方文档把定位写得很直接:基于 Cloudflare Containers,在隔离环境中安全运行不可信代码,从 Workers 应用里执行命令、管理文件、跑后台进程、暴露服务。每个沙箱是独立 Linux 容器,同时作为 Durable Object 存在。该能力标注为 Workers Paid 计划可用。

一句话:Skill 负责让编程助手按官方约定写代码;SDK 负责在边缘容器里真正把代码跑起来。

名称已经拆开,安装前先看这一节

2026 年 2 月 5 日,Cloudflare 在 cloudflare/skills 里加入了名为 sandbox-sdk 的 Skill。skills.sh / officialskills.sh 目录至今仍按这个名字收录,安装示例是:

npx skills add https://github.com/cloudflare/skills --skill sandbox-sdk

2026 年 8 月 7 日,仓库用一次提交把这个单一 Skill 拆成三条线(PR #92)。当前 main 分支的 skills/ 目录里已经没有 sandbox-sdk 文件夹,官方 README 列出的是:

Skill 用途
sandbox-stable 当前稳定版 @cloudflare/sandbox(默认 npm tag)
sandbox-next @cloudflare/sandbox@next(Sandbox SDK 1.0 预览),官方建议新项目走这条线
sandbox-migrate-to-next 把已有稳定版应用迁到 @next

官方 Sandbox 文档和 Agent setup 页与仓库一致:在稳定包上开发用 sandbox-stable;新项目用 sandbox-next;要搬家再用 sandbox-migrate-to-next。目录站上的 --skill sandbox-sdk 对应的是拆分前的名字,今天按仓库现状,应安装整个 cloudflare/skills 包,让 Agent 按依赖自动加载对应 Skill,而不是假定 sandbox-sdk 目录仍在。

下文的安装命令以仓库 README 和 Agent setup 为准;代码示例以当前稳定版文档为准。

核心功能

对照拆分前的 sandbox-sdk SKILL.md 和当前稳定版文档,Agent 被要求掌握的能力可以分成几块。

1. 沙箱生命周期

getSandbox(env.Sandbox, sandboxId) 获取实例。同一 ID 始终对应同一沙箱;getSandbox() 立即返回,容器在第一次实际操作时才懒加载启动。默认空闲约 10 分钟后容器休眠(sleepAfter 可配),休眠后再来请求会拉起全新容器,此前写入的文件、进程、解释器上下文都会丢掉。临时任务应调用 destroy() 立刻释放。

2. 命令执行与代码解释器

sandbox.exec(command) 跑 shell 命令,返回 stdoutstderrexitCodesuccess。适合脚本、构建、测试。LLM 生成的代码更推荐 createCodeContext() + runCode():支持 Python、JavaScript、TypeScript,同一 context 内变量和 import 会保留,并能带上图表、表格等富输出。官方建议:shell / 构建管道用 exec(),数据分析、模型生成代码用 runCode()

3. 文件系统

mkdirwriteFilereadFilelistFiles 操作沙箱内路径,常见工作目录是 /workspace。容器在运行期间文件还在;一旦休眠或销毁,这些文件就没了。需要跨生命周期保留数据时,官方提供把 R2 / S3 等对象存储挂进沙箱的能力,生产部署才可用。

4. 预览地址与隧道

拆分前的 Skill 用 exposePort(8080) 拿到预览 URL,并要求 Worker 入口先走 proxyToSandbox()。生产环境预览子域名需要自定义域名的通配符 DNS,.workers.dev 不支持这种子域名。当前稳定版文档另外提供 sandbox.tunnels.get(port) 得到 *.trycloudflare.com 这类免配置地址;2026 年的弃用指南把 HTTP/WebSocket 传输和 exposePort() 标为待清理项,新代码优先 RPC 传输和 tunnels API。

5. 配置契约

Worker 必须重新导出 Sandbox 类,否则无法部署。wrangler.jsonc 需要同时配置 containersdurable_objects.bindingsmigrations 三段。npm 包版本和 Dockerfile 里的基础镜像 tag 必须在同一条线上,稳定包不能配 cloudflare/sandbox:next 镜像,反过来也不行。

安装与启用

Skill 本身是 SKILL.md 指令包,不代替 @cloudflare/sandbox。本地开发还要能构建容器镜像:官方入门要求本机 Docker 可用,可用 docker info 检查。

安装 Cloudflare Skills

通用(npx skills),仓库 README 给出的命令是安装整个包:

npx skills add https://github.com/cloudflare/skills

也可以克隆仓库,把对应 Skill 目录拷到各工具的 Skill 路径:

工具 目录
Claude Code ~/.claude/skills/
Cursor ~/.cursor/skills/
OpenCode ~/.config/opencode/skills/
Codex ~/.codex/skills/

Claude Code 官方 Agent setup 要求用插件市场,不要单独再跑一遍 npx skills

/plugin marketplace add cloudflare/skills
/plugin install cloudflare@cloudflare

Cursor 可以执行 /add-plugin cloudflare,或从 Cursor Marketplace 安装;也可以在 Settings > Rules > Add Rule > Remote Rule (Github) 填 cloudflare/skills

Codex 在会话里打开 /plugins,搜索并安装 Cloudflare 插件。

装好后,对话里出现「用 Sandbox SDK 执行不可信代码 / 做代码解释器 / 给每次 CI 起隔离环境」这类需求时,Agent 会按触发条件加载 sandbox-stablesandbox-next

创建一个可运行的沙箱 Worker

官方入门用模板生成最小项目(当前稳定包):

npm create cloudflare@latest -- my-sandbox --template=cloudflare/sandbox-sdk/examples/minimal
cd my-sandbox

模板会带上 src/index.tswrangler.jsoncDockerfilewrangler.jsonc 的核心结构如下(字段名以官方入门为准,不要随意改 class_name / binding 名称):

{
  "containers": [
    {
      "class_name": "Sandbox",
      "image": "./Dockerfile",
      "instance_type": "lite",
      "max_instances": 1
    }
  ],
  "durable_objects": {
    "bindings": [
      {
        "class_name": "Sandbox",
        "name": "Sandbox"
      }
    ]
  },
  "migrations": [
    {
      "new_sqlite_classes": ["Sandbox"],
      "tag": "v1"
    }
  ]
}

多实例时再提高 max_instances。本地调试:

npm run dev

第一次会构建 Docker 镜像,官方说明大约要 2–3 分钟。部署:

npx wrangler deploy

wrangler deploy 会构建镜像、推到 Cloudflare Container Registry,再发布 Worker。首次部署后容器镜像还要 provisioning,官方建议等几分钟再打沙箱请求;可用 npx wrangler containers list 看状态。

典型用法

下面这段来自官方 Get started 模板,也是 sandbox-stable Skill 要求 Agent 遵守的最小形态:必须 export { Sandbox },用稳定 ID 取沙箱,用 exec / 文件 API 干活。面向用户的应用里,ID 应按登录用户派生,不要所有人共用一个硬编码 ID。

import { getSandbox, proxyToSandbox, type Sandbox } from "@cloudflare/sandbox";

export { Sandbox } from "@cloudflare/sandbox";

type Env = {
  Sandbox: DurableObjectNamespace<Sandbox>;
};

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url);
    const sandbox = getSandbox(env.Sandbox, "my-sandbox");

    if (url.pathname === "/run") {
      const result = await sandbox.exec('python3 -c "print(2 + 2)"');
      return Response.json({
        output: result.stdout,
        error: result.stderr,
        exitCode: result.exitCode,
        success: result.success,
      });
    }

    if (url.pathname === "/file") {
      await sandbox.writeFile("/workspace/hello.txt", "Hello, Sandbox!");
      const file = await sandbox.readFile("/workspace/hello.txt");
      return Response.json({
        content: file.content,
      });
    }

    return new Response("Try /run or /file");
  },
};

本地可以这样验证:

curl http://localhost:8787/run
curl http://localhost:8787/file

如果要执行模型生成的 Python,并在多次调用间保留变量,用代码解释器(稳定版 API):

const sandbox = getSandbox(env.Sandbox, "user-123");
const ctx = await sandbox.createCodeContext({ language: "python" });

await sandbox.runCode("data = [1, 2, 3]", { context: ctx.id });
const result = await sandbox.runCode("sum(data)", { context: ctx.id });

拆分前的 Skill 还列出一组速查方法,稳定版文档仍然适用:

const sandbox = getSandbox(env.Sandbox, "user-123");
await sandbox.exec("python script.py");
await sandbox.mkdir("/workspace/src", { recursive: true });
await sandbox.writeFile("/workspace/app.py", content);
await sandbox.readFile("/workspace/app.py");
await sandbox.listFiles("/workspace");
await sandbox.destroy();

需要对外提供沙箱内 HTTP 服务时,Worker 的 fetch 应先处理预览代理:

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const proxyResponse = await proxyToSandbox(request, env);
    if (proxyResponse) return proxyResponse;
    // 再写业务路由
  },
};

和 Agent 协作时,可以直接把任务说清楚,例如:

用 Cloudflare Sandbox SDK 在 Workers 里做一个隔离的 Python 代码执行接口。
按当前稳定版 @cloudflare/sandbox 来写,加载 sandbox-stable。
需要 exec、读写 /workspace 文件,以及正确的 wrangler.jsonc 和 export { Sandbox }。

新项目若准备跟 1.0 预览走,把依赖改成 @cloudflare/sandbox@next,并明确让 Agent 加载 sandbox-next。稳定版的 exec 吃的是命令字符串、等命令结束才返回;@nextexec 吃 argv 列表、进程启动就返回 handle,两套 API 不能混用。

适用场景与注意事项

官方文档给的典型场景包括:AI Agent / 代码助手执行模型生成的代码;带 pandas、图表输出的数据分析环境;云 IDE、编程 playground;在隔离容器里跑测试和构建。Skill 原文还强调:不要把 tool-call 代码直接跑在宿主 Worker 上。

使用前需要接受这些限制:

  1. 计划与计费:Sandbox SDK 标注为 Workers Paid;费用落在底层 Containers,并叠加 Workers、Durable Objects,以及可选的 Workers Logs。具体费率看 Containers pricing
  2. 状态是短暂的:空闲休眠或 destroy() 之后,文件、进程、解释器上下文全部清空。需要持久化就外置存储,或按官方挂载对象存储。
  3. 包和镜像必须对齐:只升级 npm 包却不改 Dockerfile 的 FROM,启动时会有版本警告,功能也可能异常。
  4. 本地依赖 Dockerwrangler deploy 和本地构建镜像都需要 Docker 守护进程。
  5. 子请求上限:默认 HTTP 传输下,每次 exec() / readFile() 等都算一次 Worker 子请求。Paid 计划每请求 1000 次,Free 是 50 次。高频操作应把 SANDBOX_TRANSPORT 设为 rpc。官方同时标明 HTTP/WebSocket 传输已弃用。
  6. 密钥不要放进沙箱环境变量:非机密配置可以进沙箱;活凭证留在 Worker,出站请求用 outbound handler 注入。
  7. 不要混用 stable / next:Skill 把这写成硬约束。自托管的 Bridge 目前仍只在稳定包和稳定镜像上。
  8. 不要走内部客户端:拆分前的 Skill 明确禁止直接用 CommandClientFileClient,应使用 sandbox.* 方法;也不要漏掉 export { Sandbox }

小结

sandbox-sdk 要解决的问题很具体:让编程助手按 Cloudflare 的约定,写出能在隔离容器里执行不可信代码的 Workers 应用。产品侧是 @cloudflare/sandbox,Skill 侧从 2026 年 8 月起已拆成 sandbox-stablesandbox-nextsandbox-migrate-to-next。装好 cloudflare/skills 之后,先看清项目用的是稳定包还是 @next,再让 Agent 加载对应 Skill,比继续按目录站上的旧名字去装一个已经不存在的文件夹更稳妥。

官方资料:

  • Skill 仓库:https://github.com/cloudflare/skills
  • 拆分前的 sandbox-sdk 目录(历史路径):https://github.com/cloudflare/skills/tree/main/skills/sandbox-sdk
  • 目录页:https://officialskills.sh/cloudflare/skills/sandbox-sdk
  • Sandbox SDK 文档:https://developers.cloudflare.com/sandbox/
  • 入门:https://developers.cloudflare.com/sandbox/get-started/
  • SDK 源码:https://github.com/cloudflare/sandbox-sdk
  • 各工具安装:https://developers.cloudflare.com/agent-setup/
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜