title: Explainable RAG System
emoji: π
colorFrom: blue
colorTo: purple
sdk: docker
hardware: cpu-upgrade
pinned: false
Explainable RAG System
π Live Demo
If the Space is sleeping, it may take ~30 seconds to wake up on first visit. Startup may also be slow as the embedding model and reranker weights load into memory. Groq free tier rate limits apply β if you get no response, wait a minute and try again.
Most RAG systems are black boxes. You type a question, get an answer, and have no idea what happened in between.
Which documents were retrieved. Why one chunk ranked above another. How the query was even interpreted.
This project opens that box. Every stage of the retrieval pipeline is visible and interactive:
- how your query gets tokenized and embedded
- how BM25 and vector search disagree
- how MMR trades off relevance for diversity
- why the reranker promotes some chunks and drops others
Ask a question. See exactly how the answer was built.
Demo
What's inside
Answer
Ask anything about the HuggingFace Transformers documentation. The system retrieves relevant chunks, reranks them, and generates an answer using Llama 3.1 via Groq.
Latency Timeline
Every stage of the pipeline: embed, vector search, BM25, hybrid fusion, MMR, rerank, LLM, broken down by time. You can see exactly where the bottleneck is.
Below it, query analysis shows each token's IDF score, its position in the embedding space, and an overall complexity rating.
Retrieval Comparison
A table showing every candidate chunk with its Vector, BM25, Hybrid, and Reranker scores side by side. You can see which chunks got promoted, which got dropped, and by how much.
MMR Visualization
MMR (Maximal Marginal Relevance) balances relevance and diversity when selecting chunks. This tab shows that tradeoff visually, a UMAP scatter of all candidates, a similarity matrix, and a live Ξ» slider to see how the selection changes in real time.
Context Chunks
The final chunks passed to the LLM, each with its reranker score and source URL.
Retrieval Pipeline
Query β Embed β Vector Search + BM25 β Hybrid Fusion β MMR β Rerank β LLM
- Vector search β BAAI/bge-small-en-v1.5 embeddings via ChromaDB
- BM25 β keyword search with BM25Okapi
- Hybrid fusion β weighted combination of both (Ξ± = 0.7)
- MMR β removes redundant chunks while preserving relevance
- Reranker β cross-encoder/ms-marco-MiniLM-L-6-v2 for final scoring
- LLM β Llama 3.1 8B via Groq API
Stack
- Backend β Flask
- Embeddings β sentence-transformers, ChromaDB
- Retrieval β rank-bm25, UMAP
- Reranker β CrossEncoder (ms-marco-MiniLM-L-6-v2)
- LLM β Llama 3.1 via Groq
- Frontend β Vanilla JS
Run it yourself
git clone https://github.com/ilaa-1505/Explainable-RAG-System
cd Explainable-RAG-System
pip install -r requirements.txt
Set up your Groq API key:
echo "GROQ_API_KEY=your_key_here" > .env
Build the index:
python src/ingestion/fetch_docs.py
python src/ingestion/chunk.py
python src/retrieval/embed_store.py
Run:
python app.py
First startup takes a minute, the embedding model (BAAI/bge-small-en-v1.5) and reranker (ms-marco-MiniLM-L-6-v2) weights load into memory on first query.
Things I learned building this
- BM25 consistently outranks vector search on exact keyword matches, hybrid fusion is genuinely worth the complexity
- MMR's Ξ» parameter matters more than expected, at Ξ»=1.0 the top chunks are nearly identical; at Ξ»=0.5 the diversity is visible in the UMAP
- The reranker and vector search frequently disagree on rank. the retrieval comparison table makes this obvious
What's next
- Support for other documentation sources beyond HuggingFace Transformers
- Side by side comparison of retrieval strategies on the same query






