# Hybrid Search and Reranking for Better RAG

> Why vector search alone misses exact terms, how to combine it with keyword search, and how a reranker improves the final top results.

- Source: https://akshaythakare.com/notes/rag/hybrid-search-and-reranking
- Topic: RAG
- Level: intermediate
- Reading time: 2 min
- Tags: rag, retrieval, search, reranking, interview
- Updated: 2026-10-11

## Vector search misses exact matches

Embeddings capture meaning, so "refund policy" finds "returns and money back". But they can miss exact tokens: product codes, error codes, names and acronyms such as `ERR-4012` or `SKU100045`.

## Hybrid search

Run both and merge:

| Retriever | Good at |
| --- | --- |
| Keyword (BM25) | Exact terms, codes, rare words |
| Vector (embeddings) | Paraphrases, meaning |

A common merge is **Reciprocal Rank Fusion**: each document scores the sum of `1 / (k + rank)` over the lists it appears in (k is often 60).

```python
def rrf(*rankings, k=60):
    scores = {}
    for ranking in rankings:
        for rank, doc_id in enumerate(ranking, start=1):
            scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank)
    return sorted(scores, key=scores.get, reverse=True)
```

## Reranking

Retrieve broadly (say the top 50), then score each candidate against the question with a **cross-encoder reranker**, which reads question and passage together. Keep the top 5 for the prompt.

```text
question → hybrid retrieve top 50 → rerank → top 5 → LLM
```

Rerankers are slower per document than embeddings, which is why they run only on a short candidate list.

## Also use metadata

Filter by permissions, product, language or date **before** ranking. It is cheaper and prevents leaking documents a user should not see.

> **Tip: Interview framing**
>
> "Hybrid retrieval for recall, a reranker for precision, metadata filters for access control — and I measure each change with retrieval evals."
