ClaudeCloudflare2026/03/24 13:00

Sandboxing AI agents, 100x faster

要点だけを先に読めるように短く再構成したセクションです。

元記事

Quick Digest

要約

要点だけを先に読めるように短く再構成したセクションです。

claudejamodel: claude-sonnet-4-20250514

CloudflareのDynamic Worker Loader:AIエージェント向け高速サンドボックス環境

Key Points

  • コンテナより100倍高速なV8 isolateベースサンドボックス
  • TypeScript APIによる簡潔なエージェント開発
  • 8年間の運用実績による堅牢なセキュリティ

Summary

Cloudflareが、AIエージェントが生成したコードを安全に実行するためのDynamic Worker Loader APIをオープンベータで提供開始。従来のコンテナベースのサンドボックスと比較して100倍高速で、10-100倍メモリ効率が良い。

Key Points

  • 高速起動: V8 isolateベースで数ミリ秒で起動、数MBのメモリ使用量
  • 無制限スケーラビリティ: 同時実行数や作成レート制限なし、毎秒数百万リクエストに対応
  • ゼロレイテンシ: 同一マシン・スレッドで実行、世界中の数百拠点で利用可能
  • TypeScript API: OpenAPIより簡潔で少ないトークンでAPI定義が可能
  • HTTP フィルタリング: 認証情報の自動注入、リクエストの検査・書き換えが可能
  • 堅牢なセキュリティ: 8年間のisolate運用実績、V8パッチの自動適用、多層防御システム

Full Translation

翻訳

原文の流れを保ったまま読める翻訳セクションです。

claudejamodel: claude-sonnet-4-20250514

AIエージェントのサンドボックス化、100倍高速化

AIエージェントのサンドボックス化、100倍高速化

2026年3月24日 | Kenton Varda、Sunil Pai、Ketan Gupta | 9分で読める

昨年9月、私たちはCode Modeを発表しました。これは、エージェントがツール呼び出しを行うのではなく、APIを呼び出すコードを書くことでタスクを実行すべきだという考えです。MCPサーバーをTypeScript APIに変換するだけで、トークン使用量を81%削減できることを示しました。また、Code ModeがMCPサーバーの前ではなく後ろで動作することも実証し、わずか2つのツールと1,000トークン未満でCloudflare API全体を公開する新しいCloudflare MCPサーバーを作成しました。

しかし、エージェント(またはMCPサーバー)がタスクを実行するためにAIによって動的に生成されたコードを実行する場合、そのコードはどこかで実行される必要があり、その場所は安全である必要があります。アプリケーション内でAI生成コードを直接eval()することはできません。悪意のあるユーザーが簡単にAIに脆弱性を注入するよう促すことができるからです。

サンドボックスが必要です。コードが意図してアクセスすべき特定の機能を除いて、アプリケーションや外部世界から隔離されたコード実行環境です。

サンドボックス化はAI業界のホットトピック

このタスクのために、多くの人がコンテナに手を伸ばしています。Linuxベースのコンテナを使用すれば、任意の種類のコード実行環境を起動できます。CloudflareもこのためにコンテナランタイムとSandbox SDKを提供しています。

しかし、コンテナは高価で起動が遅く、起動に数百ミリ秒、実行に数百メガバイトのメモリが必要です。遅延を避けるためにウォームに保つ必要があり、セキュリティを損なう複数のタスクで既存のコンテナを再利用したくなるかもしれません。

すべてのエンドユーザーがエージェント(または複数!)を持ち、すべてのエージェントがコードを書くコンシューマー規模のエージェントをサポートしたい場合、コンテナでは不十分です。より軽量なものが必要です。

そして、私たちはそれを持っています。

Dynamic Worker Loader:軽量サンドボックス

9月のCode Modeの投稿に隠れていたのは、新しい実験的機能の発表でした:Dynamic Worker Loader APIです。このAPIにより、Cloudflare Workerは実行時に指定されたコードで、独自のサンドボックス内に新しいWorkerをその場でインスタンス化できます。

Dynamic Worker Loaderは現在オープンベータで、すべての有料Workersユーザーが利用できます。完全な詳細についてはドキュメントを読んでくださいが、以下のような感じです:

// LLMにこのようなコードを生成させます
let agentCode: string = `
export default {
  async myAgent(param, env, ctx) {
    // ...
  }
}
`;

// エージェントがアクセスできるAPIを表すRPCスタブを取得
// (これは定義した任意のWorkers RPC APIです)
let chatRoomRpcStub = ...;

// ワーカーローダーバインディングを使用してコードを実行するワーカーをロード
let worker = env.LOADER.load({
  // コードを指定
  compatibilityDate: "2026-03-01",
  mainModule: "agent.js",
  modules: {
    "agent.js": agentCode
  },
  // エージェントにチャットルームAPIへのアクセスを提供
  env: {
    CHAT_ROOM: chatRoomRpcStub
  },
  // インターネットアクセスをブロック(インターセプトも可能)
  globalOutbound: null,
});

// エージェントコードによってエクスポートされたRPCメソッドを呼び出し
await worker.getEntrypoint().myAgent(param);

それだけです。

100倍高速

Dynamic Workersは、8年前のローンチ以来Cloudflare Workersプラットフォーム全体が構築されてきた同じ基盤サンドボックスメカニズムを使用します:isolatesです。

isolateは、Google Chromeで使用されているのと同じエンジンであるV8 JavaScript実行エンジンのインスタンスです。これがWorkersの仕組みです。

isolateは起動に数ミリ秒、メモリ使用量は数メガバイトです。これは典型的なコンテナより約100倍高速で、10倍から100倍メモリ効率が良いです。

つまり、ユーザーリクエストごとにオンデマンドで新しいisolateを開始し、1つのコードスニペットを実行してから破棄することができます。

無制限のスケーラビリティ

多くのコンテナベースのサンドボックスプロバイダーは、グローバル同時サンドボックス数とサンドボックス作成レートに制限を課しています。Dynamic Worker Loaderにはそのような制限がありません。これまでずっとWorkersが毎秒数百万のリクエストにシームレスにスケールできる同じ技術への単なるAPIだからです。

毎秒100万のリクエストを処理し、すべてのリクエストが個別のDynamic Workerサンドボックスをロードして同時実行したいですか?問題ありません!

ゼロレイテンシ

一回限りのDynamic Workersは通常、それを作成したWorkerと同じマシン(同じスレッドでさえ)で実行されます。ウォームサンドボックスを見つけるために世界中と通信する必要はありません。isolateは非常に軽量なので、リクエストが到着した場所で実行できます。

Dynamic Workersは世界中のCloudflareの数百の拠点すべてでサポートされています。

すべてJavaScript

コンテナと比較した唯一の制約は、エージェントがJavaScriptを書く必要があることです。技術的には、Workers(動的なものを含む)はPythonとWebAssemblyを使用できますが、エージェントによってオンデマンドで書かれるような小さなコードスニペットの場合、JavaScriptの方がはるかに高速にロードして実行されます。

私たち人間はプログラミング言語に強い好みを持つ傾向があり、多くの人がJavaScriptを愛する一方で、Python、Rust、その他無数の言語を好む人もいます。しかし、ここでは人間の話をしているのではありません。AIの話をしているのです。

AIは望む任意の言語を書きます。LLMはすべての主要言語のエキスパートです。JavaScriptでの訓練データは膨大です。JavaScriptは、Web上での性質により、サンドボックス化されるように設計されています。これは仕事に適した正しい言語です。

TypeScriptで定義されたツール

エージェントが有用なことを実行できるようにするには、外部APIと通信する必要があります。アクセスできるAPIについてどのように伝えるのでしょうか?

MCPはフラットなツール呼び出しのスキーマを定義しますが、プログラミングAPIは定義しません。OpenAPIはREST APIを表現する方法を提供しますが、スキーマ自体とそれを呼び出すために書く必要があるコードの両方で冗長です。

JavaScriptに公開されるAPIには、単一の明白な答えがあります:TypeScriptです。

エージェントはTypeScriptを知っています。TypeScriptは簡潔になるように設計されています。非常に少ないトークンで、エージェントにAPIの正確な理解を与えることができます。

// チャットルームと対話するインターフェース
interface ChatRoom {
  // チャットログの最後の`limit`件のメッセージを取得
  getHistory(limit: number): Promise<Message[]>;
  
  // 新しいメッセージを購読。返されたオブジェクトを破棄して購読解除
  subscribe(callback: (msg: Message) => void): Promise<Disposable>;
  
  // チャットにメッセージを投稿
  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は、サンドボックスとハーネスコード間でCap'n Web RPCブリッジを自動的に設定するため、エージェントはローカルライブラリを使用していることに気づくことなく、セキュリティ境界を越えてAPIを呼び出すことができます。

つまり、エージェントは次のようなコードを書くことができます:

// 思考:ユーザーはAliceからの最近のチャットメッセージの要約を求めました。
// 関連するメッセージのみを読むために、最近のメッセージ履歴をコードでフィルタリングします。
let history = await env.CHAT_ROOM.getHistory(1000);
return history.filter(msg => msg.author == "alice");

HTTPフィルタリングと認証情報注入

エージェントにHTTP APIを提供したい場合、それは完全にサポートされています。ワーカーローダーAPIのglobalOutboundオプションを使用して、すべてのHTTPリクエストで呼び出されるコールバックを登録できます。このコールバックでは、リクエストを検査、書き換え、認証キーの注入、直接応答、ブロック、その他任意の処理を行うことができます。

例えば、これを使用して認証情報注入(トークン注入)を実装できます:エージェントが認証を必要とするサービスにHTTPリクエストを行うとき、送信時にリクエストに認証情報を追加します。この方法で、エージェント自体は秘密の認証情報を知ることがなく、したがってそれらを漏洩させることができません。

プレーンなHTTPインターフェースの使用は、エージェントが訓練セットにある既知のAPIと通信する場合や、REST APIに基づいて構築されたライブラリをエージェントに使用させたい場合(ライブラリはエージェントのサンドボックス内で実行できます)に望ましい場合があります。

とはいえ、互換性要件がない場合、TypeScript RPCインターフェースはHTTPより優れています:

  • 上記のように、TypeScript インターフェースはHTTPインターフェースよりもはるかに少ないトークンで記述できます
  • エージェントは同等のHTTPよりもはるかに少ないトークンでTypeScriptインターフェースを呼び出すコードを書くことができます
  • TypeScriptインターフェースでは、独自のラッパーインターフェースを定義するため、シンプルさとセキュリティの両方のために、エージェントに提供したい機能を正確に公開するようにインターフェースを絞り込むことが簡単です
  • HTTPでは、既存のAPIに対するリクエストのフィルタリングを実装する可能性が高くなります。これは困難です。プロキシがすべてのAPI呼び出しの意味を完全に解釈して適切に許可するかどうかを決定する必要があり、HTTPリクエストは多くのヘッダーやその他のパラメータを持つ複雑なもので、すべてが意味を持つ可能性があるからです。結局、許可したい機能のみを実装するTypeScriptラッパーを書く方が簡単になります

実戦で鍛えられたセキュリティ

isolateベースのサンドボックスの強化は、ハードウェア仮想マシンよりも複雑な攻撃面であるため、困難です。すべてのサンドボックスメカニズムにはバグがありますが、V8のセキュリティバグは典型的なハイパーバイザーのセキュリティバグよりも一般的です。

悪意のある可能性のあるコードをサンドボックス化するためにisolateを使用する場合、追加の多層防御が重要です。例えば、Google Chromeはこの理由で厳格なプロセス分離を実装しましたが、それが唯一の可能な解決策ではありません。

私たちはisolateベースプラットフォームのセキュリティ確保において約10年の経験があります:

  • システムは数時間以内にV8セキュリティパッチを本番環境に自動デプロイします — Chrome自体よりも高速です
  • セキュリティアーキテクチャは、リスク評価に基づくテナントの動的隔離を備えたカスタム第2層サンドボックスを特徴としています
  • MPKなどのハードウェア機能を活用するためにV8サンドボックス自体を拡張しました
  • Spectreに対する新しい防御を開発するために主要な研究者とチームを組み(雇用もしました)
  • 悪意のあるパターンをスキャンして自動的にブロックしたり、追加のサンドボックス層を適用するシステムもあります
  • その他多数

CloudflareでDynamic Workersを使用すると、これらすべてが自動的に得られます。

ヘルパーライブラリ

私たちは多数のライブラリを構築しました