Production-Grade Retrieval-Augmented Generation (RAG) System with Hybrid Retrieval & Cross-Encoder Reranking
DocIntel AI is a modular document intelligence platform that enables users to upload PDF documents and interact with them through natural language. Unlike conventional PDF chatbots that rely solely on vector similarity search, DocIntel AI employs a two-stage retrieval pipeline combining Dense Retrieval, BM25 Sparse Retrieval, Reciprocal Rank Fusion (RRF), and Cross-Encoder Reranking to significantly improve retrieval precision before generating responses using Google's Gemini.
- ๐ Upload and index PDF documents
- ๐ฌ Natural language question answering over uploaded documents
- ๐ง Hybrid Retrieval
- Dense Semantic Search (ChromaDB)
- Sparse Keyword Search (BM25)
- LangChain EnsembleRetriever (Reciprocal Rank Fusion)
- ๐ฏ Cross-Encoder Reranking using BAAI/bge-reranker-base
- โก Modular LangChain pipeline
- ๐ Retrieval confidence and source attribution
- ๐ Metadata-aware document chunking
- โ๏ธ Fully configurable retrieval pipeline
- ๐ Structured logging for retrieval, reranking, and latency analysis
PDF Upload
โ
โผ
PyMuPDF Document Loader
โ
โผ
RecursiveCharacterTextSplitter
โ
โผ
LangChain Document Objects
โ โ
โผ โผ
Dense Embeddings BM25 Index
(HuggingFace) (Sparse Search)
โ โ
โโโโโโโโโโโฌโโโโโโโโโโโโ
โผ
EnsembleRetriever (RRF)
โ
Top-K Candidate Chunks
โผ
Cross Encoder Reranker (BAAI/bge-reranker-base)
โ
Top-N Relevant Chunks
โผ
Prompt Construction Layer
โผ
Google Gemini 2.5 Flash
โผ
Final Grounded Response
Uploading an entire document to an LLM for every query is inefficient, expensive, and doesn't scale as document sizes increase.
Instead, DocIntel AI:
- Indexes documents once
- Retrieves only the most relevant sections
- Grounds every answer in retrieved context
- Reduces hallucinations
- Lowers token usage
- Improves response quality and scalability
Documents are embedded using BAAI/bge-small-en-v1.5 and stored in ChromaDB.
Dense retrieval captures semantic similarity between user queries and document chunks.
Example:
"Explain authentication"
can retrieve content mentioning
- Login
- JWT
- Authorization
even if the exact word "authentication" isn't present.
Dense embeddings often struggle with:
- API routes
- Variable names
- Error codes
- Acronyms
- Configuration keys
BM25 complements semantic retrieval by performing lexical keyword matching.
Example:
JWT_SECRET
or
POST /dashboard/stats
are retrieved far more accurately using BM25.
DocIntel AI combines Dense Retrieval and BM25 using LangChain's built-in EnsembleRetriever, which internally performs Reciprocal Rank Fusion (RRF).
This provides the advantages of both retrieval methods:
- Semantic understanding
- Exact keyword matching
without manually implementing fusion algorithms.
Hybrid retrieval prioritizes high recall, meaning it retrieves a broad set of potentially relevant chunks.
A Cross Encoder then performs pairwise relevance scoring:
(Query, Chunk)
โ
Cross Encoder
โ
Relevance Score
The highest scoring chunks are forwarded to Gemini.
This dramatically reduces noisy context and improves answer precision.
Current reranker:
BAAI/bge-reranker-base
- FastAPI
- Python
- Google Gemini 2.5 Flash
- LangChain Core
- ChatPromptTemplate
- EnsembleRetriever
- ChromaDB
- Dense Retrieval
- BM25
- Reciprocal Rank Fusion (RRF)
- BAAI/bge-small-en-v1.5
- BAAI/bge-reranker-base
- PyMuPDF
backend/
โโโ app.py
โโโ config.py
โ
โโโ chains/
โ โโโ rag_chain.py
โ
โโโ llm/
โ โโโ gemini.py
โ
โโโ prompts/
โ โโโ rag_prompt.py
โ
โโโ retrievers/
โ โโโ dense.py
โ โโโ sparse.py
โ โโโ hybrid.py
โ โโโ factory.py
โ โโโ retriever.py
โ
โโโ rerankers/
โ โโโ base.py
โ โโโ bge.py
โ โโโ factory.py
โ
โโโ services/
โ โโโ ingest.py
โ
โโโ vectorstore/
โ โโโ chroma.py
โ โโโ bm25.py
โ
โโโ utils/
โโโ logging.py
โโโ exceptions.py
Everything is configurable through config.py.
RETRIEVER_MODE="hybrid"
TOP_K_DENSE=20
TOP_K_SPARSE=20
TOP_K_CANDIDATES=20
TOP_K_FINAL=5
RERANKER_ENABLED=True
RERANKER_MODEL="BAAI/bge-reranker-base"Switch between:
- Dense Retrieval
- Sparse Retrieval
- Hybrid Retrieval
without changing application code.
git clone <repo>
cd backend
python -m venv venv
source venv/bin/activate
pip install -r requirements
uvicorn app:app --reloadPOST /upload
Uploads and indexes a PDF document.
POST /ask
Returns:
- Generated answer
- Source chunks
- Confidence score
Every query logs:
- Dense Retrieval Latency
- BM25 Retrieval Latency
- Hybrid Retrieval Latency
- Candidate Chunk IDs
- Cross Encoder Scores
- Final Selected Chunks
- Reranking Latency
making the retrieval pipeline fully traceable and debuggable.
Dense retrieval excels at semantic similarity but struggles with exact keywords.
BM25 excels at exact matches but lacks semantic understanding.
Combining both provides significantly better retrieval quality.
Vector similarity provides approximate relevance.
Cross Encoders jointly process:
Question
+
Document Chunk
to produce significantly more accurate relevance scores before generation.
- Persistent Vector Store
- Native LangChain Integration
- Efficient Similarity Search
- Lightweight Deployment
- Single active document per session
- CPU-based reranking increases latency
- Evaluation framework (RAGAS/DeepEval) not yet integrated
- Multi-document retrieval support planned
- Multi-document Retrieval
- LangSmith Observability
- Automated Evaluation (RAGAS / DeepEval)
- Agentic RAG
- Context Compression
- Query Rewriting
- Multimodal RAG
- OCR Integration
- Vision Language Models (VLMs)
Aneesh Jantikar
Computer Science Undergraduate | AI & Machine Learning Enthusiast
- GitHub: https://github.com/aneeshj-05
- LinkedIn: www.linkedin.com/in/aneeshjantikar
โญ If you found this project interesting, consider giving it a star!