検索拡張メモリ(ケンサクカクチョウメモリ)
外部データベースから関連情報を検索しLLMの記憶を補完するアーキテクチャ。RAGの概念を対話記憶に拡張し、過去の会話や学習した知識をベクトル検索で動的に呼び出す。
検索拡張メモリ(Retrieval-Augmented Memory)とは、LLMの記憶容量をベクトルデータベースやナレッジグラフなどの外部ストレージで拡張し、必要に応じて関連する過去の記憶を検索・取得するアーキテクチャである。RAG(Retrieval-Augmented Generation)が静的な知識ベースの検索に特化するのに対し、検索拡張メモリは対話履歴・ユーザー属性・学習した事実を動的に記憶・更新・検索する点で異なる。
概要
2023年のChatGPT登場以降、LLMの「記憶がリセットされる」問題が広く認識された。コンテキストウィンドウに収まらない長期的な情報を保持するため、ベクトルDBを記憶ストレージとして活用するアーキテクチャが2024年から急速に発展した。
代表的な実装として、Zep(商用メモリサーバー)、mem0(OSS記憶レイヤー)、LangChain VectorStoreRetrieverMemoryがある。いずれも対話のたびに新しい記憶をベクトル化して保存し、次の対話時に関連記憶をコサイン類似度で検索してコンテキストに注入する。
2026年時点で、検索拡張メモリは以下の3つの記憶タイプを統合するのが標準パターンとなっている:
- エピソード記憶: 「いつ・何を話したか」の対話イベント記録
- セマンティック記憶: ユーザーの好み・事実・知識の構造化データ
- 手続き記憶: 特定タスクの実行手順・ワークフロー
主な特徴・仕組み
- ベクトル埋め込み保存: 対話メッセージをtext-embedding-3-small(OpenAI、1536次元)やVoyage-3(1024次元)で埋め込み、Pinecone/Qdrant/Weaviateに保存
- コサイン類似度検索: 新しい質問を埋め込み化し、過去の記憶から類似度Top-K(通常K=5〜20)を取得してコンテキストに注入
- 時間減衰スコアリング: 類似度スコアに時間減衰係数(exponential decay)を掛け合わせ、古い記憶の重みを下げる
- 事実抽出と構造化: 対話から「ユーザーはPythonエンジニアである」「好みのエディタはVSCode」などの事実を自動抽出し、キーバリュー形式で保存
- メモリの統合(consolidation): 類似する複数の記憶を1つに統合し、矛盾する情報を最新の事実で上書き
- ハイブリッド検索: ベクトル検索(セマンティック)とキーワード検索(BM25)を組み合わせたReciprocal Rank Fusionで検索精度を向上
- アクセスログ: 各記憶へのアクセス回数・最終アクセス日時を記録し、利用頻度の低い記憶を自動アーカイブ
検索拡張メモリ実装比較
| 製品/ライブラリ | 記憶タイプ | ストレージ | 価格帯 | 特徴 |
|---|---|---|---|---|
| Zep | エピソード+セマンティック | Neo4j+ベクトルDB | $49〜/月 | ナレッジグラフ統合 |
| mem0 | エピソード+セマンティック | Qdrant/Pinecone | OSS(無料) | 軽量・高速 |
| LangChain Memory | エピソード | 任意のベクトルDB | OSS(無料) | 柔軟な構成 |
| Letta (MemGPT) | 全3タイプ | PostgreSQL+ベクトル | $29〜/月 | ページング方式 |
| Cognee | セマンティック | Neo4j+Weaviate | OSS(無料) | ナレッジグラフ自動構築 |
具体例・対応製品
mem0: インドのスタートアップが開発したOSSメモリレイヤー。m = Memory() → m.add("I prefer dark mode", user_id="alice") → m.search("UI preferences", user_id="alice") の3ステップで記憶の保存・検索が完了する。バックエンドにQdrant/Pinecone/ChromaDBを選択可能。2026年時点でGitHub Star 25,000+。
Zep: 対話履歴からユーザーの事実を自動抽出し、ナレッジグラフとして構造化するサーバー。「ユーザーがReactを使っている」「前回Pythonのバグで困っていた」などの事実をトリプル(主語-述語-目的語)で保存し、グラフ走査で関連事実を高速取得。
LangChain VectorStoreRetrieverMemory: 任意のベクトルDBをバックエンドとして、対話メッセージをベクトル化・保存・検索するメモリモジュール。return_docs=True で検索ソースも返却可能。FAISS/Chroma/Pineconeなどに対応。
設計時の注意点
検索拡張メモリの最大の課題はプライバシーとデータ保持期間である。GDPR/個人情報保護法に準拠するため、ユーザーの「忘れられる権利」を実装する必要がある。mem0は m.delete(memory_id) でピンポイント削除、Zepは user.delete() でユーザー単位の全記憶削除に対応している。
また、記憶の品質管理も重要である。LLMが誤って抽出した事実(「ユーザーはJavaが嫌い」と誤解)がそのまま永続化されると、以降の対話品質が低下する。定期的な記憶の検証・クリーンアップメカニズムの実装が推奨される。
関連用語との違い
| 用語 | 記憶の更新 | 主な用途 |
|---|---|---|
| 検索拡張メモリ | 対話ごとに動的更新 | 長期対話の記憶保持 |
| RAG | 静的(バッチ更新) | 外部知識の参照 |
| ファインチューニング | モデル再学習時のみ | ドメイン特化 |
| プロンプトインジェクション | なし(1回限り) | 一時的な知識付与 |
よくある質問(FAQ)
Q1: 検索拡張メモリのレイテンシはどの程度ですか? A: ベクトル検索自体は50〜200msで完了する。Qdrant(ローカル)で約30ms、Pinecone(クラウド)で約100ms。ただしLLMの推論時間(1〜10秒)に比べれば無視できる水準であり、実用上のボトルネックにはならない。
Q2: どのくらいの記憶を保存できますか? A: Pineconeの無料枠で100,000ベクトル、Qdrantのセルフホストでは数百万ベクトルまでスケール可能。1対話メッセージ=1ベクトルとすると、100万件の対話履歴を保存できる。ストレージコストは1Mベクトルあたり月額$10〜50程度。
Q3: 複数ユーザーの記憶を分離するにはどうすればよいですか?
A: ベクトルDBのnamespace/collection機能でユーザー単位に記憶を分離する。Pineconeはnamespace、Qdrantはcollection + payloadフィルタでユーザーIDによる分離が可能。mem0は user_id パラメータで自動分離される。
まとめ
- 検索拡張メモリはRAGを対話記憶に拡張したアーキテクチャ
- エピソード記憶・セマンティック記憶・手続き記憶の3タイプを統合するのが標準
- mem0/Zep/LangChain Memoryなど複数の実装が利用可能
- プライバシー対応(削除権)と記憶品質管理が実装上の重要課題
- ベクトル検索のレイテンシ(50〜200ms)は実用上問題にならない