GraphRAG-SDK
The simplest, most accurate GraphRAG framework built on FalkorDB
Benchmark-leading accuracy ยท Reduce LLM hallucinations ยท FalkorDB-fast ยท Multi-tenant ยท Graph traversal ยท 5-minute setup
Most GraphRAG systems work in demos and break under production constraints. GraphRAG SDK was built from real deployments around a simple idea: the retrieval harness matters more than the model. The result is a modular, benchmark-leading framework with predictable cost and sensible defaults that gets you from raw documents to cited answers in under 5 minutes.
It is designed to reduce LLM hallucinations: answers can be grounded in context retrieved from the knowledge graph, while applications inspect that context, validate generated claims, and gate generation when evidence is insufficient. MENTIONED_IN provenance edges trace entity mentions to their source chunks โ see the Reducing LLM Hallucinations guide and the grounded answers with abstention example.
Why GraphRAG for factual reliability?
Hallucinations in RAG are usually a retrieval failure, not a model failure: the model is asked to answer from context that never contained the answer. A knowledge graph attacks that at the retrieval layer, and keeps the evidence attached to the answer.
- Relationship traversal retrieves the connected evidence vector similarity misses โ multi-hop facts rarely live in one chunk that happens to be similar to the question.
- Retrieved context is traceable to source chunks;
MENTIONED_INedges trace entity mentions, andreturn_context=Truereturns the retrieval trail for application-level validation. - The ontology constrains what can be extracted, so the graph stores typed, checkable facts instead of free-form model output.
- Your application can abstain when evidence is insufficient โ gate generation on retrieval and return an explicit "evidence-insufficient" response (example).
- Benchmark accuracy is the measurable outcome of all of the above โ see the table below.
โ Full guide: Reducing LLM hallucinations ยท API reference: Reliability and Grounding
Benchmarks
| Rank | System | Novel (Multi-Doc) | Medical (Single-Doc) | Overall |
|---|---|---|---|---|
| 1 | FalkorDB GraphRAG SDK โ | 66.09 | 76.87 | 71.48 |
| 2 | G-reasoner | 58.94 | 73.30 | 66.12 |
| 3 | AutoPrunedRetriever | 63.72 | 67.00 | 65.36 |
| 4 | HippoRAG2 | 56.48 | 64.85 | 60.67 |
| 5 | Fast-GraphRAG | 52.02 | 64.12 | 58.07 |
| 6 | RAG (w rerank) (Vector RAG) | 48.35 | 62.43 | 55.39 |
| 7 | LightRAG | 45.09 | 62.59 | 53.84 |
| 8 | HippoRAG | 44.75 | 59.08 | 51.92 |
| 9 | MS-GraphRAG (local) | 50.93 | 45.16 | 48.05 |
How these are computed. Per dataset, ACC is the unweighted mean of the four task-category scores, matching the GraphRAG-Bench leaderboard convention:
Dataset ACC = (Fact Retrieval + Complex Reasoning + Contextual Summarize + Creative Generation) / 4Overall = (Novel ACC + Medical ACC) / 2Overall is our own summary across the two datasets; the leaderboard ranks each dataset separately. Novel has 20 documents and 2,010 questions, Medical 1 corpus and 2,062 questions. FalkorDB scored August 2026 with
gpt-4o-mini(Azure OpenAI) at temperature 0.7 for both graph construction and generation,text-embedding-3-largeat 1024 dimensions, text-to-Cypher retrieval enabled, and the benchmark's owngeneration_eval.pyunmodified as the judge. Competitor numbers are from the published leaderboard, unchanged. See the GraphRAG accuracy benchmark page for the full FalkorDB vs vector RAG comparison, configuration, reproduction instructions and limitations, and the benchmark methodology page for per-category results and the full 15-system comparison.
Vectors match similar chunks. The graph traverses relationships. Every answer cites its source.
Quick Start
1. Install and start FalkorDB
pip install graphrag-sdk[litellm]
docker run -d -p 6379:6379 -p 3000:3000 --name falkordb falkordb/falkordb:latest
export OPENAI_API_KEY="sk-..."
For PDF ingestion, install the
pip install graphrag-sdk[litellm,pdf]. Ingestion sanitizes unsupported control characters in IDs and string properties before graph upserts, which helps avoid FalkorDB Cypher parse errors on noisy PDFs.
2. Ingest a document
import asyncio
from graphrag_sdk import GraphRAG, ConnectionConfig, LiteLLM, LiteLLMEmbedder
async def main():
async with GraphRAG(
connection=ConnectionConfig(host="localhost", graph_name="my_graph"), # graph_name = per-tenant isolation
llm=LiteLLM(model="openai/gpt-5.5"),
embedder=LiteLLMEmbedder(model="openai/text-embedding-3-large", dimensions=256),
) as rag:
# Ingest raw text (pass a file path with the `pdf` extra installed for PDFs)
result = await rag.ingest(
text="Alice Johnson is a software engineer at Acme Corp in London.",
document_id="my_doc",
)
print(f"Nodes: {result.nodes_created}, Edges: {result.relationships_created}")
# Finalize: deduplicate entities, backfill embeddings, create indexes
await rag.finalize()
# Full RAG: retrieve + generate
answer = await rag.completion("Where does Alice work?")
print(answer.answer)
asyncio.run(main())
3. Define a schema (optional)
from graphrag_sdk import GraphSchema, EntityType, RelationType
schema = GraphSchema(
entities=[
EntityType(label="Person", description="A human being"),
EntityType(label="Organization", description="A company or institution"),
EntityType(label="Location", description="A geographic location"),
],
relations=[
RelationType(label="WORKS_AT", description="Is employed by", patterns=[("Person", "Organization")]),
RelationType(label="LOCATED_IN", description="Is situated in", patterns=[("Organization", "Location")]),
],
)
async with GraphRAG(
connection=ConnectionConfig(host="localhost", graph_name="my_graph"),
llm=LiteLLM(model="openai/gpt-5.5"),
embedder=LiteLLMEmbedder(model="openai/text-embedding-3-large", dimensions=256),
schema=schema,
) as rag:
... # ingest / completion as above
โ Full walkthrough: Getting Started
โ Compose your own pipeline: Custom Strategies
Incremental Updates (v1.1.0)
Re-sync individual documents without rebuilding the graph. The canonical CI use case is updating the graph on PR merge โ added, modified, and deleted files in one batch:
async with GraphRAG(connection=ConnectionConfig(...), llm=..., embedder=...) as graph:
result = await graph.apply_changes(
added=["docs/new_feature.md"],
modified=["docs/api.