mem0は、LLMとの会話からファクトを抜き出して保存し、次の会話で必要な分だけ引き戻すメモリ層です。GitHubのスターは65.4k、ライセンスはApache-2.0、PyPI上の最新版は2.0.20(2026年9月2日リリース)。ここで注意がいるのは、日本語で読める解説記事の大半が v1.1〜v2 時代に書かれており、そのコードを2.0系にそのまま貼ると ValueError で止まる点です。この記事では、mem0の内部処理の流れ、2.0系で動くインストールから追加・検索までのコード、v3で削除されたグラフメモリと既定値の非互換、OSS版とマネージド版の費用の数え方、そして受託開発で採用してよい条件と見送るべき案件の型までを扱います。数値と仕様は公式ドキュメントとPyPI、GitHubリポジトリにあたって確認しました。
まとめ:mem0の採用を決める前に確認する3点とv3移行の判断順序
mem0を入れるかどうかは、機能の多さではなく次の3点で決まります。第一に、対話が単発で終わらず、同じ利用者が何度も戻ってくるプロダクトなのか。第二に、記憶が外れたときに業務上どこまで許されるのか。第三に、保存した内容の保持期間と削除の責任を誰が持つのか。
三つめを詰めずに進む例が多く見られます。メモリ層は個人の嗜好や業務情報を長期に溜め込む仕組みなので、実質的には個人データを蓄積する保管庫です。どのタイミングで消えるのかを決めないまま本番に出すと、退会したはずの利用者の発言が数か月後の応答に混ざります。
移行の順序も先に示しておきます。既存コードがv2以前で動いているなら、まず search() のエンティティIDを filters 辞書へ移し、top_k と threshold と rerank を明示指定して旧挙動を復元してから、v3の新既定値へ寄せていく順番が安全です。一気に上げると、検索件数が100件から20件に減った影響と、類似度しきい値が0.1に入った影響が混ざり、どちらで結果が変わったのか切り分けられません。
グラフメモリを前提に設計していた場合は、移行そのものを止める判断もあります。v3のOSS版では graph_store 設定と enable_graph が削除され、この機能はマネージド版へ移りました。関係性の追跡が要件の中核なら、v2系に留めるか、別のメモリ基盤を評価する方が筋が通ります。
mem0の仕組みと記憶の抽出から検索までの処理経路を実装目線で整理
「会話履歴を全部プロンプトへ入れる」方式との違いは、保存するものと引き戻すものを分離している点にあります。AIエージェントとは?基本概念とその役割を徹底解説で扱った自律的な振る舞いを長期に続けるには、履歴そのものではなく履歴から抽出した事実を持ち回る必要があります。
会話からファクトを抽出してベクトルストアへ保存する処理の流れ
add() に渡されたメッセージは、まずLLMへ送られてファクト抽出にかけられます。「昨日は疲れた」のような揮発的な発話は落ち、残るのは「PythonとAWSで開発している」のような持続する属性です。抽出された文はembeddingへ変換され、ベクトルストアへ格納されます。
v3ではこの抽出が単一パスの ADD-only へ変わりました。v2までは候補抽出のあとに ADD / UPDATE / DELETE を判定する二段構えで、LLM呼び出しが複数回走っていました。公式の移行ガイドは、これを1回のLLM呼び出しへ束ねた結果、抽出レイテンシがおよそ50%減り、LoCoMoのスコアが20ポイント上がったと記載しています。
設計への影響は小さくありません。add() の戻り値にUPDATEとDELETEが返らなくなったため、イベント種別で分岐していた既存コードは分岐そのものを外すことになります。記憶の更新は「古い記憶を書き換える」のではなく「新しい記憶を足して、検索側で新しい方を優先させる」形に変わったと理解してください。コンテキストの組み立て全体をどう設計するかはコンテキストの構成要素と効率化の実装で整理しています。
セマンティック・BM25・エンティティ一致を束ねるv3の検索方式
取り出し側は3つのシグナルを融合するハイブリッド検索になりました。意味の近さを見るセマンティック検索、語の一致を見るBM25、固有名詞の一致を見るエンティティマッチングの3つです。人名や製品名のような固有表現は、ベクトルの近さだけでは拾い漏れます。「山田さん」と「田中さん」はベクトル空間では近い位置に来てしまうためです。
この3つ目のシグナルには spaCy が要ります。導入していない環境ではエンティティマッチングが無効化され、セマンティック検索だけで動きます。Qdrantを使う場合の fastembed も同様で、入れなければBM25側が効きません。動くには動くが、公称の検索精度は出ない状態になります。
依存を落としたまま「精度が出ない」と評価してしまう事故は、この構造を知らないと起こります。ベクトル検索とキーワード検索の役割分担そのものはベクトル検索とセマンティック検索の違いで扱った通りで、mem0はその両方を内側に抱え込んだ実装だと捉えると位置づけが掴めます。
LoCoMo 92.5・p50 0.88秒という公称値の読み方と前提条件
公式リポジトリが掲げるベンチマークは3種類です。mem0ai/mem0のREADMEには、LoCoMoで精度92.5・p50レイテンシ0.88秒・トークン7.0K、LongMemEvalで精度94.4・p50 1.09秒・トークン6.8K、BEAM(1M)で精度64.1・p50 1.00秒・トークン6.7Kと記載されています。
公称値を読む際には、測定条件への注意が必要です。LoCoMoとLongMemEvalは英語の長期対話データセットで、日本語の業務会話とは分布が違います。BEAMの64.1という数字は、長さ1Mトークン規模の文脈では3分の1以上を取りこぼすという意味でもあります。記憶が外れても業務が止まらない設計にしておく前提は、この段階で置いておいてください。
トークン数の6.7K〜7.0Kは、全履歴を投げる方式との比較で効いてきます。10万トークンの履歴を毎回投げる構成と比べれば、1回の呼び出しあたりの入力量は桁で変わります。この入力量に関わる費用の内訳は、後半の章で扱う内容です。
mem0ai 2.0系のインストールから最初のメモリ追加と検索までの手順
ここからは手を動かします。2026年9月時点で動く形だけを書きます。
mem0aiのインストールとAPIキー設定を含む前提環境の準備
PyPIのmem0aiページによると、最新版は2.0.20(2026年9月2日)、対応PythonはPython 3.10以上4.0未満、ライセンスはApache-2.0です。エンティティマッチングまで効かせるなら、公式ドキュメントが推奨する nlp エクストラと spaCy の英語モデルを入れます。
pip install "mem0ai[nlp]"
python -m spacy download en_core_web_sm
export OPENAI_API_KEY="sk-xxxxxxxx"
既定のLLMは 公式のPython Quickstartにある通り OpenAI の gpt-5-mini、埋め込みは text-embedding-3-small(1536次元)です。ベクトルストアはQdrantがローカルの一時領域に、履歴DBはSQLiteがホームディレクトリ配下に作られます。つまり何も設定しなければ、外部サービスはOpenAIだけ、保存先はローカルという構成で起動します。
Memory.add と search を使った最小構成の動作コードと戻り値
次のコードが2.0系で動く最小構成です。v2までの記事と見比べると、search() の書き方が変わっているのが分かります。
from mem0 import Memory
m = Memory()
messages = [
{"role": "user", "content": "PythonとAWSで社内システムを作っています"},
{"role": "assistant", "content": "承知しました"},
]
m.add(messages, user_id="tenant-a-user-001")
results = m.search(
"この利用者の開発環境は何か",
filters={"user_id": "tenant-a-user-001"},
top_k=20,
threshold=0.1,
)
print(results)
戻り値には ADD イベントだけが入ります。v2までのように UPDATE や DELETE を待ち受ける分岐を書いても到達しません。user_id を search() の第2引数以降にキーワード引数として渡すと例外になるため、filters 辞書へ入れる形が必須です。
既定のQdrant・SQLite保存先とベクトルストアを差し替える設定
本番での運用では、保存先の明示が必要です。Memory.from_config() に辞書を渡す形で、ベクトルストア・LLM・埋め込みモデルをそれぞれ差し替えられます。mem0は20種類を超えるベクトルストアに対応しており、Qdrant・Chroma・Milvus・pgvector・Pineconeなどが選べます。
config = {
"vector_store": {
"provider": "qdrant",
"config": {
"collection_name": "mem0_tenant_a",
"host": "qdrant.internal",
"port": 6333,
},
},
"llm": {"provider": "openai", "config": {"model": "gpt-5-mini"}},
}
m = Memory.from_config(config)
v3では {collection_name}_entities という別コレクションが自動で作られます。権限を絞ったマネージドDBでは作成に失敗するため、同じ埋め込み次元であらかじめ手動で作成しておくことが必要です。検索基盤をRAGと共用する場合の組み立てはLangChainでRAGを構築する手順と併せて設計すると、コレクション名とスキーマの衝突を避けられます。
v3で消えたグラフメモリとfilters必須化を含む非互換変更の一覧
この章が、既存記事を読んで手が止まった人向けの本題です。
graph_store削除とrelationsフィールド消失が及ぼす設計への影響
v2まで、OSS版は Neo4j などの外部グラフDBを接続してエンティティ間の関係を保持できました。公式の移行ガイドによれば、v3では enable_graph、graph_store 設定、外部グラフDB統合がまとめて削除され、グラフメモリはマネージド版の組み込み機能として再実装されています。検索結果の relations フィールドも返りません。
# v2までは動いた設定(v3では graph_store が解釈されない)
config = {
"graph_store": {
"provider": "neo4j",
"config": {"url": "bolt://neo4j.internal:7687", "username": "neo4j", "password": "xxx"},
},
"version": "v1.1",
}
「AとBが同僚で、BとCが上司部下」といった関係の推論を要件に置いていたなら、OSS版のv3は選択肢から外れます。ここは言い切ります。セルフホストと関係推論の両立は、2026年9月時点のmem0では成立しません。どちらを捨てるかを先に決めてください。
filters必須化とtop_k・threshold既定値の変更が壊す既存コード
グラフメモリほど目立たないが実害が大きいのが既定値の変更です。移行ガイドの記載を表に起こします。
| 項目 | v2まで | v3 | 旧挙動に戻す指定 |
|---|---|---|---|
| エンティティID | トップレベルのキーワード引数 | filters 辞書の中 |
移設が必須(例外になる) |
top_k |
100 | 20 | top_k=100 |
threshold |
指定なし | 0.1 | threshold=0.0 |
rerank |
有効 | 無効 | rerank=True |
add() の戻り値 |
ADD / UPDATE / DELETE | ADD のみ | 戻せない(分岐を削除) |
| 設定キー名 | ファクト抽出用の旧設定キー | custom_instructions |
キー名を変更 |
表中のファクト抽出用の旧設定キーは custom_fact_extraction_prompt です。v3では custom_instructions へ名前を変更します。
厄介なのは、top_k と threshold の変更が例外を出さずに結果だけ変える点です。取得件数が5分の1になり、類似度0.1未満が切り落とされる。移行直後に「記憶が消えた」と報告が上がる典型はこれで、実際にはデータではなく取り出し条件が変わっています。TypeScript版では limit が topK へ改名されているため、同じ罠がフロント側にもあります。
OSS版とマネージド版の料金・運用負荷の違いと選び分けの判断基準
「OSSだから無料」で見積もると外します。費用は3つの場所に分かれて発生します。
Hobby無料枠1万件からProまでの料金階梯と超過時の課金の考え方
公式の料金ページに掲載されているマネージド版の区分は4つです。Hobbyが無料でメモリ追加10,000件/月・検索1,000件/月、Starterが月額19ドルで追加50,000件・検索5,000件、Proが月額249ドルで追加500,000件・検索50,000件、Enterpriseはカスタムで上限なし。固定プランに合わない利用形態向けに従量課金も用意されています。
数え方の癖に注意がいります。課金単位は「追加リクエスト」と「検索リクエスト」であって、保存されたメモリ件数ではありません。1回の会話ターンごとに add と search を1回ずつ呼ぶ設計なら、月間1万ターンでHobbyの検索枠を10倍超過します。検索枠のほうが先に尽きる構造だと理解しておくと、プラン選定を外しません。
セルフホスト時に自前で抱えるベクトルDBとLLM費用の内訳と見積り方
OSS版で消えるのはmem0への支払いだけで、内訳の残り2つは残ります。ベクトルストアの実行コスト(Qdrantを載せるコンテナとストレージ)と、抽出・検索で走るLLMおよび埋め込みの従量課金です。
- ファクト抽出:
add()1回につきLLM呼び出し1回(v3でADD-onlyに一本化) - 埋め込み:抽出されたファクト数だけ text-embedding-3-small を呼ぶ
- 検索:ハイブリッド検索のうちセマンティック側でクエリの埋め込みを1回
- インフラ:Qdrantコンテナ、履歴用SQLiteまたは外部DB、バックアップ領域
実務でまず効くのは1つめです。add の呼び出し回数がそのままLLM費用になるため、全ターンで add を呼ぶ設計にするか、セッション終了時にまとめて呼ぶかで金額が変わります。まとめて呼ぶ側に倒すのが基本で、リアルタイム性が要件でない限りターンごとの抽出は過剰です。
受託開発でmem0を採用してよい条件と見送るべきプロジェクトの型
ここは判断を書きます。ベンダーの導入事例にも個人ブログにも載らない部分です。
継続対話とユーザー個別の文脈が売上に効く案件という採用の条件
採用してよいのは、次の2つを同時に満たす案件です。同じ利用者が週に複数回戻ってくること。そして「前回の続き」を覚えていることが、利用継続や成約に直接効くこと。社内ヘルプデスク、継続支援型のカスタマーサポート、営業担当ごとの商談支援あたりが該当します。
逆に、記憶が効くかどうかを検証していない段階で基盤から入れるのは順序が違います。まずセッション内の履歴だけで動くものを作り、利用者が同じ説明を繰り返している箇所を実ログで数える。そこに具体的な件数が出てから、メモリ層を足す。この順序であれば、外した場合の損失が設計変更だけで済みます。エージェント本体の実装や既存システムとの接続まで含めて相談先を探している場合は、AIエージェント開発の実績と進め方をご覧ください。
単発問い合わせや厳密な監査要件で採用を見送るべき案件の特徴と代替案
見送るべき型は明確です。1つめは、問い合わせが1回で完結し、利用者が二度と戻らないフォーム型の窓口。記憶する相手がいないため、LLM呼び出しが1回増えるだけの構成になります。
2つめは、応答の根拠を1件ずつ提示できなければならない業務です。医療・金融・法務の一部がここに当たります。mem0が返すのはLLMが会話から抽出した二次情報であり、原文の所在が保証されません。根拠提示が要件なら、原典を引くRAG側に寄せて、メモリ層は使わない判断が正解です。
3つめは、エージェント同士が記憶を共有し、階層化された記憶構造を必要とする研究寄りの構成です。この領域はMIRIXのようなマルチエージェント記憶システムが扱う範囲で、mem0の単層のメモリとは設計思想が違います。要件が「エージェント間での記憶の受け渡し」なら、mem0を無理に伸ばさず別基盤を評価してください。
マルチテナント運用でのスコープ分離とメモリ汚染に備える設計指針
本番で詰まるのは、たいてい機能ではなく境界の設計です。
user_idとagent_idでメモリ空間を分ける設計と越境を防ぐ検証
mem0はメモリを user / session / agent の3階層で扱えます。危ないのは、複数テナントが同じコレクションを共有し、user_id だけで区切っている構成です。filters の指定漏れが1か所あれば、他テナントの記憶が検索に乗ります。
対策は2段構えにします。collection_name をテナント単位で分けて物理的に隔離したうえで、アプリ層では filters を組み立てる関数を1本に集約し、そこを通さない search() の直呼びを禁止する。そして結合テストで、テナントAの検索結果にテナントBの user_id が1件も混ざらないことをアサートしておきます。手で確認する運用にすると、必ずどこかで漏れます。
取り込み経路の人手確認と保持期間を決めるライフサイクル管理の設計
メモリ層への攻撃はすでに研究として複数報告されています。共有メモリ空間へ他者の入力経由で汚染を混ぜる型、外部コンテンツの自動取り込みを通じて偽の前提を植え付ける型、埋め込み空間にバックドアを仕込む型。いずれも「保存する内容を誰も見ていない」ことが成立条件です。
実務での歯止めは地味な2つに落ちます。外部から取り込んだテキストを無確認で add() に流す経路を作らないこと。そして保持期間を決めて、期限が来た記憶を機械的に消すこと。退会処理で user_id 配下のメモリを削除する導線も、リリース前に必ず通しておきます。後から足そうとすると、どのコレクションに何が残っているか分からなくなります。
よくある質問
mem0の導入検討でよく挙がる質問をまとめました。
mem0はOSS版とマネージド版のどちらから始めるべきですか?
検証段階ならOSS版で足ります。pip install "mem0ai[nlp]" だけでローカルのQdrantとSQLiteが自動で用意され、外部サービスはOpenAIだけで動きます。マネージド版を選ぶ理由になるのは、グラフメモリが要る場合と、ベクトルDBの運用を持ちたくない場合の2つです。Hobbyプランが無料で追加10,000件・検索1,000件まで使えるため、両方を並行して試して比較する進め方も取れます。
mem0とRAGは何が違うのですか?
引いてくる対象が違います。RAGは社内文書や仕様書といった既存のドキュメントを検索して根拠を提示します。mem0が引くのは、その利用者との会話から抽出された事実です。「この人はAWSを使っている」はmem0の領域、「AWSの料金体系はこうなっている」はRAGの領域になります。実務では併用が普通で、mem0で相手の前提を補い、RAGで根拠を出す形に落ち着きます。
v2で書いたコードはv3でそのまま動きますか?
動きません。m.search("query", user_id="alice") の形式は v3 で ValueError になり、filters={"user_id": "alice"} への書き換えが必須です。加えて top_k が100から20へ、threshold が未指定から0.1へ、rerank が有効から無効へ既定値が変わっています。この3つは例外を出さずに結果だけ変えるため、移行時は明示指定で旧挙動を復元してから、段階的に新既定値へ寄せる進め方を推奨します。
グラフメモリはOSS版でもう使えないのですか?
v3のOSS版では使えません。enable_graph と graph_store 設定、Neo4jなど外部グラフDBとの統合は削除され、マネージド版の組み込み機能として再実装されました。検索結果の relations フィールドも返らなくなります。関係性の追跡が要件の中核にあるなら、マネージド版へ移るか、v2系に留めるか、他のメモリ基盤を評価するかの三択になります。
mem0は日本語の会話でも精度が出ますか?
公称ベンチマークのLoCoMo 92.5とLongMemEval 94.4は、いずれも英語の長期対話データセットでの測定値です。日本語での同等の公開値はありません。加えてv3のエンティティマッチングは spaCy の英語モデル(en_core_web_sm)を前提にしているため、日本語の固有名詞は一致シグナルに乗りにくくなります。日本語で使う場合は、自社のログでヒット率を実測してから本番判断にかけてください。
関連記事
- コンテキストの構成要素と効率化の実装:メモリ・RAG・compactionを含むコンテキスト全体の組み立て方を扱っています。
- ベクトル検索とセマンティック検索の違い:mem0が内側で使う検索方式の前提を整理しています。
- AIエージェントとは?基本概念とその役割を徹底解説:メモリ層を載せる対象であるエージェントの基本を扱っています。
- MIRIXとは何か:マルチエージェント記憶システムの概要:階層化された記憶構造を必要とする場合の比較対象です。
- LangChainでRAGを構築する手順:根拠提示が要件の場合に組み合わせるRAG側の実装手順です。