A production-grade Retrieval-Augmented Generation system backed by a property knowledge graph. Combines dense vector search (HNSW), sparse BM25 retrieval, and multi-hop graph traversal with cross-encoder reranking to deliver grounded, cited answers.
Query → Entity Linking → [Vector Search ∥ BM25 ∥ Graph Traversal]
→ RRF Fusion → Cross-encoder Rerank → Context Assembly → LLM
- Hybrid retrieval — Reciprocal Rank Fusion over vector (pgvector HNSW), BM25 (pg full-text), and graph-derived passages
- Knowledge graph — PostgreSQL + Apache AGE for property graph; entities, typed relations, provenance
- Multi-hop traversal — configurable k-hop neighbourhood expansion with edge-weight pruning
- Cross-encoder reranking — BGE-reranker / cross-encoder on top-N fused candidates
- Provenance — every answer chunk traced back to source document + graph triple
- Async throughout — FastAPI + asyncpg, concurrent retrieval branches
- Structured ingestion — semantic chunking, GLiNER NER, relation extraction, dedup pipeline
rag-knowledge-graph/
├── src/
│ ├── ingestion/ # Document → chunks → entities → graph
│ │ ├── chunker.py
│ │ ├── entity_extractor.py
│ │ ├── relation_extractor.py
│ │ └── pipeline.py
│ ├── graph/ # Graph DB interface (AGE/Neo4j abstraction)
│ │ ├── schema.py
│ │ ├── store.py
│ │ └── traversal.py
│ ├── retrieval/ # Query planning + retrieval branches
│ │ ├── query_parser.py
│ │ ├── vector_search.py
│ │ ├── bm25_search.py
│ │ ├── hybrid_fusion.py
│ │ └── reranker.py
│ ├── llm/ # LLM client + prompt assembly
│ │ ├── client.py
│ │ └── prompts.py
│ ├── api/ # FastAPI routes
│ │ ├── routes.py
│ │ └── models.py
│ └── utils/
│ ├── config.py
│ └── logging.py
├── tests/
├── scripts/ # DB init, bulk ingest helpers
├── configs/ # YAML config profiles
└── docker/
# 1. Clone and install
git clone https://github.com/your-org/rag-knowledge-graph
cd rag-knowledge-graph
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
# 2. Start Postgres + AGE
docker compose up -d
# 3. Initialise schema
python scripts/init_db.py
# 4. Ingest documents
python scripts/ingest.py --path ./data/docs/
# 5. Run the API
uvicorn src.api.app:app --reloadAll tunables live in configs/default.yaml. Key knobs:
| Parameter | Default | Description |
|---|---|---|
retrieval.vector_top_k |
20 | HNSW candidates |
retrieval.graph_hops |
3 | Max traversal depth |
retrieval.hybrid_alpha |
0.72 | Vector weight in RRF fusion |
retrieval.context_tokens |
4000 | Token budget for LLM context |
ingestion.chunk_strategy |
semantic | semantic | fixed-512 | sentence |
ingestion.min_confidence |
0.75 | Entity extraction threshold |
POST /query — RAG query with graph retrieval
POST /ingest — Ingest a document
GET /entities — List/search graph entities
GET /graph/subgraph — Fetch subgraph around entity
GET /health — Health + index stats
See src/api/models.py for full request/response schemas.
- Python 3.11+
- PostgreSQL 15+ with pgvector and Apache AGE extensions
- OpenAI API key (or compatible embedding/LLM endpoint)