Skip to content

Latest commit

ย 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿš€ DocIntel AI

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.


๐Ÿ“Œ Features

  • ๐Ÿ“„ 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

๐Ÿ— System Architecture

                          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

๐Ÿง  Why RAG?

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

๐Ÿ” Retrieval Pipeline

1๏ธโƒฃ Dense Retrieval

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.


2๏ธโƒฃ Sparse Retrieval (BM25)

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.


3๏ธโƒฃ Hybrid Retrieval

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.


4๏ธโƒฃ Cross-Encoder Reranking

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

๐Ÿ›  Tech Stack

Backend

  • FastAPI
  • Python

LLM

  • Google Gemini 2.5 Flash

LangChain

  • LangChain Core
  • ChatPromptTemplate
  • EnsembleRetriever

Vector Database

  • ChromaDB

Retrieval

  • Dense Retrieval
  • BM25
  • Reciprocal Rank Fusion (RRF)

Embeddings

  • BAAI/bge-small-en-v1.5

Reranker

  • BAAI/bge-reranker-base

PDF Processing

  • PyMuPDF

๐Ÿ“‚ Project Structure

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

โš™ Configuration

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.


๐Ÿš€ Running Locally

git clone <repo>

cd backend

python -m venv venv

source venv/bin/activate

pip install -r requirements

uvicorn app:app --reload

๐Ÿ“ก API Endpoints

Upload Document

POST /upload

Uploads and indexes a PDF document.


Ask Questions

POST /ask

Returns:

  • Generated answer
  • Source chunks
  • Confidence score

๐Ÿ“ˆ Logging & Observability

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.


๐ŸŽฏ Design Decisions

Why Hybrid Retrieval?

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.


Why Cross Encoder?

Vector similarity provides approximate relevance.

Cross Encoders jointly process:

Question

+

Document Chunk

to produce significantly more accurate relevance scores before generation.


Why ChromaDB?

  • Persistent Vector Store
  • Native LangChain Integration
  • Efficient Similarity Search
  • Lightweight Deployment

๐Ÿšง Current Limitations

  • Single active document per session
  • CPU-based reranking increases latency
  • Evaluation framework (RAGAS/DeepEval) not yet integrated
  • Multi-document retrieval support planned

๐Ÿ”ฎ Future Roadmap

  • Multi-document Retrieval
  • LangSmith Observability
  • Automated Evaluation (RAGAS / DeepEval)
  • Agentic RAG
  • Context Compression
  • Query Rewriting
  • Multimodal RAG
  • OCR Integration
  • Vision Language Models (VLMs)

๐Ÿ‘จโ€๐Ÿ’ป Author

Aneesh Jantikar

Computer Science Undergraduate | AI & Machine Learning Enthusiast


โญ If you found this project interesting, consider giving it a star!

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages