コンテンツにスキップ

コンセプト

最新のエージェントは、ファイルシステム上の実ファイルを操作できる場合に最も効果を発揮します。 サンドボックスエージェント は、専用ツールやシェルコマンドを使用して、大規模なドキュメント群の検索や操作、ファイルの編集、成果物の生成、コマンドの実行を行えます。サンドボックスは、エージェントがユーザーに代わって作業するために使用できる永続的なワークスペースをモデルに提供します。Agents SDK のサンドボックスエージェントを使用すると、サンドボックス環境と組み合わせたエージェントを実行でき、適切なファイルをファイルシステム上に配置し、サンドボックスをオーケストレーションして、大規模なタスクの開始、停止、再開を簡単に行えます。

エージェントが必要とするデータを中心にワークスペースを定義します。新しいワークスペースには、GitHub リポジトリ、ローカルのファイルやディレクトリ、合成されたタスクファイル、S3 や Azure Blob Storage などのリモートファイルシステム、および指定したその他のサンドボックス入力からデータを配置できます。

コンピューティング機能を備えたサンドボックスエージェントハーネス

SandboxAgentAgent を拡張しているため、引き続き Agent です。instructionstoolshandoffsmcpServersmodelSettings、出力型、ガードレール、フックなど、通常のエージェントインターフェースを維持し、標準の run() および Runner API を通じて実行されます。変わるのは実行境界です。

  • SandboxAgent はエージェント自体を定義します。通常のエージェント設定に加えて、defaultManifestbaseInstructionsrunAs などのサンドボックス固有のデフォルトや、ファイルシステムツール、シェルアクセス、スキル、メモリ、コンパクションなどのケイパビリティを含みます。
  • Manifest は、ファイル、リポジトリ、マウント、環境など、新しいサンドボックスワークスペースに必要な初期内容とレイアウトを宣言します。
  • サンドボックスセッションは、コマンドが実行され、ファイルが変更される稼働中の実行環境です。
  • sandbox 実行オプションは、実行がサンドボックスセッションを取得する方法を決定します。たとえば、セッションを直接注入する、シリアライズされたサンドボックスセッション状態から再接続する、サンドボックスクライアントを通じて新しいサンドボックスセッションを作成する、といった方法があります。
  • 保存されたサンドボックス状態とスナップショットにより、後続の実行で以前の作業に再接続したり、保存済みの内容から新しいサンドボックスセッションを初期化したりできます。

Manifest は、新しいサンドボックスワークスペースの初期内容を定義します。再利用されたセッション、シリアライズされたセッション状態、スナップショットはいずれも実行時にワークスペースを提供または変更できるため、稼働中のすべてのサンドボックスに現在存在するファイルを表すものではありません。

このページでは、「サンドボックスセッション」とはサンドボックスクライアントが管理する稼働中の実行環境を指します。正確な境界はクライアントによって異なります。Unix ローカルセッションはホスト上のローカルワークスペースで実行されますが、Docker クライアントやホステッドクライアントは、より強力な環境分離を提供します。これは、セッションで説明する SDK の会話用 Session インターフェースとは異なります。

外側のランタイムは、引き続き承認、トレーシング、ハンドオフ、再開時の管理情報を所有します。サンドボックスセッションは、コマンド、ファイル変更、環境分離を所有します。この分離はモデルの中核をなす要素です。

サンドボックス実行では、エージェント定義と実行ごとのサンドボックス設定を組み合わせます。ランナーはエージェントを準備して稼働中のサンドボックスセッションに関連付け、後続の実行用に状態を保存できます。

SandboxAgentエージェントとサンドボックスのデフォルト
ランナーinstructions の準備とケイパビリティツールの関連付け
サンドボックスセッションコマンドが実行され、ファイルが変更されるワークスペース
保存済み状態後からの再開、または新しいワークスペースの初期化

サンドボックス固有のデフォルトは SandboxAgent に保持します。実行ごとのサンドボックスセッションに関する選択は、sandbox 実行オプションに保持します。

ライフサイクルは、次の 3 段階で考えます。

  1. SandboxAgentManifest、ケイパビリティを使用して、エージェントとワークスペースの初期内容を定義します。
  2. run() または Runner に、サンドボックスセッションを注入、再開、作成する sandbox 実行オプションを渡して実行します。
  3. ランナーが管理する RunState、明示的なサンドボックス sessionState、または保存済みのワークスペーススナップショットから後で続行します。

シェルアクセスが一時的にしか使用しないツールである場合は、ツールのホステッドシェルから始めてください。ワークスペースの分離、サンドボックスクライアントの選択、サンドボックスセッションの再開動作が設計の一部となる場合は、サンドボックスエージェントを使用してください。

サンドボックスエージェントは、次のようなワークスペース中心のワークフローに適しています。

  • コーディングとデバッグ:GitHub リポジトリ内の問題報告に対する自動修正をオーケストレーションし、対象を絞ったテストを実行します。
  • ドキュメントの処理と編集:ユーザーの財務書類から情報を抽出し、記入済みの税務申告書の下書きを作成します。
  • ファイルに基づくレビューや分析:回答前に、オンボーディング資料、生成されたレポート、成果物のバンドルを確認します。
  • 分離されたマルチエージェントパターン:各レビュアーまたはコーディング用サブエージェントに独自のワークスペースを割り当てます。
  • 複数ステップのワークスペースタスク:ある実行でバグを修正して後続の実行で回帰テストを追加したり、スナップショットやサンドボックスセッション状態から再開したりします。

ファイルや稼働中のファイルシステムへのアクセスが不要な場合は、引き続き Agent を使用してください。シェルアクセスが一時的にしか使用しないケイパビリティである場合はホステッドシェルを追加し、ワークスペース境界自体が機能の一部である場合はサンドボックスエージェントを使用してください。

サンドボックスクライアントの選択

Section titled “サンドボックスクライアントの選択”

macOS または Linux でのローカル開発には、まず UnixLocalSandboxClient を使用します。Windows では、代わりに DockerSandboxClient またはホステッドプロバイダーを使用してください。サポートされているどのプラットフォームでも、コンテナ分離やイメージの同一性が必要な場合は DockerSandboxClient に移行し、プロバイダー管理の実行が必要な場合はホステッドプロバイダーに移行します。

多くの場合、SandboxAgent の定義はそのまま維持し、sandbox 実行オプション内のサンドボックスクライアントとそのオプションのみを変更します。ローカル、Docker、ホステッド、リモートマウントの各オプションについては、サンドボックスクライアントを参照してください。

レイヤー主な SDK コンポーネント答える問い
エージェント定義SandboxAgentManifest、ケイパビリティどのエージェントを実行し、新しいセッションでどのワークスペース契約から開始するか?
サンドボックス実行sandbox 実行オプション、サンドボックスクライアント、稼働中のサンドボックスセッションこの実行はどのように稼働中のサンドボックスセッションを取得し、どこで作業を実行するか?
保存済みサンドボックス状態RunState のサンドボックスペイロード、sessionState、スナップショットこのワークフローは、以前のサンドボックス作業にどのように再接続するか、または保存済みの内容から新しいサンドボックスセッションをどのように初期化するか?

主な SDK コンポーネントは、次のように各レイヤーに対応します。

コンポーネント所有するもの確認する問い
SandboxAgentエージェント定義このエージェントは何を実行し、どのデフォルト設定を引き継ぐか?
Manifest新しいセッションのワークスペースに含まれるファイルとフォルダー実行開始時に、どのファイルとフォルダーがファイルシステム上に存在する必要があるか?
Capabilityサンドボックスネイティブの動作このエージェントにどのツール、instructions の断片、ランタイム動作を関連付けるか?
sandbox 実行オプション実行ごとのサンドボックスクライアントとサンドボックスセッションの取得元この実行でサンドボックスセッションを注入、再開、作成のいずれにするか?
RunStateランナーが管理する保存済みサンドボックス状態ランナーが管理していた以前のワークフローを再開し、そのサンドボックス状態を自動的に引き継ぐか?
sandbox.sessionState明示的にシリアライズされたサンドボックスセッション状態RunState の外部ですでにシリアライズしたサンドボックス状態から再開するか?
sandbox.snapshot新しいサンドボックスセッション用に保存されたワークスペース内容新しいサンドボックスセッションを保存済みのファイルや成果物から開始するか?

実用的な設計順序は次のとおりです。

  1. Manifest またはマニフェスト初期化オブジェクトを使用して、新しいセッションのワークスペース契約を定義します。
  2. SandboxAgent を使用してエージェントを定義します。
  3. 組み込みまたはカスタムのケイパビリティを追加します。
  4. run(agent, input, { sandbox: ... }) または new Runner({ sandbox: ... }) で、各実行がサンドボックスセッションを取得する方法を決定します。

実行時に、ランナーはその定義を具体的なサンドボックス対応の実行へ変換します。

  1. sandbox 実行オプションからサンドボックスセッションを解決します。
  2. 実行に有効なワークスペース入力を決定します。
  3. ケイパビリティが生成されたマニフェストを処理できるようにします。
  4. 固定された順序で最終的な instructions を構築します。明示的に上書きした場合の baseInstructions、または SDK のデフォルトサンドボックスプロンプト、続いて instructions、ケイパビリティの instructions 断片、リモートマウントのポリシーテキスト、レンダリングされたファイルシステムツリーの順です。
  5. ケイパビリティツールを稼働中のサンドボックスセッションに関連付け、標準の run() および Runner API を通じて準備済みのエージェントを実行します。

サンドボックス化によって、ターンの意味は変わりません。ターンは引き続きモデルの 1 ステップであり、単一のシェルコマンドやサンドボックス操作ではありません。サンドボックス側の操作とターンの間に、固定された 1 対 1 の対応関係はありません。実用上、サンドボックスでの作業後にエージェントランタイムが別のモデル応答を必要とする場合にのみ、次のターンが消費されます。

通常の Agent フィールドに加えて、次のサンドボックス固有のオプションがあります。

オプション最適な用途
defaultManifestランナーが作成する新しいサンドボックスセッションのデフォルトワークスペース
instructionsSDK のサンドボックスプロンプトの後に追加される、役割、ワークフロー、成功条件
baseInstructionsSDK のサンドボックスプロンプトを置き換える高度なエスケープハッチ
capabilitiesこのエージェントとともに引き継ぐサンドボックスネイティブのツールと動作
runAsシェルコマンド、ファイル読み取り、パッチなど、モデル向けサンドボックスツールで使用するユーザー ID

サンドボックスクライアントの選択、サンドボックスセッションの再利用、マニフェストの上書き、スナップショットの選択は、エージェントではなく sandbox 実行オプションに含めます。

defaultManifest は、ランナーがこのエージェント用に新しいサンドボックスセッションを作成するときに使用するデフォルトワークスペースです。Manifest インスタンス、または new Manifest(...) に渡すものと同じ初期化オブジェクトを渡します。エージェントが通常開始時に必要とするファイル、リポジトリ、補助資料、出力ディレクトリ、マウントに使用します。

defaultManifest が提供するのはデフォルトワークスペースのみです。実行では sandbox.manifest を使用して defaultManifest を上書きでき、再利用または再開されたサンドボックスセッションでは既存のワークスペース状態が維持されます。

マニフェストの定義
import { file, gitRepo, Manifest } from '@openai/agents/sandbox';
const manifest = new Manifest({
root: '/workspace',
entries: {
'task.md': file({
content: 'Fix the failing test and summarize the change.',
}),
repo: gitRepo({
repo: 'openai/openai-agents-js',
ref: 'main',
}),
},
environment: {
NODE_ENV: 'test',
},
});

異なるプロンプトでも維持する必要がある短いルールには、instructions を使用します。SandboxAgent では、これらの instructions が SDK のサンドボックス基本プロンプトの後に追加されるため、組み込みのサンドボックスガイダンスを維持しながら、独自の役割、ワークフロー、成功条件を追加できます。

SDK のサンドボックス基本プロンプトを置き換える場合にのみ、baseInstructions を使用します。ほとんどのエージェントでは設定しないでください。

配置先用途
instructionsエージェントの安定した役割、ワークフロールール、成功条件「オンボーディング書類を確認してからハンドオフする」、「最終ファイルを output/ に書き込む」
baseInstructionsSDK のサンドボックス基本プロンプトの完全な置き換えカスタムの低レベルサンドボックスラッパープロンプト
ユーザープロンプトこの実行でのみ使用するリクエスト「このワークスペースを要約してください」
マニフェスト内のワークスペースファイル長いタスク仕様、リポジトリ固有の instructions、範囲を限定した参考資料repo/task.md、ドキュメントバンドル、サンプル資料

ユーザーの一時的なタスクを instructions にコピーすること、マニフェストに含めるべき長い参考資料を埋め込むこと、組み込みケイパビリティがすでに注入するツールドキュメントを再記述すること、モデルが実行時に必要としないローカルインストール手順を混在させることは避けてください。

ケイパビリティは、サンドボックスネイティブの動作を SandboxAgent に関連付けます。実行開始前にワークスペースを形成し、サンドボックス固有の instructions を追加し、稼働中のサンドボックスセッションに関連付けられるツールを公開し、そのエージェントのモデル動作や入力処理を調整できます。

組み込みケイパビリティには次のものがあります。

ケイパビリティ追加する場面注記
shell()エージェントにシェルアクセスが必要な場合exec_command を追加し、サンドボックスクライアントが PTY 操作をサポートする場合は write_stdin も追加します。
filesystem()エージェントがファイルを編集したり、ローカル画像を確認したりする必要がある場合apply_patchview_image を追加します。相対パスは、デフォルトではワークスペースルートから、設定されている場合は sandbox.cwd から始まります。
skills()サンドボックス内でスキルの検出と実体化を行う場合サンドボックスローカルの SKILL.md スキルでは、.agents または .agents/skills を手動でマウントするよりも、こちらを優先してください。
memory()後続の実行でメモリ成果物を読み取る、または生成する必要がある場合shell() が必要です。ライブ更新には filesystem() も必要です。
compaction()長時間実行されるフローで、コンパクション項目の後にコンテキストを削減する必要がある場合モデルのサンプリングと入力処理を調整します。

デフォルトでは、SandboxAgent.capabilitiesCapabilities.default() を使用し、これには filesystem()shell()compaction() が含まれます。capabilities: [...] を渡すと、そのリストがデフォルトを置き換えるため、引き続き使用するデフォルトケイパビリティを含めてください。

view_image は、最大 10 MB の PNG、JPEG、GIF、WebP、BMP、TIFF、SVG 画像を受け付けます。SDK はラスター画像のファイル名拡張子を信用せず、ファイルシグネチャからラスター形式を検出するため、ラスター画像の拡張子が付いているだけでは、サポートされていないバイト列は有効になりません。SDK は、内容、または .svg.svgz のファイル名から SVG を認識します。

compaction() はデフォルトで DynamicCompactionPolicy を使用します。認識済みのモデルの場合、このポリシーはレンダリングされたコンテキストがそのモデルのコンテキストウィンドウの 90% に達すると、Responses API にコンパクションを要求します。モデルが指定されていないか不明な場合、ポリシーはフォールバックしきい値として 240,000 トークンを使用します。異なる比率とフォールバックしきい値を指定するには new DynamicCompactionPolicy(thresholdRatio, fallbackThreshold) を渡し、サポートするすべてのモデルで固定のトークンしきい値を使用する場合は new StaticCompactionPolicy(threshold) を使用します。動的な比率は、0 以上 1 以下の有限数である必要があります。

サーバー側のコンパクションでコンパクション項目が生成されると、ケイパビリティは古い再実行項目を破棄し、その項目と後続の入力を保持します。コンパクション項目は人間が読める要約ではなく不透明なモデル状態であるため、編集せずに引き継いでください。これらの制御は、Responses のコンパクションをサポートするモデル転送方式にのみ適用されます。

Manifest は、新しいサンドボックスセッションのワークスペースを表します。ワークスペースの root の設定、ファイルとディレクトリの宣言、ローカルファイルのコピー、Git リポジトリのクローン、リモートストレージマウントの接続、環境変数の設定、ユーザーやグループの定義、ワークスペース外の特定の絶対パスへのアクセス許可を行えます。

マニフェストの環境値は、デフォルトで永続化されます。API キー、アクセストークン、サンドボックス状態とともに保存すべきでないその他の短期間の認証情報には、{ value: "...", ephemeral: true } のような一時エントリを使用します。

マニフェストの実体化または再開時に再取得する必要があるシークレットについては、EnvValueReference をサブクラス化し、registerEnvValueReference() で登録します。参照はシークレットではない検索用メタデータのみを永続化し、resolve() を通じて現在のランタイム値を解決します。各サブクラスは、独自の安定した空でない静的 type を宣言する必要があり、serialize() に予約済みの value フィールドを含めてはなりません。マニフェストを再構築する前に各プロセスでパーサーを登録し、パーサーで検索キーの検証と許可リストによる制限を行ってください。永続化された RunState の環境参照を再開するには、対応する参照エントリを持つ、信頼できる最新のマニフェストが必要です。そうでない場合、SDK はセッションを復元する前に再開を拒否します。

マニフェストエントリのパスは、ワークスペースからの相対パスです。絶対パスにしたり、.. を使用してワークスペースの外に出たりすることはできません。これにより、ローカル、Docker、ホステッドの各クライアント間でワークスペース契約の移植性が維持されます。

作業開始前にエージェントが必要とする内容には、マニフェストエントリを使用します。

マニフェストエントリ用途
file()dir()小規模な合成入力、補助ファイル、出力ディレクトリ
localFile()localDir()サンドボックス内に実体化するホストのファイルまたはディレクトリ
gitRepo()ワークスペース内に取得するリポジトリ
s3Mount()gcsMount()r2Mount()azureBlobMount()s3FilesMount() などのマウントサンドボックス内に表示する外部ストレージ

ローカルでの実体化では、localFile()localDir() のソースパスは、ローカルソースのベースディレクトリ内に収まる必要があります。デフォルトのベースは Node プロセスの現在の作業ディレクトリであり、ローカルサンドボックスクライアントは、エントリの実体化時にクライアント固有のベースを提供する場合があります。別の絶対ホストディレクトリからソースを取得する必要がある場合は、必要最小限の Manifest.extraPathGrants エントリを追加します。

extraPathGrants は、ローカルでの遅延スキル検出にも使用されます。ソースのベースディレクトリ外を指す localDirLazySkillSource() は、マニフェストでそのディレクトリが許可されていない限り無視されます。共有スキル、データセット、参考リポジトリなどの入力バンドルには、readOnly: true を推奨します。

各パス許可には、サンドボックスパスと、必要に応じて別のホストパスがあります。

  • path は、サンドボックス内で表示される絶対 POSIX パスです。
  • hostPath は、ホストパスとサンドボックスパスが異なる場合に使用する、任意の絶対ネイティブホストパスです。Windows ではドライブ文字を含める必要があります。UNC パスとデバイスパスはサポートされません。

UnixLocalSandboxClient ではホストパスとサンドボックスパスが同一である必要があるため、hostPath は省略します。コンテナの作成に使用するマニフェストに許可が存在する場合、DockerSandboxClient は別の hostPath をサポートします。すでに実行中のコンテナに対して、そのマッピングを追加または変更することはできません。Docker コマンドでは、作成時に許可されたサンドボックスパスを workdir として使用できます。ワークスペースと設定済みの許可の外にあるパスは、引き続き拒否されます。

共有ローカルソースへのアクセス許可
import { Manifest, localDir, skills } from '@openai/agents/sandbox';
import { localDirLazySkillSource } from '@openai/agents/sandbox/local';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
const appRoot = dirname(fileURLToPath(import.meta.url));
const repoDir = join(appRoot, 'repo');
const sharedSkillsDir = '/opt/company/agent-skills';
const manifest = new Manifest({
extraPathGrants: [
{
path: sharedSkillsDir,
readOnly: true,
description: 'Shared skill bundle.',
},
],
entries: {
repo: localDir({ src: repoDir }),
},
});
const skillCapability = skills({
lazyFrom: localDirLazySkillSource({
src: sharedSkillsDir,
}),
});

マウントエントリは公開するストレージを表し、マウント戦略はサンドボックスバックエンドがそのストレージを接続する方法を表します。マウントオプションとプロバイダーのサポートについては、サンドボックスクライアントを参照してください。

Permissions は、マニフェストエントリのファイルシステム権限を制御します。これはサンドボックスが実体化するファイルに関するものであり、モデル権限、承認ポリシー、API 認証情報に関するものではありません。

ユーザーは、サンドボックス内で作業を実行できる ID です。その ID をサンドボックス内に存在させる場合はユーザーをマニフェストに追加し、シェルコマンド、ファイル読み取り、パッチなどのモデル向けサンドボックスツールをそのユーザーとして実行する場合は SandboxAgent.runAs を設定します。

ファイル単位の共有ルールも必要な場合は、ユーザーをマニフェストのグループおよびエントリの group メタデータと組み合わせます。runAs ユーザーはサンドボックスネイティブの操作を実行するユーザーを制御し、Permissions はサンドボックスがワークスペースを実体化した後、そのユーザーが読み取り、書き込み、実行できるファイルを制御します。

SnapshotSpec は、新しいサンドボックスセッションに対して、保存済みのワークスペース内容をどこから復元し、どこへ永続化するかを指定します。これはサンドボックスワークスペースのスナップショットポリシーであり、sessionState は特定のサンドボックスバックエンドを再開するためのシリアライズされた接続状態です。

ローカルで永続的なスナップショットにはローカルスナップショットを使用し、アプリがリモートスナップショットクライアントを提供する場合はリモートスナップショットを使用します。マウントされたパスと一時パスは、永続的なワークスペース内容としてスナップショットにコピーされません。ハイドレーション中、SDK はアーカイブをワークスペースに書き込む前に、保護されたマウントパスまたは一時パスと重複するアーカイブメンバーを拒否します。ワークスペースルート自体が一時的な場合は、空のアーカイブのみをハイドレーションできます。

サンドボックスのライフサイクル

Section titled “サンドボックスのライフサイクル”

ライフサイクルには、 SDK 所有開発者所有 の 2 つのモードがあります。

SDK 所有ランナーが稼働中のサンドボックスを所有します。
  1. sandbox.client を渡します。

  2. ランナーがサンドボックスセッションを作成または再開します。

  3. エージェントが実行され、スナップショットに対応したワークスペース状態を永続化できます。

  4. ランナーが所有するリソースをランナーが閉じます。

開発者所有アプリケーションが稼働中のサンドボックスを所有します。
  1. session を作成します。

  2. sandbox.session を実行に渡します。

  3. エージェントが既存のワークスペースを使用します。

  4. セッションを確認、再利用し、自分で閉じます。

サンドボックスを 1 回の実行中のみ稼働させる必要がある場合は、SDK 所有のライフサイクルを使用します。client、任意の manifest、任意の snapshot、クライアントの options を渡します。ランナーはサンドボックスを作成または再開し、エージェントを実行し、スナップショットに対応したワークスペース状態を永続化し、クライアントがランナー所有のリソースをクリーンアップできるようにします。

ランナーによるサンドボックスセッションの管理
import { run } from '@openai/agents';
import { SandboxAgent } from '@openai/agents/sandbox';
import { UnixLocalSandboxClient } 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 UnixLocalSandboxClient(),
},
});
console.log(result.finalOutput);

サンドボックスを先に作成する場合、稼働中の 1 つのサンドボックスを複数の実行で再利用する場合、実行後にファイルを確認する場合、自分で作成したサンドボックス上でストリーミングする場合、クリーンアップのタイミングを厳密に決定する場合は、開発者所有のライフサイクルを使用します。session を渡すと、ランナーはその稼働中のサンドボックスを使用しますが、代わりに閉じることはありません。

サンドボックスセッションの自己管理
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 task.', { sandbox: { session } });
await run(agent, 'Follow-up task.', { sandbox: { session } });
} finally {
await session.close?.();
}

サンドボックス操作イベントは、ランナーが管理するサンドボックス作業をプロセス全体で監視できるようにします。addSandboxEventSink() を使用して SandboxEventSink を登録すると、sandbox_operation イベントを受信できます。各操作は start フェーズを生成し、その後に end または error を生成します。終了イベントには所要時間が含まれ、エラーイベントには、プロバイダーが公開している場合、コードや再試行可能性などの正規化されたエラー詳細が含まれます。

実行で sandbox.cwd が設定されている場合、sandbox.exec イベントデータは有効な cwd 基準の workdir を報告し、sandbox.view_image イベントデータは有効な cwd 基準の path を報告します。これらの値は、サンドボックスセッションに送信されるパスと一致します。

JSONL の各行に 1 イベントを書き込むには createSandboxJsonlEventSink()、各イベントを HTTP POST として送信するには createSandboxHttpEventSink()、複数のシンクへ分配するには createChainedSandboxEventSink() を使用します。addSandboxEventSink() は削除用の関数を返します。アプリケーションがそのシンクを必要としなくなったときに呼び出すか、clearSandboxEventSinks() を使用して登録済みのすべてのシンクを削除してください。

イベントシンクは監視用です。SDK は登録済みのシンクの処理完了を待ちますが、シンクの失敗によってサンドボックス操作の実行結果やエラーが置き換えられることはありません。アプリケーションでより強力な配信保証が必要な場合は、配信の再試行、バッファリング、シンク固有の失敗をシンク内で処理してください。

sandbox 実行オプションには、サンドボックスセッションの取得元と、新しいセッションの初期化方法を決定する実行ごとのオプションが含まれます。

次のオプションは、ランナーがサンドボックスセッションを再利用、再開、作成のいずれにするかを決定します。

オプション使用する場面注記
clientランナーにサンドボックスセッションの作成、再開、クリーンアップを任せる場合稼働中のサンドボックス session を指定しない限り必須です。
session稼働中のサンドボックスセッションをすでに自分で作成している場合呼び出し元がライフサイクルを所有し、ランナーはその稼働中のサンドボックスセッションを再利用します。
sessionStateシリアライズされたサンドボックスセッション状態はあるが、稼働中のサンドボックスセッションオブジェクトがない場合client が必要です。ランナーはその明示的な状態から、所有するセッションとして再開します。

sandbox 実行設定に cwd を設定すると、ワークスペース相対のディレクトリをその実行の作業ディレクトリにできます。組み込みの exec_commandview_imageapply_patch ツールは、このディレクトリを基準に相対パスを解決します。その他のサンドボックスツールは、独自のパス契約を維持します。この設定はパス解決を変更しますが、セッションの残りのワークスペースから実行を分離するものではありません。

値は、空でないワークスペース相対の POSIX パスである必要があります。絶対パス、バックスラッシュ、親 (..) セグメントは拒否されます。モデルの各ターンの前に、ランナーはディレクトリが存在し、サンドボックスエージェントの runAs ID からアクセスできることを確認します。cwd とともに使用するカスタムセッションまたは注入されたセッションは、directoryExists() を実装する必要があります。

次のオプションは、ランナーが新しいサンドボックスセッションを作成する場合にのみ使用されます。

オプション使用する場面注記
manifest新しいセッションのワークスペースを今回の実行でのみ上書きする場合Manifest またはマニフェスト初期化オブジェクトを受け付けます。省略時は agent.defaultManifest にフォールバックします。
snapshot新しいサンドボックスセッションをスナップショットから初期化する場合再開に似たフローやリモートスナップショットクライアントに有用です。
optionsサンドボックスクライアントに作成時のオプションが必要な場合Docker イメージ、プロバイダーのタイムアウト、同様のクライアント固有設定で一般的です。

concurrencyLimits は、並列実行できるサンドボックスの実体化処理量を制御します。大規模なマニフェストやローカルディレクトリのコピーでリソースをより厳密に制御する必要がある場合は、manifestEntrieslocalDirFiles を使用します。

実体化の制御は、意図的に実行ごとに設定します。同じ SandboxAgent で、大規模なローカルディレクトリのコピーには控えめな上限を使用し、小規模なマニフェストには緩い上限を使用できるよう、sandbox 実行オプションの近くに配置してください。

マニフェストにファイル、ディレクトリ、リポジトリ、マウントなどの独立したエントリが多数ある場合は、concurrencyLimits.manifestEntries を使用します。localDir() エントリに多数のファイルが含まれ、ローカルコピーの負荷を制限する必要がある場合は、concurrencyLimits.localDirFiles を使用します。

ワークスペースのハイドレーションと再開時に、アーカイブの入力バイト数、展開後のバイト数、メンバー数を制限するには archiveLimits を使用します。空のオブジェクトを渡すと、アーカイブ入力 1 GiB、展開後 4 GiB、100,000 メンバーというデフォルトが有効になります。個別のフィールドを null に設定すると、その上限のみを無効にできます。archiveLimits を省略するか、オプション全体を null に設定すると、アーカイブの上限はすべて無効になります。

完全なコード例:コーディングタスク

Section titled “完全なコード例:コーディングタスク”

このコーディング形式のコード例は、デフォルトの出発点として適しています。

サンドボックスでのコーディングタスク
import { run } from '@openai/agents';
import {
Capabilities,
Manifest,
SandboxAgent,
localDir,
skills,
} from '@openai/agents/sandbox';
import {
UnixLocalSandboxClient,
localDirLazySkillSource,
} from '@openai/agents/sandbox/local';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
const exampleDir = dirname(fileURLToPath(import.meta.url));
const hostRepoDir = join(exampleDir, 'repo');
const hostSkillsDir = join(exampleDir, 'skills');
const manifest = new Manifest({
entries: {
repo: localDir({ src: hostRepoDir }),
},
});
const agent = new SandboxAgent({
name: 'Sandbox engineer',
model: 'gpt-5.6-sol',
instructions:
'Read `repo/task.md` before editing files. Load the `$invoice-total-fixer` skill before changing code. Stay grounded in the repository, preserve existing behavior, and mention the exact verification command you ran. If you edit files with apply_patch, paths are relative to the sandbox workspace root.',
defaultManifest: manifest,
capabilities: [
...Capabilities.default(),
skills({
lazyFrom: localDirLazySkillSource({
src: hostSkillsDir,
}),
}),
],
});
const result = await run(
agent,
'Open `repo/task.md`, fix the issue, run the targeted test, and summarize the change.',
{
sandbox: {
client: new UnixLocalSandboxClient(),
},
},
);
console.log(result.finalOutput);

上記の完全なコード例から始めてください。多くの場合、SandboxAgent 自体はそのまま維持し、サンドボックスクライアント、サンドボックスセッションの取得元、ワークスペースの取得元のみを変更できます。

サンドボックスクライアントの切り替え

Section titled “サンドボックスクライアントの切り替え”

エージェント定義はそのまま維持し、実行設定のみを変更します。コンテナ分離やイメージの同一性が必要な場合は Docker を使用し、プロバイダー管理の実行が必要な場合はホステッドプロバイダーを使用します。コード例とプロバイダーオプションについては、サンドボックスクライアントを参照してください。

エージェント定義はそのまま維持し、sandbox: { client, manifest } を使用して新しいセッションのマニフェストのみを置き換えます。同じエージェントの役割を、エージェントを再構築せずに異なるリポジトリ、資料、タスクバンドルに対して実行する場合に使用します。

サンドボックスセッションの注入

Section titled “サンドボックスセッションの注入”

明示的なライフサイクル制御、実行後の確認、出力のコピーが必要な場合は、稼働中のサンドボックスセッションを注入します。その実行では sandbox: { session } を使用し、アプリケーションコードでセッションを閉じます。

RunState の外部ですでにサンドボックス状態をシリアライズしている場合は、sandbox: { client, sessionState } を使用して、ランナーにその状態から再接続させます。サンドボックス状態が独自のストレージやジョブシステムに保存されており、Runner でそこから直接再開する場合に使用します。

sandbox: { client, snapshot } を使用して、保存済みのファイルや成果物から新しいサンドボックスを初期化します。新しい実行を agent.defaultManifest だけではなく、保存済みのワークスペース内容から開始する場合に使用します。

skills({ from: gitRepo(...) }) を使用して、ローカルスキルソースをリポジトリベースのソースに置き換えます。スキルバンドルに独自のリリースサイクルがある場合や、複数のサンドボックスで共有する場合に使用します。

ツールエージェントには独自のサンドボックス境界を割り当てることも、親の実行から稼働中のサンドボックスを再利用させることもできます。再利用は、高速な読み取り専用エクスプローラーエージェントに有用です。別のサンドボックスを作成、ハイドレーション、スナップショットするコストをかけずに、親が使用しているものと同じワークスペースを確認できます。

ツールエージェントに実際の分離が必要な場合は、代わりに sandboxAgent.asTool(...) を通じて独自の runConfig を指定します。ツールエージェントが自由に変更を加える、信頼できないコマンドを実行する、別のバックエンドやイメージを使用する場合は、別のサンドボックスを使用します。

ローカルツールおよび MCP との組み合わせ

Section titled “ローカルツールおよび MCP との組み合わせ”

サンドボックスワークスペースを維持しながら、同じエージェントで通常のツールも使用できます。サンドボックスケイパビリティは、toolsmcpServers、ハンドオフ、モデル設定、出力設定と併用できます。

将来のサンドボックスエージェント実行で、過去の実行から学習する必要がある場合は、memory() ケイパビリティを使用します。メモリは SDK の会話用 Session メモリとは別のものです。学習内容をサンドボックスワークスペース内のファイルへ抽出し、後続の実行でそれらのファイルを読み取れるようにします。

設定、読み取りと生成の動作、複数ターンの会話、レイアウト分離については、エージェントメモリを参照してください。

単一エージェントのパターンを理解した後は、より大きなシステム内でサンドボックス境界をどこに配置するかを検討します。

サンドボックスエージェントは、引き続き SDK の他の機能と組み合わせられます。

  • ハンドオフ:サンドボックスを使用しない受付エージェントから、ドキュメント中心の作業をサンドボックスレビュアーへハンドオフします。
  • Agents as tools:複数のサンドボックスエージェントをツールとして公開します。通常は、各 asTool(...) 呼び出しにサンドボックス実行設定を渡し、各ツールに独自のサンドボックス境界を割り当てます。
  • MCP と通常の関数ツール:サンドボックスケイパビリティは、mcpServers や通常のツールと併用できます。
  • エージェントの実行:サンドボックス実行でも、標準の run() および Runner API を使用します。

ハンドオフでは、引き続き 1 つのトップレベル実行と 1 つのトップレベルターンループが存在します。アクティブなエージェントは変わりますが、実行がネストされることはありません。

asTool(...) の場合は関係が異なります。外側のオーケストレーターは、外側の 1 ターンを使用してツールの呼び出しを決定し、そのツール呼び出しによってサンドボックスエージェントのネストされた実行が開始されます。ネストされた実行には、独自のターンループ、maxTurns、承認、通常は独自のサンドボックス実行設定があります。外側のオーケストレーターから見ると、その作業全体が 1 回のツール呼び出し内に収まるため、ネストされたターンによって外側の実行のターンカウンターが増えることはありません。