GraphRAG-SDK

repository·main·Indexed 21 days ago

https://github.com/falkordb/graphrag-sdk

A high-performance, modular framework for building Graph Retrieval-Augmented Generation (GraphRAG) systems built on FalkorDB. It enables the construction of knowledge graphs from raw text and PDFs and allows querying them using natural language. The SDK features swappable strategies for loading, chunking, extraction, resolution, retrieval, and reranking, with built-in support for LLM and embedding providers like LiteLLM and OpenRouter.

Tokens
59.6K
Snippets
130
Records
220
Agent score
66%

What's inside graphrag-sdk

  1. What is GraphRAG SDK?

    main
    GraphRAG SDK is an open-source Python library developed by FalkorDB designed for building retrieval systems augmented by knowledge graphs. It uses FalkorDB (a Redis-based graph database supporting openCypher) as its graph backend to store entities and their relationships, extending the standard RAG pattern with graph-structured indexing.
  2. Configure LLM and Embedder providers

    main

    GraphRAG SDK uses two types of providers: LLM (for text generation and extraction) and Embedder (for vector embeddings).

    Supported Providers

    ProviderLLM ClassEmbedder ClassInstall ExtraModels Supported
    LiteLLMLiteLLMLiteLLMEmbedderpip install graphrag-sdk[litellm]Azure OpenAI, OpenAI, Anthropic, Cohere, 100+
    OpenRouterOpenRouterLLMOpenRouterEmbedderpip install graphrag-sdk[openrouter]All OpenRouter models
    CustomSubclass LLMInterfaceSubclass Embedder--Anything

    Recommendations

    • Production (Azure): Use LiteLLM with the azure/ prefix.
    • Development (OpenAI): Use LiteLLM with OpenAI models.
    • Budget-conscious: Use OpenRouterLLM to compare model prices.
    • Local models: Implement a custom LLMInterface (e.g., wrapping Ollama or vLLM).
    • Local embeddings: Implement a custom Embedder (e.g., wrapping sentence-transformers).
  3. Prune extracted data against a Schema

    main

    You can use a GraphSchema to ensure only relevant information is stored in your knowledge graph. During the ingestion pipeline, the Prune Against Schema step filters the extracted data.

    Behavior:

    • Only entities with labels defined in your schema are kept.
    • Only relationship types defined in your schema are kept.
    • Relationships whose endpoints were pruned are also removed.
    • Exceptions: "Unknown" entities (low-confidence NER) and "RELATES" edges (the unified relationship type) always pass through.
    • Open Schema Mode: If you provide an empty GraphSchema(), this step is skipped and all extracted data is kept.
  4. How GraphStore manages node and relationship writes

    main

    The GraphStore class is the primary write path for all graph data in the SDK. It converts Python objects (GraphNode, GraphRelationship) into Cypher queries.

    Key behaviors:

    • Idempotency: It uses MERGE instead of CREATE, making re-ingestion safe as it updates existing nodes/relationships rather than creating duplicates.
    • Batching: Writes are performed in batches of 500 items using UNWIND for high performance.
    • Label Hints: To optimize performance, relationship MATCH queries use label hints (e.g., PART_OF looks for (Document)-[:PART_OF]->(Chunk)). Unknown edge types default to (__Entity__, __Entity__).
    • Error Handling: If a batch fails, GraphStore falls back to per-item upserts. For nodes, the first failure raises a DatabaseError. For relationships, failures are logged as warnings and processing continues.
    • Data Safety: It includes a None-ID Guard to prevent nodes with empty IDs from being written, and _clean_properties() to sanitize data (e.g., converting dict to JSON strings and dropping None values).
    -- Example of the internal Node MERGE pattern
    UNWIND $batch AS item
    MERGE (n:`Person` {id: item.id})
    SET n += item.properties
    SET n:__Entity__
  5. Understand the GraphRAG-SDK Ingestion Pipeline

    main

    When you call rag.ingest(), the SDK runs a 9-step sequential pipeline to transform raw text into a structured knowledge graph.

    The Pipeline Flow:

    1. Load: Reads text from files (auto-detects .pdf via PdfLoader or others via TextLoader) or direct strings.
    2. Chunk: Splits text into overlapping windows (default: 1000 chars size, 100 chars overlap) to ensure entities aren't split across boundaries.
    3. Build Lexical Graph (Mandatory): Creates the provenance backbone (Document nodes, Chunk nodes, PART_OF edges, and NEXT_CHUNK edges) so every answer is traceable to its source.
    4. Extract Entities & Relationships: Uses an LLM or local models (like GLiNER) to identify entities and their connections. 4b. Quality Filter: Removes malformed data (e.g., nodes with empty IDs).
    5. Prune Against Schema: Filters data to match your defined GraphSchema. If no schema is provided, all data passes through.
    6. Resolve Duplicates: Merges entities referring to the same real-world object (e.g., using ExactMatchResolution or DescriptionMergeResolution).
    7. Write to Graph: Persists data to FalkorDB using batched Cypher queries.
    8. Write Mentions (Parallel): Creates MENTIONED_IN edges between entities and chunks for retrieval.
    9. Index Chunks (Parallel): Embeds chunk text into vectors for similarity search.

    Steps 1-7 are sequential; steps 8-9 run in parallel.

  6. How Reranking and Fact Filtering work

    main

    GraphRAG applies different ranking and filtering logic to passages and facts because they have different semantic characteristics:

    Passage Reranking

    Candidate text chunks are ranked by semantic similarity to the question. To ensure this is near-instant, GraphRAG uses stored embeddings (computed during ingestion) and performs cosine similarity calculations locally rather than making new API calls. Only the top 15 passages are kept.

    Fact Filtering

    Knowledge graph facts (e.g., Alice —[WORKS_AT]→ Acme Corp) are filtered using a vector similarity score threshold. Because short structured strings have higher similarity variance than long prose, a higher threshold (0.25) is used, and the system always retains at least the top 3 facts to prevent noise while maintaining coverage.

  7. How the GraphRAG extraction pipeline works

    main

    The extraction process converts raw text into structured knowledge using a two-step hybrid approach:

    1. Step 1: Entity NER (Named Entity Recognition): A fast, local model (like GLiNER) or an LLM identifies potential entities (name, type, confidence, and character spans).
    2. Step 2: LLM Verify + Relationship Extraction: An LLM receives the pre-extracted entities and the original text. It verifies the entities (fixing names, adding missed ones) and extracts factual relationships between them.

    Optional Step: Coreference Resolution: Before extraction, a resolver can replace pronouns (e.g., "she") with the canonical entity name (e.g., "Alice") to improve extraction accuracy.

    Aggregation: After processing all chunks, the SDK deduplicates entities and relationships across the entire dataset, merging descriptions, source chunk IDs, and character spans.

                Text Chunk
                    |
         ┌──────────┴──────────┐
         v                      v
      (Optional)           Step 1: Entity NER
      Coreference          ┌─────────────────┐
      Resolution           │  GLiNERExtractor │  (default, local)
      (resolve pronouns)   │  LLMExtractor    │  (API-based)
      (your own)           │  Custom          │  (your own)
         |                 └────────┬────────┘
      Resolved Text                 |
                            List of entities
                            (name, type, confidence, spans)
                                    |
                         Step 2: LLM Verify + Relationships
                         ┌──────────────────────────────────┐
                         │ LLM receives:                     │
                         │   - Pre-extracted entities         │
                         │   - Original text                  │
                         │                                    │
                         │ LLM returns:                       │
                         │   - Verified entities (fixed/added) │
                         │   - Relationships with evidence     │
                         └──────────────┬───────────────────┘
                                        |
                              Aggregate across chunks
                              (dedup entities + relations)
                                        |
                              Convert to GraphData
                              (GraphNode + GraphRelationship)
  8. Understand the Retrieval Flow

    main

    The retrieval system follows a multi-path approach to find context for an LLM to answer a question:

    1. Keyword Extraction: The question is processed by an LLM to extract keywords.
    2. Embedding: The question is converted into a vector.
    3. Multi-Path Search:
      • RELATES Edge Vector Search: Searches for related facts and entity entry points.
      • 2-Path Entity Discovery: Combines Cypher substring matches and fulltext search on the entity index.
      • 4-Path Chunk Retrieval: Combines fulltext search, vector search, MENTIONED_IN traversal, and 2-hop entity-to-neighbor-to-chunk traversal.
    4. Context Assembly: Merges top entities, relationships, facts, and passages into a prompt.
    5. LLM Generation: The final RAG prompt is sent to the LLM to produce the answer.
  9. Configure Extraction Strategies

    main

    The GraphExtraction strategy is the primary way to extract entities and relations. It uses an EntityExtractor as its backend.

    Built-in Entity Extractors:

    • GLiNERExtractor(threshold=0.75, model_name="urchade/gliner_medium-v2.1"): A local NER backend (default).
    • LLMExtractor(llm, threshold=0.75): An LLM-based NER backend.

    You can also subclass EntityExtractor to implement custom extraction logic.

    from graphrag_sdk import GraphExtraction, LLMExtractor
    
    extractor = GraphExtraction(llm=my_llm, entity_extractor=LLMExtractor(llm=my_llm))
  10. How GraphExtraction extracts entities and relationships

    main

    The GraphExtraction strategy implements the ExtractionStrategy interface and requires an LLM provider. It operates via a two-step process:

    1. Local Named-Entity Recognition (NER): Powered by GLiNER to identify entities.
    2. Relationship Extraction: Uses an LLM to identify the relationships between the extracted entities.
  11. How VectorStore manages embeddings and search

    main

    The VectorStore class handles vector and fulltext operations, including index creation and retrieval.

    Indexing Types

    • Vector Indexes: Created for nodes (e.g., Chunk) or relationships (e.g., RELATES) using the CREATE VECTOR INDEX syntax.
    • Fulltext Indexes: Uses the RediSearch-based API to index text properties on nodes like Chunk or __Entity__.

    Key Ingestion Tasks

    • Chunk Indexing: Chunks are embedded in batches and written to the database using UNWIND. If batching fails, it falls back to individual processing.
    • Entity Embedding Backfill: During finalize(), the SDK identifies __Entity__ nodes where embedding IS NULL, embeds them, and writes the vectors back to the graph.
    • Relationship Embedding: RELATES edges containing a fact property but no embedding are batch-embedded and updated.

    Search Capabilities

    • Vector Search: Supports searching Chunk nodes, __Entity__ nodes, and RELATES edges. For older FalkorDB versions, relationship search falls back to a Cypher-based cosine distance scan.
    • Fulltext Search: Allows keyword-based searching on indexed text properties.
    • Optimization: The rerank_chunks() function uses stored embeddings to compute similarity locally, avoiding expensive API calls if coverage is $\ge 90%$.
  12. How GraphRAG retrieval works: The Multi-Path approach

    main
    GraphRAG uses a multi-path retrieval strategy to answer questions. Instead of relying on a single search method, it executes several retrieval paths in parallel—including keyword extraction, vector embedding, relationship searches, and text-to-Cypher graph queries—and then combines the findings. This ensures that both semantic meaning (via vectors) and structural relationships (via the graph) are captured to provide a comprehensive context for the LLM.