訂閱以接收新文章的通知:

沙箱處理 AI 智慧體,速度提升 100 倍

2026-03-24

閱讀時間:9 分鐘
本貼文還提供以下語言版本:English简体中文

去年九月,我們推出了程式碼模式,其核心概念是:智慧體不應透過呼叫工具來執行任務,而是應該編寫能夠呼叫 API 的程式碼來完成工作。我們已經證明,僅僅是將 MCP 伺服器轉換為 TypeScript API,就能減少 81% 的詞元 (token) 使用量。我們也展示了程式碼模式不僅能放在 MCP 伺服器前端,也能在後端運作,藉此打造出全新的 Cloudflare MCP 伺服器,僅用兩個工具、不到 1,000 個詞元就能開放整個 Cloudflare API

然而,如果智慧體(或 MCP 伺服器)要執行由 AI 即時產生的程式碼來完成任務,那麼這些程式碼就需要有地方執行,而且執行的環境必須安全。您不能直接在應用程式中使用 eval() 來執行 AI 產生的程式碼,因為惡意使用者可以輕易透過提示詞誘導 AI 植入漏洞。

這時候您需要一個沙箱:一個與您的應用程式及外界隔離的程式碼執行環境,僅開放該程式碼所需存取的特殊權限。

沙箱技術是 AI 產業的熱門話題。針對這項需求,大多數人會想到容器。透過 Linux 容器,您可以啟動任何您想要的程式碼執行環境。Cloudflare 甚至提供了容器執行階段Sandbox SDK 來滿足這個用途。

但容器的成本高昂且啟動速度緩慢,需要數百毫秒才能啟動,並耗費數百 MB 的記憶體來執行。您可能需要讓容器保持運作來避免延遲,甚至可能為了節省成本而將同一個容器重複用於多個任務,進而犧牲安全性。

如果我們想要支援消費者級規模的智慧體,即每位終端使用者都擁有一個(或多個)智慧體,且每個智慧體都會編寫程式碼,那光靠容器是不夠的。我們需要更輕量級的解決方案。

現在我們已經有了。

Dynamic Worker Loader:輕量級沙箱

在我們九月發表的《程式碼模式》文章中,預告了一項新的實驗性功能:Dynamic Worker Loader API。這個 API 讓 Cloudflare Worker 能夠即時實例化一個新的 Worker,在其專屬的沙箱中,使用執行階段指定的程式碼來運作。

Dynamic Worker Loader 現已推出開放測試版,可供所有付費 Workers 使用者使用。

詳細資訊請參閱文件,但實際用法大致如下:

// Have your LLM generate code like this.
let agentCode: string = `
  export default {
    async myAgent(param, env, ctx) {
      // ...
    }
  }
`;

// Get RPC stubs representing APIs the agent should be able
// to access. (This can be any Workers RPC API you define.)
let chatRoomRpcStub = ...;

// Load a worker to run the code, using the worker loader
// binding.
let worker = env.LOADER.load({
  // Specify the code.
  compatibilityDate: "2026-03-01",
  mainModule: "agent.js",
  modules: { "agent.js": agentCode },

  // Give agent access to the chat room API.
  env: { CHAT_ROOM: chatRoomRpcStub },

  // Block internet access. (You can also intercept it.)
  globalOutbound: null,
});

// Call RPC methods exported by the agent code.
await worker.getEntrypoint().myAgent(param);

就是這麼簡單。

快 100 倍

Dynamic Workers 採用了 Cloudflare Workers 平台自八年前推出以來一直使用的底層沙箱機制:isolate。isolate 是 V8 JavaScript 執行引擎(即 Google Chrome 使用的引擎)的執行個體。Workers 正是透過這種機制運作

一個 isolate 只需幾毫秒就能啟動,且僅使用數 MB 的記憶體。這比典型的容器快了大約 100 倍,記憶體效率則高出 10 到 100 倍。

這意味著,如果您想為每個使用者請求按需啟動一個新的 isolate 來執行程式碼片段,然後將其丟棄,完全可行。

無限的可擴展性

許多基於容器的沙箱提供者會對全球並行沙箱數量及沙箱建立速率施加限制。Dynamic Worker Loader 則沒有這類限制。之所以不需要,是因為它本質上只是一個 API,通往一直以來為我們平台提供動力的核心技術,而這項技術始終允許 Workers 無縫擴展到每秒數百萬個請求。

想要處理每秒數百萬個請求,而且每個請求都載入一個獨立的 Dynamic Worker 沙箱,且所有沙箱同時執行?沒問題!

零延遲

一次性的 Dynamic Workers 通常與建立它們的 Worker 在同一台機器上執行,甚至在同一個執行緒中。無需為了尋找預熱好的沙箱而繞過半個地球進行通訊。isolate 如此輕量,我們可以直接在請求抵達的位置執行它們。動態 Workers 在 Cloudflare 全球數百個據點皆受支援。

一切都是 JavaScript

與容器相比,唯一需要留意的是:您的智慧体必須撰寫 JavaScript。

從技術上講,Workers(包括動態 Workers)可以使用 Python 和 WebAssembly,但對於像智慧體按需產生的這類小型程式碼片段,JavaScript 的載入和執行速度會快得多。

我們人類通常對程式設計語言有強烈的偏好,雖然很多人喜愛 JavaScript,但其他人可能更偏好 Python、Rust 或無數其他語言。

但這裡我們談論的不是人類,而是 AI。AI 會依照您的需求撰寫任何語言的程式碼。LLM 是每種主流語言的專家,它們在 JavaScript 上更是使用了海量資料進行訓練。

JavaScript 從其在網路的本質來看,就是為沙箱化而設計的。它是這項工作的正確選擇。

以 TypeScript 定義的工具

如果我們希望智慧體能夠執行任何有用的操作,它需要與外部 API 進行通訊。那麼,我們要如何讓它知道它可以存取哪些 API 呢?

MCP 為扁平的工具呼叫定義了架構,但並不包含程式設計 API。OpenAPI 提供了一種表達 REST API 的方式,但無論是架構本身,還是呼叫它所需的程式碼,都顯得冗長繁複。

對於公開給 JavaScript 的 API 而言,有一個顯而易見的答案:TypeScript。

智慧體懂得 TypeScript。TypeScript 的設計目標就是簡潔。只需極少的詞元 (token),就能讓您的智慧體精確理解您的 API。

// Interface to interact with a chat room.
interface ChatRoom {
  // Get the last `limit` messages of the chat log.
  getHistory(limit: number): Promise<Message[]>;

  // Subscribe to new messages. Dispose the returned object
  // to unsubscribe.
  subscribe(callback: (msg: Message) => void): Promise<Disposable>;

  // Post a message to chat.
  post(text: string): Promise<void>;
}

type Message = {
  author: string;
  time: Date;
  text: string;
}

將其與等效的 OpenAPI 規範進行比較(長到您必須捲動畫面才能看完整份內容):

openapi: 3.1.0
info:
  title: ChatRoom API
  description: >
    Interface to interact with a chat room.
  version: 1.0.0

paths:
  /messages:
    get:
      operationId: getHistory
      summary: Get recent chat history
      description: Returns the last `limit` messages from the chat log, newest first.
      parameters:
        - name: limit
          in: query
          required: true
          schema:
            type: integer
            minimum: 1
      responses:
        "200":
          description: A list of messages.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Message"

    post:
      operationId: postMessage
      summary: Post a message to the chat room
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - text
              properties:
                text:
                  type: string
      responses:
        "204":
          description: Message posted successfully.

  /messages/stream:
    get:
      operationId: subscribeMessages
      summary: Subscribe to new messages via SSE
      description: >
        Opens a Server-Sent Events stream. Each event carries a JSON-encoded
        Message object. The client unsubscribes by closing the connection.
      responses:
        "200":
          description: An SSE stream of new messages.
          content:
            text/event-stream:
              schema:
                description: >
                  Each SSE `data` field contains a JSON-encoded Message object.
                $ref: "#/components/schemas/Message"

components:
  schemas:
    Message:
      type: object
      required:
        - author
        - time
        - text
      properties:
        author:
          type: string
        time:
          type: string
          format: date-time
        text:
          type: string

我們認為 TypeScript API 更勝一籌。它使用的詞元更少,而且更容易理解(無論是對智慧體還是人類而言)。

Dynamic Worker Loader 讓您能輕鬆在自己的 Worker 中實作像這樣的 TypeScript API,然後將其作為方法參數或透過 env 物件傳遞給 Dynamic Worker。Workers Runtime 會自動在沙箱與您的 harness 程式碼之間建立 Cap'n Web RPC 橋接,這樣智慧體就能跨越安全邊界呼叫您的 API,而且完全不會察覺到自己使用的並非本機函式庫。

這意味著您的智慧體可以寫出像這樣的程式碼:

// Thinking: The user asked me to summarize recent chat messages from Alice.
// I will filter the recent message history in code so that I only have to
// read the relevant messages.
let history = await env.CHAT_ROOM.getHistory(1000);
return history.filter(msg => msg.author == "alice");

HTTP 篩選和認證插入

如果您傾向於讓智慧體使用 HTTP API,這也是完全支援的。透過 worker loader API 中的 globalOutbound 選項,您可以註冊一個回呼函式,使其能在每次發起 HTTP 請求時被叫用。在這個回呼函式中,您可以檢查請求、改寫請求、插入驗證金鑰、直接回應請求、封鎖請求,或執行任何您需要的操作。

例如,您可以用這個機制來實作認證插入(又稱為權杖插入):當智慧體向需要授權的服務發出 HTTP 請求時,您在請求送出的過程中加入認證。這樣一來,智慧體本身永遠不會知道私密認證,因此也就無法洩露它們。

當智慧體需要與訓練資料集中已有的知名 API 進行通訊,或者當您希望智慧體使用基於 REST API 的函式庫(該函式庫可以在智慧體的沙箱內執行)時,使用純 HTTP 介面可能是比較理想的做法。

話雖如此,在沒有相容性需求的情況下,TypeScript RPC 介面仍然優於 HTTP:

  • 如上所示,描述 TypeScript 介面所需的詞元數量遠少於描述 HTTP 介面。

  • 智慧體撰寫呼叫 TypeScript 介面的程式碼時,所需的詞元數量也遠少於等價的 HTTP 呼叫。

  • 使用 TypeScript 介面時,由於您本來就要定義自己的包裝函式介面,因此更容易將介面限縮為只暴露您想提供給智慧體的特定功能,這樣既能簡化設計,也能提升安全性。而使用 HTTP 時,您更有可能需要實作對某些現有 API 請求的篩選功能。這相當困難,因為您的代理伺服器必須完整解讀每個 API 呼叫的意義,才能正確判斷是否允許該請求,而且 HTTP 請求本身就很複雜,包含許多可能具有意義的標頭和其他參數。到頭來,直接撰寫一個僅實作您想要允許之函數的 TypeScript 包裝函式,反而會簡單得多。

經過實戰考驗的安全性

要強化基於 isolate 的沙箱其實相當棘手,因為它的攻擊面比硬體虛擬機器更為複雜。儘管所有沙箱機制都存在漏洞,但 V8 的安全性漏洞仍比典型 hypervisor 的安全性漏洞更為常見。當使用 isolate 來沙箱化可能帶有惡意的程式碼時,加入額外的縱深防禦層非常重要。例如,Google Chrome 就是基於這個原因實作了嚴格的處理序隔離,但這並非唯一的解決方案。

我們擁有近十年來保護基於 isolate 之平台的經驗。我們的系統能在數小時內自動將 V8 安全修補程式部署到正式環境——這比 Chrome 本身還要快。我們的安全架構具備自訂的第二層沙箱,並能根據風險評估動態隔離租用戶。我們擴充了 V8 沙箱本身,使其能利用 MPK 等硬體功能。我們也與頂尖研究人員合作(並延攬了他們),共同開發對抗 Spectre 的新型防禦機制。此外,我們還有能掃描程式碼中惡意模式的系統,可自動封鎖這些模式或套用額外的沙箱層,以及更多措施。

當您在 Cloudflare 上使用 Dynamic Workers 時,您會自動獲得上述所有安全保障。

輔助函式庫

我們建置了許多函式庫,您在使用 Dynamic Workers 時可能會覺得它們很實用:

程式碼模式

@cloudflare/codemode 簡化了使用 Dynamic Workers 針對 AI 工具執行模型產生程式碼的過程。其核心是 DynamicWorkerExecutor(),它會建立一個專用的沙箱,並具備程式碼正規化功能來處理常見的格式錯誤,同時提供對 globalOutbound 擷取器的直接存取,以便控制沙箱內部的 fetch() 行為。您可以將其設為 null 以實現完全隔離,或傳入一個 Fetcher 繫結來路由、攔截或增強來自沙箱的對外請求。

const executor = new DynamicWorkerExecutor({
  loader: env.LOADER,
  globalOutbound: null, // fully isolated 
});

const codemode = createCodeTool({
  tools: myTools,
  executor,
});

return generateText({
  model,
  messages,
  tools: { codemode },
});

Code Mode SDK 還提供了兩個伺服器端實用函式。codeMcpServer({ server, executor }) 會包裝現有的 MCP 伺服器,將其工具介面替換為單一的 code() 工具。openApiMcpServer({ spec, executor, request }) 則更進一步:給定 OpenAPI 規範和一個 executor,它會建立一個完整的 MCP 伺服器,內含 search()execute() 工具(與 Cloudflare MCP 伺服器所使用的相同),並且更適合較大型的 API。

在以上兩種情況下,模型產生的程式碼都會在 Dynamic Workers 內部執行,而對外部服務的呼叫則會透過傳遞給 executor 的 RPC 繫結來進行。

進一步瞭解函式庫及其使用方式。

打包

Dynamic Workers 預期使用預先打包好的模組。@cloudflare/worker-bundler 為您處理這項工作:給定來源檔案和 package.json,它會從 registry 解析 npm 相依性,使用 esbuild 將所有內容打包,並回傳 Worker Loader 所需的模組對應表。

import { createWorker } from "@cloudflare/worker-bundler";

const worker = env.LOADER.get("my-worker", async () => {
  const { mainModule, modules } = await createWorker({
    files: {
      "src/index.ts": `
        import { Hono } from 'hono';
        import { cors } from 'hono/cors';

        const app = new Hono();
        app.use('*', cors());
        app.get('/', (c) => c.text('Hello from Hono!'));
        app.get('/json', (c) => c.json({ message: 'It works!' }));

        export default app;
      `,
      "package.json": JSON.stringify({
        dependencies: { hono: "^4.0.0" }
      })
    }
  });

  return { mainModule, modules, compatibilityDate: "2026-01-01" };
});

await worker.getEntrypoint().fetch(request);

它也透過 createApp 支援完整堆疊應用程式——將伺服器 Worker、用戶端 JavaScript 和靜態資產打包在一起,並內建資產服務功能,可處理內容類型、ETag 和 SPA 路由。

進一步瞭解函式庫及其使用方式。

檔案操作

@cloudflare/shell 為您的智慧體在 Dynamic Worker 內部提供了一個虛擬檔案系統。智慧體程式碼在 state 物件上呼叫有型別的方法(讀取、寫入、搜尋、取代、比對差異、Glob、JSON 查詢/更新、封存),這些操作都具有結構化的輸入和輸出,無需進行字串剖析。

儲存空間由持久的 Workspace (SQLite + R2) 提供支援,因此檔案會在多次執行之間持續存在。searchFilesreplaceInFilesplanEdits 等粗粒度操作能最大程度減少 RPC 往返次數——智慧體只需發出一次呼叫,而不需要逐一循環處理個別檔案。批次寫入預設為交易性:如果任何寫入失敗,先前的寫入會自動回滾。

import { Workspace } from "@cloudflare/shell";
import { stateTools } from "@cloudflare/shell/workers";
import { DynamicWorkerExecutor, resolveProvider } from "@cloudflare/codemode";

const workspace = new Workspace({
  sql: this.ctx.storage.sql, // Works with any DO's SqlStorage, D1, or custom SQL backend
  r2: this.env.MY_BUCKET, // large files spill to R2 automatically
  name: () => this.name   // lazy — resolved when needed, not at construction
});

// Code runs in an isolated Worker sandbox with no network access
const executor = new DynamicWorkerExecutor({ loader: env.LOADER });

// The LLM writes this code; `state.*` calls dispatch back to the host via RPC
const result = await executor.execute(
  `async () => {
    // Search across all TypeScript files for a pattern
    const hits = await state.searchFiles("src/**/*.ts", "answer");
    // Plan multiple edits as a single transaction
    const plan = await state.planEdits([
      { kind: "replace", path: "/src/app.ts",
        search: "42", replacement: "43" },
      { kind: "writeJson", path: "/src/config.json",
        value: { version: 2 } }
    ]);
    // Apply atomically — rolls back on failure
    return await state.applyEditPlan(plan);
  }`,
  [resolveProvider(stateTools(workspace))]
);

該套件還提供了預先建置好的 TypeScript 型別宣告檔和系統提示詞範本,讓您只需極少的詞元就能將完整的 state API 放入 LLM 的脈絡中。

進一步瞭解函式庫及其使用方式。

人們如何使用它?

程式碼模式

開發人員希望他們的智慧體能夠針對工具 API 撰寫並執行程式碼,而不是一次只進行一個循序的工具呼叫。透過 Dynamic Workers,LLM 會產生一個單一的 TypeScript 函式,將多個 API 呼叫串連在一起,在一個 Dynamic Worker 中執行,然後將最終結果回傳給智慧體。如此一來,只有輸出結果會進入脈絡視窗,而不會包含每個中間步驟。這不僅減少了延遲和詞元用量,還能產生更好的結果,尤其是在工具介面龐大的情況下。

我們自己的 Cloudflare MCP 伺服器正是以這種方式建構的:它透過僅僅兩個工具(search 和 execute),在不到 1000 個詞元內就開放了整個 Cloudflare API,因為智慧體是根據型別化的 API 撰寫程式碼,而不是瀏覽數百個獨立的工具定義。

建立自訂自動化

開發人員正使用 Dynamic Workers 讓智慧體能夠即時建立自訂的自動化流程。例如,Zite 正在打造一個應用程式平台,使用者透過聊天介面進行互動,而 LLM 會在幕後撰寫 TypeScript 程式碼來建置 CRUD 應用程式、連接到 Stripe、Airtable 和 Google Calendar 等服務,並執行後端邏輯,使用者從頭到尾都不會看到任何一行程式碼。每個自動化流程都在其專屬的 Dynamic Worker 中執行,且只能存取該端點所需的特定服務和函式庫。

「為了讓 Zite 的 LLM 產生應用程式具備伺服器端程式碼能力,我們需要一個即時、隔離且安全的執行層。Cloudflare 的 Dynamic Workers 在這三方面都達到了標準,並且在速度和函式庫支援方面表現優於我們測試過的所有其他平台。其 NodeJS 相容的執行環境支援了 Zite 的所有工作流程,允許數百個第三方整合,同時不影響啟動時間。如今,Zite 每天透過 Dynamic Workers 處理數百萬次執行請求。」

——Antony Toron,Zite 技術長兼共同創辦人

執行 AI 產生的應用程式

開發人員正在打造能夠從 AI 產生完整應用程式的平台——無論是為他們的客戶,還是為內部團隊建立原型。使用 Dynamic Workers,每個應用程式都可以按需啟動,然後放回冷儲存狀態,直到再次被呼叫。快速的啟動時間讓開發人員能夠在活躍開發期間輕鬆預覽變更。平台還可以封鎖或攔截生成程式碼發出的任何網路請求,確保 AI 產生的應用程式能夠安全執行。

定價

動態載入之 Workers 的定價為每天每個加載的唯一 Worker 0.002 美元(截至本文發佈時),此外還需支付常規工作進程的 CPU 時間和叫用費用。

對於 AI 產生的「程式碼模式」使用案例,每個 Worker 都是一次性的獨立單元,這意味著每個載入的 Worker 成本為 0.002 美元(外加 CPU 和叫用費用)。與產生程式碼所需的推斷成本相比,這個成本通常可以忽略不計。

在測試期間,0.002 美元的費用將被免除。由於定價可能變動,請務必查閱我們的 Dynamic Workers 定價頁面以取得最新資訊。

開始使用

如果您使用 Workers 付費方案,現在就可以開始使用 Dynamic Workers

Dynamic Workers 入門套件

部署到 Cloudflare

使用這個「hello world」入門套件來部署一個能夠載入和執行 Dynamic Workers 的 Worker。

Dynamic Workers Playground

部署到 Cloudflare

您也可以部署 Dynamic Workers Playground,您可以在其中撰寫或匯入程式碼,在執行階段使用 @cloudflare/worker-bundler 進行打包,透過 Dynamic Worker 執行它,並查看即時回應和執行記錄。

BLOG-3243 2

Dynamic Workers Workers 快速、可擴展且輕量。如果您有任何問題,請在 Discord 上與我們聯絡。我們很期待看到您打造的應用程式!

BLOG-3243 3

我們保護整個企業網路,協助客戶有效地建置網際網路規模的應用程式,加速任何網站或網際網路應用程式抵禦 DDoS 攻擊,阻止駭客入侵,並且可以協助您實現 Zero Trust

從任何裝置造訪 1.1.1.1,即可開始使用我們的免費應用程式,讓您的網際網路更快速、更安全。

若要進一步瞭解我們協助打造更好的網際網路的使命,請從這裡開始。如果您正在尋找新的職業方向,請查看我們的職缺
MCPWorkers AIAI代理程式開發人員平台開發人員

在 X 上進行關注

Kenton Varda|@kentonvarda
Sunil Pai|@threepointone
Cloudflare|@cloudflare

相關貼文