A production-grade, high-performance Retrieval-Augmented Generation (RAG) pipeline designed for grounded, verifiable question-answering over private documents. Connect your files (PDF, DOCX, TXT) and receive context-restricted answers with precise citations, powered by dense-lexical hybrid search, cross-encoder re-ranking, and low-latency token streaming.
Most RAG repositories demonstrate a basic split-embed-query loop. This system implements production-tier methodologies to handle real-world challenges like referential ambiguity, embedding dilution, and context attention loss:
| Dimension | Basic RAG | This Production-Grade Pipeline |
|---|---|---|
| Chunking | Fixed-size splits only | Multi-Strategy: Recursive, Semantic (z-score spikes), or Hierarchical (Parent-Child) |
| Retrieval | Single vector search | Hybrid Search: Dense Semantic (MiniLM) + Lexical (Custom BM25) fused via RRF |
| Re-ranking | First-pass results |
2-Stage Retrieval: Stage 1 candidate pool (15) |
| LLM Focus | Raw ordered contexts | Lost-in-the-Middle (LitM): Alternates chunk relevance to prompt borders |
| Recall Boost | Query vector similarity | HyDE: Generates hypothetical answer paragraph to search, bridging semantic gaps |
| Response Latency | Blocking full JSON | Real-Time Token Streaming: Server-Sent Events (SSE) yielding tokens at ~750 tok/s |
| Conversations | Single-turn Q&A | Multi-Turn Chat: Self-contained query condensation using conversation history |
| Verification | Unverifiable answers | Metadata Filters & Grounded Citations: Color-coded relevance scores + chunk source previews |
| UI Responsiveness | Sluggish blocking calls | Lag-Free UI: Caches stats, metadata, and backend health checks in Streamlit session state |
ββββββββββββββββββββββββββββββββ
β Streamlit Frontend β β Optimized state cache &
β (frontend/app.py) β Server-Sent Events reader
ββββββββββββββββ¬ββββββββββββββββ
β HTTP REST / query-stream (SSE)
βΌ
ββββββββββββββββββββββββββββββββ
β FastAPI Backend β β Schema validation & Cors
β (backend/main.py) β lifespan controllers
ββββββββββββββββ¬ββββββββββββββββ
β Internal calls
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β RAG ENGINE β
β (backend/rag_engine.py) β
ββββββββ¬βββββββββββββββββββββββ¬ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββ¬ββββββββ
β β β β
βΌ βΌ βΌ βΌ
ββββββββββββββββ βββββββββββββββββ βββββββββββββββββ ββββββββββββββββ
β DocProcessorβ β Vector Store β β LLM Handler β β Reranker β
β ββββββββββββ β β βββββββββββββ β β βββββββββββββ β β ββββββββββββ β
β Load file β β ChromaDB β β Groq API β β Cross-Encoderβ
β (pdf/docx/txt) β BM25 index β β (Llama 3.3) β β (ms-marco) β
β β β Parent lookup β β Condensation β β Sigmoid scoreβ
β Split texts: β β (JSON database) β HyDE gen β β normalizer β
β - Recursive β β β β LitM packing β β β
β - Semantic β β β β SSE stream β β β
β - ParentChildβ β β β β β β
ββββββββββββββββ βββββββββββββββββ βββββββββββββββββ ββββββββββββββββ
- File Loading: Raw text is parsed from PDFs (with
[Page N]citation markers), Word documents, or text files. - Chunking Tiers:
- Recursive: Splits text by separator priority
["\n\n", "\n", ". ", " ", ""]. - Semantic: Segments text dynamically at sentence transitions where embedding distances spike.
- Hierarchical: Splits text into large parent chunks (1500 chars) and smaller child chunks (300 chars).
- Recursive: Splits text by separator priority
- Storage Strategy: Standard and semantic chunks are saved directly in ChromaDB. Hierarchical chunks save child vectors in ChromaDB, while registering their parent structures inside
data/parent_store.json. - Lexical Synching: Rebuilds the custom in-memory BM25 index over the entire corpus.
- Condensation: Rewrites follow-up questions into standalone queries using chat history.
- HyDE Expansion (Optional): Synthesizes a hypothetical answer via Llama 3.3 to search vector space, bridging the semantic gap between questions and documents.
-
Stage 1 Search: Retrieves top 20 candidates from BM25 and ChromaDB. Merges ranks using Reciprocal Rank Fusion (RRF,
$k=60$ ). If hierarchical mode is active, child chunks are resolved to their parents viaparent_store.jsonand deduplicated. -
Stage 2 Reranking: Re-scores the top 15 candidates using a ms-marco cross-encoder. Scores are normalized to
$[0, 1]$ via Sigmoid. - LitM Packing (Optional): Re-orders the top 4 chunks (alternating high relevance to prompt edges) to bypass the transformer attention valley.
- Token streaming: Feeds context to Groq and streams text tokens back to the UI at ultra-low latency.
- Python 3.8+
- Groq API Key (Get a free key at console.groq.com)
Clone the repository and install the dependencies:
git clone https://github.com/MohansaiRitesh/rag-document-qa.git
cd rag-document-qa
pip install -r requirements.txtCreate a .env file in the backend/ directory:
# File: backend/.env
GROQ_API_KEY=gsk_your_actual_key_goes_herecd backend
python main.py- API server will start at:
http://localhost:8000 - Interactive Swagger Documentation:
http://localhost:8000/docs
cd frontend
streamlit run app.py- Streamlit application will open automatically at:
http://localhost:8501
All settings can be configured in backend/config.py or overridden via environment variables in backend/.env:
| Variable | Default | Description |
|---|---|---|
GROQ_API_KEY |
(required) | API key for Llama 3.3 Groq access |
llm_model |
llama-3.3-70b-versatile |
Llama 3.3 70B model identifier |
embedding_model |
all-MiniLM-L6-v2 |
Dense sentence-transformer model (384-dims) |
reranker_model |
ms-marco-MiniLM-L-6-v2 |
Cross-Encoder model for Stage 2 re-ranking |
chunking_strategy |
recursive |
Default strategy: "recursive", "semantic", "hierarchical" |
chunk_size |
1000 |
Target character size for standard chunks |
chunk_overlap |
200 |
Overlapping characters between consecutive chunks |
parent_chunk_size |
1500 |
Parent segment size (Hierarchical strategy) |
child_chunk_size |
300 |
Child segment size (Hierarchical strategy) |
use_hyde |
True |
Generate hypothetical answers before search |
use_litm_packing |
True |
Pack context chunks to primacy/recency boundaries |
top_k_results |
4 |
Number of context chunks fed to the LLM |
rerank_top_n |
15 |
Size of Stage 1 candidate pool before reranking |
The repository contains a self-contained system diagnostic and verification script test_system.py. You can run this script to ensure all Python dependencies are correctly installed, directory paths are active, and API integrations (e.g., Groq client validation) are operational:
python test_system.py| Method | Endpoint | Description |
|---|---|---|
GET |
/health |
Check backend components status (LLM connection, ChromaDB) |
GET |
/stats |
Retrieve total chunk count indexed in database |
GET |
/documents |
List uploaded filenames, sizes, and file types |
GET |
/metadata-values |
Fetch list of unique sources and extensions in database |
POST |
/upload |
Upload PDF, DOCX, or TXT file (Multipart Form Data) |
POST |
/query |
Ask question with history and filters (JSON body) |
POST |
/query-stream |
Ask question and stream back tokens and sources (SSE) |
DELETE |
/clear |
Purge all document vectors, parent stores, and uploads |
RAG Q&A System/
β
βββ backend/
β βββ main.py # FastAPI application, HTTP endpoints
β βββ rag_engine.py # Orchestrator (Upload and Query flows)
β βββ document_processor.py # Document loading & recursive/semantic/hierarchical splits
β βββ vector_store.py # ChromaDB, BM25, Hybrid RRF, Parent resolution
β βββ bm25.py # Tokenizer and custom BM25 fit/search implementation
β βββ llm_handler.py # Groq client, prompt construction, HyDE, LitM re-ordering
β βββ reranker.py # MS-MARCO Cross-Encoder scoring & sigmoid normalizer
β βββ config.py # Pydantic Settings loaders
β βββ data/
β βββ uploads/ # Temporary storage of parsed files
β βββ chromadb/ # ChromaDB database files
β βββ parent_store.json # Parent chunks metadata store (Hierarchical strategy)
β
βββ frontend/
β βββ app.py # Optimized Streamlit UI (caching, SSE streams, glassmorphic layout)
β
βββ test_system.py # System configuration, connection, and diagnostic tests
βββ requirements.txt # System dependencies
βββ README.md # β Root README (You are here)
- LLM Engine: Groq API for LPU-accelerated Llama 3.3 inference.
- Embeddings & Reranking: Sentence-Transformers (
all-MiniLM-L6-v2/ms-marco-MiniLM-L-6-v2). - Vector Storage: ChromaDB for persistent, localized semantic vectors.
- REST Framework: FastAPI for async ASGI endpoints and Pydantic validation.
- Web UI: Streamlit for rapid Python UI rendering.