OpenAI Agents SDKに、モデルもサンドボックスも呼ばずにエージェントの挙動をテストできるツール群が追加された
openai-agents-js v0.16.0に、ScriptedModel・scriptedSandboxSession()・ScriptedRealtimeTransportという、実モデル・実サンドボックス・実WebRTC/WebSocket接続なしでrunner・sandbox・Realtimeの動作を検証できるテストユーティリティが追加された。CI上でエージェントのロジックだけを決定論的にテストする狙いをリリースノートで確認した。

目次
エージェントの挙動をテストしようとすると、実際にモデルを呼び出す必要が出てきて、結果が毎回変わったり、テストにコストと時間がかかったりする。OpenAI Agents SDK for JavaScript v0.16.0(2026年8月15日公開)のリリースノートに、この問題を避けるための決定論的テストユーティリティが追加されたと書かれている。
3行まとめ
- openai-agents-js v0.16.0で、実モデル・実サンドボックス・実WebRTC/WebSocketなしにエージェントの挙動を検証できる
ScriptedModel・scriptedSandboxSession()・ScriptedRealtimeTransportが@openai/agents/testingとして追加された- 実装ソース(
scriptedModel.ts)を確認すると、固定の応答を返すだけでなく、直前のリクエスト内容を見て動的に応答を組み立てる「responder」関数や、エラー+リトライ助言の注入、ストリーミング応答の再現にも対応していた- スクリプトに用意した応答がテスト終了までに使い切られていないと
UnconsumedModelStepsError、想定より多くモデルが呼ばれるとUnexpectedModelCallErrorが投げられる「fail loud」設計で、公式サンプルはNode.jsのnode:testで書かれている
モデル・サンドボックス・WebRTC/WebSocketなしで動作確認する
リリースノートの説明はこうだ。
This release adds provider-neutral testing utilities through
@openai/agents/testing,@openai/agents-core/testing,@openai/agents/realtime/testing, and@openai/agents-realtime/testing.ScriptedModel,scriptedSandboxSession(), andScriptedRealtimeTransportlet applications exercise runner, sandbox, and Realtime workflows without live model, sandbox, WebRTC, or WebSocket dependencies. Existing runtime entry points and defaults remain unchanged.
(このリリースは、@openai/agents/testing・@openai/agents-core/testing・@openai/agents/realtime/testing・@openai/agents-realtime/testingを通じて、プロバイダに依存しないテストユーティリティを追加する。ScriptedModel・scriptedSandboxSession()・ScriptedRealtimeTransportにより、アプリケーションはライブのモデル・サンドボックス・WebRTC・WebSocketの依存なしに、runner・sandbox・Realtimeのワークフローを実行できる。既存のランタイムのエントリポイントとデフォルトの挙動は変わらない)
3つのユーティリティは、それぞれ別の依存先をシミュレートしている。1つ目は実際のLLM呼び出しの代わり、2つ目はコード実行サンドボックスの代わり、3つ目はWebRTC/WebSocket接続の代わりに使う、という役割分担だと名前から読み取れる。「provider-neutral(プロバイダに依存しない)」という書き方から、特定のモデルプロバイダに縛られずテストコードを書けることを意図しているとみられる。
実装ソースを読むと分かること——固定応答だけでなく「条件分岐」も書ける
リリースノートの1段落だけでは分からない実装の詳細を、実際のソースコード(packages/agents-core/src/testing/scriptedModel.ts、790行)を取得して確認した。ScriptedModelに渡せる「ステップ」には、少なくとも次の5種類があることがコードの型定義から読み取れる。
| ステップの種類 | 何をするか |
|---|---|
response |
固定の応答(ScriptedModelResponse)をそのまま返す |
error |
指定した例外を投げる。オプションで、リトライすべきかどうかを判定するretryAdvice(関数でも可)を付けられる |
responder |
直前のリクエスト内容(RecordedModelCall)を受け取り、その場で応答を組み立てて返す関数。固定文字列ではなく条件分岐を書ける |
stream |
あらかじめ用意したストリーミングイベント列をそのまま流す |
stream_responder |
リクエスト内容を見てから、ストリーミングイベント列を動的に組み立てる |
つまり、当初の疑問だった「固定文字列を返すだけなのか、条件分岐を書けるのか」という点については、responder・stream_responderという2種類のステップにより、直前のモデルへのリクエスト内容を見てから応答を動的に決める書き方が公式にサポートされていることが、ソースコードから確認できた。
公式サンプル(examples/docs/testing/requestAwareResponse.ts)は、このresponderの使い方を次のように示している。
const model = new ScriptedModel([
modelResponder((call) => {
// responderは、Model境界での正規化されたリクエストを受け取る
assert.equal(call.index, 0);
assert.equal(call.streamed, false);
assert.deepEqual(call.request.input, [
{ type: 'message', role: 'user', content: 'Summarize this' },
]);
return [assistantMessage(`Handled model call ${call.index}.`)];
}),
]);
const agent = new Agent({ name: 'Assistant', model });
const runner = new Runner({ tracingDisabled: true });
const result = await runner.run(agent, 'Summarize this');
assert.equal(result.finalOutput, 'Handled model call 0.');
model.assertComplete();
もう1つのサンプル(toolWorkflow.ts)は、ツール呼び出しを挟む複数ターンのワークフローを、固定応答のステップを2つ並べるだけで検証する例を示している——1ターン目はfunctionCallで天気ツールの呼び出しを返し、2ターン目はツールの実行結果を受け取った後の最終回答を返す、という流れだ。
ソースコードにはUnexpectedModelCallError(用意したステップより多くモデルが呼ばれた場合)とUnconsumedModelStepsError(model.assertComplete()を呼んだ時点で、用意したステップが使い切られていない場合)という2つの専用エラークラスも定義されていた。テストが「想定通りの回数だけモデルが呼ばれたか」を検証コード側で明示的にチェックできる、fail loud(黙って見過ごさず、想定外はすぐ例外で落ちる)な設計だと分かる。
同じリリースの他の変更
v0.16.0では、Standard Schema対応(別記事で扱った)に加えて、CallModelInputFilterがpreserveInputIdentity = trueで安定した準備済みアイテムの同一性を維持できるようになったことや、割り込み時のスナップショット・最大ターン数到達時の確定処理・無効なツール出力の秘匿化・Responsesの並列ツール呼び出しの転送・Chat Completionsの推論の配置・Realtimeの音声レート・未対応のアシスタント音声履歴リプレイの扱いなど、複数の安全性まわりの修正も同時に入っている。
sandboxSessionとRealtimeTransportの実装までは踏み込めていない
本記事はopenai-agents-js v0.16.0のリリースノート本文と、ScriptedModelの実装ソース(scriptedModel.ts)・公式サンプル2本を情報源としている。ただし、同時に追加されたscriptedSandboxSession()(サンドボックス実行の代役)とScriptedRealtimeTransport(WebRTC/WebSocket接続の代役)については、scriptedSandboxSession.ts側のエクスポート名(InvalidScriptedSandboxStepError・SandboxCallMatcherErrorなど)をindex.tsのエクスポート一覧から確認したのみで、ScriptedModelと同じ深さでソースコード本文までは読み込んでいない。この記事を書いている自分の手元で、実際に@openai/agents/testingをインストールしてテストコードを書き、動作を確認する検証も行っていない。
関連記事: AIコーディングアシスタント比較──Copilot/Cursor/Claude Code【2026年】 / AIエージェントとは / AnthropicとOpenAIのSDKが揃って「Standard Schema」対応
感想・指摘はコメント欄へ。
出典・参照資料
AIニュースの解説を動画でも
YouTubeでは注目ニュースの背景を解説し、Xでは新着記事をお知らせしています。
コメント
まだコメントはありません。最初のコメントを書いてみませんか?
AIについて聞きたいことはありますか?
質問箱で無料で受け付けています。回答は公開され、他の方の参考にもなります。
質問箱を見る →新しい記事をメールで受け取る
AIの新しい発表を、出典付きで整理して届けます。