ClaudeCloudflare2026/04/13 13:08

Agents have their own computers with Sandboxes GA

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

元記事

Quick Digest

要約

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

claudejamodel: claude-sonnet-4-20250514

Cloudflare Sandboxes GA - AIエージェント向け安全な実行環境

Key Points

  • AIエージェント向けサンドボックス環境がGA開始
  • 認証情報を直接渡さない安全な認証システム
  • スナップショット機能で高速な環境復旧を実現

Summary

Cloudflare SandboxesがGA(一般提供)を開始。AIエージェントが安全にコードを開発・実行できる隔離された環境を提供し、認証情報の安全な注入、リアルタイムターミナル、永続的なコード実行コンテキストなどの機能を搭載。

Key Points

  • セキュアな認証情報注入: エージェントに直接認証情報を渡すことなく、ネットワーク層でプロキシ経由で認証を処理
  • PTYサポート: WebSocket経由でxterm.js互換のリアルタイムターミナルセッションを提供
  • 永続的コード実行: Python/JavaScript/TypeScriptでJupyterノートブックのように状態を保持したコード実行が可能
  • バックグラウンドプロセス: 開発サーバーの起動と公開URLの自動生成をサポート
  • ファイルシステム監視: inotifyベースのリアルタイムファイル変更検知機能
  • スナップショット機能: ディスク状態の保存・復元により高速な環境復旧を実現
  • Active CPU Pricing: 未使用CPU時間に対する課金を回避する従量課金モデル

Full Translation

翻訳

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

claudejamodel: claude-sonnet-4-20250514

Sandboxes GAによりエージェントが独自のコンピューターを持つ

Sandboxes GAによりエージェントが独自のコンピューターを持つ

2026年4月13日 | Kate Reznykova、Mike Nomitch | 6分で読める

昨年6月にCloudflare Sandboxesをローンチした際、前提はシンプルでした:AIエージェントはコードを開発・実行する必要があり、それを安全な場所で行う必要があります。エージェントが開発者のように動作するということは、リポジトリのクローン、多言語でのコード構築、開発サーバーの実行などを意味します。これらを効果的に行うには、多くの場合フルコンピューターが必要です(必要でない場合は、軽量なものを選択できます!)。

多くの開発者がVMや既存のコンテナソリューションを使用してソリューションを組み合わせていますが、解決すべき困難な問題が多数あります:

  • バースト性 - 各セッションが独自のサンドボックスを必要とするため、多くのサンドボックスを迅速にスピンアップする必要がありますが、待機中のアイドルコンピューティングに対して支払いたくありません。
  • 迅速な状態復元 - 各セッションは迅速に開始し、迅速に再開して、過去の状態を復元する必要があります。
  • セキュリティ - エージェントはサービスに安全にアクセスする必要がありますが、認証情報を信頼することはできません。
  • 制御 - サンドボックスのライフサイクルをプログラム的に制御し、コマンドを実行し、ファイルを処理することなどを簡単に行える必要があります。
  • エルゴノミクス - 人間とエージェントの両方が一般的な操作を行うためのシンプルなインターフェースを提供する必要があります。

私たちはこれらの問題を解決するために時間を費やしてきたので、あなたがその必要はありません。

パートナーとの協力

初期ローンチ以来、Sandboxesをエージェントを大規模に実行するためのさらに優れた場所にしてきました。Figma Make でコンテナ内でエージェントを実行するFigmaなどの初期パートナーと協力してきました:

「Figma Makeは、あらゆる背景を持つビルダーやメーカーがアイデアから本番環境まで、より迅速に進むのを支援するために構築されています。その目標を達成するために、信頼できない、エージェントやユーザーが作成したコードを実行できる信頼性が高く、高度にスケーラブルなサンドボックスを提供できるインフラストラクチャソリューションが必要でした。Cloudflare Containersがそのソリューションです。」

- Alex Mullans、FigmaのAI・開発者プラットフォーム担当

Sandboxesをさらに多くの優れた組織に提供したいと考えており、本日、SandboxesとCloudflare Containersの両方が一般提供開始されることを発表できることを嬉しく思います。

Sandboxesの最近の変更

Sandboxesの最近の変更をいくつか見てみましょう:

  • 安全な認証情報注入 - エージェントが認証情報にアクセスすることなく認証済み呼び出しを行えます
  • PTYサポート - あなたとエージェントに本物のターミナルを提供します
  • 永続的なコードインタープリター - エージェントがステートフルなPython、JavaScript、TypeScriptをすぐに実行できる場所を提供します
  • バックグラウンドプロセスとライブプレビューURL - 開発サーバーとやり取りし、進行中の変更を検証するシンプルな方法を提供します
  • ファイルシステム監視 - エージェントが変更を行う際の反復速度を向上させます
  • スナップショット - エージェントのコーディングセッションを迅速に復旧できます
  • より高い制限とActive CPU Pricing - 未使用のCPUサイクルに対して支払うことなく、エージェントのフリートを大規模にデプロイできます

Sandboxes 101

最近の変更について詳しく説明する前に、基本を簡単に見てみましょう。

Cloudflare SandboxはCloudflare Containersによって動力を得る永続的で分離された環境です。名前でサンドボックスを要求します。実行中の場合は、それを取得します。実行中でない場合は、開始します。アイドル状態の場合は、自動的にスリープし、リクエストを受信すると起動します。

execgitClonewriteFileなどのメソッドを使用してサンドボックスとプログラム的にやり取りするのは簡単です。

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

export default {
  async fetch(request: Request, env: Env) {
    // 名前でサンドボックスを要求。オンデマンドで開始。
    const sandbox = getSandbox(env.Sandbox, "agent-session-47");

    // リポジトリをクローン。
    await sandbox.gitCheckout("https://github.com/org/repo", {
      targetDir: "/workspace",
      depth: 1,
    });

    // テストスイートを実行。出力をリアルタイムでストリーミング。
    return sandbox.exec("npm", ["test"], {
      stream: true
    });
  },
};

同じIDを提供する限り、後続のリクエストは世界中のどこからでもこの同じサンドボックスにアクセスできます。

安全な認証情報注入

エージェントワークロードにおける最も困難な問題の1つは認証です。多くの場合、エージェントがプライベートサービスにアクセスする必要がありますが、生の認証情報を完全に信頼することはできません。

Sandboxesは、プログラム可能なエグレスプロキシを使用してネットワーク層で認証情報を注入することでこれを解決します。これは、サンドボックスエージェントが認証情報にアクセスすることがなく、必要に応じて認証ロジックを完全にカスタマイズできることを意味します:

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 });
    }
  }
}

これがどのように動作するかの詳細については、アイデンティティ対応認証情報注入、動的ルール変更、Workers bindingsとの統合を含む、Sandbox認証に関する最近のブログ投稿をお読みください。

本物のターミナル、シミュレーションではない

初期のエージェントシステムは、多くの場合シェルアクセスをリクエスト-レスポンスループとしてモデル化していました:コマンドを実行し、出力を待ち、トランスクリプトをプロンプトに戻し、繰り返す。これは機能しますが、開発者が実際にターミナルを使用する方法ではありません。

人間は何かを実行し、出力がストリーミングされるのを見て、それを中断し、後で再接続し、続行します。エージェントも同じフィードバックループから恩恵を受けます。

2月に、PTYサポートを出荷しました。SandboxでのPseudo-terminalセッション、WebSocket経由でプロキシされ、xterm.jsと互換性があります。バックエンドを提供するにはsandbox.terminalを呼び出すだけです:

// Worker: WebSocket接続をライブターミナルセッションにアップグレード
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: xterm.jsをサンドボックスシェルに接続
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を使用してこれらのセッションをライブでデバッグできます。各ターミナルセッションは独自の分離されたシェル、独自の作業ディレクトリ、独自の環境を取得します。必要なだけ開き、自分のマシンで行うのと同じように使用できます。出力はサーバー側でバッファリングされるため、再接続すると見逃したものが再生されます。

記憶するコードインタープリター

データ分析、スクリプト作成、探索的ワークフローのために、より高レベルの抽象化も提供しています:永続的なコード実行コンテキスト。

キーワードは「永続的」です。多くのコードインタープリター実装は各スニペットを分離して実行するため、呼び出し間で状態が消失します。1つのステップで変数を設定し、次のステップで読み取ることができません。

Sandboxesでは状態を永続化する「コンテキスト」を作成できます。変数とインポートは、Jupyterノートブックと同じように呼び出し間で永続化されます:

# Pythonコンテキストを作成。状態はその生存期間中永続化。
ctx = await sandbox.createCodeContext({ language: "python" });

# 最初の実行:データをロード
await sandbox.runCode(`
import pandas as pd
df = pd.read_csv('/workspace/sales.csv')
df['margin'] = (df['revenue'] - df['cost']) / df['revenue']
`, { context: ctx });

# 2番目の実行:dfはまだそこにある
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出力、HTMLのPandasテーブルが含まれる

サーバーを開始。URLを取得。出荷。

エージェントは何かを構築してユーザーにすぐに表示できるときにより有用です。Sandboxesはバックグラウンドプロセス、準備チェック、プレビューURLをサポートします。これにより、エージェントは開発サーバーを開始し、会話を離れることなくライブリンクを共有できます。

// 開発サーバーをバックグラウンドプロセスとして開始
const server = await sandbox.startProcess("npm run dev", {
  cwd: "/workspace",
});

// サーバーが実際に準備完了するまで待機 — ただスリープして希望するのではない
await server.waitForLog(/Local:.*localhost:(\d+)/);

// 実行中のサービスをパブリックURLで公開
const { url } = await sandbox.exposePort(3000);

// urlはエージェントがユーザーと共有できるライブパブリックURL
console.log(`Preview: ${url}`);

waitForPort()waitForLog()により、エージェントは推測ではなく実行中のプログラムからの実際のシグナルに基づいて作業をシーケンスできます。これは一般的な代替手段よりもはるかに優れており、通常はsleep(2000)の何らかのバージョンに続いて希望的観測です。

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

現代の開発ループはイベント駆動です。ファイルを保存し、ビルドを再実行。設定を編集し、サーバーを再起動。テストを変更し、スイートを再実行。

3月にsandbox.watch()を出荷しました。これは、Linuxがファイルシステムイベントに使用するカーネルメカニズムであるネイティブ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' });
  }
}

これは、エージェントができることを静かに変える原始的な機能の1つです。リアルタイムでファイルシステムを観察できるエージェントは、人間の開発者と同じフィードバックループに参加できます。

スナップショットで迅速な起動

ラップトップで作業している(人間の)開発者を想像してください。リポジトリをgit clone し、npm install を実行し、コードを書き、PRをプッシュし、コードレビューを待つ間ラップトップを閉じます。作業を再開する時が来たら、ラップトップを再び開いて中断したところから続行するだけです。

エージェントがナイーブなコンテナプラットフォームでこのワークフローを複製したい場合、問題に遭遇します。中断したところから迅速に再開するにはどうすればよいでしょうか?サンドボックスを実行し続けることもできますが、その場合はアイドルコンピューティングに対して支払うことになります。コンテナイメージから新しく開始することもできますが、その場合は長いgit cloneとnpm installを待つ必要があります。

私たちの答えはスナップショットで、今後数週間でロールアウトされる予定です。スナップショットはコンテナの完全なディスク状態、OS設定、インストールされた依存関係、変更されたファイル、データファイルなどを保存します。その後、後で迅速に復元できます。

Sandboxがスリープ状態になったときに自動的にスナップショットを取るように設定できます。

class AgentDevEnvironment extends Sandbox {
  sleepAfter = "5m";
  persistAcrossSessions = {type: "disk"}; // 個別のディレクトリも指定可能
}

プログラム的にスナップショットを取得し、手動で復元することもできます。これは作業のチェックポイントやセッションのフォークに有用です。たとえば、エージェントの4つのインスタンスを並行して実行したい場合、同じ状態から4つのサンドボックスを簡単に起動できます。

class AgentDevEnvironment extends Sandbox {}

async 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の階層キャッシュシステムにより、Region: Earth全体で高速復元が可能です。

将来のリリースでは、ライブメモリ状態もキャプチャされ、実行中のプロセスが中断したところから正確に再開できるようになります。ターミナルとエディターが再び開かれます。