エージェントにおけるメモリ
メモリを保存することは物語の半分に過ぎません。重要なのは、エージェントがそれを使用することです。つまり、回答する前に適切なコンテキストを思い出し、学習した耐久性のある事実を書き戻すことです。協力するメカニズムは2つあります。
- エージェントがリコールできるようにサービスをアタッチする。
- エージェントが意図的に検索およびキュレーションできるようにツールを与える。
1. エージェントにメモリをアタッチする
MemoryServiceは、エージェントが使用するadk_core::Memoryインターフェースに、MemoryServiceAdapterを介してブリッジされ、(app, user, project?)にスコープされます。それをRunnerにアタッチすると、エージェントのsearch_memoryがバックエンドに流れます。
use adk_memory::{InMemoryMemoryService, MemoryServiceAdapter};
use std::sync::Arc;
let service = Arc::new(InMemoryMemoryService::new());
let memory: Arc<dyn adk_core::Memory> =
Arc::new(MemoryServiceAdapter::new(service.clone(), "support", "alice"));
let runner = Runner::builder()
.agent(agent)
.session_service(sessions)
.memory_service(memory) // ← the agent can now recall
.build()?;
これが整っていれば、エージェントはターン中にsearch_memory(query)を呼び出すことができますが、いつ呼び出すかは、リコールをどのように配線するかにかかっています。それがツールの目的です。
2. メモリツール (セマンティックストア)
adk-tool (feature memory-tools) は、リコールをエージェントの振る舞いに変える2つのツールを提供します。
| ツール | 実行方法 |
|---|---|
LoadMemoryTool | エージェントは、再呼び出しが必要だと判断したときに、他のツールと同様にこれを呼び出します。 |
PreloadMemoryTool | BeforeModelCallback として実行され、各ターンの開始時に関連するメモリを自動的に注入します。 |
use adk_tool::memory::{LoadMemoryTool, PreloadMemoryTool};
let load = LoadMemoryTool::builder()
.memory_service(service.clone())
.max_results(5)
.min_relevance_score(0.3)
.build()?;
let preload = PreloadMemoryTool::builder()
.memory_service(service.clone())
.max_results(3)
.build()?;
let agent = LlmAgentBuilder::new("assistant")
.model(model)
.tool(Arc::new(load)) // on-demand recall
.before_model_callback(preload.into_before_model_callback()) // automatic recall
.build()?;
preload は「常に基本を覚えておく」ために、load は「関連するときに調べる」ために使用します。完全なリファレンスについては、メモリツールを参照してください。
ナレッジグラフツール
バックエンドがGraphMemoryServiceの場合、adk-tool (feature graph-memory-tools) は、エージェントに2つのツールを提供し、それ自体でグラフを管理できるようにします。これにより、トランスクリプトをダンプする代わりに意図的に記憶します。
| ツール | モデルがそれを使って何をするか | マッピング先 |
|---|---|---|
remember (RememberTool) | エンティティに関する永続的な事実を保存する(「メールを好む」) | create_entities / add_observations |
relate (RelateTool) | 型付きの関係を記録する(「Alice → works_at → Acme」) | create_relations |
それらの説明はモデルを、安定した、再利用可能な事実(名前、好み、目標、関係)へと導き、雑談から遠ざけます。それらを個別に、またはツールセットとして登録します。
use adk_tool::memory::{RememberTool, RelateTool, GraphMemoryToolset};
use std::sync::Arc;
let kg = Arc::new(GraphMemoryService::new("sqlite://mem.db").await?);
kg.migrate().await?;
// individually…
let agent = LlmAgentBuilder::new("coach")
.model(model)
.tool(Arc::new(RememberTool::new(kg.clone())))
.tool(Arc::new(RelateTool::new(kg.clone())))
.build()?;
// …or as one toolset
let toolset = GraphMemoryToolset::new(kg.clone());
これを、セッション開始時に注入されるグラフの profile_card と組み合わせると、ユーザーが誰であるかを事前に読み取り、学習した内容を書き戻すエージェントが得られます — これがメモリをリアルに感じさせるループです。
リアルタイムセッション
同じ配線は、IntegratedRealtimeRunner を介して音声/マルチモーダルエージェントにも機能します — remember/relate はリアルタイムセッションに自動的にブリッジされ、MemoryService は接続時にコンテキストを注入し、ターンを保存します。リアルタイム → メモリ を参照してください。
完全なパターン
realtime_voice (ミアとのマインドフルネス) の例は、エンドツーエンドのリファレンスです。ファイルベースの GraphMemoryService はミアの長期記憶です。彼女のプロフィールカードはセッション開始時に注入されます。彼女は会話中に remember/relate を介して事実をキュレーションします。そして、ライブパネルが同じグラフを読み書きします。このページにあるすべての要素が連携して動作する様子を見るために、ぜひお読みください。
← メモリの概要 に戻る