Skip to main content
Applies to: Embedded ✅, Enterprise ✅ Reranking changes the order of records returned by an initial search. It can combine several ranked lists or use a model to score each candidate against the query. It cannot recover records that the initial searches did not retrieve.

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.
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.
  • Python: Install with pip install lancedb, save as rerank_search.py, then run python rerank_search.py.
  • TypeScript: Install with npm install @lancedb/lancedb, save as rerank_search.mts, then run node rerank_search.mts with Node.js 22.18 or later.
  • Rust: Download and extract the complete Rust examples, then run cargo run --locked --bin hybrid_search from the extracted directory.
The result includes _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

Use rerank_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=True to rerank_multivector(...) raises a ValueError if any of the input result sets is missing the _rowid column. Therefore, it’s recommended to add .with_row_id(True) to every table.search(...) call before reranking, or omit deduplicate=True if you don’t need it.
  • RRFReranker.rerank_multivector(...) always requires _rowid on its inputs, regardless of the deduplicate flag.

Implement a custom ranking policy

Python custom rerankers implement rerank_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

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. Calling rerank_vector or rerank_fts on an RRFReranker raises NotImplementedError.

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:

Linear combination

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:

MRR

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:

Cross encoder

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:

Building a custom reranker

You can build your own custom reranker in LanceDB by subclassing the base Reranker 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

The Reranker 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 extends CohereReranker 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.
The reranker receives and returns PyArrow tables. Use 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.
Hybrid search uses RRF by default. You do not need to call 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.
Normalization matters for algorithms that use raw scores, such as linear combination. RRF uses rank positions instead. Compare normalization settings only when the chosen reranker uses those scores. For score-based evaluation, the main built-in knobs are:
  • 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 to 1.0.
  • LinearCombinationReranker(weight=0.7, fill=1.0): blends vector and FTS scores directly; fill controls how strongly to penalize a result missing from one side.
A result on one dataset does not establish which reranker will work best on another. Include representative queries and measure both retrieval quality and ranking quality.

Historical evaluation example

The tables below preserve an earlier experiment comparing multiple rerankers on ~800 hybrid search queries. This is a modified version of an evaluation script by LlamaIndex that measures hit-rate @ top-k. The recorded results do not establish performance for current models, SDK releases or your dataset; treat them as an example of an evaluation format.

Using OpenAI text-embedding-ada-002

Vector Search baseline: 0.64

Using OpenAI text-embedding-3-small

Vector Search baseline: 0.59

Compare results on your workload

Build a set of representative queries with known relevant records. Compare retrieval alone with each reranker using the same candidate inputs and result limit. Record a relevance metric such as recall or nDCG alongside latency and provider cost. Include queries with no useful matches and queries containing exact names or identifiers. If the relevant records never reach the reranker, adjust retrieval first. Then change one ranking setting at a time and retain the configuration that meets your application’s quality and latency requirements.