What is reranking?
Vector search uses a bi-encoder: the query and each document are embedded separately into a fixed vector, then ranked by cosine similarity. It scales to billions of documents but loses fine-grained relevance because the encoders never see the query and document together. A reranker uses a cross-encoder: it scores each (query, document) pair jointly. This is far more accurate but ~100x more expensive, so you run it only on the top candidates from the bi-encoder. The standard two-stage retrieval pipeline:The Reranker interface
All four built-in providers implement the same interface so you can swap them freely.
RerankDocument
Accepts either a plain string OR an object with optional id + metadata:
RerankOptions
RerankResult
index field is the most important detail — it lets you trace each result back to the original input array without comparing strings.
Built-in providers
CohereReranker
npm install cohere-ai (optional peer dep).
Model options:
Retry behavior: automatic on HTTP 429 / 500 / 502 / 503 with exponential backoff (1s → 2s → fail), up to 2 retries.
VoyageReranker
fetch API directly. Throws Error("VoyageReranker: missing API key") if neither apiKey nor VOYAGE_API_KEY env is set.
Model options:
JinaReranker
CrossEncoderReranker (local)
@huggingface/transformers@^4.3.0 and provision model artifacts in your configured cache first. Local-only loading is the default; allow downloads explicitly with localFilesOnly: false when appropriate. ready() surfaces model-loading failures before the first query.
This adapter scores query/document pairs with a sequence-classification cross-encoder. It is not a ColBERT late-interaction implementation. The removed name ColbertReranker has no alias; update imports, config types, and stored provider IDs to cross-encoder-local.
Wiring into a vector store
EveryVectorStore in @agentium/core accepts a rerank option:
How rerankMultiplier works
When a reranker is set:
- The vector backend fetches
topK * rerankMultipliercandidates from the underlying ANN index. - The reranker scores each one against the original query.
- The reranker returns the top
topKby its own score.
rerankMultiplier defaults to 3. Larger values give the reranker more candidates to choose from (better recall) at the cost of latency + reranker tokens. topK=5, rerankMultiplier=10 is a sensible “high quality” setting.
Query types the reranker sees
The reranker requires a text query. The vector backend hands it whatever it can extract:
This matters for multimodal indexes: if you want reranking on an image query, supply a text caption alongside the image part.
Backend-by-backend behavior
All four built-in backends call the sameBaseVectorStore.applyRerank() chokepoint, so behavior is identical:
InMemoryVectorStore— fetchestopK * multiplierfrom the local cosine ranking.PgVectorStore— adjusts the SQLLIMITto the larger fetch size; doesn’t applyminScoreuntil after rerank.QdrantVectorStore— setslimit: fetchKand omitsscore_thresholdwhen reranker is set (rerank handles thresholding).MongoDBVectorStore— applies to both the Atlas$vectorSearchpath and the in-process brute-force fallback.
minScore interaction
When you pass minScore with rerank:
Standalone usage
A reranker also works without a vector store, e.g. to reorder a BM25 candidate list or to score a set of LLM-generated options:Composing rerankers
You can stack rerankers cheaply by calling them in sequence:Performance characteristics
(Numbers are rough; benchmark your own workload.)
Errors and edge cases
See also
- Tool Router narrows a large tool list before the model sees it.
- GraphRAG / HybridRetriever composes vector + graph + rerank.
- Embeddings — the first stage of two-stage retrieval.