コンテンツにスキップ

コンテキスト管理

コンテキストは、さまざまな意味で使われる用語です。考慮すべきコンテキストには、主に 2 つの種類があります。

  1. 実行中にコードからアクセスできる ローカルコンテキスト:ツールが必要とする依存関係やデータ、onHandoff などのコールバック、ライフサイクルフック
  2. 言語モデルがレスポンスを生成するときに参照できる LLM から見えるコンテキスト

ローカルコンテキストは、RunContext<T> 型で表されます。状態や依存関係を保持する任意のオブジェクトを作成し、それを Runner.run() に渡します。すべてのツール呼び出しとフックは RunContext ラッパーを受け取るため、そのオブジェクトを読み取ったり変更したりできます。

ローカルコンテキストの例
import { Agent, run, RunContext, tool } from '@openai/agents';
import { z } from 'zod';
interface UserInfo {
name: string;
uid: number;
}
const fetchUserAge = tool({
name: 'fetch_user_age',
description: 'Return the age of the current user',
parameters: z.object({}),
execute: async (
_args,
runContext?: RunContext<UserInfo>,
): Promise<string> => {
return `User ${runContext?.context.name} is 47 years old`;
},
});
async function main() {
const userInfo: UserInfo = { name: 'John', uid: 123 };
const agent = new Agent<UserInfo>({
name: 'Assistant',
tools: [fetchUserAge],
});
const result = await run(agent, 'What is the age of the user?', {
context: userInfo,
});
console.log(result.finalOutput);
// The user John is 47 years old.
}
main().catch((error) => {
console.error(error);
process.exit(1);
});

単一の実行に参加するすべてのエージェント、ツール、フックでは、同じ のコンテキストを使用する必要があります。

ローカルコンテキストは、次のような用途に使用します。

  • 実行に関するデータ(ユーザー名、ID など)
  • ロガーやデータ取得機能などの依存関係
  • ヘルパー関数

単一の実行内では、派生したコンテキストは、基になる同じアプリケーションコンテキスト、承認、および使用量の追跡を共有します。ネストされた agent.asTool() の実行には別の toolInput を関連付けられますが、デフォルトではアプリケーション状態の分離されたコピーは作成されません。

機能の可視性におけるローカルコンテキストの利用

Section titled “機能の可視性におけるローカルコンテキストの利用”

関数ツール、ローカル MCP ツール、ハンドオフが同じリクエストポリシーに依存する場合は、ポリシーの入力またはヘルパーをアプリケーションコンテキストに保持します。SDK の各インターフェースでは、それぞれのコールバックを通じて現在の実行コンテキストが公開されます。

  • tool() で作成された関数ツールでは、その isEnabled 述語に、現在の RunContextrunContext プロパティとして持つオブジェクトが渡されます。
  • ハンドオフの isEnabled 述語には、現在の RunContextrunContext プロパティとして持つオブジェクトが渡されます。
  • 呼び出し可能な MCP toolFilter には、現在の RunContextrunContext プロパティとして持つ MCPToolFilterContext が渡されます。

機能ごとに個別のリストを管理するのではなく、共有アプリケーションポリシーをこれらのコールバックに適合させてください。コールバックは、現在のターンで SDK がモデルから見えるセットに含める機能を制御します。これらは、モデルがツールまたはハンドオフの引数を生成する前に実行されるため、モデルが生成した引数やリソースの選択を認可することはできません。関数ツールの場合は、execute 内でこれらの判断を適用するか、必要に応じてツール入力ガードレール承認を追加してください。MCP サーバーは、保護された操作を自身で認可する必要があります。inputType を持つハンドオフでは、アプリケーションの副作用が発生する前に、onHandoff の先頭で解析済みの入力を確認し、認可に失敗した場合は例外をスローしてください。onHandoff が正常に終了すると転送が続行されます。また、ツール入力ガードレールはハンドオフでは実行されません。コールバックのライフサイクルについては、ハンドオフ入力を参照してください。

呼び出し可能な MCP toolFilter がリクエストコンテキストに依存する場合、エージェントが管理するサーバーでは cacheToolsList を無効のままにしてください。キャッシュされたエントリにはフィルタリング済みのツールリストが含まれますが、呼び出し可能なフィルターのデフォルトのキャッシュキーは、リクエストコンテキスト固有ではありません。getAllMcpTools(...) を直接呼び出すコードでは、代わりに関連するポリシー ID を含む generateMCPToolCacheKey を指定できます。MCP のキャッシュに関するガイダンスを参照してください。

RunContext<T> は、アプリケーションで定義したコンテキストオブジェクトのラッパーです。実際には、主に次のものを使用します。

  • 独自の変更可能なアプリケーション状態と依存関係には runContext.context
  • 現在の実行で集計されたトークンおよびリクエストの使用量には runContext.usage
  • 現在の実行が agent.asTool() 内で実行されている場合の構造化入力には runContext.toolInput
  • 承認状態をプログラムで更新する必要がある場合は runContext.approveTool(...) / runContext.rejectTool(...)

アプリケーションで定義するオブジェクトは runContext.context だけです。その他のフィールドは、SDK が管理するランタイムメタデータです。

後で Human in the loop (人間の介入)のために RunState をシリアライズすると、そのランタイムメタデータも状態とともに保存されます。シリアライズした状態を永続化または転送する予定がある場合は、runContext.context に機密情報を格納しないでください。

RunContext をサブクラス化する場合は、ネストされた実行や派生した実行でも、依存しているサブクラス固有のインスタンス状態が保持されることを確認してください。SDK は、ネストされた実行中に内部で分岐コンテキストを作成します。

LLM が呼び出されたときに参照できるデータは、会話履歴に含まれるものだけです。追加情報を利用可能にするには、次の方法があります。

  1. エージェントの instructions に追加します。これは、システムメッセージまたは開発者メッセージとも呼ばれます。静的な文字列のほか、コンテキストを受け取って文字列を返す関数も使用できます。
  2. Runner.run() を呼び出すときに input に含めます。これは instructions を使う方法と似ていますが、メッセージを指揮系統のより下位に配置できます。
  3. 追加情報を関数ツール経由で公開し、LLM が必要に応じてその情報を取得できるようにします。
  4. 検索ツールや Web 検索ツールを使用し、ファイル、データベース、または Web の関連データに基づいてレスポンスを生成します。