GraphRAG combines vector similarity with knowledge graph traversal so retrieval finds structurally connected facts, not just text that sounds related. When a ContextGraph is attached to AgentContext, every retrieval call automatically blends semantic search with multi-hop graph expansion — and query_with_reasoning() returns an auditable reasoning path alongside the LLM answer.

What Is GraphRAG?

GraphRAG (Graph-Augmented Retrieval-Augmented Generation) enhances traditional RAG by combining vector similarity search with knowledge graph traversal. Instead of retrieving only semantically similar text, GraphRAG follows relationships between entities to find connected evidence across multiple documents. GraphRAG vs. traditional vector-only RAG: Vector RAG finds documents similar to your query text. GraphRAG finds documents similar to your query AND documents connected to those through entity relationships, even if they don’t mention your query terms directly. The role of graph traversal: Starting from entities found in vector-similar documents, GraphRAG expands outward through relationship edges to discover related facts. This reveals connections that pure text similarity would miss — like finding that a threat actor targets healthcare by following the path: Actor → Tool → Victim Organization → Industry Sector.

Why Use GraphRAG?

Multi-hop discovery. Find facts that are 2-3 relationship steps away from your query. A question about “APT29 healthcare targeting” can surface evidence about specific hospitals by traversing: APT29 → HAMMERTOSS → LifeCare → Healthcare Sector. Connected evidence. Instead of isolated document fragments, retrieve coherent chains of related entities and their relationships. This provides richer context for LLM responses and human analysis. Investigation workflows. Follow evidence trails by expanding from known entities through their connections. Start with a suspicious IP and discover the full infrastructure chain, or trace a drug interaction through metabolic pathways. Richer retrieval context. Graph expansion surfaces relevant context that keyword or semantic search alone would miss, leading to more complete and accurate LLM responses. Explainability. GraphRAG provides audit trails showing exactly which entities and relationships led to each piece of retrieved evidence, making the retrieval process transparent and verifiable.

When To Use / When Not To Use

GraphRAG adds value when:
  • Your domain has rich entity relationships (threat intelligence, clinical data, regulatory documents)
  • Questions require connecting facts across multiple documents
  • Investigation workflows benefit from following entity connections
  • Explainability and audit trails are important
  • You have well-structured knowledge graphs with meaningful relationships
Simple vector search may be sufficient for:
  • Document retrieval based on topic similarity
  • Single-document question answering
  • Exploratory search where you don’t know what you’re looking for
  • Domains with few meaningful entity relationships
Latency and complexity considerations:
  • GraphRAG adds computational overhead from graph traversal
  • Multi-hop expansion increases retrieval time and token usage
  • Graph quality directly impacts retrieval quality
  • Setup requires entity extraction and relationship building
GraphRAG may be overkill for:
  • Simple lookup queries with known answers in specific documents
  • Real-time applications where latency is critical
  • Domains where entity relationships don’t provide additional value

Typical GraphRAG Workflow

Ingest → Build Graph → Retrieve → Expand Context → Reason → Answer
  1. Ingest your documents using AgentContext.store() with entity extraction enabled
  2. Build Graph through Named Entity Recognition (NER) and relationship extraction to populate the ContextGraph
  3. Retrieve semantically similar documents and identify seed entities for graph expansion
  4. Expand Context by following entity relationships within your specified hop limit
  5. Reason (optional) using the expanded context with reasoning engines
  6. Answer by providing the enriched context to an LLM through query_with_reasoning()
Graph Quality Dependency: GraphRAG retrieval quality depends heavily on graph quality, consistent entity linking, and meaningful relationships. Poor entity extraction, duplicate entities, or weak relationships directly impact retrieval effectiveness.
Context Expansion Warning: Larger hop counts exponentially increase the amount of retrieved context, which can significantly increase LLM token usage and processing time. Start with 2-3 hops and monitor context size for your use case.
GraphRAG activates automatically when you pass knowledge_graph= to AgentContext. There is no separate mode to switch on. The hybrid_alpha parameter and proximity_weight argument control how much influence graph structure has relative to vector similarity.

Building the graph and loading your intelligence

Before you can query the graph, you need to build it. The setup is three objects: a vector store for embedding-based retrieval, a ContextGraph for structural traversal, and an AgentContext that wires them together.
Now ingest your documents. store() with extract_entities=True runs the full extraction pipeline internally — Named Entity Recognition (NER), relation extraction, and entity linking — and populates both the vector index and the graph simultaneously:
The graph now contains a connected subgraph linking APT29 to healthcare infrastructure across four document boundaries — something that would be invisible to a pure vector search.

Retrieving the relevant subgraph

With the graph populated, a plain retrieve() call already does more than vector search. When use_graph=True, the retriever seeds the graph traversal from the top-k vector matches and expands outward by following edges, collecting connected facts within max_hops:
Notice the top results: while pure vector search might rank connected facts lower because they lack keyword overlap, GraphRAG boosts their final score because they are structurally adjacent to the seed nodes in the graph. The returned score is a transparent blend of vector relevance and graph connectivity. When you know specifically which entity you want to anchor the traversal to, pass anchor_node:

Getting a grounded LLM answer with a reasoning path

retrieve() gives you the grounded context. query_with_reasoning() goes one step further: it passes that subgraph context to an LLM and returns the answer together with the multi-hop path the retrieval system traced through the graph. That path is your audit trail.
The reasoning_path field is what separates GraphRAG from a black-box LLM call. When an analyst asks “how do you know APT29 targeted healthcare?”, you can show them the exact traversal the system made across your own documents — not a claim the model generated from training data. The full return structure from query_with_reasoning():

Domain examples

Multi-INT intelligence fusion: OSINT threat feeds, NVD CVE data, and HUMINT summaries ingested into a single graph, then queried with multi-hop reasoning to trace C2 infrastructure chains and attribute campaigns to specific actors.In classified environments the graph can be partitioned by data handling caveat — each AgentContext operates over the subset of documents cleared for the querying user. The reasoning_path output doubles as a sanitisable audit trail for downgraded reporting.

Common Pitfalls

Excessive hop counts. Setting max_expansion_hops too high (>4) creates exponentially large context that overwhelms LLMs and increases costs. Start with 2-3 hops and increase only if needed. Poor graph quality. GraphRAG amplifies graph quality issues. Duplicate entities, inconsistent naming, and weak relationships produce poor retrieval results. Clean your graph data before relying on GraphRAG for important queries. Duplicate entities. Having “APT-29”, “APT29”, and “Cozy Bear” as separate nodes breaks relationship traversal. Entity linking during ingestion helps, but manual deduplication may be necessary. Using GraphRAG for simple lookup queries. If you know the answer exists in a specific document and just need to retrieve it, traditional vector search is faster and simpler than GraphRAG. Assuming graph expansion is always beneficial. More context isn’t always better. Sometimes precise, focused retrieval outperforms broad graph expansion. Test both approaches for your specific use cases.

Tuning the vector-graph balance

The hybrid_alpha parameter set in the AgentContext constructor establishes a default blend between vector similarity and graph influence. 0.0 is pure vector retrieval; 1.0 is pure graph traversal. The recommended starting point is 0.5. When targeting a specific anchor_node, you can apply proximity_weight in retrieve() to dynamically blend structural distance from the anchor into the final score:
Each additional hop in max_hops exponentially increases the subgraph size. Practical defaults by domain:
Set globally in the constructor; override per call with the max_hops argument to retrieve().

How GraphRAG works internally

The vector search and graph traversal run independently, then their scores are fused. The graph traversal uses breadth-first expansion from the seed nodes identified by the vector search, so the graph component is always anchored in semantic relevance rather than exploring the entire graph blindly.