OpenAICloudflare2026/04/13 13:08

Agents have their own computers with Sandboxes GA

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

元記事

Quick Digest

要約

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

openaijamodel: gpt-5-mini-2025-08-07

Sandboxes GA:エージェント専用コンピュータが利用可能に

Key Points

  • 資格情報注入
  • PTY対応
  • スナップショット復元

Summary

Cloudflare SandboxesがGAとなり、エージェント向けの永続・隔離されたコンピュート環境を正式提供します。IDベースの起動・スリープ、ネットワーク層での安全な資格情報注入、PTY端末、永続的なコード実行コンテキスト(Python/JS/TS)、バックグラウンドプロセスと公開プレビューURL、ファイル監視、スナップショットによる高速復元、そしてActive CPU課金と高いリソース上限により、エージェントを大規模に安全かつコスト効率よく運用できます。主要API(getSandbox, exec, gitCheckout, terminal, createCodeContext, startProcess, exposePort, watch, snapshot)を使った実運用のポイントを以下にまとめます。

Key Points

  • 起動・永続性
    • 同一IDでgetSandboxすれば同じセッションに接続可能。アイドル時は自動でsleepし、スナップショットで高速復元できる。
  • 認証(セキュリティ)
    • 資格情報はエグレスプロキシで注入され、エージェントは生のクレデンシャルに触れない。ホスト単位で注入ルールを定義可能。
  • ターミナルとデバッグ
    • sandbox.terminalで本物のPTYを提供(xterm.js互換)。出力バッファにより再接続時のログ再生も可能。
  • 永続的コード実行コンテキスト
    • createCodeContext/runCodeで変数・インポートがセッション間で持続。データ解析や対話的スクリプトに有効。
  • 開発サーバとプレビュー
    • startProcess + waitForLog/waitForPortで確実に起動を検知し、exposePortで公開プレビューURLを発行してユーザーに共有できる。
  • ファイル監視と高速反応
    • sandbox.watchはinotifyベースのSSEを提供。ファイル変更でビルドやテストをトリガーしてフィードバックループを短縮。
  • スケーリングと運用
    • スナップショットはR2に保存され、複数フォークの高速起動が可能。Active CPU課金によりアイドル時のコストを削減できる。

実践的には、CI/自動エージェント用途では「スナップショット保存+ID管理」でセッション再現性を確保し、外部サービスアクセスは資格情報注入で最小権限化する運用を推奨します。

Full Translation

翻訳

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

openaijamodel: gpt-5-mini-2025-08-07

エージェントは独自のコンピュータを持つ — Sandboxes が一般提供(GA)に

Agents have their own computers with Sandboxes GA

公開日: 2026-04-13 執筆: Kate Reznykova, Mike Nomitch

昨年6月に Cloudflare Sandboxes をローンチした際の前提はシンプルでした。AI エージェントはコードを開発・実行する必要があり、それを安全に実行できる場所が必要です。エージェントが開発者のように振る舞うなら、リポジトリのクローン、複数言語でのビルド、開発サーバの起動などが発生します。これらを効果的に行うには、フルなコンピュータ環境が必要になることが多く(必要がなければ軽量な環境を使えばよい)、多くの開発者は VM や既存のコンテナを組み合わせて解決しようとしていますが、以下のような難題が残ります:

  • バースト性: セッションごとに個別のサンドボックスが必要で、多数を短時間で起動したいが、待機中の無駄なコンピュートには課金したくない。
  • 高速な状態復元: 各セッションは高速に開始・再開でき、過去の状態を継続できるべき。
  • セキュリティ: エージェントにサービスへのアクセスを許可したいが、資格情報を直接預けられない。
  • 制御: サンドボックスのライフサイクル制御、コマンド実行、ファイル操作などをプログラムから簡単に扱える必要がある。
  • 操作性: 人間とエージェントの双方にとって共通操作がシンプルなインターフェースで提供されるべき。

これらの問題を解くために時間を費やしてきました。初期ローンチ以降、Sandboxes は大規模なエージェント実行にさらに適した環境になっています。初期パートナーの一つである Figma の事例もあります。Figma は Figma Make 上でコンテナ内にエージェントを走らせています:

"Figma Make is built to help builders and makers of all backgrounds go from idea to production, faster. To deliver on that goal, we needed an infrastructure solution that could provide reliable, highly-scalable sandboxes where we could run untrusted agent- and user-authored code. Cloudflare Containers is that solution." — Alex Mullans, AI and Developer Platforms at Figma

本日、Sandboxes と Cloudflare Containers の両方が一般提供(GA)になったことをお知らせします。以下は Sandboxes に加わった最近の変更点の概要です:

  • セキュアな資格情報注入(Secure credential injection)により、エージェントが資格情報にアクセスせずに認証済みリクエストを実行可能
  • PTY サポートにより、エージェントと人間のための実際の端末が利用可能
  • 永続的なコード実行インタープリタ(Python / JavaScript / TypeScript)で状態を持つ実行コンテキストを提供
  • バックグラウンドプロセスとライブプレビュー URL で開発サーバを簡単に共有
  • ファイルシステム監視でエージェントの変更に即時反応
  • スナップショットでエージェントのコーディングセッションを素早く復元
  • 高い上限と Active CPU Pricing により、未使用 CPU に課金せずエージェント群を展開可能

Sandboxes 101

Sandboxes の基本を簡単に説明します。Cloudflare Sandbox は Cloudflare Containers によって提供される永続化された隔離環境です。名前でサンドボックスを要求します。既に実行中ならそれを取得し、実行されていなければ起動します。アイドル状態では自動的にスリープし、リクエストが来ると再び起動します。

プログラムからは exec、gitClone、writeFile といったメソッドを使って簡単に操作できます。例:

import { getSandbox } from "@cloudflare/sandbox";
export { Sandbox } from "@cloudflare/sandbox";
export default {
  async fetch(request: Request, env: Env) {
    // Ask for a sandbox by name. It starts on demand.
    const sandbox = getSandbox(env.Sandbox, "agent-session-47");

    // Clone a repository into it.
    await sandbox.gitCheckout("https://github.com/org/repo", {
      targetDir: "/workspace",
      depth: 1,
    });

    // Run the test suite. Stream output back in real time.
    return sandbox.exec("npm", ["test"], { stream: true });
  },
};

同じ ID を指定すれば、以降のリクエストは世界中どこからでも同じサンドボックスに到達できます。

セキュアな資格情報注入

エージェントワークロードにおける最も難しい問題の一つが認証です。エージェントにプライベートサービスへアクセスさせたいが、生の資格情報を完全に信頼して渡せません。Sandboxes はプログラム可能な egress proxy によるネットワーク層での資格情報注入でこれを解決します。つまり、サンドボックス内のエージェントは資格情報に直接アクセスすることがなく、認証ロジックを柔軟にカスタマイズできます:

class OpenCodeInABox extends Sandbox {
  static outboundByHost = {
    "my-internal-vcs.dev": (request, env, ctx) => {
      const headersWithAuth = new Headers(request.headers);
      headersWithAuth.set("x-auth-token", env.SECRET);
      return fetch(request, { headers: headersWithAuth });
    }
  }
}

詳細(identity-aware credential injection、ルールの動的変更、Workers バインディングとの連携など)については、Sandbox auth に関するブログ記事をご参照ください。

実際の端末(PTY) — シミュレーションではなく

初期のエージェント実装はシェルアクセスをリクエスト-レスポンスのループとして扱うことが多く、コマンドを実行して出力を待ち、トランスクリプトをプロンプトに戻すといった方式でした。それでも動きますが、開発者が実際に端末を使うやり方ではありません。人間はコマンドを実行して出力をストリームで見て、割り込みをかけ、後で再接続して続けます。エージェントも同じフィードバックループから利得を得ます。

2月に PTY サポートを提供しました。Sandbox 内の疑似端末セッションが WebSocket を介してプロキシされ、xterm.js と互換です。バックエンドは sandbox.terminal を呼び出して提供します:

// Worker: upgrade a WebSocket connection into a live terminal session
export default {
  async fetch(request: Request, env: Env) {
    const url = new URL(request.url);
    if (url.pathname === "/terminal") {
      const sandbox = getSandbox(env.Sandbox, "my-session");
      return sandbox.terminal(request, { cols: 80, rows: 24 });
    }
    return new Response("Not found", { status: 404 });
  },
};

クライアント側は xterm アドオンを使って接続します:

// Browser: connect xterm.js to the sandbox shell
import { Terminal } from "xterm";
import { SandboxAddon } from "@cloudflare/sandbox/xterm";
const term = new Terminal();
const addon = new SandboxAddon({ getWebSocketUrl: ({ origin }) => `${origin}/terminal`, });
term.loadAddon(addon);
term.open(document.getElementById("terminal-container")!);
addon.connect({ sandboxId: "my-session" });

これにより、エージェントと開発者は完全な PTY を使ってセッションをライブでデバッグできます。各ターミナルセッションは独立したシェル、作業ディレクトリ、環境を持ち、必要なだけ開くことができます。出力はサーバ側でバッファされ、再接続時に見逃した出力の再生が可能です。

状態を覚えるコードインタープリタ

データ解析、スクリプト、探索的ワークフローのために、より高レベルな抽象として『永続的なコード実行コンテキスト』を提供します。キーワードは「永続」です。多くのコードインタープリタは各スニペットを独立して実行し、呼び出し間で状態が失われますが、Sandboxes のコンテキストは状態を保持します。変数やインポートは Jupyter notebook のように呼び出し間で持続します:

// Create a Python context. State persists for its lifetime.
const ctx = await sandbox.createCodeContext({ language: "python" });

// First execution: load data
await sandbox.runCode(`
import pandas as pd
df = pd.read_csv('/workspace/sales.csv')
df['margin'] = (df['revenue'] - df['cost']) / df['revenue']
`, { context: ctx });

// Second execution: df is still there
const result = await sandbox.runCode(`
df.groupby('region')['margin'].mean().sort_values(ascending=False)
`, { context: ctx, onStdout: (line) => console.log(line.text) });

result には matplotlib チャート、構造化された JSON 出力、Pandas のテーブル(HTML)などが含まれます。

サーバを起動して URL を取得、公開するワークフロー

エージェントは何かをビルドしてすぐにユーザーに見せられると役立ちます。Sandboxes はバックグラウンドプロセス、レディネスチェック、preview URLs をサポートしており、エージェントは会話の流れを離れずに開発サーバを起動してライブリンクを共有できます。

// Start a dev server as a background process
const server = await sandbox.startProcess("npm run dev", { cwd: "/workspace" });

// Wait until the server is actually ready — don't just sleep and hope
await server.waitForLog(/Local:.*localhost:(\d+)/);

// Expose the running service with a public URL
const { url } = await sandbox.exposePort(3000);
// url is a live public URL the agent can share with the user
console.log(`Preview: ${url}`);

waitForPort() や waitForLog() により、実行中プログラムからの実際のシグナルに基づいて作業を順序付けできます。これは単に sleep(2000) して期待する、という代替手段よりずっと堅牢です。

ファイルシステムを監視して即時反応

現代の開発ループはイベント駆動です。ファイルを保存すればビルドが再実行される。設定を編集すればサーバが再起動する。テストを変更すればテストスイートが再実行される。3月に sandbox.watch() を公開しました。これはネイティブ inotify による SSE ストリームを返します。

import { parseSSEStream, type FileWatchSSEEvent } from '@cloudflare/sandbox';
const stream = await sandbox.watch('/workspace/src', { recursive: true, include: ['*.ts', '*.tsx'] });

for await (const event of parseSSEStream<FileWatchSSEEvent>(stream)) {
  if (event.type === 'modify' && event.path.endsWith('.ts')) {
    await sandbox.exec('npx tsc --noEmit', { cwd: '/workspace' });
  }
}

これは、エージェントがファイルシステムの変化をリアルタイムで観察できるようにし、人間の開発者と同等のフィードバックループに参加できるという点で重要なプリミティブです。

スナップショットで素早く復帰

人間の開発者がラップトップで作業する様子を想像してください。git clone して npm install を実行し、コードを書いて PR を出し、レビュー待ちでラップトップを閉じます。作業を再開するときはラップトップを開くだけで続きができます。エージェントが同様のワークフローを、単純なコンテナ環境で再現しようとすると問題が出ます。どうやってすばやく再開しますか?サンドボックスを常時稼働させればアイドル費用がかかるし、コンテナイメージから再起動すれば git clone と npm install を待たねばなりません。

我々の答えはスナップショットです。今後数週間で展開されます。スナップショットはコンテナのディスク全体の状態、OS 設定、インストール済み依存関係、変更済みファイル、データファイルなどを保存し、後で高速に復元できます。サンドボックスをスリープに入れる際に自動スナップショットを取るよう設定することも可能です:

class AgentDevEnvironment extends Sandbox {
  sleepAfter = "5m";
  persistAcrossSessions = {type: "disk"};
  // you can also specify individual directories
}

プログラムからスナップショットを作成したり手動で復元したりすることも可能で、チェックポイントやセッションのフォークに便利です。例えば同じ状態からエージェントのインスタンスを4つ並列起動する場合:

class AgentDevEnvironment extends Sandbox {}
async function forkDevEnvironment(baseId, numberOfForks) {
  const baseInstance = await getSandbox(baseId);
  const snapshotId = await baseInstance.snapshot();
  const forks = Array.from({ length: numberOfForks }, async (_, i) => {
    const newInstance = await getSandbox(`${baseId}-fork-${i}`);
    return newInstance.start({ snapshot: snapshotId });
  });
  await Promise.all(forks);
}

スナップショットはあなたのアカウント内の R2 に保存され、耐久性とロケーション非依存性を提供します。R2 の階層キャッシュにより、全リージョンでの高速復元が可能です。将来のリリースではライブメモリ状態もキャプチャされ、実行中プロセスをそのまま再開できるようになります。端末とエディタが再度開かれ...

(記事は続きます)