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/
羽毛球分组比赛记分
小程序二维码

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

小夜