GraphRAG Tutorial: Microsoft GraphRAG, LightRAG, and Neo4j Implementation Guide for 2026
TL;DR — GraphRAG tutorial: Microsoft GraphRAG, LightRAG, Neo4j. Paperclipped: "GraphRAG: extract entities → build KG → Leiden community detection → hierarchical summaries. Global queries aggregate community summaries, local queries hit entity neighborhoods. DRIFT combines both, 40-60% cost reduction. Dynamic Community Selection saved 79% tokens. Indexing: 500 pages = 45 min, $50-200 GPT-4." Microsoft GraphRAG API: "Four search methods: Global (community summaries), Local (entity context), DRIFT (iterative feedback), Basic (vector similarity)." CodeBrewTools: "LightRAG: 6000x cheaper (100 vs 610K tokens/query), 80ms latency, incremental updates, dual-level retrieval. GraphRAG: best global summarization but brutal indexing cost, no incremental." BestAIWeb: "Five contracts: ingest, extraction, dual storage, retriever, synthesis. neo4j-graphrag 1.15.0+, QdrantNeo4jRetriever, hybrid vector+graph." Learn more with knowledge graph basics, build from documents, RAG pipeline, and model selection.
Paperclipped defines GraphRAG: "Graph RAG is not just RAG with a graph database bolted on. Microsoft Research's GraphRAG paper defines it as a system that extracts entities and relationships from source documents, builds a knowledge graph from those extractions, detects communities of related entities, and generates hierarchical summaries of those communities."
CodeBrewTools contrasts the frameworks: "Microsoft's GraphRAG pioneered hierarchical community summaries for global context but introduced massive computational and financial overhead. HKUDS's LightRAG has emerged as a highly efficient competitor, delivering the same rich relational context at a fraction of the cost."
GraphRAG Architecture
Load documents
Split into chunks"] Extract["2. Extract
LLM extracts entities
and relationships
from each chunk"] Graph["3. Build Graph
Knowledge graph
nodes + edges
with properties"] Community["4. Community Detection
Leiden algorithm
groups related entities
hierarchical levels"] Summarize["5. Summarize
Generate community
summaries at each
hierarchy level"] end subgraph Queries["Query Types"] Global["Global Search
'What are main themes?'
Aggregate community
summaries
Map-Reduce pipeline"] Local["Local Search
'Tell me about X'
Entity neighborhoods
Specific facts
Direct retrieval"] DRIFT["DRIFT Search
'Explain connections'
Combines local + global
Iterative feedback
40-60% cost reduction"] Basic["Basic Search
'Find info about X'
Vector similarity
Over text units
Simplest"] end subgraph Frameworks["Framework Comparison"] MS["Microsoft GraphRAG
14K GitHub stars
Leiden communities
Hierarchical summaries
Best global queries
Brutal indexing cost
No incremental updates
500 pages: 45 min, $50-200"] Light["LightRAG
HKUDS, EMNLP 2025
Dual-level retrieval
KV + graph
~100 tokens/query
vs 610K GraphRAG
6000x cheaper
Incremental updates
80ms latency
Runs on laptops"] Neo4j["Neo4j + Graphiti
Hybrid graph + vector
neo4j-graphrag 1.15.0+
QdrantNeo4jRetriever
Cypher + vector search
Production deployment"] end subgraph Production["Production Pattern"] Hybrid["Hybrid Routing
Simple factual → vector RAG
Complex multi-hop → GraphRAG
Recommended adoption path
Type 1 → Type 2 gradual"] Cost["Cost Monitoring
Indexing: 58% of tokens
Dynamic Community Selection
79% token reduction
LightRAG for budget"] Incremental["Incremental Updates
GraphRAG: full rebuild
LightRAG: seamless union
Neo4j: MERGE upsert
Graphiti: temporal edges"] end Ingest --> Extract Extract --> Graph Graph --> Community Community --> Summarize Summarize --> Global Graph --> Local Graph --> DRIFT Graph --> Basic MS --> Global Light --> Local Neo4j --> Hybrid Global --> Cost Light --> Incremental Neo4j --> Hybrid style Indexing fill:#4169E1,color:#fff style Queries fill:#39FF14,color:#000 style Frameworks fill:#2D1B69,color:#fff style Production fill:#FF6B6B,color:#fff
Framework Comparison
| Feature | Microsoft GraphRAG | LightRAG | Neo4j + Graphiti |
|---|---|---|---|
| Indexing | Leiden communities, hierarchical | KV + graph, dual-level | Graph + vector hybrid |
| Retrieval | Community report map-reduce | Dual-level vector-graph | Cypher + vector search |
| Latency | High (multi-second) | Low (~80-100ms) | Medium |
| Incremental | ❌ Full rebuild | ✅ Seamless union | ✅ MERGE upsert |
| Cost/query | ~610K tokens | ~100 tokens (6000x less) | Variable |
| Global queries | ✅ Best-in-class | ⚠️ Weaker | ✅ Good |
| Local queries | ⚠️ Misses details | ✅ Strong | ✅ Strong |
| Hardware | Heavy (high VRAM) | Light (laptops) | Medium |
| GitHub stars | ~14K | Growing | Neo4j ecosystem |
| Best for | Global summarization | Cost-constrained, incremental | Production hybrid |
Implementation
from dataclasses import dataclass
from typing import Optional
from enum import Enum
class SearchMethod(Enum):
GLOBAL = "global"
LOCAL = "local"
DRIFT = "drift"
BASIC = "basic"
@dataclass
class GraphRAGTutorialGuide:
"""GraphRAG tutorial implementation guide."""
def get_microsoft_graphrag(self) -> str:
"""Microsoft GraphRAG Python API."""
return (
"# === MICROSOFT GRAPHRAG ===\n"
"import asyncio\n"
"import pandas as pd\n"
"from pathlib import Path\n"
"from graphrag.config.models.\n"
" graph_rag_config import\n"
" GraphRagConfig\n"
"from graphrag.api import (\n"
" build_index,\n"
" global_search,\n"
" global_search_streaming,\n"
" local_search,\n"
" local_search_streaming,\n"
" drift_search,\n"
" drift_search_streaming,\n"
" basic_search,\n"
" basic_search_streaming,\n"
")\n"
"\n"
"async def main():\n"
" # 1. SETUP CONFIG\n"
" project_root = Path(\n"
" './my-graphrag-project')\n"
" config = (\n"
" GraphRagConfig.from_file(\n"
" project_root /\n"
" 'settings.yaml'))\n"
" output_dir = (\n"
" project_root / 'output')\n"
" \n"
" # 2. BUILD INDEX\n"
" print('Building index...')\n"
" results = await build_index(\n"
" config=config, verbose=True)\n"
" for result in results:\n"
" if result.error:\n"
" print(f'Error: {result.error}')\n"
" return\n"
" print('Index built!')\n"
" \n"
" # 3. LOAD INDEXED DATA\n"
" entities = pd.read_parquet(\n"
" output_dir / 'entities.parquet')\n"
" communities = pd.read_parquet(\n"
" output_dir / 'communities.parquet')\n"
" reports = pd.read_parquet(\n"
" output_dir /\n"
" 'community_reports.parquet')\n"
" text_units = pd.read_parquet(\n"
" output_dir /\n"
" 'text_units.parquet')\n"
" relationships = pd.read_parquet(\n"
" output_dir /\n"
" 'relationships.parquet')\n"
" \n"
" # 4. GLOBAL SEARCH\n"
" # (themes across corpus)\n"
" response, context = (\n"
" await global_search(\n"
" config=config,\n"
" entities=entities,\n"
" communities=communities,\n"
" community_reports=reports,\n"
" community_level=2,\n"
" dynamic_community_selection=\n"
" False,\n"
" response_type=\n"
" 'Multiple Paragraphs',\n"
" query='What are the main'\n"
" 'themes?'))\n"
" print(response)\n"
" \n"
" # 5. LOCAL SEARCH\n"
" # (entity-specific)\n"
" response, context = (\n"
" await local_search(\n"
" config=config,\n"
" entities=entities,\n"
" communities=communities,\n"
" community_reports=reports,\n"
" text_units=text_units,\n"
" relationships=relationships,\n"
" community_level=2,\n"
" query='Tell me about'\n"
" ' John Smith'))\n"
" print(response)\n"
" \n"
" # 6. DRIFT SEARCH\n"
" # (complex multi-hop)\n"
" response, context = (\n"
" await drift_search(\n"
" config=config,\n"
" entities=entities,\n"
" communities=communities,\n"
" community_reports=reports,\n"
" text_units=text_units,\n"
" relationships=relationships,\n"
" community_level=2,\n"
" query='Explain connections'\n"
" ' between topics'))\n"
" print(response)\n"
"\n"
"asyncio.run(main())"
)
def get_lightrag(self) -> str:
"""LightRAG implementation."""
return (
"# === LIGHTRAG ===\n"
"from lightrag import LightRAG\n"
"from lightrag.llm import ollama_complete\n"
"from lightrag import QueryParam\n"
"\n"
"# 1. INITIALIZE\n"
"rag = LightRAG(\n"
" working_dir='./lightrag_data',\n"
" llm_model_func=ollama_complete,\n"
" llm_model_name='llama3.2',\n"
" embedding_model_func=\n"
" local_embedding_func,\n"
")\n"
"\n"
"# 2. INGEST DOCUMENTS\n"
"rag.insert(\n"
" 'Dr. Smith works at AI Lab.'\n"
" ' He published papers on'\n"
" ' neural networks.')\n"
"rag.insert(\n"
" 'AI Lab partners with'\n"
" ' TechCorp on AI research.')\n"
"\n"
"# 3. INCREMENTAL UPDATE\n"
"# (no full rebuild needed!)\n"
"rag.insert(\n"
" 'TechCorp announced a new'\n"
" ' partnership with DataInc.')\n"
"# Graph updates seamlessly\n"
"# via union operations\n"
"\n"
"# 4. QUERY — DUAL LEVEL\n"
"# mode: local, global, hybrid\n"
"response = rag.query(\n"
" 'Who works at AI Lab?',\n"
" param=QueryParam(\n"
" mode='local'\n"
" ) # specific facts\n"
")\n"
"print(response)\n"
"\n"
"response = rag.query(\n"
" 'What are the main themes?',\n"
" param=QueryParam(\n"
" mode='global'\n"
" ) # high-level themes\n"
")\n"
"print(response)\n"
"\n"
"response = rag.query(\n"
" 'Explain all connections',\n"
" param=QueryParam(\n"
" mode='hybrid'\n"
" ) # both levels\n"
")\n"
"print(response)\n"
"\n"
"# LightRAG: ~100 tokens/query\n"
"# vs GraphRAG ~610K tokens\n"
"# 6000x cheaper, 80ms latency"
)
def get_neo4j_production(self) -> str:
"""Neo4j + GraphRAG production setup."""
return (
"# === NEO4J PRODUCTION ===\n"
"# pip install neo4j-graphrag\n"
"# >=1.15.0 (NOT neo4j-genai)\n"
"\n"
"from neo4j import GraphDatabase\n"
"from neo4j_graphrag.retrievers\n"
" import QdrantNeo4jRetriever\n"
"\n"
"# 1. NEO4J DRIVER\n"
"driver = GraphDatabase.driver(\n"
" 'bolt://localhost:7687',\n"
" auth=('neo4j', 'password'))\n"
"\n"
"# 2. HYBRID RETRIEVER\n"
"# (Neo4j graph + Qdrant vector)\n"
"retriever = QdrantNeo4jRetriever(\n"
" driver=driver,\n"
" client=qdrant_client,\n"
" collection_name='embeddings',\n"
" id_property_external='chunk_id',\n"
" id_property_neo4j='id',\n"
")\n"
"\n"
"# 3. QUERY\n"
"results = retriever.search(\n"
" query_vector=embed(\n"
" 'Who works at AI Lab?'),\n"
" top_k=5,\n"
")\n"
"# Returns: graph nodes\n"
"# + vector matches\n"
"# joined on shared IDs\n"
"\n"
"# 4. CYPHER + VECTOR HYBRID\n"
"with driver.session() as sess:\n"
" result = sess.run(\n"
" '''CALL db.index.\n"
" vector.queryNodes(\n"
" 'chunk_embeddings',\n"
" 5, $emb)\n"
" YIELD node, score\n"
" MATCH (node)-\n"
" [:MENTIONS]->(e)\n"
" MATCH (e)<-[:MENTIONS]-\n"
" (c2:Chunk)\n"
" RETURN c2.text,\n"
" collect(e.name)\n"
" AS entities, score\n"
" LIMIT 10''',\n"
" emb=embed(\n"
" 'Who works at AI Lab?')\n"
" )\n"
" for record in result:\n"
" print(record['c2.text'])\n"
"\n"
"driver.close()"
)
def get_query_comparison(self) -> dict:
"""Query type comparison."""
return {
"global_search": {
"use_case": "What are the main themes in the dataset?",
"mechanism": "Hierarchical community summaries, map-reduce pipeline",
"strength": "Best-in-class for corpus-level questions",
"weakness": "Misses specific details not in community reports",
"cost": "High (multi-stage map-reduce)",
},
"local_search": {
"use_case": "Tell me about John Smith",
"mechanism": "Entity neighborhoods, direct retrieval",
"strength": "Specific entity-focused queries",
"weakness": "Limited to local context, no global themes",
"cost": "Medium",
},
"drift_search": {
"use_case": "Explain connections between these topics",
"mechanism": "Combines local + global, iterative feedback and traversal",
"strength": "Complex multi-hop, 40-60% cost reduction vs separate",
"weakness": "More complex to configure",
"cost": "Medium (40-60% less than separate local+global)",
},
"basic_search": {
"use_case": "Find information about topic X",
"mechanism": "Vector similarity over text units",
"strength": "Simplest, fastest for straightforward queries",
"weakness": "No graph traversal, no multi-hop",
"cost": "Low",
},
}
def get_cost_comparison(self) -> dict:
"""Cost and performance comparison."""
return {
"microsoft_graphrag": {
"indexing_cost": "500 pages: 45 min, $50-200 at GPT-4 pricing",
"tokens_per_query": "~610,000",
"latency": "High (multi-second, map-reduce)",
"incremental": "No — full rebuild required",
"dynamic_community_selection": "79% token reduction (Jan 2025)",
"best_for": "Global summarization, corpus-level themes",
},
"lightrag": {
"indexing_cost": "Much lower, runs on standard laptops",
"tokens_per_query": "~100",
"latency": "~80-100ms",
"incremental": "Yes — seamless union operations",
"cost_reduction": "6000x cheaper than GraphRAG",
"best_for": "Cost-constrained, incremental updates, specific queries",
},
"neo4j_hybrid": {
"indexing_cost": "Variable, depends on document size",
"tokens_per_query": "Variable",
"latency": "Medium",
"incremental": "Yes — MERGE upsert, Graphiti temporal edges",
"best_for": "Production hybrid (vector + graph), multi-hop",
},
}
GraphRAG Tutorial Checklist
- [ ] GraphRAG: not just RAG with a graph database — entity extraction + community detection + hierarchical summaries
- [ ] Microsoft GraphRAG pipeline: ingest → extract entities/relationships → build knowledge graph → Leiden community detection → hierarchical community summaries
- [ ] Leiden algorithm: groups related entities into communities at multiple hierarchy levels
- [ ] Community summaries: pre-generated at each hierarchy level for global queries
- [ ] Dynamic Community Selection (Jan 2025): reduced token usage by 79% while maintaining quality
- [ ] Indexing cost: 500-page corpus = 45 minutes, $50-200 at GPT-4 pricing
- [ ] Entity extraction consumes 58% of total indexing tokens
- [ ] Re-indexing: full pipeline re-run required when documents change (no native incremental)
- [ ] Four search methods: Global, Local, DRIFT, Basic — each with streaming variant
- [ ] Global search: query entire knowledge graph using hierarchical community summaries, map-reduce
- [ ] Global search: best for "What are the main themes in the dataset?"
- [ ] Local search: query specific entities and their local context, entity neighborhoods
- [ ] Local search: best for "Tell me about John Smith"
- [ ] DRIFT search: dynamic reasoning with iterative feedback and traversal, combines local + global
- [ ] DRIFT search: 40-60% cost reduction on complex queries, best for multi-hop
- [ ] Basic search: simple vector similarity over text units, simplest and fastest
- [ ] Microsoft GraphRAG API: GraphRagConfig.from_file, build_index, load parquet, search functions
- [ ] Microsoft GraphRAG: ~14,000 GitHub stars, most researched and benchmarked
- [ ] LightRAG: HKUDS, EMNLP 2025, v1.4.10 Feb 2026
- [ ] LightRAG: dual-level retrieval (low-level specific + high-level thematic)
- [ ] LightRAG: ~100 tokens per query vs ~610,000 for GraphRAG — 6000x cheaper
- [ ] LightRAG: ~80ms response vs 120ms baseline RAG
- [ ] LightRAG: seamless incremental updates via union operations (no full rebuild)
- [ ] LightRAG: runs on standard developer laptops (light hardware)
- [ ] LightRAG: QueryParam(mode='local'|'global'|'hybrid')
- [ ] LightRAG: weaker on global summarization vs GraphRAG (no hierarchical communities)
- [ ] GraphRAG weakness: struggles with specific localized queries — details not in community reports are missed
- [ ] Neo4j production: neo4j-graphrag v1.15.0+ (NOT deprecated neo4j-genai)
- [ ] Neo4j production: QdrantNeo4jRetriever for hybrid graph + vector retrieval with shared IDs
- [ ] Neo4j production: Qdrant for vectors > 4096 dimensions (Neo4j cap)
- [ ] Neo4j production: Cypher + vector hybrid: db.index.vector.queryNodes + graph traversal
- [ ] Five-contract decomposition: ingest, extraction, dual storage, retriever, synthesis
- [ ] Production hybrid: route simple factual → vector RAG, complex multi-hop → GraphRAG
- [ ] Recommended adoption: start with graph-enhanced vector (Type 1), add graph-guided (Type 2) gradually
- [ ] Neo4j Graphiti: natively supports hybrid graph + vector retrieval, temporal edges
- [ ] Cost monitoring: indexing is expensive, track per-document budget
- [ ] LazyGraphRAG: lower-cost alternative (Microsoft Discovery, Azure Local preview)
- [ ] Failure mode: global summarization returns random chunks = skipped community detection
- [ ] Failure mode: indexing one doc costs more than monthly budget = switch to LightRAG
- [ ] Read knowledge graph basics for concepts
- [ ] Read build from documents for extraction
- [ ] Read RAG pipeline for vector RAG
- [ ] Read model selection for LLM choice
- [ ] Test: global search returns corpus-level themes, not random chunks
- [ ] Test: local search returns entity-specific facts
- [ ] Test: DRIFT search handles multi-hop queries with cost reduction
- [ ] Test: LightRAG incremental update works without full rebuild
- [ ] Test: Neo4j hybrid retrieval combines vector + graph results
- [ ] Test: indexing cost within budget for your corpus size
- [ ] Document framework choice, search methods, indexing cost, retrieval strategy, hybrid routing
FAQ
What is GraphRAG and how does Microsoft GraphRAG work?
GraphRAG extracts entities/relationships, builds knowledge graph, detects communities, generates hierarchical summaries for global queries. Paperclipped: "Graph RAG is not just RAG with a graph database bolted on. Microsoft Research GraphRAG: extracts entities and relationships, builds knowledge graph, applies Leiden community detection to group related entities, pre-generates summaries at multiple hierarchy levels. Queries route to appropriate community level: local queries hit entity neighborhoods, global queries aggregate across community summaries. January 2025 update: Dynamic Community Selection reduced token usage by 79%." Microsoft GraphRAG API: "Four search methods: Global search (hierarchical community summaries), Local search (specific entities and context), DRIFT search (dynamic reasoning with iterative feedback and traversal), Basic search (vector similarity over text units)." Microsoft GraphRAG: (1) Extract entities/relationships from documents via LLM. (2) Build knowledge graph. (3) Leiden community detection groups related entities. (4) Generate hierarchical community summaries. (5) Global search: aggregate community summaries. (6) Local search: entity neighborhoods. (7) DRIFT search: combines local + global, 40-60% cost reduction.
How does LightRAG compare to Microsoft GraphRAG?
LightRAG is 6000x cheaper per query with incremental updates; GraphRAG has superior global summarization. Paperclipped: "Microsoft GraphRAG: heavyweight, full entity extraction, community detection, hierarchical summarization. 14,000 GitHub stars. Best-in-class global query performance. Indexing cost brutal: 500-page corpus takes 45 minutes and $50-200 at GPT-4 pricing. Re-indexing means re-running full pipeline. LightRAG: incremental graph updates without full rebuild, simpler dual-level retrieval. ~100 tokens per query vs ~610,000 for GraphRAG on UltraDomain benchmark — about 6,000x lower. 80ms response vs 120ms baseline RAG." CodeBrewTools: "Microsoft GraphRAG: Leiden-clustered hierarchical communities, community report traversal (Map-Reduce), high latency, no incremental updates, heavy hardware. LightRAG: Graph-enhanced KV pairs, dual-level (low+high) vector-graph search, ~80-100ms latency, seamless incremental updates, runs on standard laptops. GraphRAG struggles with specific localized queries — if detail not in community report, global search misses it." Comparison: (1) GraphRAG: best global summarization, brutal indexing cost, no incremental updates. (2) LightRAG: 6000x cheaper, incremental updates, dual-level retrieval, lighter hardware. (3) Choose GraphRAG for global analytical queries; LightRAG for cost-constrained incremental.
How do you use the Microsoft GraphRAG Python API?
Use build_index for indexing, then global_search, local_search, drift_search, or basic_search for queries. Microsoft GraphRAG API: "GraphRagConfig.from_file(settings.yaml), build_index(config=config, verbose=True). Load parquet files: entities, communities, community_reports, text_units, relationships. global_search(config, entities, communities, community_reports, community_level=2, query). local_search(config, entities, communities, community_reports, text_units, relationships, covariates, query). drift_search for combined local+global. basic_search for vector similarity." Query API: "Four search methods: Global (hierarchical community summaries), Local (specific entities), DRIFT (dynamic reasoning with iterative feedback and traversal), Basic (vector similarity over text units). Each has standard and streaming variant." Usage: (1) GraphRagConfig.from_file('settings.yaml'). (2) await build_index(config=config). (3) Load parquet outputs. (4) global_search for themes. (5) local_search for entity queries. (6) drift_search for complex multi-hop. (7) basic_search for simple vector.
What are the GraphRAG query types and when to use each?
Global for corpus-level themes, local for entity-specific, DRIFT for complex multi-hop, basic for simple vector. Paperclipped: "Local queries hit specific entity neighborhoods, global queries aggregate across community summaries. DRIFT search combines local and global for 40-60% cost reduction on complex queries. Dynamic Community Selection reduced token usage by 79%." Microsoft GraphRAG API: "Global search: query entire knowledge graph using hierarchical community summaries. Local search: query specific entities and their local context. DRIFT search: dynamic reasoning with iterative feedback and traversal. Basic search: simple vector similarity search over text units." Query types: (1) Global: 'What are the main themes in the dataset?' — community summaries, map-reduce. (2) Local: 'Tell me about John Smith' — entity neighborhoods, specific facts. (3) DRIFT: 'Explain connections between these topics' — combines local+global, iterative traversal, 40-60% cheaper. (4) Basic: 'Find information about topic X' — vector similarity, simplest.
How do you deploy GraphRAG in production with Neo4j?
Use microsoft/graphrag for indexing, neo4j-graphrag v1.15.0+ for driver, hybrid vector+graph retrieval. BestAIWeb: "Five-contract decomposition: ingest, extraction, dual storage, retriever, synthesis. Use microsoft/graphrag for indexer, neo4j-graphrag 1.15.0+ for driver, Qdrant when embeddings exceed Neo4j 4096-dimension cap. Wire via QdrantNeo4jRetriever with shared IDs. Do NOT use neo4j-genai (deprecated)." Paperclipped: "Hybrid approach routes simple factual queries to vector RAG and complex multi-hop to Graph RAG. Neo4j Graphiti natively supports hybrid graph+vector. Start with graph-enhanced vector search (Type 1) and gradually add graph-guided retrieval (Type 2) — recommended adoption path." Production: (1) microsoft/graphrag for indexing pipeline. (2) neo4j-graphrag >=1.15.0 for driver (not deprecated neo4j-genai). (3) Neo4j for graph storage + Qdrant for vectors > 4096 dims. (4) QdrantNeo4jRetriever with shared IDs. (5) Hybrid: vector RAG for simple, GraphRAG for complex. (6) Cost monitoring for indexing. (7) LightRAG for cost-constrained incremental updates.
Want a self-hosted AI company brain that does all of this out of the box?
Book a demo →