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
| Parameter | Type | Default | Description |
|---|---|---|---|
query | str | Required | The search query |
documents | list[str] | Required | List of documents to rerank |
top_k | int | None | Return only top K results (None = all) |
Config Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
timeout | float | 60.0 | Request 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
- Transformers Advanced Features: docs/advanced/transformers-features.md
- Timeout Configuration: docs/advanced/timeout-configuration.md
- Resource Management: docs/advanced/connection-resource-management.md