コンテンツにスキップ

サンドボックスクライアント

サンドボックスでの作業をどこで実行するかを選択するには、このページを使用してください。ほとんどの場合、SandboxAgent の定義はそのままで、sandbox 実行オプション内のサンドボックスクライアントとクライアント固有のオプションのみを変更します。

目的最初の選択肢理由
macOS または Linux で最速のローカルイテレーションUnixLocalSandboxClient追加のサービス依存関係がなく、シンプルなローカルファイルシステムのワークフローを利用できます。
基本的なコンテナ分離DockerSandboxClient指定したイメージを使用して Docker 内で作業を実行します。
ホステッド実行または本番環境相当の分離ホステッドサンドボックスクライアントワークスペースの境界をプロバイダー管理の環境へ移します。

ほとんどのユーザーは、次の 2 つのサンドボックスクライアントのいずれかから始めることをおすすめします。

クライアントインストール選択する状況
UnixLocalSandboxClientなしmacOS または Linux で最速のローカルイテレーションが必要な場合。ローカル開発に適したデフォルトです。
DockerSandboxClientローカルで Docker CLI が利用可能コンテナ分離が必要な場合、またはローカル環境と同等にするために特定のイメージを使用したい場合。

Unix ローカルは、ローカルファイルシステムを対象とする開発を始める最も簡単な方法です。より強力な環境分離や本番環境相当の構成が必要になったら、Docker またはホステッドプロバイダーへ移行してください。

Unix ローカルから Docker へ切り替えるには、エージェント定義はそのままにして、クライアントのみを変更します。

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

ライフサイクルには 2 つの方式があります。

方式渡すものセッションを閉じる主体使用する状況
SDK 管理sandbox: { client }Runnerサンドボックスを 1 回の実行中だけ存続させればよい場合。
開発者管理sandbox: { session }アプリケーションコード後でファイルを確認する場合、同じライブセッションを再利用する場合、または複数の実行を連携させる場合。

正常終了時または失敗時には、Runner が 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?.();
}

サンドボックスの状態と会話の状態は別々です。

  • SDK の会話状態は、result.history、SDK の SessionconversationId、または previousResponseId に保存されます。
  • サンドボックスの状態は、ライブサンドボックスセッション、シリアライズされた sessionStateRunState のサンドボックスペイロード、またはスナップショットに保存されます。

サンドボックスクライアントを介して同じバックエンドセッションへ再接続する場合は、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 で Runner 管理のサンドボックス状態を保持することもできます。シリアライズされた実行とは別にサンドボックスのライフサイクルを管理する場合は、明示的な sessionState を使用してください。

Docker では、同じインメモリの RunState から再開する場合、SDK がコンテナの ID を検証し、現在のマニフェスト、環境、パス権限を再検証した後にのみ、ライブコンテナを再利用できます。ライブ再利用が利用できない場合や拒否された場合、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 を使用します。これらの場所を利用できない場合は、ホームディレクトリまたは一時ディレクトリへフォールバックします。

マニフェストのエントリは、エージェントの実行前に準備されます。展開時の並行処理数は、実行ごと、またはクライアントの作成呼び出しごとに調整できます。

マニフェスト展開の並行処理数の調整
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() エントリ内のファイルコピーの並行処理数を制限します。

セッションが pathExists() を実装している場合、false は、そのパスが存在しないことをバックエンドが確認したことを意味します。権限エラー、I/O 障害、プロバイダーによる確認処理の失敗は、パスが存在しないものとして扱われず、プロバイダーエラーとして拒否されます。これにより、存在する可能性はあるもののアクセスできないパスを、エディター、マニフェスト、メモリの処理が上書きまたは置換することを防ぎます。

マウントとリモートストレージ

Section titled “マウントとリモートストレージ”

マウントエントリは公開するストレージを記述し、マウント戦略はサンドボックスバックエンドがそのストレージを接続する方法を記述します。組み込みのマウントエントリと汎用戦略は、@openai/agents/sandbox からインポートします。

一般的なマウントオプションは次のとおりです。

  • mountPath:サンドボックス内でストレージを公開する場所。相対パスはマニフェストルートを基準に解決され、絶対パスはそのまま使用されます。
  • readOnly:サンドボックスからマウント済みストレージへ書き戻さない場合に設定します。
  • mountStrategy:マウントエントリとサンドボックスバックエンドの両方に適合する戦略を使用します。

マウントは一時的なワークスペースエントリとして扱われます。スナップショットと永続化の処理では、マウント済みのリモートストレージを保存対象のワークスペースへコピーせず、マウントされたパスを切り離すかスキップします。

汎用的なローカル/コンテナ戦略は次のとおりです。

戦略またはパターン使用する状況注記
inContainerMountStrategy(...)サンドボックスイメージで rclonemount-s3blobfuse2 などのマウントコマンドを実行できる場合。汎用戦略として利用できます。対応状況はバックエンドによって異なります。
dockerVolumeMountStrategy(...)コンテナの起動前に、Docker でボリュームドライバーを使用したマウントを接続する場合。Docker 専用です。
localBindMountStrategy()ローカルバックエンドで、ローカルの絶対パスをワークスペースへバインドする場合。許可されている場合、ローカルワークスペースの展開で対応します。

バックエンドの対応状況は、意図的に明示されています。

バックエンドマウントに関する注記
UnixLocalSandboxClientローカルワークスペースモデルを通じて、ローカルのバインド形式のマウントに対応します。
DockerSandboxClientDocker がストレージを接続できる場合、ローカルバインドマウントと Docker ボリューム形式の戦略に対応します。
ホステッドプロバイダープロバイダー固有の戦略は、各プロバイダーの実装に含まれています。対応するマウントと必要なセットアップについては、そのプロバイダーのドキュメントを確認してください。

マウントエントリがすべてのバックエンドで動作するとは限りません。クライアントがマニフェストのメタデータ、ID、またはマウント動作を適用できない場合、マニフェストの該当部分を暗黙的に無視するのではなく、早期に失敗する必要があります。

対応するホステッドプラットフォーム

Section titled “対応するホステッドプラットフォーム”

ホステッド環境が必要な場合でも、通常は同じ SandboxAgent 定義を引き続き使用でき、sandbox 実行オプション内のサンドボックスクライアントのみを変更します。

ホステッドプロバイダーの実装は、@openai/agents-extensions のプロバイダー別サブパスから利用できます。正確な環境変数、実行可能なコード例、ポート動作、PTY 対応、スナップショット動作、クリーンアップ動作については、プロバイダーのドキュメントを確認してください。

@openai/agents-extensions をインストールし、そのパッケージレベルのピア依存関係を満たしてください。各プロバイダーでは、プロバイダー SDK パッケージまたはバックエンドのセットアップも必要になる場合があります。

クライアントインポートパスプロバイダーの要件
BlaxelSandboxClient@openai/agents-extensions/sandbox/blaxelnpm ピア:@blaxel/core
CloudflareSandboxClient@openai/agents-extensions/sandbox/cloudflareCloudflare Sandbox ブリッジの Worker URL と Worker 認証
DaytonaSandboxClient@openai/agents-extensions/sandbox/daytonanpm ピア:@daytonaio/sdk
E2BSandboxClient@openai/agents-extensions/sandbox/e2bnpm ピア:e2b または @e2b/code-interpreter
ModalSandboxClient@openai/agents-extensions/sandbox/modalnpm ピア:modal
RunloopSandboxClient@openai/agents-extensions/sandbox/runloopnpm ピア:@runloop/api-client
VercelSandboxClient@openai/agents-extensions/sandbox/vercelnpm ピア:@vercel/sandbox

CloudflareSandboxClient は Cloudflare の npm SDK をインポートしません。代わりに、デプロイ済みの Cloudflare Sandbox ブリッジ Worker と HTTP 経由で通信します。

VercelSandboxClient は、各 PAT 認証情報フィールドを、作成ごとのオプション、コンストラクターオプション、VERCEL_PROJECT_IDVERCEL_TEAM_IDVERCEL_TOKEN の順で解決します。解決後の projectIdteamIdtoken がすべて空でない場合にのみ、認証情報を転送します。それ以外の場合は 3 つのフィールドをすべて省略し、プラットフォーム OIDC やローカルプロバイダーの認証情報を含め、@vercel/sandbox に認証の解決を委ねます。完全に解決された認証情報は、セッションのシリアライズおよび再開時にも保持されます。シリアライズされた認証情報は完全な 3 要素の組として扱われ、現在のオプションや環境変数とは組み合わされません。不完全なシリアライズ済み認証情報は破棄され、その後フォールバックとして現在の設定が解決されます。シリアライズされたセッション状態にはトークンが残るため、その状態は安全に保存してください。

ホステッドサンドボックスクライアントは、プロバイダー固有のマウント戦略を公開します。ストレージプロバイダーに最適なバックエンドとマウント戦略を選択してください。

サンドボックス内でヘルパーを実行する、認証情報を伴うマウントは、モデルが制御するコードからそのヘルパープロセスの認証情報へアクセスできるため、デフォルトでは拒否されます。これには、対応するマウントフィールドを通じて指定された認証情報、環境内の AWS または GCP 認証情報、RCLONE_CONFIG_* の値、ワークロード ID またはマネージド ID の検出が含まれます。認証情報を使用しない rclone およびマウントポイントのヘルパーは、環境またはメタデータによる認証を無効にし、バックエンドが対応している場合は匿名アクセスを使用します。Docker ボリューム、Modal クラウドバケット、Cloudflare バケットマウントなど、外部戦略またはプロバイダーのネイティブ戦略を優先してください。

サンドボックス内ヘルパーが必要な場合は、アプリケーションが作成したマニフェスト上で、信頼する実効マウントパスをそれぞれ承認してください。型付きマウントフィールドを通じて直接指定するマウント単位の認証情報には、manifest.withInContainerMountCredentialExposureAcknowledged('mounted/path') が返すマニフェストを使用します。環境内の認証情報、ワークロード ID またはマネージド ID、外部の認証情報ファイルまたは設定ファイルには、manifest.withInContainerMountBroadCredentialExposureAcknowledged('mounted/path') が返すマニフェストが必要です。両方の種類の権限情報を使用するマウントには、両方の承認が必要です。これらの完全一致パスに対する承認は実行時のみ有効であり、マニフェストの初期化オブジェクトやシリアライズされたマニフェストデータからは決して受け入れられません。承認により、選択したヘルパーが認証情報を受け取れるようになりますが、その認証情報の使用範囲がマウントパス内に制限されるわけではありません。そのため、同じサンドボックス内でモデルが制御する他のコードから認証情報を取得できる可能性があります。サンドボックス単位で、短期間のみ有効かつ最小権限の認証情報を使用してください。

マウントが参照する認証情報ファイルは、直接またはシンボリックリンク経由で、シリアライズ可能なマニフェストエントリへ解決されてはなりません。動的なマニフェスト変更はセッションごとにシリアライズされます。プロバイダー側の処理が開始された可能性がある状態で、特権マウントへの切り替えまたは置換に伴うアンマウントに失敗した場合、SDK は曖昧な状態を再利用または永続化せず、そのセッションを無効化して終了します。

シリアライズされたサンドボックス状態では、サンドボックス内のマウントヘルパーが選択した環境内の認証情報を含め、マウント認証情報が省略されます。永続化されたマウントトポロジーを使用するには、再開前に現在の信頼済みマニフェストが必要です。再開可能な外部マウントまたはプロバイダーのネイティブマウントでは、認証情報を除いた現在のマウントトポロジーと永続化済みのマウントトポロジーが一致した後にのみ、SDK が認証情報を復元します。明示的な sessionState で既存のプロバイダーネイティブマウントへ再接続できるのは、マスキングされていないライブ権限情報が現在の信頼済みマニフェストと引き続き一致する場合だけです。権限情報がマスキング、ローテーション、または削除されている場合は、新しいサンドボックスが必要です。認証情報を含まないトポロジーと分離できない不透明な設定は、再開できません。Runner が、サンドボックス内のマウントヘルパーを使用していたシリアライズ済み RunState エントリを復元する場合、保存済みセッションを破棄し、現在の信頼済み設定から新しいサンドボックスを作成します。呼び出し元が指定した明示的な sessionState とプロバイダーからの直接再開では、コンテナ内のマウント状態が拒否されます。新しいサンドボックスを明示的に開始してください。不透明な secretRefs を通じて指定された Runloop の認証情報ファイル変数は、コンテナ内マウントでは拒否されます。SDK がマウント前に実効パスを検証できるように、現在の信頼済みパスを managedSecrets で指定してください。

バックエンドマウントに関する注記
DockerinContainerMountStrategy()dockerVolumeMountStrategy() などのローカル戦略を使用する s3Mount()gcsMount()r2Mount()azureBlobMount()boxMount()s3FilesMount() に対応します。
ModalSandboxClientS3、R2、HMAC 認証済み GCS のマウントエントリで、ModalCloudBucketMountStrategy を使用したクラウドバケットマウントに対応します。
CloudflareSandboxClientS3、R2、HMAC 認証済み GCS のマウントエントリで、CloudflareBucketMountStrategy を使用した Cloudflare バケットマウントに対応します。
BlaxelSandboxClientS3、R2、GCS のマウントエントリで、BlaxelCloudBucketMountStrategy を使用したクラウドバケットマウントに対応します。認証情報を伴うクラウドマウントには SDK 管理のサンドボックスが必要です。SDK が所有しない再利用済みの名前付きサンドボックスでは、認証情報を使用しないクラウドマウント、または BlaxelDriveMountBlaxelDriveMountStrategy を使用する永続的な Blaxel Drives を利用できます。
DaytonaSandboxClientS3、GCS、R2、Azure Blob、Box のマウントエントリで、DaytonaCloudBucketMountStrategy を使用した rclone ベースのマウントに対応します。
E2BSandboxClientS3、GCS、R2、Azure Blob、Box のマウントエントリで、E2BCloudBucketMountStrategy を使用した rclone ベースのマウントに対応します。
RunloopSandboxClientS3、GCS、R2、Azure Blob、Box のマウントエントリで、RunloopCloudBucketMountStrategy を使用した rclone ベースのマウントに対応します。
VercelSandboxClientVercelCloudBucketMountStrategy を使用した作成時の S3 マウントに対応します。新しいコードでは、各マウントの完全一致パスに対して withInContainerMountCredentialExposureAcknowledged() を使用し、インライン認証情報を承認してください。非推奨の allowS3CredentialExposure: true オプションは、リリース済みのインライン S3 認証情報設定との互換性のために引き続き受け入れられますが、環境内の認証情報やその他の広範な権限情報は許可しません。シリアライズされたマウント状態は直接再開できないため、マウント済みのライブセッションを再利用してください。

E2B および Runloop の rclone ベースのマウントでは、利用可能な場合、SDK は既存の rclone バイナリを使用します。それ以外の場合、SHA-256 チェックサムを検証した後にのみ、SDK でバージョン固定された Linux アーカイブをインストールします。対応していないアーキテクチャやチェックサムの検証失敗があると、マウントは中止されます。

次の表は、各バックエンドが直接マウントできるリモートストレージエントリをまとめたものです。

バックエンドAWS S3Cloudflare R2GCSAzure Blob StorageBoxS3 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],
});
機能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 がなく、SDK が対話型 stdin、シグナル処理、終了ステータスの報告に標準的な POSIX PTY の動作を必要とします。SDK コードを実行する環境に python3 をインストールするか、OPENAI_AGENTS_PYTHON に Python 3 の実行ファイルを設定してください。これは、Docker サンドボックスイメージ内にインストールされている Python のバージョンとは別のものです。

ホステッドプロバイダーの対応状況は、プロバイダーごとに異なります。正確なオプション、環境変数、ポート動作、PTY 対応、スナップショット動作、クリーンアップ動作については、プロバイダー固有のドキュメントを確認してください。