Skip to main content

Graph RAG library leveraging post-graph and pgvector on PostgreSQL with OpenAI-compatible LLMs.

Project description

post-graph-rag

PyPI version License: MIT Python 3.9+

Production-Grade, High-Performance Knowledge Graph RAG Engine Native to PostgreSQL.

post-graph-rag seamlessly combines automated LLM-based entity & triple extraction, vector similarity search via pgvector, and graph relationship traversal directly on PostgreSQL using the post-graph graph database library.

It connects to any OpenAI-compatible API (LiteLLM, vLLM, Ollama, DeepSeek, OpenAI) for zero-shot domain-agnostic knowledge extraction, structured document metadata tracking, and context-aware answer synthesis.


🌟 Why post-graph-rag?

Traditional Vector RAG systems suffer from "chunk isolation"—they retrieve isolated text passages based purely on semantic similarity, missing higher-level relationships and cross-document entity connections.

post-graph-rag solves this by building a dual representation inside PostgreSQL:

  1. Unstructured Vector Passages: Full document chunks indexed with pgvector HNSW embeddings.
  2. Knowledge Graph Triples: Extracted Subject-Predicate-Object entities connected by graph edges.
  3. Structured Document Metadata: Rich metadata tracking (source, category, collection, document, page, paragraph).

🏗️ Architecture Workflow

graph TD
    subgraph INDEXING ["1. Knowledge Graph & Vector Indexing"]
        A[Document Text + Metadata] --> B[Embedding Service]
        A --> C[LLM GraphExtractor]
        
        B -->|Vectors| D[post-graph Store]
        C -->|Entities & Triples| D
        
        D --> E[(PostgreSQL + pgvector)]
        E -->|Tables| E1[documents]
        E -->|Tables| E2[entities]
        E -->|Edges| E3[relations]
        E -->|Edges| E4[doc_mentions]
    end

    subgraph RETRIEVAL ["2. Hybrid Retrieval & Synthesis"]
        Q[User Question] --> R[GraphRAG Query Engine]
        R -->|Embedding| S[pgvector Similarity Search]
        E1 & E2 -->|Top-K Passages & Entities| S
        S --> T[1-Hop Graph Relationship Traversal]
        E3 -->|Subject-Predicate-Object| T
        
        S & T --> U[LLM Answer Synthesis]
        U --> V[Final Answer + Citations + Graph Triples]
    end

📦 Installation

Install post-graph-rag via pip or uv:

pip install post-graph-rag

Or using uv:

uv add post-graph-rag

PostgreSQL Requirements

Ensure PostgreSQL is running with the pgvector extension installed:

CREATE EXTENSION IF NOT EXISTS vector;

🚀 Quick Start

1. Basic Indexing & Querying

import asyncio
from post_graph_rag import GraphRAG, RAGConfig, DocumentMetadata

async def main():
    # 1. Configure GraphRAG engine
    config = RAGConfig(
        api_base="http://localhost:4000/v1",       # OpenAI-compatible router endpoint
        api_key="BEVZ-6L81-OZ8Y",                 # Master or OpenAI API Key
        model="DeepSeek-V3.2",                    # LLM model for extraction & synthesis
        embedding_model="text-embedding-3-small", # Embedding model
        embedding_dim=1536,                       # Vector dimensionality
        db_uri="postgresql://user:password@localhost:5432/postgres",
        realm="enterprise_kb"
    )

    rag = GraphRAG(config)
    
    # 2. Connect & initialize PostgreSQL graph schema
    await rag.initialize()

    # 3. Index unstructured documents
    doc_text = (
        "Zeus is the king of the Olympian gods, ruling sky and thunder from Mount Olympus. "
        "He is the son of Cronus and Rhea, and married to Hera. "
        "Zeus defeated the Titans in the Titanomachy to establish his rule."
    )
    
    result = await rag.index_document(doc_text, metadata={"source": "greek_mythology.txt"})
    print(f"Indexed document {result['document_id']}: Extracted {result['entities_extracted']} entities.")

    # 4. Perform Hybrid RAG Query
    response = await rag.query("Who are the parents of Zeus and what did he defeat?")
    
    print("\n=== SYNTHESIZED ANSWER ===")
    print(response["answer"])

    print("\n=== RETRIEVED GRAPH TRIPLES ===")
    for triple in response["retrieved_graph_triples"]:
        print(f"  - {triple}")

    # 5. Clean up
    await rag.close()

if __name__ == "__main__":
    asyncio.run(main())

📋 Document Metadata (DocumentMetadata)

post-graph-rag includes structured document metadata tracking via the DocumentMetadata model:

from post_graph_rag import DocumentMetadata

metadata = DocumentMetadata(
    source="https://mythology.org/zeus.html",  # Document origin (URL, filepath, API)
    category="greek_mythology",               # Document category/topic
    collection="olympian_deities",             # Collection namespace
    document="zeus_overview.pdf",              # Title or filename
    page=1,                                    # 1-based page number
    paragraph=2,                               # 1-based paragraph index
    extra={"author": "Homer", "year": -700}    # Custom metadata key-value pairs
)

await rag.index_document(chunk_text, metadata=metadata)

Design Rationale: Optional vs. Required

  • All metadata fields are optional with default None. This allows seamless indexing of raw strings, short code snippets, webhooks, or unformatted text, while offering rich structural provenance tracking when indexing multi-page PDFs or categorized enterprise documents.

⚙️ Configuration Reference (RAGConfig)

RAGConfig can be configured explicitly or automatically loaded from environment variables:

Option Environment Variable Default Value Description
api_base OPENAI_API_BASE http://localhost:4000/v1 Base URL for OpenAI-compatible LLM endpoint
api_key OPENAI_API_KEY BEVZ-6L81-OZ8Y API Key for authorization
model RAG_MODEL DeepSeek-V3.2 Primary LLM model for triple extraction & synthesis
embedding_model RAG_EMBEDDING_MODEL text-embedding-3-small Model for vector embedding generation
embedding_dim RAG_EMBEDDING_DIM 1536 Dimensionality of embedding vectors
db_uri POSTGRES_URI postgresql://crajah@localhost:5432/postgres PostgreSQL connection DSN
realm RAG_REALM default Multi-tenant graph namespace

📖 API Reference

GraphRAG

The main orchestrator class for indexing and querying.

  • await initialize(): Connects to PostgreSQL and creates necessary graph tables (documents, entities, relations, doc_mentions).
  • await index_document(text: str, metadata: Optional[Union[Dict[str, Any], DocumentMetadata]] = None) -> Dict[str, Any]: Computes document embeddings, extracts entity/triple structures via LLM, and persists graph nodes/edges into PostgreSQL.
  • await query(question: str, top_k: int = 5) -> Dict[str, Any]: Executes hybrid vector similarity search over documents and entities, traverses 1-hop graph relationship edges, and synthesizes a comprehensive answer. Returns dictionary with question, answer, retrieved_documents, retrieved_entities, and retrieved_graph_triples.
  • await close(): Closes database connection pools.

DocumentMetadata

Data container for structured document metadata.

  • source: Optional[str]: Document URL, path, or origin.
  • category: Optional[str]: Document category or domain.
  • collection: Optional[str]: Document collection or folder.
  • document: Optional[str]: File title or filename.
  • page: Optional[int]: 1-based page number.
  • paragraph: Optional[int]: 1-based paragraph index.
  • extra: Dict[str, Any]: Custom user metadata.
  • to_dict() -> Dict[str, Any]: Serializes non-None fields to dictionary representation.
  • from_dict(data: Dict[str, Any]) -> DocumentMetadata: Deserializes dictionary data.

RAGGraphStore

Database layer wrapping post-graph.

  • add_document(text, embedding, metadata): Inserts a document vertex into the documents table.
  • upsert_entity(name, entity_type, description, embedding): Upserts an entity vertex into the entities table.
  • add_relation(from_entity, to_entity, relation_type, description): Connects entity vertices with a directed relation edge.
  • search_similar_entities(query_vec, top_k): Executes pgvector HNSW similarity search over entities.
  • search_similar_documents(query_vec, top_k): Executes pgvector HNSW similarity search over documents.

🗄️ PostgreSQL Database Schema

post-graph-rag automatically provisions and manages the following graph schema in PostgreSQL powered by post-graph:

Table Name Type Key Columns Description
{realm}_documents Vertex Table id, payload, embedding (vector) Stores raw text chunks and DocumentMetadata payloads
{realm}_entities Vertex Table id, payload, embedding (vector) Canonical entity nodes (name, type, description)
{realm}_relations Edge Table from_id, to_id, relation_type, payload Directed edges representing entity-to-entity triples
{realm}_doc_mentions Edge Table from_id, to_id, relation_type Directed edges connecting document chunks to mentioned entities
{table}_audit Audit Table audit_id, action, changed_by, changed_at Automatic shadow audit logging for all graph mutations
{table}_data History Table data_id, payload, timestamp, embedding Append-only historical records for vertices and edges

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

Developed by Chandan Rajah (chandan.rajah@gmail.com).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

post_graph_rag-0.1.3.tar.gz (18.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

post_graph_rag-0.1.3-py3-none-any.whl (17.6 kB view details)

Uploaded Python 3

File details

Details for the file post_graph_rag-0.1.3.tar.gz.

File metadata

  • Download URL: post_graph_rag-0.1.3.tar.gz
  • Upload date:
  • Size: 18.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for post_graph_rag-0.1.3.tar.gz
Algorithm Hash digest
SHA256 d076e507a7f123eb6cfda2d5d4e55b85dba4f64ef12b6b254055e6396ebef8fe
MD5 02215bc90f4f3112f175b1a9dda03def
BLAKE2b-256 e964ed901bb127aac7de4a3add8bee04cf99bf2d9b9e74262819eb91cf8129b4

See more details on using hashes here.

File details

Details for the file post_graph_rag-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: post_graph_rag-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 17.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for post_graph_rag-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 75bc93d8d7d24f6d6c2717b61347e79c5bf0939d0dfdf7204e8217df462c7483
MD5 06c123bd4d947d3e0a76eac56dfcf355
BLAKE2b-256 e2b8f60abb9f9ddb0db96797e0d06c7f9a0d13358d974a845157f269dcfca0c7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page