コンテンツにスキップ

エージェントメモリ

メモリにより、将来のサンドボックスエージェント実行は過去の実行から学習できます。これは、メッセージ履歴を保存する SDK の会話用セッションメモリとは別のものです。メモリは、過去の実行から得た学びをサンドボックスワークスペース内のファイルに抽出します。そのため、生成されたメモリアーティファクトは保持データとして扱い、ワークスペースに使用するものと同じ機密性および保持ポリシーを適用してください。

メモリは、将来の実行における 3 種類のコストを削減できます。

  1. エージェントのコスト:エージェントがワークフローの完了に長時間かかった場合、次回の実行では探索の必要性が少なくなるはずです。これにより、トークン使用量と完了までの時間を削減できます。
  2. ユーザーのコスト:ユーザーがエージェントを修正したり、好みを示したりした場合、将来の実行でそのフィードバックを記憶できます。これにより、人間の介入を減らせます。
  3. コンテキストのコスト:エージェントが以前にタスクを完了しており、ユーザーがそのタスクを土台にしたい場合、ユーザーは以前のスレッドを探したり、すべてのコンテキストを再入力したりする必要がなくなるはずです。これにより、タスクの説明を短くできます。

サンドボックスエージェントに機能として memory() を追加します。

メモリの有効化
import {
filesystem,
Manifest,
memory,
SandboxAgent,
shell,
} from '@openai/agents/sandbox';
const manifest = new Manifest({
entries: {
'README.md': {
type: 'file',
content: '# Memory demo\n\nA workspace for follow-up runs.\n',
},
},
});
const agent = new SandboxAgent({
name: 'Memory-enabled reviewer',
model: 'gpt-5.5',
instructions:
'Inspect the workspace, verify important claims, and preserve useful lessons for follow-up runs.',
defaultManifest: manifest,
capabilities: [filesystem(), shell(), memory()],
});

読み取りが有効な場合、memory() には shell() が必要です。これにより、注入された要約だけでは不十分なときに、エージェントがメモリファイルを読み取ったり検索したりできます。ライブメモリ更新はデフォルトで有効になっており、その場合は filesystem() も必要です。これにより、エージェントが古いメモリを見つけた場合や、ユーザーがメモリの更新を求めた場合に、memories/MEMORY.md を更新できます。

デフォルトでは、メモリアーティファクトはサンドボックスワークスペース内の memories/ に保存されます。後の実行で再利用するには、同じライブサンドボックスセッションを維持するか、永続化されたセッション状態またはスナップショットから再開して、設定済みのメモリディレクトリ全体を保持し再利用してください。新しい空のサンドボックスは空のメモリで開始します。

memory() はメモリの読み取りと生成の両方を有効にします。メモリを読み取る必要はあるが新しいメモリを生成すべきではないエージェントには、memory({ generate: false }) を使用します。たとえば、内部エージェント、サブエージェント、チェッカー、または実行によって多くのシグナルが追加されない単発のツールエージェントなどです。実行で後のためのメモリを生成する必要はあるが、ユーザーが既存のメモリによる影響を望まない場合は、memory({ read: null }) を使用します。

読み取り専用メモリの設定
import { memory } from '@openai/agents/sandbox';
const readOnlyMemory = memory({
read: { liveUpdate: false },
generate: false,
});

メモリの読み取りでは段階的開示を使用します。実行の開始時に、SDK は一般的に有用なヒント、ユーザーの好み、利用可能なメモリについての小さな要約(memory_summary.md)を、エージェントの開発者プロンプトに注入します。これにより、過去の作業が関連する可能性があるかどうかを判断するのに十分なコンテキストがエージェントに与えられます。

過去の作業が関連していそうな場合、エージェントは現在のタスクから得たキーワードで、設定済みのメモリインデックス(memoriesDir 配下の MEMORY.md)を検索します。タスクにさらに詳細が必要な場合にのみ、設定済みの rollout_summaries/ ディレクトリ配下にある対応する過去のロールアウト要約を開きます。

メモリは古くなることがあります。エージェントには、メモリをあくまで参考情報として扱い、現在の環境を信頼するよう指示されます。デフォルトでは、メモリ読み取りで liveUpdate が有効になっているため、エージェントが古いメモリを見つけた場合、同じ実行内で設定済みの MEMORY.md を更新できます。たとえば実行がレイテンシーに敏感な場合など、エージェントにメモリを読み取らせるが実行中に変更させたくない場合は、ライブ更新を無効にしてください。

実行が完了すると、サンドボックスランタイムはその実行セグメントを会話ファイルに追記します。蓄積された会話ファイルは、サンドボックスセッションが閉じられるときに処理されます。これらの会話ファイルには、ユーザー入力、アシスタントおよびツールの項目、中断、最終出力が含まれる可能性があるため、機密性の高いワークロードには適切なメモリストアと保持ポリシーを使用してください。

メモリ生成には 2 つのフェーズがあります。

  1. フェーズ 1:会話の抽出。メモリ生成モデルが蓄積された 1 つの会話ファイルを処理し、会話要約を生成します。system、developer、および reasoning の内容は省略されます。会話が長すぎる場合は、先頭と末尾を保持したまま、コンテキストウィンドウに収まるように切り詰められます。また、元メモリ抽出も生成します。これはフェーズ 2 が統合できる、会話からのコンパクトなメモです。
  2. フェーズ 2:レイアウト統合。統合エージェントが 1 つのメモリレイアウトについて元メモリを読み取り、より多くの証拠が必要な場合は会話要約を開き、パターンを MEMORY.mdmemory_summary.md に抽出します。

デフォルトのワークスペースレイアウトは次のとおりです。

workspace/
├── sessions/
│ └── <rollout-id>.jsonl
└── memories/
├── memory_summary.md
├── MEMORY.md
├── raw_memories.md
├── raw_memories/
└── rollout_summaries/

memory({ generate: ... }) でメモリ生成を設定できます。

メモリ生成の設定
import { memory } from '@openai/agents/sandbox';
const memoryCapability = memory({
generate: {
maxRawMemoriesForConsolidation: 128,
phaseOneModel: 'gpt-5.4-mini',
phaseTwoModel: 'gpt-5.4',
extraPrompt:
'Prioritize workflow corrections, verification commands, and user preferences.',
},
});

extraPrompt を使用して、GTM エージェントにおける顧客や会社の詳細など、ユースケースで最も重要なシグナルをメモリ生成器に伝えます。

最近の元メモリが maxRawMemoriesForConsolidation を超える場合、フェーズ 2 は最新の会話からのメモリだけを保持し、古いものを削除します。新しさは、会話が最後に更新された時刻に基づきます。この忘却メカニズムにより、メモリが最新の環境を反映しやすくなります。

マルチターンのサンドボックスチャットでは、通常の SDK Session を同じライブサンドボックスセッションと組み合わせて使用します。

1 つの SDK セッションと 1 つのサンドボックスセッションの使用
import { MemorySession, run } from '@openai/agents';
import {
filesystem,
Manifest,
memory,
SandboxAgent,
shell,
} from '@openai/agents/sandbox';
import { UnixLocalSandboxClient } from '@openai/agents/sandbox/local';
const manifest = new Manifest();
const agent = new SandboxAgent({
name: 'Memory-enabled reviewer',
model: 'gpt-5.5',
instructions: 'Inspect the workspace before answering.',
capabilities: [filesystem(), shell(), memory()],
});
const conversation = new MemorySession({ sessionId: 'workspace-review' });
const sandbox = await new UnixLocalSandboxClient().create({ manifest });
try {
await run(agent, 'Analyze data/leads.csv.', {
session: conversation,
sandbox: { session: sandbox },
});
await run(agent, 'Write a follow-up recommendation.', {
session: conversation,
sandbox: { session: sandbox },
});
} finally {
await sandbox.close?.();
}

どちらの実行も、同じ SDK 会話セッションを渡しているため同じセッション ID を共有し、1 つのメモリ会話ファイルに追記されます。これは、ライブワークスペースを識別し、メモリ会話 ID としては使用されないサンドボックスとは異なります。フェーズ 1 はサンドボックスセッションが閉じられるときに蓄積された会話を参照するため、2 つの独立したターンではなく、やり取り全体からメモリを抽出できます。

複数の run(...) 呼び出しを 1 つのメモリ会話にしたい場合は、それらの呼び出し間で安定した識別子を渡してください。メモリが実行を会話に関連付けるとき、次の順序で解決します。

  1. run(...) に渡した場合は conversationId
  2. SDK Session を渡した場合は SDK session ID
  3. 上記のいずれも存在しない場合は groupId
  4. 安定した識別子が存在しない場合は、実行ごとに生成される ID

異なるエージェントのメモリを分離するためのレイアウトの使い分け

Section titled “異なるエージェントのメモリを分離するためのレイアウトの使い分け”

メモリの分離は、エージェント名ではなく MemoryLayoutConfig に基づきます。同じレイアウトと同じメモリ会話 ID を持つエージェントは、1 つのメモリ会話と 1 つの統合メモリを共有します。異なるレイアウトを持つエージェントは、同じサンドボックスワークスペースを共有している場合でも、別々のロールアウトファイル、元メモリ、MEMORY.mdmemory_summary.md を保持します。

複数のエージェントが 1 つのサンドボックスを共有するが、メモリは共有すべきでない場合は、個別のレイアウトを使用します。

個別のメモリレイアウトの使用
import { memory } from '@openai/agents/sandbox';
const engineeringMemory = memory({
layout: {
memoriesDir: 'memories/engineering',
sessionsDir: 'sessions/engineering',
},
});
const financeMemory = memory({
layout: {
memoriesDir: 'memories/finance',
sessionsDir: 'sessions/finance',
},
});

これにより、あるドメインの分析が別のドメインのメモリに統合されることを防ぎ、その逆も防ぎます。