Graph RAG
On this page
[!WARNING] External dependency
graph_rag.pyimportsfrom ....chunks import DocumentChunk— four package levels above this archive. This symbol is not defined anywhere in the uploaded files, soGraphRAGcannot be instantiated standalone without the parent "zerda" project supplying achunksmodule.KnowledgeGraph,GraphNode, andGraphEdgehave no such dependency and can be used independently.
Overview
GraphRAG combines a vector database with an in-memory KnowledgeGraph of
entities (GraphNode) and relations (GraphEdge), expanding initial
semantic search hits via BFS graph traversal to pull in connected context
before generation.
ConfigGraphRAG
@dataclass
class ConfigGraphRAG:
l1_size: int = 50
l2_size: int = 50
l3_size: int = 50
cache_ttl: int = 300
k: int = 5
context_depth: int = 2
max_depth: int = 2
embedder_name: str = "paraphrase-multilingual-MiniLM-L12-v2"
embedding_dim: Optional[int] = None
batch_size: int = 32
normalize_embeddings: bool = True
use_gpu: bool = False
faiss_nlist: Optional[int] = None
faiss_nprobe: int = 10
rebuild_threshold: int = 100
enable_hybrid_search: bool = False
hybrid_alpha: float = 0.5
max_cache_embeddings: int = 1000
parallel_processing: bool = True
log_level: str = "INFO"
from_env() (classmethod) builds a config from environment variables
(GRAPHRAG_K, GRAPHRAG_EMBEDDER, GRAPHRAG_BATCH_SIZE, GRAPHRAG_USE_GPU,
GRAPHRAG_LOG_LEVEL). to_dict() serializes the config.
GraphNode
@dataclass
class GraphNode:
id: str
content: str
node_type: str
metadata: Dict[str, Any] = field(default_factory=dict)
embedding: Optional[List[float]] = None
GraphEdge
@dataclass
class GraphEdge:
source: str
target: str
relation: str
weight: float = 1.0
metadata: Dict[str, Any] = field(default_factory=dict)
bidirectional: bool = False
Represents (source) --[relation]--> (target), e.g. (Paris) --[capital_of]--> (France).
KnowledgeGraph
class KnowledgeGraph:
def __init__(self, config: Optional[ConfigGraphRAG] = None): ...
Defaults to ConfigGraphRAG() when no config is supplied — the docstring
notes this specifically so standalone usage (without GraphRAG) still
works.
GraphRAG
Constructor
def __init__(self, vector_db, llm: Optional[Any] = None, config: Optional[ConfigGraphRAG] = None)
vector_db is required; llm is any object exposing .generate(prompt).
Core methods
Async API
aquery, agenerate (delegates to aquery), aretrieve, plus
__aenter__/__aexit__.
[!NOTE] Default language is Arabic
query()'slanguageparameter defaults to"ar"— passlanguage="en"explicitly for English prompts.
Complete example
from zerda.rag.types.graph_rag import GraphRAG, ConfigGraphRAG
config = ConfigGraphRAG(k=8, context_depth=2, max_depth=3)
graph_rag = GraphRAG(vector_db=my_vector_db, llm=my_llm, config=config)
graph_rag.add_document_with_relations(
content="Paris is the capital of France. The Eiffel Tower is in Paris.",
entities=[{"id": "paris", "content": "Paris", "node_type": "city"},
{"id": "france", "content": "France", "node_type": "country"},
{"id": "eiffel_tower", "content": "Eiffel Tower", "node_type": "landmark"}],
relations=[{"source": "paris", "target": "france", "relation": "capital_of"},
{"source": "eiffel_tower", "target": "paris", "relation": "located_in"}],
doc_id="doc_1",
)
answer = graph_rag.query("What landmark is in the French capital?", language="en")
print(answer)
Best practices
- Keep
max_depthsmall (2–3); BFS expansion cost and noise both grow quickly with depth in dense graphs. - Use
KnowledgeGraphdirectly (withoutGraphRAG) if you only need graph storage/traversal utilities and already have your own vector search.
Common mistakes
- Instantiating
GraphRAGwithout a working....chunks.DocumentChunkimport available in the parent project — this will raise anImportErrorat module load time, not at call time. - Forgetting
query()defaults to Arabic output — a common surprise when testing with English-only content.
Related APIs
- Hybrid Search — combine with
enable_hybrid_searchinConfigGraphRAGfor keyword+semantic+graph retrieval.