A Django REST API and React application for comparing embedding cosine-similarity retrieval with Groq LLM reranking.
I’m @Devn913, building practical projects to understand agentic AI, embeddings, retrieval, reranking, and RAG systems. I created this explorer to make the difference between semantic search and LLM-assisted relevance ranking visible and easier to experiment with.
cp .env.example .env
python3 -m venv .venv
.venv/bin/pip install -r backend/requirements.txt
cd frontend && npm installAdd a GROQ_API_KEY to .env to use the reranking page. The default GROQ_RERANK_MODEL is llama-3.1-8b-instant; override it only with a model enabled for the deployment Groq account. Embeddings are generated locally with the configurable Hugging Face sentence-transformer model.
set -a && source .env && set +a
.venv/bin/python backend/manage.py runserverIn another terminal:
cd frontend && npm run devThe React development server proxies /api to Django. Each non-empty input line is one document chunk; no documents or embeddings are persisted.
POST /api/retrieve/: returns top-k cosine-similarity results and 2D embedding positions.POST /api/rerank/: returns the same retrieval results plus a Groq LLM reranking of the top-k candidates.
Both accept { "documents": ["chunk one"], "query": "text", "top_k": 3 }.
This example shows why a semantic retrieval stage and an LLM reranker complement each other. Enter the following document chunks, one per line:
| Document | Chunk | Expected relevance |
|---|---|---|
| A | My 2012 Maruti Suzuki Alto petrol car costs around ₹7,000 per month in India for fuel, basic servicing, and third-party insurance. | Correct |
| B | A new Tata Nexon electric car in India costs just ₹1,500 per month for home charging, but the showroom price is much higher than a petrol car. | Wrong |
| C | My Royal Enfield motorcycle gives a mileage of 35 km/l, so my monthly petrol and service cost in India is only around ₹2,500. | Wrong |
| D | Petrol prices in Indian cities like Mumbai and Delhi change daily due to international crude rates and local VAT taxes. | Distractor |
Use this query and set Relevant results to top 4:
What is the monthly running cost of my old petrol car in India?
Cosine similarity retrieves chunks whose embeddings are closest to the query. In this captured run, Document C ranks first (0.650) because it shares concepts such as monthly, petrol, service, and cost; the correct Alto document is second (0.614). This is a plausible semantic match, but it does not fully distinguish a motorcycle from the user's old car.
The reranker receives the cosine top-k candidates and evaluates each one against the full query. It recognizes that Document A is specifically about the user's old petrol car and moves it from cosine rank 2 to rank 1 with a relevance score of 95.0. Documents about general fuel prices, a motorcycle, and an electric car follow.
The exact scores can vary by reranker model, but the intended outcome is that the LLM uses the query's details—old petrol car, India, and monthly running cost—to prioritize Document A over superficially similar alternatives.
Retrieval-augmented generation (RAG) grounds an LLM response in relevant external documents instead of relying only on the model's trained knowledge. This application visualizes the retrieval portion of that pipeline and shows why reranking can improve the context sent to the answering model.
| RAG stage | What happens here | Old-car example |
|---|---|---|
| 1. Index documents | Split source material into chunks and convert each chunk into an embedding vector. | Documents A-D are the chunks to search. |
| 2. Retrieve | Embed the user's question and use cosine similarity to select the nearest top_k chunks. |
The motorcycle chunk is retrieved first because its wording is very similar to the query. |
| 3. Rerank | Ask a stronger relevance model to compare the retrieved candidates with the complete query. | The Groq LLM recognizes that the Alto chunk answers the question and moves Document A to rank 1. |
| 4. Augment and generate | Put the best reranked chunks into the prompt as context, then ask a generation LLM to answer with that evidence. | A RAG assistant could answer: “Your 2012 Maruti Suzuki Alto costs around ₹7,000 per month for fuel, basic servicing, and third-party insurance.” |
In a production RAG system, only the highest-ranked chunks are typically included in the final prompt to control token cost and reduce irrelevant context. The explorer stops after retrieval and reranking, making it possible to inspect whether the context would be correct before connecting it to a generation model.
.venv/bin/python backend/manage.py test retrieval.tests
cd frontend && npm test && npm run lint && npm run build
