Home 論文解説: LightRAG — デュアルレベル検索とインクリメンタル更新で実現する軽量グラフRAG
投稿
キャンセル

📄 論文解説: LightRAG — デュアルレベル検索とインクリメンタル更新で実現する軽量グラフRAG

論文概要(Abstract)

LightRAGは、GraphRAGの2つの根本的課題—単一レベル検索とインクリメンタル更新不可—を解決する軽量・高速なグラフRAGフレームワークである。デュアルレベル検索(エンティティ粒度のLow-Level + 関係粒度のHigh-Level)と差分グラフ更新機構を導入し、5ドメインの実験でGraphRAGを含む既存手法を上回る性能を達成した。香港大学のチームが開発し、GitHubで14,000以上のスターを獲得しているOSSプロジェクトである。

この記事は Zenn記事: LlamaIndex v0.14実践ガイド:AgentWorkflowで本番RAGを構築する の深掘りです。

情報源

  • arXiv ID: 2412.15605
  • URL: https://arxiv.org/abs/2412.15605
  • 著者: Zirui Guo, Lianghao Xia, Yanhua Yu, Tu Ao, Chao Huang (University of Hong Kong)
  • 発表年: 2024
  • 分野: cs.IR, cs.AI

背景と動機(Background & Motivation)

GraphRAG(Microsoft)はナレッジグラフとコミュニティ構造を活用してRAGのグローバルな回答能力を大幅に向上させたが、実用上2つの大きな課題を抱えている。

課題1: 単一レベル検索の制約 GraphRAGはLocal Search(エンティティ近傍)とGlobal Search(コミュニティ要約)を提供するが、この2つは独立した検索モードであり、クエリの性質に応じて事前に選択する必要がある。実際のユースケースでは「特定のエンティティについて知りたいが、関連するトレンドも知りたい」というように、複数粒度の情報を同時に求めるクエリが多い。

課題2: インクリメンタル更新の困難 GraphRAGではコーパスを更新するたびにグラフ全体を再構築する必要がある。大規模コーパスでは構築に数時間〜数日かかるため、動的に更新されるナレッジベースには不向きである。

LightRAGはこの2つの課題を同時に解決する。Zenn記事のPropertyGraphIndex(Stage 3)を検討する際、GraphRAGの代替実装として検討する価値が高い。

主要な貢献(Key Contributions)

  • 貢献1: デュアルレベル検索(Low-Level: エンティティ粒度、High-Level: 関係/概念粒度)とHybridモードを設計し、クエリ性質に応じた柔軟な検索を実現
  • 貢献2: 差分グラフ更新機構により、新規ドキュメント追加時にグラフ全体の再構築を不要にした
  • 貢献3: 5ドメイン(Agriculture, CS, Legal, Mix, General)の実験でGraphRAGを含む既存手法を上回る性能を達成
  • 貢献4: Neo4j, PostgreSQL, Milvus等の外部DBに対応し、本番環境への統合を容易にした

技術的詳細(Technical Details)

アーキテクチャ概要

LightRAGのアーキテクチャは、インデックスパイプラインと検索エンジンの2つの主要コンポーネントで構成される。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌─────────────────────────────────────────────────┐
│                LightRAG Core                     │
│                                                  │
│  ┌──────────────┐    ┌─────────────────────────┐│
│  │  Indexing     │    │   Retrieval Engine      ││
│  │  Pipeline     │    │                         ││
│  │              │    │  ┌───────────────┐      ││
│  │  Text→Chunk  │    │  │ Low-Level     │      ││
│  │  →Extract    │    │  │ (Entity)      │      ││
│  │  →Graph      │    │  ├───────────────┤      ││
│  │  →Embed      │    │  │ High-Level    │      ││
│  │              │    │  │ (Relation)    │      ││
│  └──────┬───────┘    │  ├───────────────┤      ││
│         │            │  │ Hybrid        │      ││
│  ┌──────▼───────┐    │  │ (LL+HL)       │      ││
│  │ Graph Storage │    │  ├───────────────┤      ││
│  │ + Vector DB   │    │  │ Naive         │      ││
│  └──────────────┘    │  └───────────────┘      ││
│                      └─────────────────────────┘│
└─────────────────────────────────────────────────┘

デュアルレベル検索メカニズム

LightRAGの核心は、検索対象をエンティティ(ノード)と関係(エッジ)の2つのレベルに分け、それぞれに独立したベクトルインデックスを構築する点にある。

Low-Level Retrieval(低レベル: エンティティ粒度)

クエリに対して、エンティティの埋め込みベクトルとの類似度でtop-kエンティティを検索し、その近傍サブグラフを取得する。

\[\mathcal{E}_q = \text{top-k}\left(\text{sim}(\mathbf{h}_q, \mathbf{h}_{e_i}) \mid e_i \in \mathcal{V}\right)\]

ここで、

  • $\mathcal{E}_q$: クエリ$q$に最も関連するエンティティ集合
  • $\mathbf{h}_q$: クエリの埋め込みベクトル
  • $\mathbf{h}_{e_i}$: エンティティ$e_i$の埋め込みベクトル
  • $\mathcal{V}$: グラフの全ノード集合
  • $\text{sim}$: コサイン類似度

適用例: 「LlamaIndexのAgentWorkflowとは何か?」「PropertyGraphIndexの内部実装は?」

High-Level Retrieval(高レベル: 関係/概念粒度)

クエリに対して、関係(エッジ)の埋め込みベクトルとの類似度で検索する。関係はエンティティ間の意味的つながりを表すため、より抽象的・概念的な検索が可能。

\[\mathcal{R}_q = \text{top-k}\left(\text{sim}(\mathbf{h}_q, \mathbf{h}_{r_j}) \mid r_j \in \mathcal{E}\right)\]

ここで、

  • $\mathcal{R}_q$: クエリ$q$に最も関連する関係集合
  • $\mathbf{h}_{r_j}$: 関係$r_j$の埋め込みベクトル
  • $\mathcal{E}$: グラフの全エッジ集合

適用例: 「RAGフレームワークの最近のトレンドは?」「マルチエージェントとRAGの関係性は?」

Hybrid Mode(ハイブリッド: 推奨デフォルト)

Low-LevelとHigh-Levelの両方を実行し、結果を統合する。クエリの性質が事前に分からない場合に最適。

\[\mathcal{C}_q = \text{Merge}(\mathcal{E}_q, \mathcal{R}_q)\]

インクリメンタル更新メカニズム

GraphRAGの最大の弱点であるグラフ再構築問題を解決する。

既存手法(GraphRAG)の問題: \(\text{Cost}(\text{update}) = O(|\mathcal{D}|) \quad \text{(全コーパス再処理)}\)

LightRAGの解決策: \(\text{Cost}(\text{update}) = O(|\mathcal{D}_{\text{new}}|) \quad \text{(新規ドキュメントのみ処理)}\)

更新アルゴリズム:

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
def incremental_update(
    graph: KnowledgeGraph,
    new_documents: list[str]
) -> KnowledgeGraph:
    """差分更新アルゴリズム"""
    for doc in new_documents:
        # 1. 新チャンクのみ処理
        chunks = chunk_text(doc)

        for chunk in chunks:
            # 2. エンティティ・関係抽出
            entities, relations = extract_from_chunk(chunk)

            for entity in entities:
                if entity.name in graph.nodes:
                    # 3a. 既存エンティティ: 記述を統合
                    existing = graph.nodes[entity.name]
                    merged_desc = llm_summarize(
                        existing.description,
                        entity.description
                    )
                    graph.update_node(entity.name, merged_desc)
                else:
                    # 3b. 新規エンティティ: 追加
                    graph.add_node(entity)

            for relation in relations:
                if relation in graph.edges:
                    # 4a. 既存関係: 強度スコア更新
                    graph.update_edge_weight(relation)
                else:
                    # 4b. 新規関係: 追加
                    graph.add_edge(relation)

        # 5. ベクトルインデックスを差分更新
        graph.update_vector_index(new_entities, new_relations)

    return graph

GraphRAGとの機能比較

機能GraphRAGLightRAG
検索粒度Local/Globalの二択Low/High/Hybrid/Naive
差分更新不可(全再構築)可(新チャンクのみ)
外部DBサポート限定的Neo4j, PostgreSQL, Milvus, Qdrant
ローカルLLM対応限定的Ollama完全対応
コスト中(30-40%削減)
チャンクサイズ2400トークン1200トークン
ライセンスMITMIT

実装のポイント(Implementation)

インストールと基本使用法

1
pip install lightrag-hku
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
from lightrag import LightRAG, QueryParam
from lightrag.llm import gpt_4o_mini_complete

# 初期化
rag = LightRAG(
    working_dir="./ragtest",
    llm_model_func=gpt_4o_mini_complete
)

# ドキュメント挿入(インクリメンタル対応)
with open("document.txt") as f:
    rag.insert(f.read())

# 追加ドキュメント(差分更新)
with open("new_document.txt") as f:
    rag.insert(f.read())  # グラフ全体の再構築は不要

# 各モードでクエリ
# Low-Level: 特定エンティティの詳細
result_ll = rag.query(
    "LlamaIndexのAgentWorkflowとは?",
    param=QueryParam(mode="local")
)

# High-Level: 抽象的テーマ
result_hl = rag.query(
    "RAGフレームワークの最近のトレンドは?",
    param=QueryParam(mode="global")
)

# Hybrid: 推奨デフォルト
result_hybrid = rag.query(
    "AgentWorkflowがRAGにもたらす変化とは?",
    param=QueryParam(mode="hybrid")
)

外部DB設定(Neo4j)

1
2
3
4
5
6
7
8
9
10
11
12
from lightrag import LightRAG

rag = LightRAG(
    working_dir="./ragtest",
    graph_storage="Neo4JStorage",
    log_level="DEBUG",
    llm_model_func=gpt_4o_mini_complete,
    # Neo4j設定
    neo4j_uri="bolt://localhost:7687",
    neo4j_user="neo4j",
    neo4j_password="password",
)

Ollama(ローカルLLM)対応

1
2
3
4
5
6
7
8
9
10
11
12
from lightrag.llm import ollama_model_complete, ollama_embedding

rag = LightRAG(
    working_dir="./ragtest",
    llm_model_func=ollama_model_complete,
    llm_model_name="llama3.1:8b",
    embedding_func=EmbeddingFunc(
        embedding_dim=768,
        max_token_size=8192,
        func=lambda texts: ollama_embedding(texts, embed_model="nomic-embed-text")
    ),
)

主要ハイパーパラメータ

パラメータデフォルト値推奨範囲説明
chunk_token_size1200800-1600チャンクサイズ(GraphRAGの半分)
chunk_overlap_token_size10050-200オーバーラップ
entity_extract_max_gleaning11-3エンティティ抽出反復回数
top_k6030-100検索時の近傍数
max_token_for_local_context40962048-8192ローカル検索コンテキスト上限
max_token_for_global_context40962048-8192グローバル検索コンテキスト上限

Production Deployment Guide

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

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

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

Small構成の詳細 (月額$60-150):

  • Lambda: 1GB RAM, 90秒タイムアウト ($20/月)
  • Bedrock: Claude 3.5 Haiku ($60/月) — エンティティ抽出・回答生成
  • S3: グラフストレージ(LightRAGデフォルトのJSONファイル) ($5/月)
  • CloudWatch: 基本監視 ($5/月)

GraphRAG比との差別化:

  • Neptune不要(Small構成ではS3のJSONファイルで十分)→ $50/月削減
  • インクリメンタル更新により再構築LLMコストが不要 → 長期的に大幅コスト削減
  • チャンクサイズ半分 → エンティティ抽出のLLMコスト約30%削減

コスト試算の注意事項:

  • 上記は2026年2月時点のAWS ap-northeast-1(東京)リージョン料金に基づく概算値
  • インクリメンタル更新の頻度により月間Bedrockコストが変動
  • 最新料金は AWS料金計算ツール で確認してください

Terraformインフラコード

Small構成 (Serverless): Lambda + Bedrock + S3

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# --- S3(LightRAGグラフストレージ) ---
resource "aws_s3_bucket" "lightrag_storage" {
  bucket = "lightrag-graph-storage"
}

resource "aws_s3_bucket_versioning" "lightrag_storage" {
  bucket = aws_s3_bucket.lightrag_storage.id
  versioning_configuration { status = "Enabled" }
}

resource "aws_s3_bucket_server_side_encryption_configuration" "lightrag" {
  bucket = aws_s3_bucket.lightrag_storage.id
  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "aws:kms"
    }
  }
}

# --- Lambda関数(LightRAGクエリハンドラ) ---
resource "aws_lambda_function" "lightrag_query" {
  filename      = "lightrag_query.zip"
  function_name = "lightrag-query-handler"
  role          = aws_iam_role.lightrag_lambda.arn
  handler       = "index.handler"
  runtime       = "python3.12"
  timeout       = 90
  memory_size   = 1024

  environment {
    variables = {
      S3_BUCKET           = aws_s3_bucket.lightrag_storage.id
      BEDROCK_MODEL_ID    = "anthropic.claude-3-5-haiku-20241022-v1:0"
      DEFAULT_QUERY_MODE  = "hybrid"
      TOP_K               = "60"
    }
  }
}

# --- EventBridge(インクリメンタル更新スケジュール) ---
resource "aws_cloudwatch_event_rule" "incremental_update" {
  name                = "lightrag-incremental-update"
  description         = "LightRAGの差分グラフ更新を定期実行"
  schedule_expression = "rate(1 hour)"
}

resource "aws_cloudwatch_event_target" "update_lambda" {
  rule = aws_cloudwatch_event_rule.incremental_update.name
  arn  = aws_lambda_function.lightrag_update.arn
}

# --- 差分更新Lambda ---
resource "aws_lambda_function" "lightrag_update" {
  filename      = "lightrag_update.zip"
  function_name = "lightrag-incremental-update"
  role          = aws_iam_role.lightrag_lambda.arn
  handler       = "update.handler"
  runtime       = "python3.12"
  timeout       = 300  # 差分更新は5分以内を想定
  memory_size   = 2048

  environment {
    variables = {
      S3_BUCKET        = aws_s3_bucket.lightrag_storage.id
      BEDROCK_MODEL_ID = "anthropic.claude-3-5-haiku-20241022-v1:0"
    }
  }
}

# --- IAMロール ---
resource "aws_iam_role" "lightrag_lambda" {
  name = "lightrag-lambda-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action = "sts:AssumeRole"
      Effect = "Allow"
      Principal = { Service = "lambda.amazonaws.com" }
    }]
  })
}

運用・監視設定

CloudWatch Logs Insights — 検索モード別レイテンシ:

1
2
3
4
5
6
fields @timestamp, query_mode, duration_ms, entity_count, relation_count
| stats avg(duration_ms) as avg_latency,
        pct(duration_ms, 95) as p95_latency,
        count(*) as query_count
  by query_mode
| sort avg_latency desc

インクリメンタル更新監視(Python):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import boto3

cloudwatch = boto3.client('cloudwatch')
cloudwatch.put_metric_alarm(
    AlarmName='lightrag-update-duration',
    ComparisonOperator='GreaterThanThreshold',
    EvaluationPeriods=1,
    MetricName='Duration',
    Namespace='AWS/Lambda',
    Period=300,
    Statistic='Average',
    Threshold=180000,  # 3分超過でアラート
    AlarmDescription='LightRAG差分更新時間異常(グラフ肥大化の兆候)',
    Dimensions=[{
        'Name': 'FunctionName',
        'Value': 'lightrag-incremental-update'
    }]
)

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

  • Small構成ではS3ストレージを使用(Neptune不要でコスト大幅削減)
  • インクリメンタル更新を活用(GraphRAGの全再構築コスト回避)
  • デフォルトHybridモードを使用(Low/Highの個別呼び出しは不要)
  • チャンクサイズ1200トークン(GraphRAGの半分でLLMコスト約30%削減)
  • Ollama対応でローカルLLM使用(APIコストゼロ化可能)
  • S3バージョニングでグラフのバックアップ自動化
  • EventBridge定期更新で差分更新を自動化
  • AWS Budgets月額予算設定

実験結果(Results)

データセット(5ドメイン):

  1. Agriculture(農業)
  2. CS(コンピュータサイエンス)
  3. Legal(法律)
  4. Mix(複合)
  5. General(汎用)

比較手法: NaiveRAG, RQ-RAG, HyDE, GraphRAG (Local/Global)

LightRAG Hybrid vs 各手法の勝率(Overall):

比較手法LightRAG Hybrid 勝率
NaiveRAG~90% win
RQ-RAG~85% win
HyDE~80% win
GraphRAG (Global)~65% win
GraphRAG (Local)~72% win

評価軸別(vs GraphRAG Global):

評価軸LightRAG Hybrid 勝率
Comprehensiveness63%
Diversity67%
Empowerment65%
Overall65%

分析ポイント:

  • LightRAG HybridはGraphRAGの両モード(Local/Global)を同時に上回る
  • 特にDiversity(多様性)での改善が顕著 — デュアルレベル検索により異なる粒度の情報を統合
  • NaiveRAGとの差は90%勝率と圧倒的 — グラフ構造の導入効果が明確
  • コスト効率はGraphRAGの30-40%削減で同等以上の性能

実運用への応用(Practical Applications)

LlamaIndex v0.14との組み合わせ

Zenn記事のStage 3(PropertyGraphIndex)の代替・補完として、LightRAGを以下のように活用できる。

シナリオ推奨理由
静的ドキュメント、グローバル分析重視GraphRAGコミュニティレポートの品質が高い
動的ドキュメント、コスト重視LightRAGインクリメンタル更新・低コスト
特定エンティティ詳細PropertyGraphIndexLlamaIndex統合が容易
マルチホップ推論HippoRAGPPRベースの関連エンティティ拡張

導入フローチャート

1
2
3
4
5
6
7
8
9
ドキュメント更新頻度は?
├─ 低い(月1回以下)→ GraphRAGを検討
├─ 中程度(週1回程度)→ LightRAGを推奨
└─ 高い(毎日〜リアルタイム)→ LightRAGを強く推奨

クエリの性質は?
├─ 特定エンティティ → Low-Level mode
├─ 抽象的テーマ → High-Level mode
└─ 両方/不明 → Hybrid mode(推奨デフォルト)

関連研究(Related Work)

  • GraphRAG (2404.16130): LightRAGの直接的な先行研究。コミュニティ構造ベースのGlobal Searchが特徴だが、差分更新が不可能
  • HippoRAG (2408.08921): 海馬モデルベースのRAG。Personalized PageRankによるマルチホップ推論に強みがあるが、実装複雑度が高い
  • RQ-RAG: クエリ再構成によるRAG改善。LightRAGのHigh-Level検索と相補的なアプローチ

まとめと今後の展望

LightRAGはGraphRAGの概念をより実用的な形に進化させた重要なフレームワークである。デュアルレベル検索により単一の検索モードを超え、インクリメンタル更新により動的なナレッジベースへの対応を実現した。

LlamaIndex v0.14のPropertyGraphIndex(Stage 3)を検討する際、コスト効率と更新頻度を重視する場合はLightRAGが有力な選択肢となる。特にpip install lightrag-hkuで即座に試せるアクセシビリティの高さは、プロトタイピングにおいて大きなアドバンテージである。

今後の課題として、(1) 大規模グラフ(10M+エンティティ)でのスケーラビリティ検証、(2) 日本語テキストでのエンティティ抽出精度向上、(3) LLM-as-Judge以外の客観的評価指標の確立が挙げられる。

参考文献

  • arXiv: https://arxiv.org/abs/2412.15605
  • Code: https://github.com/HKUDS/LightRAG (MIT License)
  • Related Zenn article: https://zenn.dev/0h_n0/articles/62e946539206db
  • GraphRAG (Microsoft): https://arxiv.org/abs/2404.16130
この投稿は CC BY 4.0 でライセンスされています。