Skip to content

Repository files navigation

GraphRAG — Neo4j & PostgreSQL Knowledge Graph Engine

Natural language conversation and retrieval-augmented generation over a Neo4j knowledge graph and PostgreSQL (pgvector) database — eliminating lossy Text2SQL models.


Table of Contents

  1. Quick Start & Installation
  2. System Architecture & Workflow
  3. UI Pages & Features
  4. Directory Structure

Quick Start & Installation

Prerequisites

  • Docker & Docker Compose
  • Python 3.10+ (if running scripts locally)
  • Ollama running locally or accessible via network (default model: gemma4:31b-cloud)

Running with Docker Compose

To build and start all containers (PostgreSQL + pgvector, Neo4j + APOC, and the Streamlit App):

docker compose up --build -d

Check the status of running services:

docker compose ps

Data Migration

To migrate relational data from your source database into the containerized PostgreSQL database and build the Neo4j graph:

# Run from outside Docker:
python .\scripts\migrate_db.py

# Or execute inside the app container:
docker exec -it kg_app python scripts/migrate_db.py

Accessing the Web UI

Once the containers are running:


System Architecture & Workflow

The platform implements a Hybrid Two-Tier GraphRAG Retrieval Architecture.

High-Level Architecture Diagram

graph TD
    User["User Question"] --> UI["Streamlit Web Interface (ui/app.py)"]

    subgraph Core Engine ["GraphRAG Core Engine"]
        Retriever["GraphRetriever (kg/retrieval/retriever.py)"]
        T2C["Text2Cypher Engine (kg/retrieval/text2cypher.py)"]
        VectorSearch["Semantic Vector Search (kg/retrieval/vector_search.py)"]
        GraphEngine["Neo4j Engine (kg/graph/neo4j_engine.py)"]
        OntologyStore["Ontology Store (kg/ontology/store.py)"]
    end

    subgraph Data Stores ["Storage Layer (Docker Containerized)"]
        Postgres[("PostgreSQL + pgvector (kg_db:5432)")]
        Neo4jDB[("Neo4j Knowledge Graph (bolt:7687)")]
    end

    subgraph Inference ["LLM Provider"]
        Ollama["Ollama API / LLM Server (gemma4:31b-cloud)"]
    end

    UI -->|1. Submit Question| Retriever
    Retriever -->|Check Active Schema| OntologyStore
    Retriever -->|Tier 1: Translate Query| T2C
    T2C -->|Schema Prompt| Ollama
    Ollama -->|JSON Cypher| T2C
    T2C -->|Execute Query| GraphEngine
    GraphEngine <-->|Bolt Protocol| Neo4jDB

    Retriever -->|Tier 2: Fallback Vector Search| VectorSearch
    VectorSearch <-->|Cosine Similarity| Postgres
    VectorSearch -->|Seed Node IDs| GraphEngine
    GraphEngine -->|Expand Subgraph| Neo4jDB

    Retriever -->|Context Text| UI
    UI -->|Stream Context + Question| Ollama
    Ollama -->|Token Stream| UI
Loading

End-to-End Retrieval Sequence

sequenceDiagram
    autonumber
    actor User as User
    participant UI as Streamlit UI
    participant GR as GraphRetriever
    participant T2C as Text2Cypher
    participant Neo4j as Neo4j Engine
    participant Vec as VectorSearch
    participant LLM as Ollama LLM

    User->>UI: Submit Question
    UI->>GR: retrieve(question)
    
    rect rgb(240, 245, 255)
        note over GR,T2C: Tier 1: Text2Cypher Query Translation
        GR->>T2C: text2cypher_query
        T2C->>LLM: Schema Prompt + Rules
        LLM-->>T2C: Return JSON Cypher
        
        alt Query Validated and Executed
            T2C->>Neo4j: run_cypher
            Neo4j-->>T2C: Return Records
            T2C-->>GR: Return cypher_records
        else Query Error
            T2C->>T2C: Retry Loop with Error Trace
        end
    end

    rect rgb(254, 242, 242)
        note over GR,Vec: Tier 2: Hybrid Fallback
        opt If cypher_records is Empty
            GR->>Vec: semantic_search
            Vec->>Vec: Compute Embeddings
            Vec-->>GR: Return Seed Node Hits
            GR->>Neo4j: expand_from_seeds
            Neo4j-->>GR: Return SubgraphResult
        end
    end

    GR-->>UI: Return RetrievalResult
    UI->>UI: Format Context Text
    UI->>LLM: Stream Prompt
    LLM-->>UI: Stream Tokens
    UI-->>User: Render Final Answer
Loading

Security Guardrails & Reflection Loop

flowchart TD
    Start["User Question"] --> BuildPrompt["1. Build Schema-Aware System Prompt"]
    BuildPrompt --> CallLLM["2. Call LLM for JSON Cypher Output"]
    CallLLM --> ParseJSON{"3. Valid JSON Output?"}
    
    ParseJSON -- No --> Fallback["Transition to Tier 2: Vector Search"]
    ParseJSON -- Yes --> RegexCheck{"4. Security Check: Forbidden Keywords?"}
    
    RegexCheck -- Invalid Mutation --> FailSecurity["Reject Cypher (Security Violation)"] --> Fallback
    RegexCheck -- Safe Query --> ExecCypher["5. Execute Cypher against Neo4j Engine"]
    
    ExecCypher --> ExecCheck{"6. Neo4j Execution Result"}
    ExecCheck -- Success with Records --> SuccessReturn["Return Records to Retriever"]
    ExecCheck -- Error / Exception --> CheckAttempts{"7. Attempt Count < Max Retries?"}
    
    CheckAttempts -- Yes --> Retrify["Feedback Loop: Append Error Trace"] --> CallLLM
    CheckAttempts -- No --> Fallback
Loading

UI Pages & Features

  • Chat (app.py): Interactive GraphRAG chat interface with full retrieval transparency (preview generated Cypher, fallback mode, raw context, and RTL support).
  • Ontology (pages/1_ontology.py): Define, edit, and discover graph schemas and relationships from PostgreSQL tables.
  • Graph Management (pages/2_graph_admin.py): Rebuild the Neo4j graph and update pgvector semantic embeddings.

Directory Structure

kg_project/
├── kg/
│   ├── graph/             # Neo4j engine & graph builder (maps PG to Neo4j)
│   ├── ontology/          # Ontology config, schema models & DB auto-discovery
│   ├── retrieval/         # Text2Cypher + Vector Search + Hybrid Graph Retriever
│   ├── embeddings.py      # pgvector embedding creation via sentence-transformers
│   ├── db.py              # PostgreSQL connection pool
│   └── llm.py             # Ollama chat & JSON parsing interface
├── ui/
│   ├── app.py             # Main Streamlit Chat Interface
│   └── pages/             # Ontology Manager & Graph Admin UI
├── scripts/
│   ├── migrate_db.py      # Database migration script from source DB
│   └── mock_data.py       # Mock data generator
├── docker-compose.yml     # PostgreSQL + Neo4j + App containerization
└── requirements.txt       # Python dependencies

About

An intelligent GraphRAG system that transforms any database into a knowledge graph using Neo4j, combines pgvector semantic search with graph reasoning, and enables natural language question answering over structured data.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages