Quick start:LightRAGを使って5分でGraph RAGを構築する
MicrosoftのGraphRAGを試したことがある方なら、最大のハードルがAPIコストと処理速度にあることをご存じでしょう。100ページのPDFをインデックス化するだけで数十ドルのトークン費用と数時間の処理時間がかかることも珍しくありません。LightRAGは、無駄を削ぎ落としたエンティティ抽出メカニズムと2層構造のリトリーバル(dual-level retrieval)アーキテクチャにより、このボトルネックを解消します。
pip経由でライブラリをインストールします:
pip install lightrag-hku openai
テキストのインデックス化とクエリ検証を行う quickstart.py ファイルを作成します:
import os
from lightrag import LightRAG, QueryParam
from lightrag.llm import gpt_4o_mini_complete, openai_embedding
# ナレッジグラフの保存先ディレクトリを設定
WORKING_DIR = "./lightrag_storage"
os.makedirs(WORKING_DIR, exist_ok=True)
rag = LightRAG(
working_dir=WORKING_DIR,
llm_model_func=gpt_4o_mini_complete,
embedding_func=openai_embedding,
)
# インデックス対象のサンプルデータ
sample_text = """
グエン・ズー(Nguyễn Du)は1765年にタンロン(現ハノイ)で生まれたベトナムの大文豪です。
彼は『トゥイ・キエウの物語(金雲翹伝)』の作者です。
『トゥイ・キエウの物語』はチュノム(字喃)で書かれ、3254行の六八体(ルックバット)詩で構成されています。
"""
# 1. データの挿入(Insert & Graph Indexing)
rag.insert(sample_text)
# 2. ハイブリッドモードによるクエリ実行
query = "グエン・ズーはどのような作品を執筆し、それにはどのような特徴がありますか?"
response = rag.query(query, param=QueryParam(mode="hybrid"))
print(response)
スクリプトを実行します:
export OPENAI_API_KEY="sk-proj-..."
python quickstart.py
実行が完了すると、LightRAGはグエン・ズー、トゥイ・キエウの物語、チュノムといったエンティティおよびそれらの関係性を自動的に抽出します。グラフ全体はローカルの ./lightrag_storage ディレクトリに保存されます。
なぜLightRAGは全体的な要約・俯瞰クエリにおいてNaive RAGよりも優れているのか?
単なるVector Searchが抱える構造的限界
Naive RAGはテキストを約500〜1000トークンの固定長チャンクに分割します。この手法は特定の事実やピンポイントな情報を検索する際には効果的です。しかし、「50個のドキュメント全体に散在しているアーキテクチャ上のリスクをすべてまとめてください」といった包括的な質問に対しては、Vector Searchは機能しなくなります。回答に必要な情報が複数ファイルに分散しており、単一のチャンク内に収まっていないためです。
LightRAGのDual-Level Retrievalメカニズム
LightRAGはナレッジグラフと柔軟な2層リトリーバルを統合しています:
- Low-level retrieval(詳細層): エンティティノードとその近隣エッジを追跡します。具体的な数値、エラーコード、詳細な事実関係の検索に適しています。
- High-level retrieval(グローバル層): グラフ全体の関連トピッククラスターを集約します。全体像の把握やトレンド分析などの要約処理を支援します。
本ライブラリは、用途に応じて使い分け可能な4つのクエリモードを提供しています:
naive:テキストチャンクに基づく標準的なベクトル検索。local:近隣エンティティの探索に特化した検索。global:上位レイヤーの包括的な関係性をスキャンする検索。hybrid:localとglobalを組み合わせ、詳細さと包括性を兼ね備えた回答を生成する検索。
応用編:OllamaによるLocal LLMの実行とストレージのカスタマイズ
社内データの保護やAPIコスト削減を目的に、Ollamaを介してオープンソースモデルを利用することも可能です。
import asyncio
from lightrag import LightRAG, QueryParam
from lightrag.llm import ollama_model_complete, ollama_embedding
from lightrag.utils import EmbeddingFunc
WORKING_DIR = "./local_rag_storage"
async def main():
rag = LightRAG(
working_dir=WORKING_DIR,
llm_model_func=ollama_model_complete,
llm_model_name="qwen2.5:7b",
llm_model_kwargs={"host": "http://localhost:11434"},
embedding_func=EmbeddingFunc(
embedding_dim=768,
max_token_size=8192,
func=lambda texts: ollama_embedding(
texts,
embed_model="nomic-embed-text",
host="http://localhost:11434"
)
)
)
# 長文ドキュメントを非同期でインデックス化
with open("system_spec.txt", "r", encoding="utf-8") as f:
await rag.ainsert(f.read())
# グローバルモードでクエリを実行
res = await rag.aquery(
"ネットワークアーキテクチャの概要と潜在的なボトルネックを要約してください",
param=QueryParam(mode="global")
)
print(res)
if __name__ == "__main__":
asyncio.run(main())
LightRAGは同期インターフェースと非同期インターフェース(ainsert, aquery)の両方を標準でサポートしています。これにより、FastAPIやSanicなどの非同期バックエンドへの統合もスムーズに行えます。
LightRAGを本番環境へ導入する際の実践的ノウハウ
実際の業務検索システムにLightRAGを導入する際は、コストと安定性を最適化するために以下のポイントに注意してください:
1. 適切なエンティティ抽出モデルの選定
インデックスフェーズでは、LLMが各段落を解析してエンティティやリレーションシップを抽出するため、最も多くのトークンを消費します。gpt-4o-mini や gemini-1.5-flash のような、正確なJSON出力が可能な軽量モデルを優先的に選択してください。大型モデルと比較してグラフの品質を維持しながら、APIコストを80〜90%削減できます。
2. インクリメンタルアップデート(差分更新)の活用
LightRAGはグラフのマイクロアップデートに対応しています。新しいドキュメントが追加されるたびに、グラフ全体を最初から再構築する必要はありません:
# 新しいテキストを追加するだけで、LightRAGが既存のグラフへ自動統合
rag.insert("セキュリティポリシー v2.0に関する追加ドキュメント...")
システムは新しいエンティティを既存のネットワークへ自動的にリンクさせます。エンドユーザーの検索処理を中断することなくシームレスに更新可能です。
3. インテントに応じたクエリモードのルーティング
hybrid モードはコンテキスト集約のためにLLMを2回呼び出すため、すべてのリクエストで多用するのは避けるべきです。クエリを実行する前にユーザーの意図(インテント)を分類しましょう:
- 定義、エラーコード、技術仕様の検索:高速レスポンスかつトークンを節約できる
localを選択。 - アーキテクチャの比較、リスク評価、トレンド分析:
globalを選択。 - 曖昧な質問や多角的な分析が必要な場合:
hybridを選択。
4. グラフストレージのバックアップと分離
デフォルトでは、LightRAGはグラフ構造を working_dir 内の graph_chunk_entity_relation.graphml およびKey-Value JSONファイルに保存します。Dockerコンテナで運用する場合は、このディレクトリを外部のPersistent Volumeにマウントしてください。これにより、コンテナの再起動や再デプロイ時にもグラフデータの永続性が担保されます。

