サンドボックスクライアント
このページでは、サンドボックスでの作業をどこで実行するかを選択します。ほとんどの場合、SandboxAgent の定義はそのままにして、sandbox 実行オプション内のサンドボックスクライアントとクライアント固有のオプションのみを変更します。
| 目的 | 最初に選ぶもの | 理由 |
|---|---|---|
| macOS または Linux で最速のローカル反復開発 | UnixLocalSandboxClient | 追加のサービス依存関係がなく、ローカルファイルシステムを使ったワークフローがシンプルです。 |
| 基本的なコンテナー分離 | DockerSandboxClient | 指定したイメージを使用して Docker 内で作業を実行します。 |
| ホステッド実行または本番環境相当の分離 | ホステッドサンドボックスクライアント | ワークスペースの境界をプロバイダー管理の環境へ移します。 |
ローカルクライアント
Section titled “ローカルクライアント”ほとんどのユーザーは、次の 2 つのサンドボックスクライアントのいずれかから始めることをおすすめします。
| クライアント | インストール | 選択する場合 |
|---|---|---|
UnixLocalSandboxClient | 不要 | macOS または Linux で最速のローカル反復開発が必要な場合。ローカル開発に適したデフォルトです。 |
DockerSandboxClient | ローカルで Docker CLI を利用可能 | コンテナー分離が必要な場合、またはローカル環境との整合性を保つために特定のイメージを使用する場合。 |
Unix ローカルは、ローカルファイルシステムを使用した開発を始める最も簡単な方法です。より強力な環境分離や本番環境相当の整合性が必要になったら、Docker またはホステッドプロバイダーへ移行してください。
Unix ローカルから Docker へ切り替えるには、エージェントの定義はそのままにして、クライアントのみを変更します。
import { run } from '@openai/agents';import { SandboxAgent } from '@openai/agents/sandbox';import { DockerSandboxClient } from '@openai/agents/sandbox/local';
const agent = new SandboxAgent({ name: 'Workspace reviewer', model: 'gpt-5.6-sol', instructions: 'Inspect the sandbox workspace before answering.',});
const result = await run(agent, 'Inspect the workspace.', { sandbox: { client: new DockerSandboxClient({ image: 'node:22-bookworm-slim' }), },});
console.log(result.finalOutput);通常、同じエージェントをどちらのローカルクライアントでも実行できます。
import { DockerSandboxClient, UnixLocalSandboxClient,} from '@openai/agents/sandbox/local';
const client = process.env.USE_DOCKER ? new DockerSandboxClient({ image: 'node:22-bookworm-slim' }) : new UnixLocalSandboxClient();DockerSandboxClient は、クライアントのコンストラクターまたは実行ごとの sandbox.options で networkMode: 'none' を設定しない限り、Docker のデフォルトネットワークを使用します。'none' モードでは、ネットワークを無効にしてコンテナーを起動します。このモードは exposedPorts と組み合わせることができません。SDK はコンテナーを作成または再開する前に、その設定を拒否します。現在、明示的な networkMode の値はほかにサポートされていません。
セッションの所有権
Section titled “セッションの所有権”ライフサイクルには 2 つの方式があります。
| 方式 | 渡すもの | セッションを閉じる主体 | 使用する場合 |
|---|---|---|---|
| SDK 所有 | sandbox: { client } | ランナー | サンドボックスが 1 回の実行中だけ存在すればよい場合。 |
| 開発者所有 | sandbox: { session } | アプリケーションコード | 後からファイルを確認する場合、同じライブセッションを再利用する場合、または複数の実行を調整する場合。 |
正常完了時または失敗時には、ランナーが SDK 所有のセッションを閉じます。承認による中断で実行が一時停止した場合や、未完了のストリーミング実行がキャンセルされた場合は、同じ実行を継続できるように、ランナーは所有するサンドボックスの状態を RunState に保持します。
セッションを自分で作成した場合は、自分で閉じてください。
import { run } from '@openai/agents';import { Manifest, SandboxAgent } from '@openai/agents/sandbox';import { UnixLocalSandboxClient } from '@openai/agents/sandbox/local';
const manifest = new Manifest();const agent = new SandboxAgent({ name: 'Workspace reviewer', model: 'gpt-5.6-sol', instructions: 'Inspect the sandbox workspace before answering.',});
const client = new UnixLocalSandboxClient();const session = await client.create({ manifest });
try { await run(agent, 'First pass.', { sandbox: { session } }); await run(agent, 'Follow-up pass.', { sandbox: { session } });} finally { await session.close?.();}再開とスナップショット
Section titled “再開とスナップショット”サンドボックスの状態と会話の状態は別々に管理されます。
- SDK の会話状態は、
result.history、SDK のSession、conversationId、またはpreviousResponseIdに保存されます。 - サンドボックスの状態は、ライブサンドボックスセッション、シリアライズされた
sessionState、RunStateのサンドボックスペイロード、またはスナップショットに保存されます。
サンドボックスクライアントを通じて同じバックエンドセッションへ再接続する場合は、sessionState を使用します。保存済みのワークスペース内容を初期状態として新しいセッションを作成する場合は、スナップショットを使用します。
import { Manifest } from '@openai/agents/sandbox';import { UnixLocalSandboxClient } from '@openai/agents/sandbox/local';
const manifest = new Manifest();const client = new UnixLocalSandboxClient({ snapshot: { type: 'local', baseDir: '/tmp/my-sandbox-snapshots' },});
const session = await client.create({ manifest });const state = await client.serializeSessionState?.(session.state);await session.close?.();
if (state) { const restored = await client.resume?.( await client.deserializeSessionState!(state), ); await restored?.close?.();}大規模なワークフローを一時停止または再開するときは、RunState でもランナーが管理するサンドボックス状態を保持できます。シリアライズされた実行とは別にサンドボックスのライフサイクルを管理する場合は、明示的な sessionState を使用してください。
Docker では、同じメモリ内の RunState を再開すると、SDK がコンテナーの識別情報を検証し、現在のマニフェスト、環境、パス許可を再検証した後に限り、ライブコンテナーを再利用できます。ライブでの再利用が利用できない場合や拒否された場合、Docker は復元可能なスナップショットへフォールバックします。RunState.fromString(...) でシリアライズして再構築した RunState には、信頼済みのライブコンテナー権限が含まれません。そのため、Docker はシリアライズされたコンテナー ID へ接続せず、スナップショットから復元します。復元可能なスナップショットが設定されていない場合、未検証のコンテナーへ接続するのではなく、再開が失敗します。
明示的な baseDir がないローカルスナップショットでは、保存先ディレクトリを上書きするために OPENAI_AGENTS_SANDBOX_SNAPSHOT_DIR を設定します。それ以外の場合、SDK は macOS では ~/Library/Application Support/openai-agents-js/sandbox-snapshots、Windows では %LOCALAPPDATA%\openai-agents-js\sandbox-snapshots、その他のプラットフォームでは $XDG_STATE_HOME/openai-agents-js/sandbox-snapshots を使用します。これらの場所を利用できない場合は、ホームディレクトリまたは一時ディレクトリへフォールバックします。
マニフェストの実体化
Section titled “マニフェストの実体化”マニフェストのエントリは、エージェントの実行前に準備されます。実体化の並行処理数は、実行ごと、またはクライアントの作成呼び出しごとに調整できます。
import { run } from '@openai/agents';import { SandboxAgent } from '@openai/agents/sandbox';import { UnixLocalSandboxClient } from '@openai/agents/sandbox/local';
const agent = new SandboxAgent({ name: 'Repository inspector', model: 'gpt-5.6-sol', instructions: 'Inspect the repository before answering.',});
await run(agent, 'Inspect the repo.', { sandbox: { client: new UnixLocalSandboxClient(), concurrencyLimits: { manifestEntries: 4, localDirFiles: 16, }, },});manifestEntries は、トップレベルのエントリに対する並列処理数を制限します。localDirFiles は、localDir() エントリ内でのファイルコピーの並行処理数を制限します。
ファイルシステムの存在確認
Section titled “ファイルシステムの存在確認”セッションが pathExists() を実装している場合、false は、そのパスが存在しないことをバックエンドが確認したことを意味します。権限エラー、I/O 障害、プロバイダーの確認処理の失敗は、パスが存在しないものとして扱われず、プロバイダーエラーとして拒否されます。これにより、存在する可能性はあるもののアクセスできないパスを、エディター、マニフェスト、メモリの各フローが上書きまたは置換することを防ぎます。
マウントとリモートストレージ
Section titled “マウントとリモートストレージ”マウントエントリは公開するストレージを記述し、マウント戦略はサンドボックスバックエンドがそのストレージを接続する方法を記述します。組み込みのマウントエントリと汎用戦略は、@openai/agents/sandbox からインポートします。
一般的なマウントオプションは次のとおりです。
mountPath: サンドボックス内でストレージが配置される場所。相対パスはマニフェストのルートを基準に解決され、絶対パスはそのまま使用されます。readOnly: サンドボックスからマウント済みストレージへ書き戻さない場合に設定します。mountStrategy: マウントエントリとサンドボックスバックエンドの両方に適合する戦略を使用します。
マウントは、一時的なワークスペースエントリとして扱われます。スナップショットと永続化のフローでは、マウント済みのリモートストレージを保存済みワークスペースへコピーせず、マウントされたパスを切り離すかスキップします。
汎用的なローカルおよびコンテナー向け戦略は次のとおりです。
| 戦略またはパターン | 使用する場合 | 注記 |
|---|---|---|
inContainerMountStrategy(...) | サンドボックスイメージが rclone、mount-s3、blobfuse2 などのマウントコマンドを実行できる場合。 | 汎用戦略として利用できます。サポート状況はバックエンドによって異なります。 |
dockerVolumeMountStrategy(...) | コンテナーの起動前に、Docker でボリュームドライバーを使用するマウントを接続する場合。 | Docker 専用です。 |
localBindMountStrategy() | ローカルバックエンドで、ローカルの絶対パスをワークスペースへバインドする場合。 | 許可されているローカルワークスペースの実体化でサポートされます。 |
バックエンドのサポート範囲は、意図的に明示されています。
| バックエンド | マウントに関する注記 |
|---|---|
UnixLocalSandboxClient | ローカルワークスペースモデルを通じて、ローカルのバインド形式のマウントをサポートします。 |
DockerSandboxClient | Docker がストレージを接続できる場合、ローカルバインドマウントと Docker ボリューム形式の戦略をサポートします。 |
| ホステッドプロバイダー | プロバイダー固有の戦略は、各プロバイダーの実装に含まれます。サポートされるマウントと必要な設定については、そのプロバイダーのドキュメントを確認してください。 |
マウントエントリがすべてのバックエンドで動作するとは限りません。クライアントがマニフェストのメタデータ、識別情報、またはマウント動作を適用できない場合、その部分を暗黙的に無視するのではなく、早期に失敗する必要があります。
サポート対象のホステッドプラットフォーム
Section titled “サポート対象のホステッドプラットフォーム”ホステッド環境が必要な場合でも、通常は同じ SandboxAgent 定義をそのまま利用し、sandbox 実行オプション内のサンドボックスクライアントのみを変更できます。
ホステッドプロバイダーの実装は、@openai/agents-extensions のプロバイダー別サブパスから利用できます。正確な環境変数、実行可能なコード例、ポートの動作、PTY のサポート、スナップショットの動作、クリーンアップの動作については、各プロバイダーのドキュメントを確認してください。
@openai/agents-extensions をインストールし、そのパッケージレベルのピア依存関係を満たしてください。各プロバイダーでは、プロバイダーの SDK パッケージやバックエンドの設定が追加で必要になる場合もあります。
| クライアント | インポートパス | プロバイダーの要件 |
|---|---|---|
BlaxelSandboxClient | @openai/agents-extensions/sandbox/blaxel | npm ピア依存関係: @blaxel/core |
CloudflareSandboxClient | @openai/agents-extensions/sandbox/cloudflare | Cloudflare Sandbox ブリッジの Worker URL と Worker 認証 |
DaytonaSandboxClient | @openai/agents-extensions/sandbox/daytona | npm ピア依存関係: @daytonaio/sdk |
E2BSandboxClient | @openai/agents-extensions/sandbox/e2b | npm ピア依存関係: e2b または @e2b/code-interpreter |
ModalSandboxClient | @openai/agents-extensions/sandbox/modal | npm ピア依存関係: modal |
RunloopSandboxClient | @openai/agents-extensions/sandbox/runloop | npm ピア依存関係: @runloop/api-client |
VercelSandboxClient | @openai/agents-extensions/sandbox/vercel | npm ピア依存関係: @vercel/sandbox |
ModalSandboxClient でサンドボックスを作成するときは、CPU とメモリの予約量を要求するために cpu と memoryMiB を使用します。上限を設定するには、cpuLimit と memoryLimitMiB を使用します。これらのオプションは、クライアントのコンストラクターまたは実行ごとの sandbox.options で設定できます。実行ごとの値は、コンストラクターのデフォルト値を上書きします。すべての値は、有限の正数でなければなりません。cpuLimit を指定するには cpu が必要で、cpuLimit を cpu より小さくすることはできません。同様に、memoryLimitMiB を指定するには memoryMiB が必要で、memoryLimitMiB を memoryMiB より小さくすることはできません。
CloudflareSandboxClient は、Cloudflare の npm SDK をインポートしません。代わりに、デプロイ済みの Cloudflare Sandbox ブリッジ Worker と HTTP 経由で通信します。
VercelSandboxClient は、各 PAT 認証情報フィールドを、作成ごとのオプション、コンストラクターオプション、VERCEL_PROJECT_ID、VERCEL_TEAM_ID、VERCEL_TOKEN の順に優先して解決します。解決後の projectId、teamId、token がすべて空でない場合に限り、認証情報を転送します。それ以外の場合は 3 つのフィールドをすべて省略し、プラットフォームの OIDC やローカルプロバイダーの認証情報を含め、@vercel/sandbox に認証の解決を委ねます。完全に解決された認証情報は、セッションをシリアライズして再開するときにも保持されます。シリアライズされた認証情報は完全な 3 要素の組として扱われ、現在のオプションや環境変数とは組み合わされません。不完全なシリアライズ済み認証情報は破棄され、その後、フォールバックとして現在の設定が解決されます。シリアライズされたセッション状態にはトークンが残るため、その状態は安全に保管してください。
ホステッドサンドボックスクライアントは、プロバイダー固有のマウント戦略を公開します。ストレージプロバイダーに最適なバックエンドとマウント戦略を選択してください。
サンドボックス内でヘルパーを実行する認証情報付きマウントは、モデルによって制御されるコードがそのヘルパープロセスの認証情報へアクセスできるため、デフォルトで拒否されます。これには、サポート対象のマウントフィールドから指定された認証情報、環境内の AWS または GCP 環境変数、RCLONE_CONFIG_* の値、ワークロード ID またはマネージド ID の検出が含まれます。認証情報を持たない rclone および mountpoint ヘルパーでは、環境由来またはメタデータによる認証を無効にし、バックエンドがサポートしている場合は匿名アクセスを使用します。Docker ボリューム、Modal クラウドバケット、Cloudflare バケットマウントなど、外部戦略またはプロバイダー固有の戦略を優先してください。
サンドボックス内のヘルパーが必要な場合は、アプリケーションが作成したマニフェスト上で、信頼する各実効マウントパスを確認済みとして指定します。型付きマウントフィールドから直接渡すマウント固有の認証情報には、manifest.withInContainerMountCredentialExposureAcknowledged('mounted/path') が返すマニフェストを使用します。環境由来の認証情報、ワークロード ID またはマネージド ID、外部の認証情報ファイルまたは設定ファイルには、manifest.withInContainerMountBroadCredentialExposureAcknowledged('mounted/path') が返すマニフェストを使用します。両方の種類の権限情報を使用するマウントには、両方の確認が必要です。これらの正確なパスを対象とする確認は実行時専用であり、マニフェストの初期化オブジェクトやシリアライズされたマニフェストデータからは一切受け付けられません。これらは選択したヘルパーによる認証情報の受け取りを許可しますが、認証情報をマウントパス内へ限定するものではありません。そのため、同じサンドボックス内でモデルによって制御されるほかのコードも、引き続き認証情報を取得できる可能性があります。サンドボックス単位で、有効期間が短く、最小権限の認証情報を使用してください。
マウントが参照する認証情報ファイルは、直接またはシンボリックリンクを通じて、シリアライズ可能なマニフェストエントリへ解決されてはなりません。動的なマニフェスト変更はセッションごとに直列化されます。プロバイダー側の処理が開始された可能性のある段階で、特権マウントの切り替えまたは置換時のアンマウントに失敗した場合、SDK は不明確な状態を再利用または永続化せず、そのセッションを無効化して終了します。
シリアライズされたサンドボックス状態では、サンドボックス内のマウントヘルパーが選択した環境由来の認証情報を含め、マウント認証情報が省略されます。永続化されたマウント構成を再開するには、現在の信頼済みマニフェストが必要です。再開可能な外部マウントまたはプロバイダー固有のマウントでは、現在と永続化済みの認証情報を除くマウント構成が一致した場合に限り、SDK が認証情報を復元します。明示的な sessionState で既存のプロバイダー固有マウントへ再接続できるのは、秘匿化されていないライブ権限情報が現在の信頼済みマニフェストと引き続き一致する場合だけです。権限情報が秘匿化、ローテーション、または削除されている場合は、新しいサンドボックスが必要です。認証情報を除いた構成として分離できない不透明な設定は、再開できません。サンドボックス内のマウントヘルパーを使用したシリアライズ済みの RunState エントリをランナーが復元するときは、保存されたセッションを破棄し、現在の信頼済み設定から新しいサンドボックスを作成します。呼び出し元が指定した明示的な sessionState とプロバイダーの直接再開では、コンテナー内のマウント状態が拒否されます。明示的に新しいサンドボックスを開始してください。不透明な secretRefs を通じて指定された Runloop の認証情報ファイル変数は、コンテナー内マウントでは拒否されます。SDK がマウント前に実効パスを検証できるよう、現在の信頼済みパスを managedSecrets から指定してください。
| バックエンド | マウントに関する注記 |
|---|---|
| Docker | s3Mount()、gcsMount()、r2Mount()、azureBlobMount()、boxMount()、s3FilesMount() を、inContainerMountStrategy() や dockerVolumeMountStrategy() などのローカル戦略と組み合わせてサポートします。 |
ModalSandboxClient | S3、R2、および HMAC 認証を使用する GCS のマウントエントリで、ModalCloudBucketMountStrategy によるクラウドバケットマウントをサポートします。 |
CloudflareSandboxClient | S3、R2、および HMAC 認証を使用する GCS のマウントエントリで、CloudflareBucketMountStrategy による Cloudflare バケットマウントをサポートします。 |
BlaxelSandboxClient | S3、R2、GCS のマウントエントリで、BlaxelCloudBucketMountStrategy によるクラウドバケットマウントをサポートします。認証情報付きクラウドマウントには、SDK 所有のサンドボックスが必要です。SDK が所有しない再利用済みの名前付きサンドボックスでは、認証情報のないクラウドマウント、または BlaxelDriveMount と BlaxelDriveMountStrategy を使用する永続的な Blaxel Drive を利用できます。 |
DaytonaSandboxClient | S3、GCS、R2、Azure Blob、Box のマウントエントリで、DaytonaCloudBucketMountStrategy による rclone ベースのマウントをサポートします。 |
E2BSandboxClient | S3、GCS、R2、Azure Blob、Box のマウントエントリで、E2BCloudBucketMountStrategy による rclone ベースのマウントをサポートします。 |
RunloopSandboxClient | S3、GCS、R2、Azure Blob、Box のマウントエントリで、RunloopCloudBucketMountStrategy による rclone ベースのマウントをサポートします。 |
VercelSandboxClient | VercelCloudBucketMountStrategy による、作成時の S3 マウントをサポートします。新しいコードでは、マウントの正確なパスごとに withInContainerMountCredentialExposureAcknowledged() を使用して、インライン認証情報を確認済みとして指定してください。非推奨の allowS3CredentialExposure: true オプションは、リリース済みのインライン S3 認証情報設定との互換性のために引き続き受け付けられますが、環境由来の認証情報やその他の広範な権限情報は許可しません。シリアライズされたマウント状態は直接再開できないため、マウント済みのライブセッションを再利用してください。 |
E2B と Runloop の rclone ベースのマウントでは、利用可能な場合、SDK は既存の rclone バイナリを使用します。それ以外の場合、SHA-256 チェックサムを検証した後に限り、SDK でバージョンを固定した Linux アーカイブをインストールします。サポート対象外のアーキテクチャやチェックサム検証の失敗がある場合、マウントを中止します。
次の表は、各バックエンドが直接マウントできるリモートストレージエントリをまとめたものです。
| バックエンド | AWS S3 | Cloudflare R2 | GCS | Azure Blob Storage | Box | S3 Files |
|---|---|---|---|---|---|---|
| Docker | はい | はい | はい | はい | はい | はい |
ModalSandboxClient | はい | はい | はい | いいえ | いいえ | いいえ |
CloudflareSandboxClient | はい | はい | はい | いいえ | いいえ | いいえ |
BlaxelSandboxClient | はい | はい | はい | いいえ | いいえ | いいえ |
DaytonaSandboxClient | はい | はい | はい | はい | はい | いいえ |
E2BSandboxClient | はい | はい | はい | はい | はい | いいえ |
RunloopSandboxClient | はい | はい | はい | はい | はい | いいえ |
VercelSandboxClient | はい | いいえ | いいえ | いいえ | いいえ | いいえ |
「はい」は、そのバックエンドが該当する種類のストレージマウントを実行できることを意味します。前述の認証情報の境界を回避できるわけではありません。Docker の dockerVolumeMountStrategy()、Modal のクラウドバケットマウント、Cloudflare のバケットマウントでは、マウント認証情報がモデルによって制御されるサンドボックスの外部に保持されます。Docker の inContainerMountStrategy() と、Daytona、E2B、Runloop の rclone 戦略では、認証情報を受け取るたびに正確なパスの確認が必要です。Box マウントには認証が必要なため、Box の権限情報が型付きマウントフィールドから指定されるか、外部の認証情報ファイルまたは設定ファイルから指定されるかに応じて、適切な確認方法を選択してください。Docker の S3 Files マウントは広範なワークロード ID を使用するため、withInContainerMountBroadCredentialExposureAcknowledged() が必要です。
バックエンドがサポートしている場合、サンドボックスクライアントは resolveExposedPort(port) を通じてエンドポイントを公開できます。
| クライアント | 動作 |
|---|---|
UnixLocalSandboxClient | 設定されたポートを 127.0.0.1 に解決します。 |
DockerSandboxClient | 設定されたコンテナーポートを公開し、そのホスト側エンドポイントを解決します。 |
バックエンドで許可リストを適用する必要がある場合は、クライアントオプションでポートを宣言します。
import { DockerSandboxClient } from '@openai/agents/sandbox/local';
const client = new DockerSandboxClient({ image: 'node:22-bookworm-slim', exposedPorts: [3000],});機能サポートマトリクス
Section titled “機能サポートマトリクス”| 機能 | Unix ローカル | Docker |
|---|---|---|
exec_command | サポート | サポート |
PTY write_stdin | サポート | サポート |
apply_patch | サポート | ワークスペースファイル API を通じてサポート |
view_image | サポート | ワークスペースファイル API を通じてサポート |
コマンドの runAs | ホストがユーザーを解決して切り替えられる場合にサポート | コンテナーおよびユーザー設定による制限あり |
| ローカルスナップショット | サポート | サポート |
| ローカル / Docker マウント | ローカルバインド形式をサポート | バインド形式と Docker ボリューム形式をサポート |
ローカルの PTY サポートでは、SDK プロセス内で小規模な Python 3 ブリッジを使用します。このブリッジは tty: true のセッションでのみ使用されます。Node.js には組み込みの PTY API がなく、対話型の標準入力、シグナル処理、終了ステータスの報告に標準的な POSIX PTY の動作が必要になるためです。SDK コードを実行する環境に python3 をインストールするか、Python 3 の実行ファイルを指すように OPENAI_AGENTS_PYTHON を設定してください。これは、Docker サンドボックスイメージ内にインストールされている Python のバージョンとは別のものです。
ホステッドプロバイダーのサポート状況は、プロバイダーによって異なります。正確なオプション、環境変数、ポートの動作、PTY のサポート、スナップショットの動作、クリーンアップの動作については、プロバイダー固有のドキュメントを確認してください。