GraphRAG: Knowledge Graphs, Communities and Global Search

An engineering guide to GraphRAG: how an LLM turns documents into a knowledge graph and community summaries, how the four query modes use them, what indexing costs, and when a graph beats plain vector retrieval.

11 min read Updated GraphRAG knowledge graphs RAG community detection retrieval

Vector retrieval finds passages that resemble a question. It struggles when the answer is not in any one passage: when the question is about the whole corpus, or when it has to follow connections between documents. GraphRAG adds a structured layer between the documents and the model: an LLM-built knowledge graph, clustered into communities with pre-written summaries. This article explains how that layer is built, how each query mode uses it, what it costs, and when it is worth it.

Where vector RAG breaks

The retrieval pipeline from Embeddings, Vector Databases and RAG works well when a question has a local answer: a few passages somewhere in the corpus contain it, and they look like the question. Hybrid search and a reranker make that dependable. Three kinds of question break the assumption.

  • Global questions. "What are the main themes in these documents?" There is no passage to find: the answer summarises the whole corpus, a task the GraphRAG paper calls query-focused summarisation. Top-k retrieval returns a few chunks that happen to sit near the question and misses the rest.
  • Multi-hop questions. The answer chains facts from different documents: who escalated whom, which contract covers that carrier, what it says about penalties. Each hop may share few words with the question.
  • Scattered facts. An entity is mentioned briefly in hundreds of documents, so no single chunk describes it well.

A running example: a freight forwarder has a few thousand incident reports, carrier emails and weekly operations notes from a dozen hubs. Two questions:

  • Global: "What are the recurring causes of delivery delays across regions?"
  • Local: "Which carriers did the Rotterdam hub escalate, and why?"

Vector RAG handles the second question reasonably and the first poorly. GraphRAG, published by Microsoft Research in 2024, was designed for the first kind and also helps with the second. It builds a knowledge graph of entities and relationships from the text, groups densely connected entities into communities, and has an LLM summarise each community ahead of time. At query time, those summaries stand in for the corpus.

The indexing pipeline

All the expensive work in GraphRAG happens at indexing time. The open-source graphrag package, at version 3.3 as of November 2026, runs these steps:

  1. Text units. Documents are split into chunks, 1,200 tokens by default. Larger chunks mean fewer LLM calls but less faithful extraction and coarser citations.
  2. Graph extraction. An LLM reads every text unit and lists its entities (name, type, short description) and the relationships between them (description, strength score). The default entity types are organisation, person, geo and event.
  3. Description summarisation. An entity seen in many text units gets many descriptions; an LLM merges them into one per entity and per relationship.
  4. Claims (optional). An extra pass records claims, such as alleged fraud with dates and a status. It is off by default.
  5. Communities. The graph is clustered with the hierarchical Leiden algorithm, described in the next section.
  6. Community reports. An LLM writes a report for every community at every level of the hierarchy.
  7. Embeddings. Text units, entity descriptions and report contents are embedded for similarity lookup at query time.
The GraphRAG indexing pipeline Documents are chunked into text units. An LLM extracts entities and relationships from each text unit, and another LLM pass merges their descriptions. The resulting graph is clustered into hierarchical Leiden communities, an LLM writes a report for each community, and text units, entity descriptions and reports are embedded. Each stage writes a table: documents, text_units, entities, relationships, communities and community_reports, plus an optional graph.graphml snapshot. Documents txt, csv, json Text units 1,200-token chunks Extract graph LLM per text unit Summarise merge descriptions documents text_units entities relationships Graph weighted edges Communities hierarchical Leiden Community reports LLM per community Embeddings for vector lookup graph.graphml communities community_reports vector store LLM calls monospace names: tables written to output/ as parquet
Indexing runs once per corpus and is dominated by LLM calls in the highlighted stages. Every stage writes a table, so the graph can be inspected, reused and loaded into other tools. The GraphML snapshot is optional.

Here is what extraction produces from one text unit, simplified. Later stages merge these records across all text units.

Text unit 1842:
  "On 14 March the Rotterdam hub escalated NordFreight after three missed
   pickups during the port strike. Ops manager Anna Visser moved the
   Tilburg lanes to BlueLine Haulage until further notice."

Entities
  ROTTERDAM HUB      organization  Distribution hub; escalated NordFreight in March
  NORDFREIGHT        organization  Road carrier; missed three pickups during the strike
  PORT STRIKE        event         March strike at the port that disrupted pickups
  ANNA VISSER        person        Operations manager at the Rotterdam hub
  BLUELINE HAULAGE   organization  Carrier that took over the Tilburg lanes

Relationships                                                            strength
  ROTTERDAM HUB → NORDFREIGHT       escalated after three missed pickups        8
  NORDFREIGHT   → PORT STRIKE       pickups missed during the strike            6
  ANNA VISSER   → ROTTERDAM HUB     operations manager at the hub               9
  ANNA VISSER   → BLUELINE HAULAGE  moved the Tilburg lanes to BlueLine         7

Every entity and relationship keeps the IDs of the text units it came from. That provenance lets answers cite source passages, and it is the first thing to check when the graph contains something surprising.

Communities and community reports

A graph extracted from a few thousand documents can have tens of thousands of nodes. Community detection finds groups of nodes densely linked to each other and sparsely linked to the rest. GraphRAG uses the Leiden algorithm, an improvement on the older Louvain method that guarantees every community is internally connected. It runs hierarchically, splitting communities again and again until they fall below a size threshold.

The result is a tree. Level 0 holds the broadest communities; each higher level holds smaller, more specific ones. In the freight corpus, a level-0 community might gather everything about sea-freight disruption, with level-1 children for the Rotterdam port strike and for customs holds in Antwerp.

Hierarchical communities and their reports On the left, an entity graph is split into two level-0 communities, A and B. Community A contains level-1 sub-communities A1, port strike, and A2, customs holds; community B contains B1, carrier delays, and B2, winter weather. Nodes are densely linked inside sub-communities, with a few dashed links between communities. On the right, each community at each level has its own report: report A for sea-freight disruption with child reports A1 and A2, and report B for road-carrier delays with child reports B1 and B2. Entity graph, clustered by Leiden Community reports Level 0 · community A A1 · port strike A2 · customs holds Level 0 · community B B1 · carrier delays B2 · winter weather A · level 0 sea-freight disruption A1 · Rotterdam strike A2 · customs holds B · level 0 road-carrier delays B1 · carrier delays B2 · winter weather dashed edges link communities; Leiden keeps densely linked nodes together
Leiden splits the graph into broad communities and then splits each of those again. An LLM writes a report for every community at every level, so the corpus is summarised at several resolutions before any question arrives. The labels are illustrative.

For each community, GraphRAG gathers the descriptions of its entities and relationships (and claims, if extracted) and asks an LLM for a report. A report has a title, a summary, a list of five to ten findings with explanations, and a rank that estimates the community's importance. The community_reports table stores each one with its level, parent and children.

Pre-summarising is what makes global questions answerable. "What are the recurring causes of delays?" matches no passage, but it can be answered by reading every community report at one level, because together they cover the whole graph in a form that fits into a series of LLM calls.

Four ways to query the graph

The query engine offers four methods. They differ in where they start and how much of the index they read.

Global search answers questions about the dataset as a whole. It takes all community reports from one level of the hierarchy (level 2 by default in the CLI), shuffles them into batches that fit the context window, and runs a map-reduce. In the map step, each batch produces a partial answer as a list of points, each with an importance rating. In the reduce step, the highest-rated points across all batches are collected and the LLM writes the final answer from them.

Global search as map-reduce over community reports The question is sent with each batch of community reports to a map step, where an LLM returns key points with importance ratings. The reduce step keeps the highest-rated points from all batches and an LLM writes the final answer from them. Question Reports batch 1 Reports batch 2 Reports batch N Map: LLM rated key points Map: LLM rated key points Map: LLM rated key points Reduce top points Answer keep highest-rated reports from one hierarchy level, shuffled and packed into context-sized batches
Global search reads every report at the chosen level, so its cost grows with the number of communities. Higher levels mean more, smaller reports: more detailed answers at a higher cost.

Global search is the most expensive mode. The CLI's dynamic community selection reduces the cost: it starts at the root, has an LLM rate each report's relevance, and descends only into relevant branches.

Local search answers questions about specific entities. It embeds the question, finds entities with similar descriptions, and uses them as entry points into the graph. From there it collects connected entities, relationships, claims, the reports of their communities, and the text units that mention them, ranks the candidates to fit one context window, and answers in a single call. For the Rotterdam question, the entry point is ROTTERDAM HUB, and its escalation relationships lead straight to the carriers and the passages describing each case.

DRIFT (Dynamic Reasoning and Inference with Flexible Traversal) combines the two. It compares the question with the most relevant community reports, drafts a broad initial answer and generates follow-up questions, each answered with local search. The resulting ranked hierarchy of questions and answers is summarised into the final response.

Basic search is plain vector RAG over the text units. It provides a baseline on the same index and remains the right tool for single-fact lookups.

ModeBest forContext it buildsRelative costExample question
GlobalThemes and patterns across the corpusAll community reports at one level, map-reducedHigh: one call per batch plus a reduce callWhat are the recurring causes of delivery delays across regions?
LocalSpecific entities and their neighboursMatched entities, neighbours, relationships, community reports and source text unitsLow: one call after retrievalWhich carriers did the Rotterdam hub escalate, and why?
DRIFTSpecific questions that need wider contextA primer from community reports, then several rounds of local searchMedium to high: several callsHow did the March port strike affect carriers outside Rotterdam?
BasicSingle facts stated in one passageTop-k text units by vector similarityLowWhat is the claims deadline in the NordFreight contract?

Hands-on with the graphrag package

The package documentation opens with a warning that GraphRAG can consume a lot of LLM resources. Take it seriously: index a small sample with an inexpensive model first, read the extracted graph, and only then index the full corpus. The CLI covers the whole workflow:

# Python 3.10–3.12, inside a virtual environment
mkdir freight-graph && cd freight-graph
python -m venv .venv && source .venv/bin/activate
python -m pip install graphrag

graphrag init       # asks for chat and embedding models; writes settings.yaml, .env, input/
# put your key in .env (GRAPHRAG_API_KEY=...), then copy a SMALL sample
cp ~/exports/incidents/2026-03/*.txt input/

# Optional: generate domain-specific extraction prompts (saved to prompts/)
graphrag prompt-tune --domain "logistics incident reports"

graphrag index      # builds the graph; parquet tables land in output/

graphrag query "What are the recurring causes of delivery delays across regions?"
graphrag query "Which carriers did the Rotterdam hub escalate, and why?" --method local
graphrag query "How did the March port strike affect carriers outside Rotterdam?" --method drift

Without --method, graphrag query runs global search. Because the index is a set of ordinary tables, you can inspect it with pandas and rebuild the graph in networkx for your own analysis:

import pandas as pd
import networkx as nx

out = "output"
entities = pd.read_parquet(f"{out}/entities.parquet")
relationships = pd.read_parquet(f"{out}/relationships.parquet")
reports = pd.read_parquet(f"{out}/community_reports.parquet")

# The most connected entities: hubs, big carriers, recurring events
print(entities.nlargest(10, "degree")[["title", "type", "degree"]])

# Level 0 holds the broadest communities; rank estimates importance
broad = reports[reports["level"] == 0].sort_values("rank", ascending=False)
print(broad[["title", "rank"]].head(10))

# Rebuild the graph for paths, centrality or export to a graph database
G = nx.Graph()
for r in relationships.itertuples():
    G.add_edge(r.source, r.target, weight=r.weight, description=r.description)

if nx.has_path(G, "ROTTERDAM HUB", "BLUELINE HAULAGE"):
    print(nx.shortest_path(G, "ROTTERDAM HUB", "BLUELINE HAULAGE"))

Reading the top entities and level-0 report titles is the fastest quality check. If the top entities are generic words, or the reports describe themes nobody in the business would recognise, fix extraction before indexing more data. The optional GraphML snapshot, enabled in settings.yaml, opens in tools such as Gephi.

Cost, quality and operations

Where the money goes

Standard indexing makes at least one LLM call per text unit for extraction, plus optional "gleaning" passes that ask the model what it missed, then summarisation calls for repeated entities and relationships, and one call per community report. The documentation estimates graph extraction at roughly 75% of indexing cost. Before a full run, multiply the number of text units by the tokens per call and price it.

  • FastGraphRAG (graphrag index --method fast) replaces LLM extraction with NLP: noun phrases become entities and co-occurrence in a text unit becomes a relationship, with small chunks of 50–100 tokens recommended. Only the community reports use an LLM. The graph is noisier and has no descriptions, but the docs recommend it when the main goal is global summary questions.
  • LazyGraphRAG, announced by Microsoft Research in November 2024, also builds a lightweight graph without LLM extraction and defers LLM work to query time. The announcement reported indexing costs identical to vector RAG and 0.1% of full GraphRAG, and answer quality comparable to GraphRAG global search on global queries at more than 700 times lower query cost. Check the current documentation for its availability in the release you use.

Graph quality

The graph is only as good as extraction. The default entity types rarely match a business domain; prompt tuning discovers types from your data, and you can edit the prompts to name them yourself: carrier, hub, lane, incident. Duplicate entities are the most common defect. Mentions are merged by name, so "NordFreight", "Nord Freight BV" and "NF" become three nodes with fragmented descriptions. Normalise names before indexing, or merge nodes afterwards with an alias table. An LLM can also hallucinate relationships; the text unit IDs on every edge let you audit them.

Freshness, evaluation and access control

  • Updates. graphrag update adds new documents to an existing index instead of rebuilding it. Community structure drifts as data accumulates, so schedule periodic full rebuilds for a fast-changing corpus.
  • Evaluation. Build a golden set with both global and local questions. Local questions have reference answers and are scored as in ordinary RAG evals. Global questions usually do not, so compare answers pairwise with an LLM judge on criteria such as comprehensiveness and diversity, as the GraphRAG paper did, with basic search as the baseline.
  • Citations. Answers can reference report, entity and relationship IDs, each leading back to text units. Render them as links to the source passages.
  • Permissions. A community report blends facts from many documents, so it can expose content a given user may not read, and query-time filters cannot remove one sentence from a summary. Build separate indexes per access domain, or restrict global search to data everyone may see.

Alternatives and how to choose

Microsoft's GraphRAG is the best-known design, not the only one.

  • LightRAG, from the University of Hong Kong, extracts entities and relationships similarly but skips community reports. It retrieves at two levels, specific entities and broader themes, using keywords extracted from the query, and merges new documents into the graph incrementally. It is cheaper to build and update, and is actively maintained as of November 2026.
  • HippoRAG ranks passages with Personalised PageRank seeded from the entities in the question, following multi-hop connections in a single retrieval step. HippoRAG 2 refines the approach.
  • A property graph database such as Neo4j suits structured data and questions that need exact traversals or aggregations ("how many escalations per carrier in Q1?"). An LLM translates the question into a Cypher query and the database answers precisely.
  • KAG starts from a schema rather than open extraction, and plans questions as logical-form steps over the graph and the text. It is covered in KAG: Knowledge Augmented Generation.

Comparative studies, such as Han et al.'s 2025 systematic evaluation, agree with practical experience: graph retrieval helps on multi-hop and corpus-wide questions, while vector retrieval stays strong, and cheaper, on single-detail questions. The two are complementary.

Question or corpusStart with
Single facts stated in one passageVector or hybrid RAG with reranking
Themes and patterns across the whole corpusGraphRAG global search; FastGraphRAG or LazyGraphRAG to cut cost
Multi-hop questions about named entitiesGraphRAG local or DRIFT search, LightRAG or HippoRAG
Exact counts, filters and aggregations over well-defined entitiesA property graph or SQL with text-to-query generation
Professional domains with strict schemas, rules and numbersKAG
Fast-changing corpus on a tight budgetVector RAG first; LightRAG if you need a graph

In one system, a cheap classification step can route each question: corpus-wide questions to global search, questions naming entities to local or DRIFT search, and everything else to basic retrieval. The same idea can run inside an agent, with each mode exposed as a separate search tool, as described in AI agents, tool calling and MCP.

Key takeaways

  • Vector RAG answers questions whose answer sits in a few passages. GraphRAG targets corpus-wide and multi-hop questions that no single passage answers.
  • Indexing extracts entities and relationships with an LLM, clusters them into hierarchical Leiden communities and pre-writes a report for every community.
  • Global search map-reduces community reports; local search expands from matched entities; DRIFT combines the two; basic search is the vector baseline.
  • Indexing cost is dominated by extraction. Sample first, price the run, and consider FastGraphRAG or LazyGraphRAG for summary-oriented workloads.
  • Tune prompts and entity types for your domain, deduplicate entity names, and keep provenance for citations and audits.
  • Community reports mix documents, so plan access control at index time. Route questions between graph and vector retrieval rather than choosing one.

Sources and further reading

  1. Edge et al., From Local to Global: A Graph RAG Approach to Query-Focused Summarization (2024).
  2. Microsoft, GraphRAG documentation and microsoft/graphrag on GitHub.
  3. Microsoft Research, Introducing DRIFT Search: Combining global and local search methods to improve quality and efficiency (2024).
  4. Microsoft Research, LazyGraphRAG: Setting a new standard for quality and cost (2024).
  5. Traag, Waltman, van Eck, From Louvain to Leiden: guaranteeing well-connected communities (2019).
  6. Guo et al., LightRAG: Simple and Fast Retrieval-Augmented Generation (2024).
  7. Gutiérrez et al., HippoRAG: Neurobiologically Inspired Long-Term Memory for Large Language Models (2024).
  8. Han et al., RAG vs. GraphRAG: A Systematic Evaluation and Key Insights (2025).