エージェントの「記憶」設計は、しばしば「ベクトルDB 対 ファイル」と二分される。だがこれは誤った対立だ。実際には直交する2つの設計判断がある——single source of truth(以下 SSOT)をファイルに置くかDBに置くか、そして検索を字句スキャン(grep)で行うか事前計算インデックスで行うか。この2軸を倒す力がスケールである。本稿は15のツールをこの座標に置き、ポータビリティとクロスエージェント性まで技術的に検討する。
エージェントの記憶層がやることは2つに尽きる。セッションを越えて状態を永続化することと、必要な断片だけをコンテキストウィンドウに戻すこと(検索)。この2つはそれぞれ独立した設計判断であり、混ぜると議論が濁る。
grep / ripgrep / BM25)か、事前計算した dense ベクトルインデックス(近似最近傍)か、グラフ走査か、これらのハイブリッドか。重要なのは A と B が独立している点だ。「ファイル SSOT + ベクトルインデックス」も「DB SSOT + 字句検索」も成立する。前者は実際に最も人気の中間解になっている。だから「ファイルか、ベクトルか」は座標の取り違えで、正しくは2次元の地図になる。
この2軸は独立した二択だ——「ファイル + ベクトル」も「DB + 字句」も成立する。規模が大きくなるほど、軸Aは DB・軸Bはインデックスが選ばれやすくなる。
正本を Markdown 等のプレーンテキストファイルとしてファイルシステムに置く。技術的な帰結は次の通り。
blame・revert・ブランチ。記憶の変更が監査可能になり、壊れたら巻き戻せる。これを DB で得るには監査ログとスナップショットを別途作る必要がある。ripgrep・Tree-sitter で動く(§03)。記憶もファイルなら、コードを読むのと同じツール経路で記憶を読める。新しい検索インフラが要らない。正本を DB の状態(行・ベクトル・グラフのノード/エッジ)として持つ。代わりに次が手に入る。
user_id 単位のマルチテナント分離・並行書き込みの調停がエンジン側の保証として付く。多人数サービスではこれが事実上必須になる。grep / BM25)— インデックスを事前計算しないエージェントが正本を直接走査する。静的な RAG(事前にチャンク化して埋め込み、クエリ時に近傍取得)と根本的に違うのは、LLM が実行時にツールを選び、反復で絞り込む点だ。コーディングエージェントの典型ループ:
具体的には、ディレクトリ一覧で構造を把握し、grep -r "def processPayment" . や ripgrep で定義箇所を引き、必要なファイルだけを読み、Tree-sitter で AST(関数定義・クラス階層・import グラフ)をたどる。ベクトル検索が苦手とする構造関係(呼び出しグラフ、定義の一意性)をここで捉える。コード文脈ではベクトルのチャンク境界問題や silent failure(存在しない関数を自信満々に呼ぶ)を回避できる。
字句検索が効くのは、書いた本人が探すと語彙が一致し、クエリと文書の意味ギャップがほぼ無いから。ある実装報告では、個人ノート規模で BM25 が9割超の確率で正しい文書を引き、FTS5 のランキングが崩れ始めるのは1万件超だとする。Anthropic 自身も「まず agentic search から始め、必要になってから semantic を足せ」と公式に推奨している。
テキストを埋め込みベクトルにし、HNSW や IVF といった近似最近傍(ANN)インデックスで近傍検索する。言い換え・同義・cross-lingual に強い。代償は書き込み増幅(write amplification)だ。
bi-temporal)事実をノードとエッジで持ち、関係をたどる。Zep の Graphiti は各事実に2つの時間軸——valid-time(その事実が世界で真だった期間)と transaction-time(システムがそれを取り込んだ時刻)——を持つ bi-temporal モデルを採る。矛盾する新事実が来ても古い事実を削除せず、valid-time の区間を閉じて無効化する。これにより「ある時点で何が真だったか / 何を信じていたか」という point-in-time クエリが成立する。記憶の更新を「上書き」でなく「履歴の積層」として扱う設計だ。
RRF / HyDE — 実務はほぼ全部ここ疎(BM25)と密(ベクトル)、さらにグラフやキー一致を併用し、順位を融合する。標準的な融合手法が Reciprocal Rank Fusion だ。スコアが互いに非互換な複数のランキングを、順位だけで統合する:
もう一つよく使われるのが HyDE(Hypothetical Document Embeddings)。クエリをそのまま埋め込む代わりに、LLM に仮説的な回答文を生成させ、その回答文を埋め込んで近傍検索する。短い質問より、生成された回答文のほうが本物の回答文書に埋め込み空間で近いことを利用する。Cloudflare Agent Memory は全文・キー一致・原文・ベクトル・HyDE の5系統を重み付き RRF で融合している。
軸Aと軸Bをどちらに選ぶかは、規模によって変わる。効くのは検索精度だけではない。多テナント分離・並行書き込み・書き込み頻度も同時に効く。
FTS5 のランキングが劣化し始める。これは厳密な閾値ではなく、書き手・検索者・言い換え率に依存する経験則として読むべき。grep の併用で+12.5% の精度を報告。純 grep でも純ベクトルでもなく、併用が勝つことを示す。2軸を取ると、実在ツールは3つの安定領域に集まる。「DB を SSOT にしつつ字句スキャンだけで引く」左下はほぼ空で、DB を選んだ時点でインデックスも持つのが自然だからだ。
縦軸 = SSOT の所在(上:ファイル / 下:DB)、横軸 = 検索戦略(左:字句スキャン / 右:インデックス)。右下へ行くほど規模が大きい。
左上が最も「所有・可搬・filesystem-native」、右下が最も「分離・一貫・マネージド」。左下(DB を SSOT にしつつ字句スキャンだけ)はほぼ空——DB を選んだ時点でインデックスも持つのが自然だからだ。
2026年6月時点の検証済みデータ。SSOT の所在で陣営を分け、検索戦略・想定規模帯・ポータビリティを併記する。スター数は変動が速いので目安。
| ツール | SSOT | 正本 / 構造 | 検索戦略 | 想定規模帯 | ライセンス / ★ |
|---|---|---|---|---|---|
| Claude Code memoryAnthropic(公式) | ファイル | `CLAUDE.md` 階層 + 自動メモリ(`MEMORY.md` を索引とするプレーンマークダウン) | 字句スキャン(`@path` インポート + 都度ファイル読み、インデックスなし) | 個人 | 製品同梱 — |
| memweaveSachin Sharma | ファイル | `memory/*.md` が SSOT。SQLite(FTS5 + sqlite-vec)は再構築可能なキャッシュ | ハイブリッド(ベクトル0.7 / BM25 0.3)+時間減衰 | 個人〜中 | MIT ★ 42 |
| memsearchZilliz | ファイル | マークダウンが常に SSOT、Milvus は「影の索引」(再構築可) | 密ベクトル+疎BM25を`RRF`で再ランク、3段階で展開 | 個人〜中 | MIT ★ ~2k |
| GBrainGarry Tan | ファイル | Git内のマークダウンが SSOT。Postgres+pgvector / PGLite と自動生成グラフは派生 | ベクトル+BM25+`RRF`+グラフ巡回+合成回答 | 個人〜中 | MIT ★ 22.3k |
| basic-memoryBasic Machines | ファイル | ディスク上のマークダウンが SSOT。観察+wikilinkでグラフ化。SQLite/Postgres は派生 | 全文+意味ベクトルのハイブリッド | 個人〜中 | AGPL-3.0 ★ 3.2k |
| mem0Mem0 Inc. (YC S24) | DB | 事実を抽出して DB に保存。ベクトル+BM25+エンティティ連結+時間ランク | ハイブリッド + 多層スコープ(user / session / agent) | 中〜大・多人数 | Apache-2.0 ★ 58.4k |
| SupermemoryDhravya Shah | DB | 会話から事実抽出 + ユーザープロファイル + 矛盾解消 | RAG文書検索 + 個別化メモリのハイブリッド(~50ms) | 中〜大・多人数 | MIT ★ 26.8k |
| Cloudflare Agent MemoryCloudflare | DB | Durable Objects + SQLite + Vectorize + Workers AI。4種別(事実/イベント/指示/タスク) | 5系統(全文・key・原文・ベクトル・HyDE)を重み付き`RRF` | 大・多人数 | 非公開 — |
| agentmemoryrohitg00 | DB | フックで自動捕捉→圧縮。SQLite + ベクトル + 知識グラフ(外部DB不要) | 三系統(BM25 / ベクトル / グラフ)を`RRF`、p50 14ms | 中・コーディング | Apache-2.0 ★ 22.4k |
| Zep / GraphitiZep | DB | `bi-temporal` 知識グラフ。矛盾事実は削除せず valid-time を閉じて無効化、point-in-time クエリ可 | グラフ検索 + 意味/全文(~155ms) | 大・企業 | Apache-2.0 ★ 27.3k |
| Letta(旧MemGPT)UC Berkeley 発 | DB | エージェント自身が編集する「メモリブロック」+ ベクトルDBの保管領域(OS的ページング) | エージェント主導の出し入れ + 保管領域検索 | 中〜大 | Apache-2.0 ★ 23.3k |
| LangMemLangChain | DB | 保管先非依存(LangGraph の BaseStore に委譲、典型的にはPostgres+ベクトル) | 意味/エピソード/手続き記憶。自前の検索プロダクトは持たない | 中〜大 | OSS — |
軸A をファイルに倒す最大の見返りは、検索精度ではなく所有と相互運用にある。ここが「ベクトルDB 対 ファイル」の対立では見えなくなる論点だ。
軸A(SSOT の所在)の判断を、5つの問いで近似する。検索戦略(軸B)は規模に応じて後から足せるが、SSOT の選択は土台なので先に決まる。
各問いで左を選ぶほどファイル SSOT、右を選ぶほど DB SSOT が向く。
注意: これは軸A の判断であって、検索戦略(軸B)は独立だ。ファイル SSOT を選んでも、規模が増えれば grep → ハイブリッド(`RRF`)へ検索層だけ足せる(memweave・GBrain がその形)。「まず単純に始め、実際に壊れてから層を足す」が一貫した助言だ。
各サービスは LoCoMo や LongMemEval のスコアを誇る。だが横並び比較には致命的な前提がある。
LoCoMo(arXiv 2402.17753)は、最大35セッション・平均約300ターンの超長期会話で記憶を試す学術ベンチマークで、単一ホップ・複数ホップ・時間推論・敵対的質問を QA で測る。問題は、公表スコアのほぼ全てがベンダー自己申告で測定条件が各社で異なること。mem0 が 91.6、Zep が 94.7 と並んでも、埋め込みモデル・チャンク設計・採点プロンプトが違えば比較は成り立たない。`LongMemEval` や `BEAM` も同様だ。スコアは「そのツールが何を得意と主張しているか」を読む材料であって、優劣の判定材料ではない。
CLAUDE.md / 自動メモリ)に記憶を置く。SSOT を人が読めるテキストに置くか、見えない合成状態に置くか——本稿の軸A が、製品レベルでも最も鋭く現れている対比だ。
「ベクトルDB 対 ファイル」は、座標の取り違えだった。SSOT の所在(軸A)と検索戦略(軸B)は独立で、検索は規模に応じて誰もがハイブリッドへ収束する。
だから本当の設計判断は一つに絞られる——記憶の SSOT を、ポータブルで監査可能でクロスエージェントなファイルに置くか、分離と一貫性を保証するマネージドな DB に置くか。検索層はその上で、字句スキャンから始めて必要な分だけインデックスを足せばよい。多くの個人・少人数の用途では、ファイル SSOT + 字句スキャンで始め、壊れた層だけハイブリッドへ昇格させるのが、最もコストの低い正解になる。