Reranking Models

July 30, 2026 Ā· View on GitHub

Overview

Reranking models improve search relevance by re-scoring retrieved documents against a query. Unlike embeddings which compute similarity in vector space, rerankers directly score query-document pairs for more accurate relevance assessment.

Common Use Cases

  • Search Refinement: Re-order initial retrieval results for better accuracy
  • Retrieval-Augmented Generation (RAG): Select most relevant context for LLMs
  • Question Answering: Rank candidate passages by relevance to question
  • Document Filtering: Score and filter documents by relevance threshold

Interface

Creating a Reranker

from esperanto.factory import AIFactory

# Basic usage
reranker = AIFactory.create_reranker(
    provider="jina",
    model_name="jina-reranker-v2-base-multilingual"
)

# With configuration
reranker = AIFactory.create_reranker(
    provider="transformers",
    model_name="BAAI/bge-reranker-base",
    config={
        "timeout": 60.0
    }
)

Core Methods

rerank(query, documents, top_k=None)

Synchronous reranking of documents against a query.

query = "What is machine learning?"
documents = [
    "Machine learning is a subset of artificial intelligence",
    "The weather is nice today",
    "Python is a programming language used in ML"
]

response = reranker.rerank(query, documents, top_k=2)

# Results are sorted by relevance (highest first)
for result in response.results:
    print(f"Score: {result.relevance_score:.4f} - {result.document}")

arerank(query, documents, top_k=None)

Asynchronous reranking (identical interface to rerank).

response = await reranker.arerank(query, documents, top_k=2)

Parameters

Method Parameters

ParameterTypeDefaultDescription
querystrRequiredThe search query
documentslist[str]RequiredList of documents to rerank
top_kintNoneReturn only top K results (None = all)

Config Parameters

ParameterTypeDefaultDescription
timeoutfloat60.0Request timeout in seconds

Response Structure

All reranker providers return standardized RerankResponse objects:

response = reranker.rerank(query, documents, top_k=3)

# Results are pre-sorted by relevance score (highest first)
response.results[0].document           # Most relevant document text
response.results[0].relevance_score    # Normalized score (0-1)
response.results[0].index              # Original position in input list

# Metadata
response.model                         # Model name used

# Iterate results
for result in response.results:
    print(f"[{result.index}] Score: {result.relevance_score:.4f}")
    print(f"  {result.document[:100]}...")

Relevance Scores

  • Range: 0.0 to 1.0 (normalized across providers)
  • Interpretation: Higher scores indicate greater relevance
  • Ordering: Results are always sorted by score (descending)
  • Comparison: Scores are relative within a single rerank call

Provider Selection

→ See Provider Comparison for detailed comparison and selection guide.

Quick Provider Guide

  • Jina: Strong multilingual support, API-based, good performance
  • Voyage: Specialized for retrieval, excellent accuracy
  • Transformers: Local deployment, privacy-focused, various model choices

Examples

Basic Reranking

from esperanto.factory import AIFactory

reranker = AIFactory.create_reranker("jina", "jina-reranker-v2-base-multilingual")

query = "How to train neural networks?"
documents = [
    "Neural networks learn through backpropagation and gradient descent",
    "The weather forecast predicts rain tomorrow",
    "Training requires labeled data and computational resources",
    "Cooking pasta takes about 10 minutes"
]

response = reranker.rerank(query, documents, top_k=2)

print("Most relevant documents:")
for i, result in enumerate(response.results, 1):
    print(f"{i}. Score: {result.relevance_score:.4f}")
    print(f"   {result.document}\n")

RAG Pipeline Integration

from esperanto.factory import AIFactory

# Step 1: Initial retrieval with embeddings
embedder = AIFactory.create_embedding("openai", "text-embedding-3-small")
query = "What causes climate change?"

# Assume we retrieved 20 candidate documents
candidates = [...]  # Initial retrieval results

# Step 2: Rerank to get best matches
reranker = AIFactory.create_reranker("voyage", "rerank-1")
reranked = reranker.rerank(query, candidates, top_k=5)

# Step 3: Use top results as context for LLM
top_docs = [r.document for r in reranked.results]
context = "\n\n".join(top_docs)

model = AIFactory.create_language("anthropic", "claude-sonnet-5")
messages = [{
    "role": "user",
    "content": f"Context:\n{context}\n\nQuestion: {query}"
}]

answer = model.chat_complete(messages)
print(answer.content)

Async Batch Processing

reranker = AIFactory.create_reranker("transformers", "BAAI/bge-reranker-base")

queries = [
    "machine learning algorithms",
    "natural language processing",
    "computer vision applications"
]

document_sets = [
    [...],  # Documents for query 1
    [...],  # Documents for query 2
    [...]   # Documents for query 3
]

# Process multiple queries asynchronously
import asyncio

async def rerank_all():
    tasks = [
        reranker.arerank(q, docs, top_k=3)
        for q, docs in zip(queries, document_sets)
    ]
    return await asyncio.gather(*tasks)

results = await rerank_all()

Score Filtering

reranker = AIFactory.create_reranker("jina", "jina-reranker-v2-base-multilingual")

query = "Python web frameworks"
documents = [
    "Django is a high-level Python web framework",
    "Flask is a lightweight Python framework",
    "React is a JavaScript library",
    "FastAPI is a modern Python framework",
    "The ocean is very deep"
]

response = reranker.rerank(query, documents)

# Filter by relevance threshold
threshold = 0.5
relevant_docs = [
    r for r in response.results
    if r.relevance_score >= threshold
]

print(f"Found {len(relevant_docs)} relevant documents:")
for doc in relevant_docs:
    print(f"  [{doc.relevance_score:.4f}] {doc.document}")

Comparing Providers

from esperanto.factory import AIFactory

query = "quantum computing applications"
documents = [
    "Quantum computers use qubits for computation",
    "Classical computers use binary bits",
    "Quantum algorithms can solve certain problems faster"
]

providers = [
    ("jina", "jina-reranker-v2-base-multilingual"),
    ("voyage", "rerank-1"),
    ("transformers", "BAAI/bge-reranker-base")
]

for provider, model in providers:
    reranker = AIFactory.create_reranker(provider, model)
    response = reranker.rerank(query, documents)

    print(f"\n{provider} ({model}):")
    for r in response.results:
        print(f"  [{r.index}] Score: {r.relevance_score:.4f}")

Best Practices

When to Use Reranking

Use reranking when:

  • You have an initial candidate set from embedding-based retrieval
  • Precision is more important than speed
  • You need to score specific query-document pairs

Don't use reranking when:

  • You need to search millions of documents (use embeddings first)
  • Real-time response is critical (reranking adds latency)
  • You only have a single document to evaluate

Optimal Workflow

# 1. Cast wide net with embeddings (fast, approximate)
embedder = AIFactory.create_embedding("openai", "text-embedding-3-small")
# ... retrieve top 50-100 candidates

# 2. Refine with reranker (slower, accurate)
reranker = AIFactory.create_reranker("jina", "jina-reranker-v2-base-multilingual")
final_results = reranker.rerank(query, candidates, top_k=5)

# 3. Use top results

Performance Considerations

  • Batch size: Rerankers process query-document pairs, so 100 documents = 100 pairs
  • Latency: Expect 100-500ms for small batches, more for larger sets
  • Local vs API: Transformers provider runs locally (privacy, no costs), API providers are faster

Advanced Topics

See Also