コンテンツにスキップ

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

このページを使用して、サンドボックスの処理を実行する場所を選択します。ほとんどの場合、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();

クライアントコンストラクターまたは実行ごとの sandbox.options で networkMode: 'none' を設定しない限り、DockerSandboxClient は Docker のデフォルトネットワークを使用します。'none' モードでは、ネットワークを無効にしてコンテナを起動します。このモードは exposedPorts と併用できません。SDK はコンテナを作成または再開する前に、この設定を拒否します。現在、これ以外の明示的な networkMode 値はサポートされていません。

DockerSandboxClient のコンストラクターまたは実行ごとの sandbox.options で labels: Record<string, string> を設定すると、作成されるコンテナにユーザー定義ラベルを適用できます。実行ごとの labels レコードは、コンストラクターのレコードとマージされるのではなく、置き換えます。SDK は文字列以外の値を拒否し、所有権確認のために openai-agents-sandbox、openai-agents-sandbox.session-identity、openai-agents-sandbox.mount-authority-fingerprint を予約しています。

SDK は、ユーザー定義ラベルをシリアライズされた Docker セッション状態へコピーします。その状態を明示的に再開する場合、呼び出し元から提供するラベルは、保存済みのラベルレコードと完全に一致する必要があります。ラベルを変更するには、新しいサンドボックスセッションを開始してください。稼働中のコンテナを再利用する場合も、設定されたすべてのラベルが必要な値を維持していることを確認します。SDK 外部で追加された無関係なラベルは、再利用を妨げません。

ライフサイクルには 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?.();
}

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

  • 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 がコンテナの 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(...)サンドボックスイメージで rclone、mount-s3、blobfuse2 などのマウントコマンドを実行できる場合。汎用戦略として利用できます。サポート状況はバックエンドによって異なります。
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

ModalSandboxClient でサンドボックスを作成する場合、CPU とメモリの予約量を要求するには cpu と memoryMiB を使用します。上限を設定するには cpuLimit と memoryLimitMiB を使用します。これらのオプションは、クライアントコンストラクターまたは実行ごとの sandbox.options で設定できます。実行ごとの値は、コンストラクターのデフォルト値を上書きします。すべての値は、正の有限数である必要があります。cpuLimit を使用するには cpu が必要であり、それより小さい値にはできません。同様に、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 およびマウントポイントヘルパーは、環境またはメタデータによる認証を無効にし、バックエンドが対応している場合は匿名アクセスを使用します。Docker ボリューム、Modal クラウドバケット、Cloudflare バケットマウントなど、外部またはプロバイダー固有の戦略を優先してください。

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

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

シリアライズされたサンドボックス状態では、サンドボックス内のマウントヘルパーが選択した環境内の認証情報を含め、マウント認証情報が省略されます。永続化されたマウントトポロジーを再開するには、現在の信頼済みマニフェストが必要です。再開可能な外部またはプロバイダー固有のマウントでは、認証情報を除いた現在と永続化済みのマウントトポロジーが一致した後にのみ、SDK が認証情報を復元します。明示的な sessionState で既存のプロバイダー固有マウントへ再接続できるのは、秘匿されていない稼働中の権限が現在の信頼済みマニフェストと一致する場合のみです。権限が秘匿、ローテーション、または削除されている場合は、新しいサンドボックスが必要です。認証情報を除いたトポロジーと分離できない不透明な設定は、再開できません。ランナーが、サンドボックス内のマウントヘルパーを使用していたシリアライズ済み 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 所有のサンドボックスが必要です。再利用される非所有の名前付きサンドボックスでは、認証情報を使用しないクラウドマウント、または BlaxelDriveMount と BlaxelDriveMountStrategy を使用した永続的な Blaxel Drive を利用できます。
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 が対話型の標準入力、シグナル処理、終了ステータスの報告に標準的な POSIX PTY 動作を必要とするためです。SDK コードを実行する環境に python3 をインストールするか、Python 3 の実行可能ファイルを OPENAI_AGENTS_PYTHON に設定してください。これは、Docker サンドボックスイメージ内にインストールされている Python のバージョンとは別のものです。

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