How it works
Vector similarity search ranks results by approximate proximity in embedding space. This is fast but imprecise. A document can be a close neighbour in embedding space without actually answering the query.
A cross-encoder reranker fixes this. Instead of comparing independent embeddings, it receives the query and each candidate document together and produces an exact relevance score using bidirectional attention:
search() fetches top_k × 2 candidates from a vector store (over-fetch)
- The cross-encoder scores every candidate against the query in a single batch
- Results are re-sorted by cross-encoder score and truncated to
top_k
Enabling the reranker
Reranking is disabled by default. Enable it with a single config flag:
The model is lazy-loaded, it is downloaded and initialised only on the first search() call that triggers reranking, not at every startup.
Changing the model
The default model is Xenova/ms-marco-MiniLM-L-6-v2, a lightweight MS MARCO-trained cross-encoder. Swap it via reranker_model_name:
Any ONNX cross-encoder supported by FastEmbed can be used here.
Combining with hybrid search
For the best retrieval quality, run both hybrid search and reranking together:
The pipeline becomes: sparse + dense fusion → cross-encoder rescore → top-k.
Hybrid search and reranking complement each other. Hybrid search maximises recall; the reranker maximises precision from those candidates.
Reranking only applies to search(). The recall() method uses graph-based BFS traversal and is not affected by use_reranking.
Configuration reference