エージェントの実行結果
エージェントの実行 を行うと、次のいずれかを受け取ります。
stream: trueを指定せずにrunを呼び出した場合はRunResultstream: trueを指定してrunを呼び出した場合はStreamedRunResult。ストリーミングの詳細は、ストリーミング ガイド も参照してください。
どちらの result 型でも、finalOutput、newItems、interruptions、state など、同じ中核的な result のインターフェースが提供されます。StreamedRunResult には、completed、toStream()、toTextStream()、currentAgent などのストリーミング制御も追加されています。
適切な result インターフェースの選択
Section titled “適切な result インターフェースの選択”ほとんどのアプリケーションで必要になるのは、いくつかのプロパティだけです。
| 必要なもの | 使用するもの |
|---|---|
| ユーザーに表示する最終回答 | finalOutput |
| 完全なローカル transcript を含む、再生可能な次ターン入力 | history |
| この run で新しく生成された model 形式の item のみ | output |
| エージェント / ツール / ハンドオフ のメタデータを持つ詳細な run item | newItems |
| 通常、次のユーザーターンを担当すべきエージェント | lastAgent または activeAgent |
OpenAI Responses API の chaining に使う previousResponseId | lastResponseId |
| 保留中の承認と再開可能な snapshot | interruptions と state |
| アプリ context、承認、usage、ネストされた agent-tool input | runContext |
現在のネストされた Agent.asTool() 呼び出しに関するメタデータ。たとえば customOutputExtractor 内で使用 | agentToolInvocation |
| 元の model 呼び出しやガードレール診断 | rawResponses とガードレール result 配列 |
finalOutput プロパティには、最後に実行されたエージェントの最終出力が含まれます。この result は次のいずれかです。
string—outputTypeが定義されていないエージェントのデフォルトunknown— エージェントの出力型として JSON schema が定義されている場合。この場合 JSON は parse されていますが、型の検証は引き続き手動で行う必要がありますz.infer<outputType>— エージェントの出力型として Zod schema が定義されている場合。出力はこの schema に対して自動的に parse されますundefined— エージェントが出力を生成しなかった場合(たとえば、出力を生成する前に停止した場合)
ストリーミングされた run がまだ進行中の場合や、最終出力に到達する前に承認の interruption で run が一時停止した場合も、finalOutput は undefined です。
異なる出力型を持つハンドオフを使用している場合は、エージェントの作成に new Agent() コンストラクターではなく Agent.create() メソッドを使用してください。
これにより、SDK はすべての可能なハンドオフにまたがる出力型を推論でき、finalOutput プロパティに union 型を提供できます。
例:
import { Agent, run } from '@openai/agents';import { z } from 'zod';
const refundAgent = new Agent({ name: 'Refund Agent', instructions: 'You are a refund agent. You are responsible for refunding customers.', outputType: z.object({ refundApproved: z.boolean(), }),});
const orderAgent = new Agent({ name: 'Order Agent', instructions: 'You are an order agent. You are responsible for processing orders.', outputType: z.object({ orderId: z.string(), }),});
const triageAgent = Agent.create({ name: 'Triage Agent', instructions: 'You are a triage agent. You are responsible for triaging customer issues.', handoffs: [refundAgent, orderAgent],});
const result = await run(triageAgent, 'I need to a refund for my order');
const output = result.finalOutput;// ^? { refundApproved: boolean } | { orderId: string } | string | undefined入出力インターフェース
Section titled “入出力インターフェース”これらのプロパティは、それぞれ異なる問いに答えます。
| プロパティ | 含まれるもの | 最適な用途 |
|---|---|---|
input | この run のベース入力。ハンドオフ input filter が履歴を書き換えた場合、run がそのまま継続した filter 後の入力が反映されます | この run が実際に入力として何を使ったかの監査 |
output | この run で生成された model 形式の item のみ。エージェントのメタデータは含みません | 新しい model の差分だけを保存または再生 |
newItems | エージェント / ツール / ハンドオフ のメタデータを持つ、リッチな RunItem ラッパー | ログ、UI、監査、デバッグ |
history | input + newItems から構築される、再生可能な次ターン入力 | 手動の chat ループやクライアント管理の会話 state |
実際には次のように使い分けます。
- アプリケーション側で会話全体を手動で保持している場合は
historyを使います - 以前の履歴をすでに別の場所に保存していて、この run で新しく生成された item だけが欲しい場合は
outputを使います - エージェントとの関連付け、ツール出力、ハンドオフの境界、承認 item が必要な場合は
newItemsを使います conversationIdやpreviousResponseIdを使っている場合、通常はhistoryをrun()に戻して渡しません。代わりに、新しいユーザー入力だけを渡し、サーバー管理の ID を再利用します。完全な比較は エージェントの実行 を参照してください
history は、chat のようなユースケースで完全な履歴を維持するための便利な方法です。
import { Agent, user, run } from '@openai/agents';import type { AgentInputItem } from '@openai/agents';
const agent = new Agent({ name: 'Assistant', instructions: 'You are a helpful assistant knowledgeable about recent AGI research.',});
let history: AgentInputItem[] = [ // initial message user('Are we there yet?'),];
for (let i = 0; i < 10; i++) { // run 10 times const result = await run(agent, history);
// update the history to the new output history = result.history;
history.push(user('How about now?'));}新しい item
Section titled “新しい item”newItems は、run 中に何が起こったかをもっとも豊富に把握できるビューを提供します。一般的な item 型は次のとおりです。
- アシスタントメッセージ用の
RunMessageOutputItem - reasoning item 用の
RunReasoningItem - Responses のツール検索リクエストと、それが返すロード済みツール定義用の
RunToolSearchCallItemおよびRunToolSearchOutputItem - ツール呼び出しとその結果用の
RunToolCallItemおよびRunToolCallOutputItem - 承認のために一時停止したツール呼び出し用の
RunToolApprovalItem - ハンドオフ要求と完了した転送用の
RunHandoffCallItemおよびRunHandoffOutputItem
どのエージェントが item を生成したか、あるいはそれがツール、ツール検索、ハンドオフ、承認の境界を示しているかを知る必要がある場合は、output ではなく newItems を選んでください。toolSearchTool() を使う場合、通常のツール呼び出しが発生する前に、どの遅延ツールや namespace がロードされたかを確認するもっとも簡単な方法が、これらのツール検索 item です。
会話の継続または再開
Section titled “会話の継続または再開”アクティブエージェント
Section titled “アクティブエージェント”lastAgent プロパティには、最後に実行されたエージェントが入ります。これは、ハンドオフ後の次のユーザーターンで再利用するエージェントとして最適なことが多いです。activeAgent は同じ値の alias です。
ストリーミング モードでは、currentAgent によって、run がまだ進行中の間にどのエージェントが現在アクティブかを確認できます。
中断と再開可能な state
Section titled “中断と再開可能な state”ツールが承認を必要とする場合、run は一時停止し、interruptions には保留中の RunToolApprovalItem が入ります。これには、直接のツール、ハンドオフ後に到達したツール、ネストされた agent.asTool() run で発生した承認が含まれる場合があります。
result.state.approve(...) / result.state.reject(...) で承認を解決し、その後、同じ state を run() に戻して渡して再開します。すべての interruption を一度に解決する必要はありません。一部の item だけを処理して再実行した場合、解決済みの呼び出しは続行され、未解決のものは保留のままとなり、run は再び一時停止します。
state プロパティは、この result の背後にある serializable な snapshot です。人間の介入(HITL)、リトライフロー、または一時停止した run を後で再開する必要があるあらゆるケースで使用します。
サーバー管理の継続
Section titled “サーバー管理の継続”lastResponseId は、OpenAI Responses API chaining を使用している場合に、次のターンで previousResponseId として渡す値です。
すでに history、session、または conversationId で会話を継続している場合、通常は lastResponseId は必要ありません。複数ステップの run におけるすべての元の model response が必要な場合は、代わりに rawResponses を確認してください。
ネストされた agent-tool のメタデータ
Section titled “ネストされた agent-tool のメタデータ”agentToolInvocation は、ネストされた Agent.asTool() の result 用で、特に customOutputExtractor 内で現在のツール呼び出しに関するメタデータが欲しい場合に使います。これは、一般的な「run 全体が完了した」ことを示す summary フィールドではありません。
このネストされたコンテキストでは、agentToolInvocation は次を公開します。
toolNametoolCallIdtoolArguments
ネストされた agent-tool run に渡された構造化 input も必要な場合は、result.runContext.toolInput と組み合わせて使ってください。
通常のトップレベル run() の result では、これは通常 undefined です。このメタデータは runtime 限定であり、RunState には serialize されません。周辺のパターンについては、Agents as tools を参照してください。
ストリーミングされた result
Section titled “ストリーミングされた result”StreamedRunResult は上記と同じ result インターフェースを継承しますが、ストリーミング固有の制御が追加されています。
- アシスタントのテキストのみに対する
toTextStream() - 完全なイベント stream に対する
toStream()またはfor await ... of stream - run とすべての後処理 callback が完了するまで待つための
completed - 終端時のストリーミング state を確認するための
errorとcancelled - run の途中でアクティブなエージェントを追跡するための
currentAgent
ストリーミングされた run の確定した最終 state が必要な場合は、finalOutput、history、interruptions、その他の summary プロパティを読む前に completed を待ってください。イベントごとの処理については、ストリーミング ガイド を参照してください。
ストリーミングされた run がキャンセルされた場合でも、クリーンアップ後に completed は resolve され、cancelled は true になります。ただし、現在のターンが完了していないため、finalOutput のようなターン終端フィールドは未設定のままになることがあります。その未完了ターンは、新しいユーザーメッセージを追加するのではなく、result.state(必要に応じて同じ session も)で再開してください。
診断と高度なフィールド
Section titled “診断と高度なフィールド”Run context
Section titled “Run context”runContext プロパティは、result 上の run context に対する、サポート対象の公開ビューです。result.runContext.context はアプリの context であり、同じオブジェクトには承認、usage、ネストされた toolInput などの SDK 管理 runtime メタデータも含まれます。完全な shape については コンテキスト管理 を参照してください。
元の response
Section titled “元の response”rawResponses には、run 中に収集された元の model response が含まれます。複数ステップの run では、たとえばハンドオフや、ツール / model サイクルの繰り返しをまたいで、複数の response が生成されることがあります。
ガードレール結果
Section titled “ガードレール結果”inputGuardrailResults と outputGuardrailResults プロパティには、エージェントレベルのガードレール result が含まれます。ツールのガードレール result は、toolInputGuardrailResults と toolOutputGuardrailResults を通じて別途公開されます。
これらの配列は、ガードレールの判断をログに残したい場合、ガードレール関数が返す追加メタデータを確認したい場合、あるいは run がブロックされた理由をデバッグしたい場合に使います。
トークン usage は result.state.usage に集約されており、run のリクエスト数とトークン総数を追跡します。同じ usage オブジェクトは result.runContext.usage からも利用できます。ストリーミング run では、このデータは response の到着に応じて更新されます。
import { Agent, run } from '@openai/agents';
const agent = new Agent({ name: 'Usage Tracker', instructions: 'Summarize the latest project update in one sentence.',});
const result = await run( agent, 'Summarize this: key customer feedback themes and the next product iteration.',);
const usage = result.state.usage;console.log({ requests: usage.requests, inputTokens: usage.inputTokens, outputTokens: usage.outputTokens, totalTokens: usage.totalTokens,});
if (usage.requestUsageEntries) { for (const entry of usage.requestUsageEntries) { console.log('request', { endpoint: entry.endpoint, inputTokens: entry.inputTokens, outputTokens: entry.outputTokens, totalTokens: entry.totalTokens, }); }}