Skip to main content
Intermediate7 min read4 of 5

GraphRAG Explained

Standard RAG retrieves isolated text chunks. GraphRAG traverses relationships — surfacing connected context that no single chunk could contain.

GraphRAG Explained

Standard RAG works like this: embed a query, find the most similar text chunks, hand them to a language model. It is fast, general-purpose, and good at finding relevant passages.

But it has a fundamental limitation: every retrieval is independent. Each chunk is scored in isolation. There is no awareness of how entities relate to each other, no traversal of connections, no way to assemble a picture from distributed evidence.

GraphRAG solves this by replacing chunk retrieval with graph traversal.


The Core Limitation of Chunk-Based RAG

Imagine asking: "Which of our suppliers have had compliance issues and are also connected to the contract currently under review?"

A chunk-based RAG system would:

  1. Embed the query
  2. Find chunks semantically similar to the question
  3. Return the top-K passages

None of those chunks individually answer the question — the answer exists in the relationships between supplier records, compliance history, and contract data. No amount of semantic similarity retrieval can surface what is inherently a graph traversal problem.

flowchart LR
  subgraph CHUNKRAG["Chunk RAG — misses the connection"]
    Q1[Query] --> EMB[Embed]
    EMB --> NN[Find similar chunks]
    NN --> C1["Chunk: supplier profile"]
    NN --> C2["Chunk: compliance report"]
    NN --> C3["Chunk: contract details"]
    C1 -.->|no link| C2
    C2 -.->|no link| C3
  end
flowchart LR
  subgraph GRAPHRAG["GraphRAG — traverses the connection"]
    Q2[Query] --> ENT["Extract entities: supplier, contract, compliance"]
    ENT --> TR["Traverse graph from contract node"]
    TR --> SUP["Supplier entity: linked to contract"]
    SUP --> COMP["Compliance history: 2 flags"]
    TR --> POL["Policy: regulated supplier — legal review required"]
    SUP & COMP & POL --> CTX["Assembled context: complete picture"]
    CTX --> LLM["LLM generates grounded answer"]
  end

How GraphRAG Works

GraphRAG has three distinct steps that differ from standard RAG:

Step 1: Entity extraction and anchoring

Instead of embedding the raw query text, GraphRAG extracts the entities in the query and anchors them to nodes in the knowledge graph.

flowchart TD
  Q["Query: 'What compliance issues exist for suppliers on contract C-4421?'"] --> EE["Entity extraction"]
  EE --> E1["contract: C-4421"]
  EE --> E2["entity type: supplier"]
  EE --> E3["topic: compliance issues"]
  E1 --> KG[(Knowledge Graph: locate C-4421 node)]

Step 2: Graph traversal

Starting from the anchor node, the system traverses outbound relationships to collect connected entities and facts relevant to the query.

flowchart TD
  CONTRACT["Contract C-4421"] --> SUP1["Supplier: Acme Corp\n[industry: regulated]"]
  CONTRACT --> SUP2["Supplier: Beta Ltd\n[industry: tech]"]
  SUP1 --> COMP1["Compliance event: 2024-11\n[severity: high]"]
  SUP1 --> COMP2["Compliance event: 2025-03\n[severity: medium]"]
  SUP1 --> POL["Policy: regulated-vendor-review\n[status: not triggered]"]
  style COMP1 fill:#f43f5e,color:#fff
  style POL fill:#f59e0b,color:#000

The traversal is guided by the query intent — a compliance question triggers traversal through compliance-related relationship types; a financial question traverses financial relationship types.

Step 3: Context assembly and generation

The traversed subgraph is assembled into a structured context package and passed to the language model.

flowchart TD
  TRAV["Traversed subgraph"] --> PACK["Structured context:\n- Contract C-4421 has 2 suppliers\n- Acme Corp: regulated industry, 2 compliance flags (high+medium)\n- Policy: regulated-vendor-review not yet triggered\n- Beta Ltd: no compliance issues"]
  PACK --> LLM["LLM prompt: CONTEXT + QUESTION"]
  LLM --> ANS["'Acme Corp (regulated supplier on this contract) has 2 compliance flags — a high-severity event in Nov 2024 and medium in Mar 2025. The required regulated-vendor-review policy has not been triggered. Beta Ltd has no compliance issues.'"]

GraphRAG vs Standard RAG: When to Use Each

ScenarioStandard RAGGraphRAG
Retrieving a policy document✅ GoodUnnecessary overhead
Finding an answer in a single passage✅ GoodUnnecessary overhead
Multi-hop reasoning across entities❌ Misses connections✅ Native to graph traversal
Assembling a 360-view of a customer❌ Chunks don't link✅ Traverse from customer node
Checking business rule compliance❌ Rules not in text✅ Rules as explicit graph edges
Temporal reasoning across events❌ Chunks lack timeline✅ Event chains in graph
Questions that require joining two facts❌ Each chunk is separate✅ Traversal bridges them

[Key Insight] Standard RAG and GraphRAG are not competing approaches — they solve different retrieval problems. The strongest production AI systems use both: standard RAG for document passage retrieval, GraphRAG for entity-centric questions that require traversing relationships.


Community Detection: Summarising at Scale

One of the most powerful GraphRAG techniques is community detection — using graph algorithms to identify clusters of tightly connected entities, then generating summaries for each community rather than for individual chunks.

flowchart TD
  KG[(Full Knowledge Graph)] --> COMM["Community detection algorithm\n(Leiden / Louvain)"]
  COMM --> C1["Community 1: Procurement cluster\n(8 suppliers, 3 policies, 12 contracts)"]
  COMM --> C2["Community 2: Customer cluster\n(customer segments, products, support history)"]
  COMM --> C3["Community 3: Compliance cluster\n(regulations, audit events, obligations)"]
  C1 --> SUM1["LLM: generate community summary"]
  C2 --> SUM2["LLM: generate community summary"]
  C3 --> SUM3["LLM: generate community summary"]
  SUM1 & SUM2 & SUM3 --> IDX["Community summary index"]
  Q[Query] --> IDX
  IDX --> RELEVANT["Select relevant community → traverse from there"]

Community summaries act as a high-level index. A broad query first identifies which community is relevant, then traverses within it — much more efficient than scanning the full graph.


The Quality Hierarchy

The quality of GraphRAG output is directly dependent on the quality of the underlying knowledge graph:

flowchart TD
  style L1 fill:#f43f5e,color:#fff
  style L2 fill:#f59e0b,color:#000
  style L3 fill:#10b981,color:#fff

  L1["❌ Poor KG: missing entities, wrong relationships, stale data\n→ GraphRAG surfaces wrong or incomplete context"]
  L2["⚠ Partial KG: good coverage in one domain, gaps in others\n→ GraphRAG works for covered queries, fails silently for gaps"]
  L3["✅ Rich KG: complete entities, typed relationships, current data\n→ GraphRAG delivers grounded, explainable, trustworthy answers"]

This is why knowledge graph quality is not a technical detail — it is the foundational investment that determines what GraphRAG can do.


GraphRAG in Practice

A minimal GraphRAG architecture for a business domain:

flowchart LR
  DATA["Source systems\n(CRM, ERP, docs, events)"] --> ETL["Extraction + entity resolution"]
  ETL --> KG[(Knowledge Graph)]
  KG --> GR["GraphRAG retrieval layer"]
  Q[User query] --> GR
  GR --> LLM["Language model"]
  LLM --> ANS["Grounded answer with source attribution"]
  ANS --> AUDIT[(Audit log: which nodes traversed)]

What makes this production-ready:

  • Entity resolution: same entity across systems maps to one node
  • Relationship typing: edges carry meaning, not just connections
  • Freshness: graph updated as source systems change
  • Audit trail: every answer traceable to the graph nodes that produced it

Next in this series: Ontology and Schema Design — how to design the schema that makes a knowledge graph useful rather than just large.