Choose a reranker
- Rank fusion: start with RRF for hybrid search. It combines vector and full-text rankings without a model or a provider API call.
- Model-based reranking: try a cross encoder or hosted reranking model when you need a different relevance judgment over the retrieved text. Compare the relevance gain with added latency and provider cost.
- Custom ranking: implement the reranker interface when your application needs its own scoring policy.
Run a complete RRF example in Python, TypeScript or Rust
Run a complete RRF example in Python, TypeScript or Rust
These examples use three sample records and hand-written vectors, so no
embedding service is needed. Each program creates a temporary local table
and removes it when finished.The result includes
- Python: Install with
pip install lancedb, save asrerank_search.py, then runpython rerank_search.py. - TypeScript: Install with
npm install @lancedb/lancedb, save asrerank_search.mts, then runnode rerank_search.mtswith Node.js 22.18 or later. - Rust: Download and extract the complete Rust examples, then run
cargo run --locked --bin hybrid_searchfrom the extracted directory.
_relevance_score in descending order. RRF is already the
hybrid-search default; passing it explicitly shows where to substitute another
reranker. These scores express a ranking, not a probability of correctness.Supported rerankers
Use rank fusion to combine search results without a model, or a model-based reranker to score each document against the query. Reranking runs in your application after retrieval, including when the table is in Enterprise.
Local model rerankers need their model runtime packages. Hosted rerankers need
provider credentials and make API calls. See reranking integrations
for provider setup and model selection; specify a model supported by your provider.
Rerankers add
_relevance_score and return rows ordered by descending relevance. Python rerankers
accept a return_score option; use "all" where supported to keep the
original vector distance or FTS score columns for debugging. Model-based rerankers read from
column="text" by default, so either return that column in the search results or pass a different
column.
refine_factor expands the vector index’s internal candidate pool and rescores
those candidates using full vectors before keeping the requested limit. It
can improve the candidates available for reranking, but it does not multiply
the final result count. Compare retrieval recall and total query latency.
SDK coverage differs across languagesThe provider-specific rerankers in the table above
(
CohereReranker, CrossEncoderReranker, ColbertReranker, and others under lancedb.rerankers)
are currently Python-only. The TypeScript and Rust SDKs currently expose hybrid reranking through
the generic Reranker interface (rerankHybrid / rerank_hybrid) and the built-in RRFReranker.
In TypeScript, create the built-in RRF reranker with await RRFReranker.create(k). To use a
model-based reranker from TypeScript or Rust, you must implement the hybrid reranker interface
yourself.Multi-vector reranking
Usererank_multivector() to combine result sets from several vector queries.
The example below assumes table has three vector columns with embedding
metadata and uses a cross encoder to rerank their candidates.
- Passing
deduplicate=Truetorerank_multivector(...)raises aValueErrorif any of the input result sets is missing the_rowidcolumn. Therefore, it’s recommended to add.with_row_id(True)to everytable.search(...)call before reranking, or omitdeduplicate=Trueif you don’t need it. RRFReranker.rerank_multivector(...)always requires_rowidon its inputs, regardless of thededuplicateflag.
Implement a custom ranking policy
Python custom rerankers implementrerank_hybrid() and can optionally implement
rerank_vector() and rerank_fts(). TypeScript and Rust expose hybrid reranking
interfaces. See the interface requirements before implementing one.
Algorithm options
The following sections describe the Python constructor options and examples. Provider and local-model examples require their additional packages and model or credential setup. They are separate programs, not steps to concatenate.Reciprocal rank fusion
RRF options and examples
RRF options and examples
Reciprocal Rank Fusion (RRF) is a model-free way to merge several ranked result lists into a
single ordering. Rather than comparing raw similarity scores (which aren’t directly comparable
across, say, a vector search and a full-text search), RRF looks only at each document’s rank
position in each list. It scores every document with the formula
1 / (rank + K), sums those
contributions across the lists, and re-sorts by the total. Documents that rank highly in more than
one search rise to the top. Because there’s no model to load or call, it’s fast and cheap, which is
why it’s the default reranker for LanceDB hybrid search. The implementation follows the
Cormack et al. paper.Supported query types: hybrid search and multi-vector reranking. Because RRF fuses two or more ranked lists, it can’t rerank a single vector or full-text result set on its own. Callingrerank_vectororrerank_ftson anRRFRerankerraisesNotImplementedError.
Python arguments
K must be greater than 0. In TypeScript, construct the built-in reranker with
await RRFReranker.create(k) before passing it to .rerank(...).Multi-vector reranking
RRFReranker can also fuse the results of several vector searches with rerank_multivector, applying
the same rank-fusion algorithm across more than two lists. Every input result set must include the
_rowid column, so add .with_row_id(True) to each table.search(...) call before reranking,
otherwise the call raises a ValueError. See multi-vector reranking
for a full example.Supported Scores for each query type
You can specify the type of scores you want the reranker to return. The following are the supported scores for each query type:Hybrid Search
Linear combination
Linear combination options (deprecated)
Linear combination options (deprecated)
Note: This reranker is deprecated. Use RRFReranker to combine vector and full-text rankings.
The Linear Combination Reranker combines the results of semantic and full-text search using a linear combination of the scores. The weights for the linear combination can be specified, and defaults to 0.7, i.e, 70% weight for semantic search and 30% weight for full-text search.Note: Supported query type: Hybrid search only.
Python arguments
weight must be between 0 and 1. If either the vector or FTS side returns no rows, the reranker
returns the non-empty side with _relevance_score attached rather than failing.Supported Scores for each query type
You can specify the type of scores you want the reranker to return. The following are the supported scores for each query type:Hybrid Search
MRR
MRR options and examples
MRR options and examples
This reranker uses the Mean Reciprocal Rank (MRR) algorithm to combine and rerank search results from vector and full-text search. You can use this reranker by passing
MRRReranker() to the rerank() method. The MRR algorithm calculates the average of reciprocal ranks across different search results, providing a balanced way to merge results from multiple ranking systems.Note: Supported query types: Hybrid and Multivector search.
Python arguments
Note:
weight_vector + weight_fts must equal 1.0.For multivector reranking, input result sets need _rowid so LanceDB can identify the same row
across the ranked lists. Add .with_row_id(True) to each vector search before passing the results
to the reranker.Supported Scores for each query type
You can specify the type of scores you want the reranker to return. The following are the supported scores for each query type:Hybrid Search
Multivector Search
Cross encoder
Cross-encoder options and examples
Cross-encoder options and examples
This reranker uses Cross Encoder models from sentence-transformers to rerank the search results. You can use this reranker by passing
CrossEncoderReranker() to the rerank() method.Note: Supported query types: Hybrid, Vector, and FTS.
Python arguments
The reranker loads the model locally through
sentence-transformers, so install the local model
runtime dependencies you need, such as PyTorch and any device-specific acceleration packages.Supported Scores for each query type
You can specify the type of scores you want the reranker to return. The following are the supported scores for each query type:Hybrid Search
Vector Search
FTS Search
Building a custom reranker
You can build your own custom reranker in LanceDB by subclassing the baseReranker class. At a
minimum, you need to implement rerank_hybrid(), which is the logic that combines vector and
full-text search results. Beyond that, you can optionally implement rerank_vector() and
rerank_fts() if you want your reranker to also handle pure vector or pure full-text searches.
Implement the hooks your query paths call. The base class raises
NotImplementedError for vector-only or FTS-only reranking unless you
implement those methods.
The Python base class exposes hybrid, vector-only, and FTS-only rerank hooks. TypeScript and Rust
currently expose the custom reranker interface for hybrid reranking. In Rust, a custom reranker must
also satisfy the trait bounds Debug + Send + Sync.
Interface
TheReranker base interface comes with a merge_results() method that can be used to combine the
results of semantic and full-text search. This is a vanilla merging algorithm that simply concatenates
the results and removes the duplicates without taking the scores into consideration. It only keeps the
first copy of the row encountered. This works well in cases that don’t require the scores of semantic
and full-text search to combine the results. If you want to use the scores or want to support
return_score="all", you’ll need to implement your own merging algorithm. The base
return_score option accepts only "relevance" and "all".
Whichever methods you override, your reranker has one job on the way out: attach a
_relevance_score column with the most relevant rows at the top. LanceDB will reject the result
if that column is missing, and downstream .limit(...) calls trust the order you return, so
sort descending before handing the table back.
For vector-only reranking in Python, pass a text query to .rerank(..., query_string="...").
The vector query itself may be numeric, but rerank_vector(query, vector_results) still receives
a string query so your reranker can score each candidate against the user’s text intent.
The method contract is:
Implement only the single-search hooks your application uses. The base class
raises
NotImplementedError for those hooks until they are implemented.
Extend an existing reranker
This class definition extendsCohereReranker to exclude text patterns after
reranking. It requires the Cohere package and credentials when instantiated.
It can return fewer results because exclusions happen after retrieval; use a
query predicate instead when a metadata filter expresses the same restriction.
to_pandas() for a
DataFrame transformation and pa.Table.from_pandas() to convert the result
back, preserving _relevance_score and the desired row order.
Evaluate relevance, latency and cost
Compare rerankers on the same candidate inputs so you can distinguish ranking changes from retrieval changes. For hybrid retrieval, prepare the text index and query vectors before collecting those candidates.Reranking strategies
Compare these approaches:- Rank fusion: RRF and MRR combine rank positions from multiple result lists.
- Score blending: linear combination mixes normalized vector and text scores.
- Model-based reranking: a model scores each query-document pair.
rerank() to select
it. Pass a reranker when you want a different algorithm or configuration.
By default, rerankers return _relevance_score. Pass return_score="all" when a reranker
supports it, and you also need the original vector or FTS scores for debugging.
Evaluation code can rely on returned rows being ordered by descending _relevance_score. Empty
reranked result sets still include the _relevance_score column.
The synchronous Python hybrid rerank(...) method also accepts a normalize argument that controls how the raw
vector and FTS scores are made comparable before reranking:
normalize="score"(the default); normalizes the raw vector and FTS scores directly.normalize="rank"; converts each result list to ranks first, then normalizes.
RRFReranker(K=60): rank fusion with a positive smoothing constant.MRRReranker(weight_vector=0.5, weight_fts=0.5): weighted reciprocal rank fusion where the weights must sum to1.0.LinearCombinationReranker(weight=0.7, fill=1.0): blends vector and FTS scores directly;fillcontrols how strongly to penalize a result missing from one side.