Reranking & RAG Evaluation
Retrieval gets you candidates fast. Reranking gets the right ones to the top. Evaluation tells you if any of it worked.
Vector similarity search (a "bi-encoder": query and document embedded independently, then compared) is fast enough to run over millions of chunks, but the independence that makes it fast also makes it a coarser relevance signal. A cross-encoder reranker takes the query and a candidate chunk together as joint input and scores relevance directly — much more accurate, but too slow to run over a whole corpus. The standard pattern: retrieve a wide candidate set cheaply (e.g. top 50 by vector similarity), then rerank just those with the expensive cross-encoder down to the top 5-10 that actually go in the prompt.
candidates = vector_search(query, k=50) # cheap, broad recall
reranked = cross_encoder.rank(query, candidates) # expensive, narrow precision
top_chunks = reranked[:8] # what actually enters the prompt
| Metric | Answers |
|---|---|
| Recall@k | Of the chunks actually relevant to the query, what fraction appear in the top k retrieved? |
| Precision@k | Of the top k retrieved chunks, what fraction are actually relevant? |
| MRR (Mean Reciprocal Rank) | On average, how high does the first relevant chunk rank? |
| Metric | Checks |
|---|---|
| Faithfulness | Is every claim in the generated answer actually supported by the retrieved context, or did the model add unsupported claims? |
| Answer relevancy | Does the answer actually address the question asked, independent of whether it's factually grounded? |
| Context precision/recall | Retrieval quality, scored automatically instead of by hand |