Home 論文解説: Mem0 — ベクトルDB×グラフDBで実現するプロダクション向けLLMエージェント長期記憶
投稿
キャンセル

📄 論文解説: Mem0 — ベクトルDB×グラフDBで実現するプロダクション向けLLMエージェント長期記憶

本記事は arXiv:2501.13956 Mem0: Building Production-Ready AI Agents with Scalable Long-Term Memory の解説記事です。

論文概要(Abstract)

著者ら(Deshraj Yadav, Taranjeet Singh, Dev Khant, 2025年1月)は、LLMエージェントにスケーラブルな長期記憶を付与するためのメモリ中心アーキテクチャ「Mem0」を提案している。Mem0は、ベクトルDB(pgvector/Qdrant/Weaviate)、グラフDB(Neo4j)、KVストアの3つのストレージバックエンドを統合し、会話からメモリを自動抽出・保存・更新・削除するMemory Managerを中核に据える。user_id/agent_id/run_idの3スコープによる名前空間管理と、LLMによる既存メモリとの矛盾検出・解決メカニズムが特徴である。

この記事は Zenn記事: LangGraph Store APIで実装するマルチエージェントRAGの共有メモリと長期記憶 の深掘りです。

情報源

背景と動機(Background & Motivation)

既存のLLMエージェントフレームワーク(LangChain, LlamaIndex等)は、会話履歴の保持にはCheckpointerやMessage Bufferを提供するものの、セッションを跨いだ長期記憶の管理にはアプリケーション開発者が独自に実装する必要がある。著者らは、以下の3つの課題がプロダクション環境での長期記憶実装を困難にしていると指摘している。

  1. メモリの自動抽出: 会話のどの部分を記憶として保存すべきかの判断がヒューリスティックに依存
  2. メモリの矛盾解決: 過去のメモリと新しい情報が矛盾する場合の更新・削除ポリシーが未定義
  3. マルチスコープ管理: ユーザー固有、エージェント固有、セッション固有のメモリを統一的に管理するAPIが不在

主要な貢献(Key Contributions)

  • 貢献1: ベクトルDB + グラフDB + KVストアを統合した3層ストレージアーキテクチャの設計。関係性メモリ(グラフ)と意味的類似性検索(ベクトル)を組み合わせることで、単一ストレージでは実現困難な複合クエリに対応
  • 貢献2: LLMベースのMemory Manager。会話から{fact, category, timestamp}形式のメモリを自動抽出し、既存メモリとの矛盾をLLMで検出してUPDATE/DELETE/NOOPを判定する
  • 貢献3: user_id/agent_id/run_idの3スコープによる名前空間管理。マルチテナント・マルチエージェント環境でのメモリ分離と共有を制御

技術的詳細(Technical Details)

Mem0のメモリアーキテクチャ

Mem0のアーキテクチャは、メモリの書き込み(Memory Formation)と読み出し(Memory Retrieval)の2つのパイプラインで構成される。

Memory Formation Pipeline(書き込み):

\[\text{memories} = \text{LLM}_{\text{extract}}(\text{messages}) \rightarrow \text{deduplicate}(\text{existing}) \rightarrow \text{store}(\text{vector} \cup \text{graph} \cup \text{kv})\]

ここで、

  • $\text{LLM}_{\text{extract}}$: 会話メッセージから記憶すべき事実を抽出するLLM呼び出し
  • $\text{deduplicate}$: 既存メモリとの重複・矛盾を検出する処理
  • $\text{store}$: 3つのストレージバックエンドへの書き込み

Memory Retrieval Pipeline(読み出し):

\[\text{relevant\_memories} = \text{TopK}\left(\alpha \cdot \text{sim}_{\text{vector}}(q, m) + \beta \cdot \text{sim}_{\text{graph}}(q, m) + \gamma \cdot \text{recency}(m)\right)\]

ここで、

  • $q$: 検索クエリ
  • $m$: メモリエントリ
  • $\text{sim}_{\text{vector}}$: ベクトルコサイン類似度
  • $\text{sim}_{\text{graph}}$: グラフ上のパス距離に基づく関連度
  • $\text{recency}(m)$: メモリの鮮度スコア(指数減衰)
  • $\alpha, \beta, \gamma$: 重み係数(デフォルト: $\alpha=0.5, \beta=0.3, \gamma=0.2$)

Memory Managerの矛盾解決メカニズム

Mem0の中核的な差別化要素は、新しいメモリと既存メモリの矛盾を自動的に検出・解決するMemory Managerである。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
from mem0 import Memory

# Mem0初期化(pgvectorバックエンド)
config = {
    "vector_store": {
        "provider": "pgvector",
        "config": {
            "dbname": "mem0_store",
            "collection_name": "memories",
            "embedding_model_dims": 1024,
            "host": "localhost",
            "port": 5432,
        },
    },
    "graph_store": {
        "provider": "neo4j",
        "config": {
            "url": "bolt://localhost:7687",
            "username": "neo4j",
            "password": "password",
        },
    },
    "llm": {
        "provider": "anthropic",
        "config": {
            "model": "claude-sonnet-4-6-20250514",
            "temperature": 0.0,
        },
    },
}

m = Memory.from_config(config)

# メモリの追加(自動抽出 + 矛盾解決)
result = m.add(
    messages=[
        {"role": "user", "content": "RAGシステムのベクトルDBにpgvectorを使っています"},
        {"role": "assistant", "content": "pgvectorはPostgreSQLの拡張で、HNSWインデックスが推奨です"},
    ],
    user_id="user-abc",
    agent_id="rag-advisor",
)
# result: [
#   {"id": "mem-xxx", "event": "ADD", "data": "ユーザーはRAGにpgvectorを使用"}
# ]

# 矛盾するメモリの更新
result = m.add(
    messages=[
        {"role": "user", "content": "pgvectorからQdrantに移行することにしました"},
    ],
    user_id="user-abc",
    agent_id="rag-advisor",
)
# result: [
#   {"id": "mem-xxx", "event": "UPDATE",
#    "old_data": "ユーザーはRAGにpgvectorを使用",
#    "data": "ユーザーはRAGにQdrantを使用(pgvectorから移行)"}
# ]

矛盾解決のアルゴリズム:

  1. 新メモリ候補を既存メモリとベクトル検索で照合(類似度閾値0.7以上)
  2. 類似メモリが存在する場合、LLMに以下を判定させる
    • UPDATE: 新情報が既存メモリの更新版である場合(例: 使用ツールの変更)
    • DELETE: 既存メモリが完全に無効化された場合(例: プロジェクト終了)
    • NOOP: 新情報と既存メモリが矛盾しない場合(両方保持)

3スコープの名前空間管理

Mem0はuser_id/agent_id/run_idの3つの識別子の組み合わせでメモリのスコープを制御する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# ユーザー固有メモリ(全エージェントから参照可能)
m.add(messages, user_id="user-abc")

# エージェント固有メモリ(特定エージェントのみ)
m.add(messages, agent_id="query-analyzer")

# ユーザー×エージェント固有メモリ(最も限定的)
m.add(messages, user_id="user-abc", agent_id="query-analyzer")

# セッション固有メモリ(run_id指定)
m.add(messages, user_id="user-abc", run_id="session-001")

# メモリ検索もスコープを指定
results = m.search(
    query="pgvectorの設定方法",
    user_id="user-abc",
    agent_id="rag-advisor",
    limit=5,
)

LangGraph Store APIとの名前空間対応:

Mem0LangGraph Store用途
user_id("rag", "users", user_id)ユーザー固有の嗜好・設定
agent_id("rag", "agents", agent_id)エージェント固有の専門知識
user_id + agent_id("rag", "users", user_id, agent_id)ユーザー×エージェント固有
run_idthread_id(Checkpointer)セッション固有の状態
スコープなし("rag", "shared", "knowledge")グローバル共有メモリ

グラフメモリの実装

Mem0のグラフメモリはNeo4jを使用し、エンティティ間の関係性を保持する。

1
2
3
4
5
6
7
8
9
10
11
12
# グラフメモリの構造
# ノード: エンティティ(ユーザー、ツール、概念等)
# エッジ: 関係性(uses, prefers, works_with等)

# 例: "ユーザーABCがpgvectorを使用" という関係
# (User:user-abc) -[USES]-> (Tool:pgvector)
# (Tool:pgvector) -[EXTENDS]-> (Database:PostgreSQL)

# グラフ検索クエリ(Cypher)
MATCH (u:User {id: $user_id})-[r]->(t:Tool)
WHERE t.category = 'vector_store'
RETURN t.name, type(r), r.since

実装のポイント(Implementation)

pgvectorバックエンドの設定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# pgvector使用時の推奨設定
config = {
    "vector_store": {
        "provider": "pgvector",
        "config": {
            "dbname": "mem0_production",
            "collection_name": "agent_memories",
            "embedding_model_dims": 1024,  # Voyage AI推奨
            "host": "aurora-cluster.xxx.ap-northeast-1.rds.amazonaws.com",
            "port": 5432,
            "user": "mem0_app",
            "password": "${SECRETS_MANAGER_VALUE}",
            # HNSWインデックス設定
            "hnsw_m": 16,              # ビーム幅(精度↑ = サイズ↑)
            "hnsw_ef_construction": 64, # 構築時探索幅
            "hnsw_ef_search": 40,       # 検索時探索幅
        },
    },
}

パフォーマンス特性

著者らは論文中で以下のレイテンシを報告している。

操作レイテンシ備考
メモリ追加(add100-300msLLM抽出 + ベクトル化 + 書き込み
メモリ検索(search50-150msベクトル検索 + グラフ検索 + マージ
矛盾解決200-500ms既存メモリ検索 + LLM判定

注意: これらの値はLLM呼び出しを含むため、使用するモデルとAPIレイテンシに大きく依存する。HaikuやGPT-4o-miniのような高速モデルを使用することでメモリ追加のレイテンシを半減できると著者らは述べている。

Production Deployment Guide

AWS実装パターン(コスト最適化重視)

トラフィック量別の推奨構成:

規模月間リクエスト推奨構成月額コスト主要サービス
Small~3,000 (100/日)Serverless$80-200Lambda + Bedrock + Aurora Serverless + Neptune Serverless
Medium~30,000 (1,000/日)Hybrid$400-1,000ECS Fargate + Aurora Provisioned + Neptune
Large300,000+ (10,000/日)Container$2,500-6,000EKS + Aurora Multi-AZ + Neptune + ElastiCache

Small構成の詳細(月額$80-200):

  • Lambda: 1GB RAM, 120秒タイムアウト($25/月)— Memory Manager処理
  • Bedrock: Claude 3.5 Haiku($80/月)— メモリ抽出・矛盾解決
  • Aurora Serverless v2 + pgvector: 0.5-2 ACU($43-90/月)— ベクトルストア
  • Neptune Serverless: 1-2 NCU($30-60/月)— グラフストア

コスト試算の注意事項: 上記は2026年2月時点のAWS ap-northeast-1(東京)リージョン料金に基づく概算値です。実際のコストはトラフィックパターンにより変動します。最新料金は AWS料金計算ツール で確認してください。

Terraformインフラコード

Small構成 (Serverless):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# --- Aurora Serverless v2 + pgvector ---
module "aurora_mem0" {
  source  = "terraform-aws-modules/rds-aurora/aws"
  version = "~> 9.0"

  name           = "mem0-vector-store"
  engine         = "aurora-postgresql"
  engine_version = "15.4"
  serverlessv2_scaling_configuration = {
    min_capacity = 0.5  # アイドル時$43/月
    max_capacity = 4.0
  }
  instance_class = "db.serverless"
  instances      = { 1 = {} }

  vpc_id  = module.vpc.vpc_id
  subnets = module.vpc.private_subnets
  storage_encrypted = true
}

# --- Neptune Serverless (グラフDB) ---
resource "aws_neptune_cluster" "mem0_graph" {
  cluster_identifier = "mem0-graph-store"
  engine             = "neptune"
  serverless_v2_scaling_configuration {
    min_capacity = 1.0
    max_capacity = 4.0
  }
  storage_encrypted = true
  vpc_security_group_ids = [aws_security_group.neptune_sg.id]
  neptune_subnet_group_name = aws_neptune_subnet_group.mem0.name
}

# --- Lambda(Memory Manager) ---
resource "aws_lambda_function" "mem0_manager" {
  filename      = "mem0_lambda.zip"
  function_name = "mem0-memory-manager"
  role          = aws_iam_role.mem0_lambda.arn
  handler       = "handler.main"
  runtime       = "python3.12"
  timeout       = 120
  memory_size   = 1024

  environment {
    variables = {
      AURORA_ENDPOINT  = module.aurora_mem0.cluster_endpoint
      NEPTUNE_ENDPOINT = aws_neptune_cluster.mem0_graph.endpoint
      BEDROCK_MODEL_ID = "anthropic.claude-3-5-haiku-20241022-v1:0"
    }
  }
}

運用・監視設定

メモリ操作の監視クエリ:

1
2
3
4
5
fields @timestamp, operation, user_id, agent_id, latency_ms
| filter operation in ["ADD", "UPDATE", "DELETE", "SEARCH"]
| stats count(*) as ops, avg(latency_ms) as avg_latency,
        pct(latency_ms, 95) as p95 by operation
| sort ops desc

コスト最適化チェックリスト

  • Aurora Serverless v2: アイドル時0.5 ACUで$43/月
  • Neptune Serverless: 最小1 NCUで$30/月
  • Bedrock Haiku: メモリ抽出にはHaiku($0.25/MTok)を使用
  • Prompt Caching: Memory Managerのシステムプロンプトをキャッシュ
  • バッチ処理: 非リアルタイムのメモリ整理はBatch APIで50%削減
  • グラフDB省略: 関係性メモリが不要ならNeptune省略で$30/月削減

実験結果(Results)

著者らは、LocomotionQA、MultiHop-RAG、PersonalQAの3つのベンチマークで評価を行っている。

ベンチマークMem0 (F1)MemGPT (F1)Zep (F1)MemoryBank (F1)
LocomotionQA0.830.570.620.51
MultiHop-RAG0.710.550.480.42
PersonalQA0.780.640.590.53

論文Table 1より、Mem0はLocomotionQAでMemGPTと比較してF1スコアを26ポイント改善(0.57→0.83)したと報告されている。著者らはこの改善の主因を、グラフメモリによる関係性推論と矛盾解決メカニズムに帰している。

制約: 上記のベンチマークはMem0の著者ら自身が実施した評価であり、第三者による独立した再現実験は本稿執筆時点で確認されていない。

実運用への応用(Practical Applications)

Mem0の設計はLangGraph Store APIと高い親和性を持つ。

LangGraph統合パターン:

  • Mem0のuser_id/agent_idスコープ → LangGraph Storeの名前空間タプル ("rag", "users", user_id), ("rag", "agents", agent_id) に直接マッピング
  • Mem0のMemory Manager → LangMem SDKのバックグラウンドメモリマネージャーと同等の役割
  • Mem0のグラフメモリ → LangGraph Storeでは未サポート(PostgresStore + Neo4j併用が必要)

マルチエージェントRAGでの活用: Zenn記事で解説した名前空間設計(グローバル共有 / エージェント固有 / ユーザー固有の3層)は、Mem0のuser_id/agent_idスコープと概念的に一致する。Mem0の矛盾解決メカニズムをLangGraph Storeのput操作に組み込むことで、複数エージェントが同一ユーザーのメモリを更新する際の整合性を保証できる。

関連研究(Related Work)

  • MemGPT(Packer et al., 2023): OS仮想メモリ概念をLLMメモリ管理に適用。Mem0との違いは、MemGPTがLLM自身のFunction Callingでメモリ操作を制御するのに対し、Mem0は外部Memory Managerが自動的にメモリを抽出・管理する点
  • MemoryBank(Zhong et al., 2024): Ebbinghaus忘却曲線によるメモリ重要度管理。Mem0と異なりグラフメモリを持たず、関係性推論ができない
  • LangGraph Store API: Mem0の名前空間設計と類似のタプルベース名前空間を提供。ただしグラフストアの統合は現時点で未サポート

まとめと今後の展望

Mem0は、LLMエージェントの長期記憶をプロダクション環境で運用するための実践的なアーキテクチャを提供している。ベクトルDB + グラフDB + KVストアの3層統合、LLMベースの自動メモリ抽出と矛盾解決、そしてuser_id/agent_id/run_idの3スコープ管理は、LangGraph Store APIの名前空間設計の延長線上に位置する。

今後の課題として、メモリ抽出・矛盾解決のLLM呼び出しコスト削減(蒸留モデルの活用)、グラフメモリのスケーラビリティ改善、およびマルチエージェント環境でのメモリ一貫性保証が挙げられる。

参考文献

この投稿は CC BY 4.0 でライセンスされています。