コンテンツにスキップ

コンセプト

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

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

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

SandboxAgent は Agent を拡張しているため、引き続き Agent として扱えます。instructions、tools、handoffs、mcpServers、modelSettings、出力型、ガードレール、フックといった通常のエージェントインターフェースを維持し、通常の run() および Runner API を通じて実行されます。変わるのは実行境界です。

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

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

このページでは、「サンドボックスセッション」はサンドボックスクライアントが管理する稼働中の実行環境を指します。具体的な境界はクライアントと設定によって異なります。Unix ローカルセッションは、macOS や Linux 上で OS レベルの隔離を追加せずにホストプロセスを実行します。一方、Docker クライアントやホスト型クライアントは、コンテナまたはプロバイダーが管理する実行環境を使用します。これは、セッションで説明している SDK の会話用 Session インターフェースとは異なります。

外側のランタイムは、引き続き承認、トレーシング、ハンドオフ、再開に必要な管理情報を担当します。サンドボックスセッションはコマンドとファイルの変更を管理します。実行環境が提供する隔離は、バックエンドと設定によって決まります。

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

SandboxAgentエージェントとサンドボックスのデフォルト設定
ランナー指示の準備とケイパビリティツールのバインド
サンドボックスセッションコマンドが実行され、ファイルが変更されるワークスペース
保存済み状態後で再開、または新規ワークスペースを初期化

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

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

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

シェルアクセスが、たまに使うツールの 1 つにすぎない場合は、ツールで説明しているホスト型シェルから始めてください。ワークスペース管理、サンドボックスクライアントの選択、サンドボックスセッションの再開動作が設計の一部となる場合は、サンドボックスエージェントを選んでください。

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

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

ファイルや、作業中に変化するファイルシステムへのアクセスが不要であれば、引き続き Agent を使用してください。シェルアクセスが、たまに使う機能の 1 つにすぎない場合は、ホスト型シェルを追加してください。ワークスペースの境界自体が機能の一部である場合は、サンドボックスエージェントを使用してください。

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

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

UnixLocalSandboxClient は、macOS または Linux 上での信頼できるローカル開発、または外部で隔離された環境内で使用してください。Unix ローカルのワークスペース、作業ディレクトリ、HOME 環境変数は、OS レベルの隔離を提供しません。信頼できない入力の影響を受けるコマンドを含め、信頼できないコマンドには、適切に設定した DockerSandboxClient またはホスト型プロバイダーを選ぶか、外部の隔離を用意してください。Windows では、Docker またはホスト型プロバイダーを使用してください。Unix ローカル実行の制限を参照してください。

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

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

主な SDK の構成要素は、これらのレイヤーに次のように対応します。

構成要素担当範囲確認する問い
SandboxAgentエージェント定義このエージェントに何をさせ、どのデフォルト設定を持たせるか?
Manifest新規セッションのワークスペースのファイルとフォルダー実行開始時に、どのファイルとフォルダーがファイルシステム上に存在すべきか?
Capabilityサンドボックスネイティブの動作このエージェントにどのツール、指示の断片、ランタイム動作を追加するか?
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. 最終的な指示を固定の順序で構築します。まず SDK のデフォルトのサンドボックスプロンプト、または明示的に上書きした場合は baseInstructions、次に 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 では、これらの指示は SDK のサンドボックス基本プロンプトの後に追加されるため、組み込みのサンドボックスガイダンスを保持しながら、独自の役割、ワークフロー、成功基準を追加できます。

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

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

ユーザーの一度限りのタスクを instructions にコピーしたり、マニフェストに含めるべき長い参照資料を埋め込んだり、組み込みケイパビリティがすでに注入するツールのドキュメントを繰り返したり、モデルが実行時に必要としないローカルインストールの注意事項を混ぜたりしないでください。

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

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

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

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

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

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 として使用できます。ワークスペースと設定済みの許可パスの外にあるパスは、引き続き拒否されます。

Unix ローカルセッションでは、これらの許可は、SDK を通じたローカルソースへのアクセスと、SDK のファイル API がアクセスするパスを制御します。readOnly: true の許可は、許可されたパスへの SDK のファイル API による書き込みを防ぎます。これらの許可は、macOS や Linux 上の任意のシェルコマンドを制約しません。コマンドは、プロセスの権限と外部の隔離によって許されるホストパスに、そのパスへの許可がなくてもアクセスできます。

共有ローカルソースへのアクセス許可
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)

Section titled “スナップショット仕様 (SnapshotSpec)”

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 行につき 1 件書き込むには createSandboxJsonlEventSink()、各イベントを HTTP POST として送信するには createSandboxHttpEventSink()、複数のシンクに配信するには createChainedSandboxEventSink() を使用してください。addSandboxEventSink() は登録解除関数を返します。アプリケーションでそのシンクが不要になったら呼び出すか、clearSandboxEventSinks() を使って登録済みのシンクをすべて削除してください。

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

sandbox 実行オプションは、サンドボックスセッションの取得元と、新規セッションの初期化方法を決める、実行ごとのオプションを保持します。

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

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

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

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

これらのオプションが関係するのは、ランナーが新規サンドボックスセッションを作成する場合のみです。

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

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

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

マニフェストにファイル、ディレクトリ、リポジトリ、マウントなど、多数の独立したエントリがある場合は、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 を指定してください。信頼できないコマンドには、必要な隔離を提供するバックエンドと設定を選択してください。別の Unix ローカルセッションを用意するだけでは、OS レベルの隔離は提供されません。

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

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

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

今後のサンドボックスエージェントの実行で、以前の実行から学んだことを活用するには、memory() ケイパビリティを使用してください。メモリは、SDK の会話用 Session メモリとは別のものです。学んだことをサンドボックスワークスペース内のファイルにまとめ、後続の実行でそのファイルを読み取れるようにします。

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

単一エージェントのパターンが明確になったら、次の設計上の問いは、より大きなシステムのどこにサンドボックスの境界を置くかです。

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

  • ハンドオフ:ドキュメント中心の作業を、サンドボックスを使わない受付エージェントから、サンドボックスを使うレビュー担当に引き渡します。
  • Agents as tools:複数のサンドボックスエージェントをツールとして公開します。通常は、各 asTool(...) 呼び出しでサンドボックスの実行設定を渡し、各ツールが専用のセッションを持つようにします。各セッションが提供する隔離は、バックエンドと設定によって決まります。
  • MCP 連携と通常の関数ツール:サンドボックスのケイパビリティは、mcpServers や通常のツールと併用できます。
  • エージェントの実行:サンドボックスでの実行でも、通常の run() および Runner API を使用します。

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

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