セッション
セッションは Agents SDK に 永続メモリレイヤー を提供します。Session インターフェースを実装した任意のオブジェクトを Runner.run に渡すだけで、残りは SDK が処理します。セッションがある場合、ランナーは自動的に次を行います。
- 以前に保存された会話アイテムを取得し、次のターンの先頭に追加します
- 各実行完了後に、新しいユーザー入力とアシスタント出力を永続化します
- 新しいユーザーテキストでランナーを呼ぶ場合でも、中断した
RunStateから再開する場合でも、将来のターンでセッションを利用可能に保ちます
これにより、toInputList() を手動で呼んだり、ターン間で履歴を結合したりする必要がなくなります。TypeScript SDK には 2 つの実装が含まれています。Conversations API 向けの OpenAIConversationsSession と、ローカル開発向けの MemorySession です。どちらも Session インターフェースを共有しているため、独自のストレージバックエンドを差し込めます。Conversations API 以外の参考例として、examples/memory/ 配下のサンプルセッションバックエンド(Prisma、ファイルベースなど)を確認してください。OpenAI Responses モデルを使う場合は、任意のセッションを OpenAIResponsesCompactionSession でラップすると、responses.compact により保存済み会話履歴を自動的に縮小できます。
ヒント: このページの
OpenAIConversationsSessionの例を実行するには、SDK が Conversations API を呼び出せるようにOPENAI_API_KEY環境変数を設定してください(またはセッション構築時にapiKeyを指定してください)。
セッションは、SDK にクライアント側メモリ管理を任せたい場合に使います。すでに conversationId や previousResponseId で OpenAI のサーバー管理状態を使っている場合、通常は同じ会話履歴に対してセッションを併用する必要はありません。
クイックスタート
Section titled “クイックスタート”Conversations API とメモリを同期するには OpenAIConversationsSession を使います。あるいは他の Session 実装に差し替えることもできます。
import { Agent, OpenAIConversationsSession, run } from '@openai/agents';
const agent = new Agent({ name: 'TourGuide', instructions: 'Answer with compact travel facts.',});
// Any object that implements the Session interface works here. This example uses// the built-in OpenAIConversationsSession, but you can swap in a custom Session.const session = new OpenAIConversationsSession();
const firstTurn = await run(agent, 'What city is the Golden Gate Bridge in?', { session,});console.log(firstTurn.finalOutput); // "San Francisco"
const secondTurn = await run(agent, 'What state is it in?', { session });console.log(secondTurn.finalOutput); // "California"同じセッションインスタンスを再利用すると、エージェントは毎ターン前に完全な会話履歴を受け取り、新しいアイテムも自動で永続化されます。別の Session 実装への切り替えには、他のコード変更は不要です。
ローカルデモ、テスト、またはプロセスローカルなチャット状態には、MemorySession が OpenAI と通信せずに同じインターフェースを提供します。
import { Agent, MemorySession, run } from '@openai/agents';
const agent = new Agent({ name: 'TourGuide', instructions: 'Answer with compact travel facts.',});
const session = new MemorySession();const result = await run(agent, 'What city is the Golden Gate Bridge in?', { session,});
console.log(result.finalOutput);OpenAIConversationsSession のコンストラクターオプション:
| Option | Type | Notes |
|---|---|---|
conversationId | string | 遅延作成する代わりに既存の会話を再利用します |
client | OpenAI | 事前設定済みの OpenAI クライアントを渡します |
apiKey | string | 内部 OpenAI クライアント作成時に使う API キーです |
baseURL | string | OpenAI 互換エンドポイントのベース URL です |
organization | string | リクエストに使う OpenAI organization ID です |
project | string | リクエストに使う OpenAI project ID です |
MemorySession のコンストラクターオプション:
| Option | Type | Notes |
|---|---|---|
sessionId | string | ログやテスト向けの安定した識別子です。デフォルトで自動生成されます |
initialItems | AgentInputItem[] | 既存履歴でセッションを初期化します |
logger | Logger | デバッグ出力に使うロガーを上書きします |
MemorySession はすべてをローカルプロセスメモリに保存するため、プロセス終了時にリセットされます。
セッション構築前に会話 ID を事前作成したい場合は、startOpenAIConversationsSession(client?) を使い、返された ID を conversationId として渡します。
セッションのコア動作
Section titled “セッションのコア動作”ランナーでのセッション利用方法
Section titled “ランナーでのセッション利用方法”- 各実行前 にセッション履歴を取得し、新しいターン入力とマージして、結合済みリストをエージェントに渡します
- 非ストリーミング実行後 は
session.addItems()を 1 回呼び、元のユーザー入力と最新ターンのモデル出力をまとめて永続化します - ストリーミング実行 では、最初にユーザー入力を書き込み、ターン完了後にストリーム出力を追記します
RunResult.stateから再開する場合(承認や他の中断)も同じsessionを渡し続けてください。再開ターンは入力を再準備せずメモリに追加されます
履歴の確認と編集
Section titled “履歴の確認と編集”セッションはシンプルな CRUD ヘルパーを提供するため、「元に戻す」「チャットをクリア」「監査」機能を実装できます。
import { OpenAIConversationsSession } from '@openai/agents';import type { AgentInputItem } from '@openai/agents-core';
// Replace OpenAIConversationsSession with any other Session implementation that// supports get/add/pop/clear if you store history elsewhere.const session = new OpenAIConversationsSession({ conversationId: 'conv_123', // Resume an existing conversation if you have one.});
const history = await session.getItems();console.log(`Loaded ${history.length} prior items.`);
const followUp: AgentInputItem[] = [ { type: 'message', role: 'user', content: [{ type: 'input_text', text: 'Let’s continue later.' }], },];await session.addItems(followUp);
const undone = await session.popItem();
if (undone?.type === 'message') { console.log(undone.role); // "user"}
await session.clearSession();session.getItems() は保存済みの AgentInputItem[] を返します。末尾エントリーを削除するには popItem() を呼びます。エージェント再実行前のユーザー修正に便利です。
カスタムストレージとマージ動作
Section titled “カスタムストレージとマージ動作”独自ストレージの利用
Section titled “独自ストレージの利用”Session インターフェースを実装すると、Redis、DynamoDB、SQLite などのデータストアでメモリを管理できます。必要なのは非同期メソッド 5 つだけです。
import { Agent, run } from '@openai/agents';import { randomUUID } from '@openai/agents-core/_shims';import { getLogger } from '@openai/agents-core';import type { AgentInputItem, Session } from '@openai/agents-core';
/** * Minimal example of a Session implementation; swap this class for any storage-backed version. */export class CustomMemorySession implements Session { private readonly sessionId: string; private readonly logger: ReturnType<typeof getLogger>;
private items: AgentInputItem[];
constructor( options: { sessionId?: string; initialItems?: AgentInputItem[]; logger?: ReturnType<typeof getLogger>; } = {}, ) { this.sessionId = options.sessionId ?? randomUUID(); this.items = options.initialItems ? options.initialItems.map(cloneAgentItem) : []; this.logger = options.logger ?? getLogger('openai-agents:memory-session'); }
async getSessionId(): Promise<string> { return this.sessionId; }
async getItems(limit?: number): Promise<AgentInputItem[]> { if (limit === undefined) { const cloned = this.items.map(cloneAgentItem); this.logger.debug( `Getting items from memory session (${this.sessionId}): ${JSON.stringify(cloned)}`, ); return cloned; } if (limit <= 0) { return []; } const start = Math.max(this.items.length - limit, 0); const items = this.items.slice(start).map(cloneAgentItem); this.logger.debug( `Getting items from memory session (${this.sessionId}): ${JSON.stringify(items)}`, ); return items; }
async addItems(items: AgentInputItem[]): Promise<void> { if (items.length === 0) { return; } const cloned = items.map(cloneAgentItem); this.logger.debug( `Adding items to memory session (${this.sessionId}): ${JSON.stringify(cloned)}`, ); this.items = [...this.items, ...cloned]; }
async popItem(): Promise<AgentInputItem | undefined> { if (this.items.length === 0) { return undefined; } const item = this.items[this.items.length - 1]; const cloned = cloneAgentItem(item); this.logger.debug( `Popping item from memory session (${this.sessionId}): ${JSON.stringify(cloned)}`, ); this.items = this.items.slice(0, -1); return cloned; }
async clearSession(): Promise<void> { this.logger.debug(`Clearing memory session (${this.sessionId})`); this.items = []; }}
function cloneAgentItem<T extends AgentInputItem>(item: T): T { return structuredClone(item);}
const agent = new Agent({ name: 'MemoryDemo', instructions: 'Remember the running total.',});
// Using the above custom memory session implementation hereconst session = new CustomMemorySession({ sessionId: 'session-123-4567',});
const first = await run(agent, 'Add 3 to the total.', { session });console.log(first.finalOutput);
const second = await run(agent, 'Add 4 more.', { session });console.log(second.finalOutput);カスタムセッションを使うと、保持ポリシーの適用、暗号化の追加、永続化前の各会話ターンへのメタデータ付与が可能です。
履歴と新規アイテムのマージ方法の制御
Section titled “履歴と新規アイテムのマージ方法の制御”実行入力として AgentInputItem の配列を渡す場合は、sessionInputCallback を指定して保存済み履歴と決定的にマージしてください。ランナーは既存履歴を読み込み、モデル呼び出し前 にコールバックを実行し、返された配列をそのターンの完全入力としてモデルに渡します。このフックは、古いアイテムの削減、ツール結果の重複排除、モデルに見せたいコンテキストだけの強調に最適です。
import { Agent, OpenAIConversationsSession, run } from '@openai/agents';import type { AgentInputItem } from '@openai/agents-core';
const agent = new Agent({ name: 'Planner', instructions: 'Track outstanding tasks before responding.',});
// Any Session implementation can be passed here; customize storage as needed.const session = new OpenAIConversationsSession();
const todoUpdate: AgentInputItem[] = [ { type: 'message', role: 'user', content: [ { type: 'input_text', text: 'Add booking a hotel to my todo list.' }, ], },];
await run(agent, todoUpdate, { session, // function that combines session history with new input items before the model call sessionInputCallback: (history, newItems) => { const recentHistory = history.slice(-8); return [...recentHistory, ...newItems]; },});文字列入力ではランナーが履歴を自動マージするため、コールバックは任意です。コールバックはターン入力がすでにアイテム配列の場合にのみ実行されます。
conversationId や previousResponseId も使っている場合、コールバック結果には現在ターンの新規アイテムを少なくとも 1 つ残してください。これらのサーバー管理 API は現在ターン差分に依存します。コールバックで新規アイテムがすべて削除された場合、SDK は空の差分を送る代わりに元の新規入力を復元し、警告ログを出します。
再開可能な実行
Section titled “再開可能な実行”承認と再開可能な実行の処理
Section titled “承認と再開可能な実行の処理”Human in the loop (人間の介入) のフローでは、承認待ちのために実行を一時停止することがよくあります。
import { Agent, MemorySession, Runner } from '@openai/agents';
const agent = new Agent({ name: 'Trip Planner', instructions: 'Plan trips and ask for approval before booking anything.',});
const runner = new Runner();const session = new MemorySession();
const result = await runner.run(agent, 'Search the itinerary', { session,});
if (result.interruptions?.length) { // ... collect user feedback, then resume the agent in a later turn. for (const interruption of result.interruptions) { result.state.approve(interruption); }
const continuation = await runner.run(agent, result.state, { session }); console.log(continuation.finalOutput);}以前の RunState から再開すると、新しいターンは同じメモリ記録に追記され、単一の会話履歴が保持されます。Human in the loop (人間の介入)(HITL)フローとの互換性も完全に保たれます。承認チェックポイントは引き続き RunState を往復しつつ、セッションが会話履歴の完全性を維持します。
高度な使い方: 履歴コンパクション
Section titled “高度な使い方: 履歴コンパクション”OpenAI Responses 履歴の自動コンパクト化
Section titled “OpenAI Responses 履歴の自動コンパクト化”OpenAIResponsesCompactionSession は任意の Session をデコレートし、OpenAI Responses API を使って、長い保存履歴を同等でより短い会話アイテムリストに置き換えます。各ターンの永続化後、ランナーは最新の responseId を runCompaction に渡し、判定フックが true を返すと responses.compact を呼びます。compactionMode に応じて、リクエストは最新の Responses API チェーン、またはセッションの現在アイテムから構築されます。デフォルトのトリガーは非ユーザーアイテムが少なくとも 10 件蓄積した時点でコンパクト化します。トークン数や独自ヒューリスティクスに基づいて判定するには shouldTriggerCompaction を上書きしてください。コンパクト化後、デコレーターは基盤セッションをクリアし、削減済みアイテムリストで再書き込みします。OpenAIConversationsSession は異なるサーバー管理履歴フローを使うため、組み合わせないでください。
import { Agent, MemorySession, OpenAIResponsesCompactionSession, run,} from '@openai/agents';
const agent = new Agent({ name: 'Support', instructions: 'Answer briefly and keep track of prior context.', model: 'gpt-5.4',});
// Wrap any Session to trigger responses.compact once history grows beyond your threshold.const session = new OpenAIResponsesCompactionSession({ // You can pass any Session implementation except OpenAIConversationsSession underlyingSession: new MemorySession(), // (optional) The model used for calling responses.compact API model: 'gpt-5.4', // (optional) your custom logic here shouldTriggerCompaction: ({ compactionCandidateItems }) => { return compactionCandidateItems.length >= 12; },});
await run(agent, 'Summarize order #8472 in one sentence.', { session });await run(agent, 'Remind me of the shipping address.', { session });
// Compaction runs automatically after each persisted turn. You can also force it manually.await session.runCompaction({ force: true });OpenAIResponsesCompactionSession のコンストラクターオプション:
| Option | Type | Notes |
|---|---|---|
client | OpenAI | responses.compact に使う OpenAI クライアントです |
underlyingSession | Session | コンパクト化アイテムでクリア/再書き込みする基盤セッションストアです。デモではインメモリセッションがデフォルトで、OpenAIConversationsSession は指定できません |
model | OpenAI.ResponsesModel | コンパクト化リクエストで使うモデルです。デフォルトは SDK の現在の既定 OpenAI モデルです |
compactionMode | 'auto' | 'previous_response_id' | 'input' | コンパクト化でサーバー応答チェーンを使うか、ローカル入力アイテムを使うかを制御します |
shouldTriggerCompaction | (context) => boolean | Promise<boolean> | responseId、compactionMode、候補アイテム、現在のセッションアイテムに基づくカスタムトリガーフックです |
compactionMode: 'previous_response_id' は、すでに Responses API の response ID でターンを連結している場合に有用です。compactionMode: 'input' は現在のセッションアイテムからコンパクト化リクエストを再構築します。response チェーンが使えない場合や、基盤セッション内容を信頼できる情報源にしたい場合に役立ちます。
runCompaction(args) のオプション:
| Option | Type | Notes |
|---|---|---|
responseId | string | previous_response_id モード用の最新 Responses API response id です |
compactionMode | 'auto' | 'previous_response_id' | 'input' | 設定済みモードを呼び出し単位で上書きする任意オプションです |
store | boolean | 直前の実行でサーバー状態を保存したかを示します |
force | boolean | shouldTriggerCompaction をバイパスして即時にコンパクト化します |
低レイテンシーストリーミング向け手動コンパクション
Section titled “低レイテンシーストリーミング向け手動コンパクション”コンパクションは基盤セッションをクリアして再書き込みするため、SDK はストリーミング実行を解決する前にその完了を待ちます。コンパクションが重い場合、最後の出力トークン後もしばらく result.completed が保留のままになることがあります。低レイテンシーストリーミングやターン間の応答速度向上のため、オートコンパクションを無効化し、ターン間(またはアイドル時間)に runCompaction を手動で呼んでください。
import { Agent, MemorySession, OpenAIResponsesCompactionSession, run,} from '@openai/agents';
const agent = new Agent({ name: 'Support', instructions: 'Answer briefly and keep track of prior context.', model: 'gpt-5.4',});
// Disable auto-compaction to avoid delaying stream completion.const session = new OpenAIResponsesCompactionSession({ underlyingSession: new MemorySession(), shouldTriggerCompaction: () => false,});
const result = await run(agent, 'Share the latest ticket update.', { session, stream: true,});
// Wait for the streaming run to finish before compacting.await result.completed;
// Choose force based on your own thresholds or heuristics, between turns or during idle time.await session.runCompaction({ force: true });履歴をアーカイブやハンドオフ前に縮小するため、runCompaction({ force: true }) はいつでも呼び出せます。コンパクション判定を追跡するには DEBUG=openai-agents:openai:compaction でデバッグログを有効化してください。