Spaces:
Sleeping
Sleeping
| title: Adaptive RAG Backend | |
| emoji: π | |
| colorFrom: purple | |
| colorTo: blue | |
| sdk: docker | |
| pinned: false | |
| # Adaptive Hybrid RAG Pipeline | |
| A retrieval-augmented generation system over 443k chunks from 10,000 arXiv papers. Combines BM25, dense vector search, and a cross-encoder reranker with LLM-based query routing, query rewriting, and retrieval grading. | |
| ## How it works | |
| A query goes through four stages: | |
| 1. **Route** β an LLM classifier picks the retrieval strategy (`bm25`, `dense`, `hybrid`, or `hybrid_rerank`) based on query type | |
| 2. **Retrieve** β hybrid search with query expansion via RRF fusion, with up to 2 automatic retries if retrieval confidence is low. On each retry the query is rewritten using a different strategy before trying again | |
| 3. **Rerank** β a cross-encoder scores the top candidates; skipped if pre-rerank confidence already clears the threshold | |
| 4. **Generate** β Groq LLaMA produces a grounded answer from the retrieved chunks | |
| ## Benchmark (50 queries, corpus-grounded) | |
| | Metric | Score | | |
| |---|---| | |
| | Recall@50 pre-rerank | 0.880 | | |
| | Recall@5 post-rerank (exact) | 0.820 | | |
| | Recall@5 post-rerank (paper) | 0.900 | | |
| | MRR exact | 0.663 | | |
| | MRR paper | 0.830 | | |
| | Reranker lift @5 | +0.040 | | |
| | Generation eval (10 queries) | 10/10 relevant | | |
| ## Stack | |
| | Component | Library | | |
| |---|---| | |
| | Sparse retrieval | `bm25s` | | |
| | Dense retrieval | `all-MiniLM-L6-v2` + Qdrant | | |
| | Fusion | Reciprocal Rank Fusion | | |
| | Reranker | `cross-encoder/ms-marco-MiniLM-L-12-v2` | | |
| | LLM (routing / generation / grading) | Groq `llama-3.1-8b-instant` | | |
| ## Setup | |
| **Prerequisites:** Python 3.11+, Docker (for Qdrant) | |
| ```bash | |
| git clone https://github.com/MilanMishra19/adaptive-rag | |
| cd adaptive-rag | |
| pip install -r requirements.txt | |
| ``` | |
| ```bash | |
| # Start Qdrant | |
| docker run -p 6333:6333 qdrant/qdrant | |
| ``` | |
| ```bash | |
| # Set env vars | |
| export GROQ_API_KEY=your_key_here | |
| ``` | |
| ```bash | |
| # Build all indexes (downloads dataset, encodes chunks, builds BM25 + Qdrant) | |
| python setup.py | |
| ``` | |
| This takes a while on first run β it encodes 443k chunks. Subsequent runs skip already-built indexes automatically. If you have a laptop lacking a GPU, I suggest using Google Colab with runtime set to T4 GPU. Download the embeddings in the form of .npy as well as .json | |
| **Custom dataset size:** | |
| ```bash | |
| python setup.py --papers 5000 | |
| ``` | |
| **Bring your own chunks:** | |
| ```bash | |
| python setup.py --chunks-file ./my_chunks.json | |
| ``` | |
| **Rebuild a single index:** | |
| ```bash | |
| python setup.py --only bm25 | |
| python setup.py --only qdrant | |
| python setup.py --only embeddings | |
| ``` | |
| ## Usage | |
| ```python | |
| from rag_pipeline.app import Pipeline | |
| pipe = Pipeline() # loads all indexes once | |
| result = pipe.query("any query you would like..") | |
| print(result["answer"]) | |
| print(result["strategy"]) # which retrieval strategy was used | |
| print(result["confidence"]) # float in [0, 1] | |
| print(result["sources"]) # retrieved chunks with scores | |
| ``` | |
| ## Project structure | |
| ``` | |
| rag_pipeline/ | |
| βββ data/ | |
| β βββ load_data.py # dataset download, cleaning, chunking | |
| βββ retrieval/ | |
| β βββ bm25.py # BM25 index build + search | |
| β βββ semantic.py # Qdrant index build + dense search | |
| β βββ hybrid.py # RRF fusion, query expansion | |
| βββ reranking/ | |
| β βββ rerank.py # cross-encoder rerank, confidence scoring, retry loop | |
| βββ routing/ | |
| β βββ router.py # LLM-based routing | |
| βββ generation/ | |
| β βββ generate.py # to generate queries grounded to the corpus | |
| βββ eval_ragas/ | |
| β βββ metrics.py # recall, MRR, grading | |
| β βββ benchmark.py # benchmark builder | |
| βββ config.py # all paths and model names, env-configurable, make necessary changes here only | |
| βββ app.py # Pipeline class β combines the module | |
| setup.py # first-time index builder for adding your own dataset etc. | |
| ``` | |
| ## Environment variables | |
| | Variable | Default | Description | | |
| |---|---|---| | |
| | `GROQ_API_KEY` | β | Required | | |
| | `HF_TOKEN` | β | Only needed for gated HuggingFace datasets | | |
| | `BM25_INDEX_PATH` | `./bm25_index_10k` | Where to save/load the BM25 index | | |
| | `QDRANT_PATH` | `localhost:6333` | Qdrant connection | | |
| | `CHUNKS_PATH` | `./all_chunks_slim.json` | Chunks JSON | | |
| | `EMBEDDINGS_PATH` | `./chunk_embeddings.npy` | Embeddings array | | |