コンテンツにスキップ

コンセプト

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

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

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

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

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

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

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

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

サンドボックス実行では、エージェント定義と実行ごとのサンドボックス設定を組み合わせます。Runner はエージェントを準備し、ライブサンドボックスセッションにバインドし、後続の実行に備えて状態を保存できます。

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

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

ライフサイクルは、次の 3 つのフェーズで考えます。

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

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

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

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

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

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

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

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

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

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

SDK の主要要素は、次のように各レイヤーに対応します。

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

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

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

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

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

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

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

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

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

defaultManifest は、Runner がこのエージェント用に新しいサンドボックスセッションを作成するときに使用するデフォルトワークスペースです。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 のサンドボックス基本プロンプトの完全な置き換えカスタムの低レベルサンドボックスラッパープロンプト
ユーザープロンプトこの実行に対する 1 回限りのリクエスト「このワークスペースを要約してください」
マニフェスト内のワークスペースファイル長いタスク仕様、リポジトリ固有の instructions、範囲が限定された参照資料repo/task.md、ドキュメントバンドル、サンプル資料

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

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

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

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

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

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 管理Runner がライブサンドボックスを管理します。
  1. sandbox.client を渡します。

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

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

  4. Runner が管理するリソースを Runner が閉じます。

開発者管理アプリケーションがライブサンドボックスを管理します。
  1. session を作成します。

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

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

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

サンドボックスを 1 回の実行でのみ存続させる場合は、SDK 管理のライフサイクルを使用します。client、任意の manifest、任意の snapshot、クライアントの options を渡すと、Runner がサンドボックスを作成または再開し、エージェントを実行し、スナップショットに基づくワークスペース状態を永続化して、クライアントが Runner 管理のリソースをクリーンアップできるようにします。

Runner によるサンドボックスセッションの管理
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 を渡すと、そのライブサンドボックスを使用するよう Runner に指示しますが、Runner がセッションを閉じることはありません。

サンドボックスセッションの自己管理
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?.();
}

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

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

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

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

オプション使用する場面注記
manifest新しいセッションのワークスペースを 1 回限り上書きする場合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 にその状態から再接続させます。サンドボックス状態を独自のストレージやジョブシステムに保存し、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 回のツール呼び出しの背後で行われるため、ネストされたターンによって外側の実行のターンカウンターが増えることはありません。