Reranking
POST /v1/rerank speaks the Cohere request and response format: query,
documents, top_n. The model field is one of your configured model ids
(the id in a [[providers.models]] block - see Providers).
Request
curl -s http://localhost:8080/v1/rerank \
-H 'content-type: application/json' \
-d '{
"model": "rerank-english",
"query": "What is the capital of France?",
"documents": ["Paris is the capital of France.", "Berlin is in Germany."],
"top_n": 2
}'
Response
{
"results": [
{ "index": 0, "relevance_score": 0.98 },
{ "index": 1, "relevance_score": 0.02 }
],
"usage": { "search_units": 1, "total_tokens": 42, "tokens_estimated": true }
}
Results come back sorted by descending relevance_score. Each result’s
index points back to the position of that document in the request’s
documents array, not the sorted position.
Empty documents
documents must be non-empty. An empty list is rejected before any upstream
call with LM-2010 (400). See Error codes.
Billing: search units and tokens
Rerank billing units vary by upstream: Cohere and Pinecone bill in search
units (one unit is approximately one query over up to 100 documents),
while Jina and Voyage bill in tokens. Set cost_per_1k_searches on a
model’s [[providers.models]] block to price the search-unit case:
[[providers.models]]
id = "rerank-english"
upstream_id = "rerank-v3.5"
capabilities = ["rerank"]
cost_per_1k_searches = 2.0
Search units are counted on the lumen_rerank_search_units_total{model, provider} Prometheus counter for every request, upstream-reported when
available, otherwise a gateway estimate (usage.estimated: true).
Independently of the billing unit, every /v1/rerank response also carries a
usage.total_tokens count (ADR 003), for uniform token observability across
capabilities: Jina and Voyage surface their upstream-reported token count
unflagged; every other provider (Cohere, TEI, Pinecone, …) gets a
gateway-derived query + documents heuristic flagged
"tokens_estimated": true. This token count also feeds
lumen_tokens_total{capability="rerank",...} and usage_log, alongside the
search-unit accounting - see
Token accounting & cost.
One model, two capabilities
A single model id can serve both embed and rerank if the underlying
upstream model supports both, for example Cohere’s embed-v4.0:
[[providers.models]]
id = "embed-multilingual"
upstream_id = "embed-v4.0"
capabilities = ["embed", "rerank"]
Cross-vendor fallback
Like any capability, rerank can fall back across different provider kinds, through a virtual model. A three-hop chain across Cohere, Jina and Voyage survives any single vendor outage:
[[providers.models]]
id = "cohere/rerank-english"
upstream_id = "rerank-v3.5"
capabilities = ["rerank"]
[[virtual_models]]
id = "rerank-english"
capability = "rerank"
strategy = "fallback"
targets = [{ model = "cohere/rerank-english" }, { model = "jina-rerank" }, { model = "voyage-rerank" }]
The foundation model that actually served the request (primary or a fallback)
is reported in the x-lumen-model-used response header, and the path taken in
x-lumen-route. See Resilience.
Decision models as rerankers (Jev, Perplexity, OpenAI, Ollama, Cloudflare)
A rerank virtual model
whose target carries a remap is served by a decision model. The target
points at any foundation model that declares decisions (typesafe,
perplexity, openai, ollama or cloudflare kinds; a typesafe model can
no longer declare rerank itself). Each request becomes decision calls whose
state is {"query": ...} and whose questions, by default, are one
predicate (alias noul) per document, the document carried in structured
instructions; the predicate’s calibrated probability that the document is
relevant is the relevance_score. Jev receives the same bytes as before the
rename; an OpenAI target receives the structured instructions as compact JSON
text. The examples below use Jev.
[[providers]]
name = "typesafe"
kind = "typesafe"
api_key_env = "TYPESAFE_API_KEY"
[[providers.models]]
id = "jev"
upstream_id = "jev-latest"
capabilities = ["decisions"]
cost_per_1m_input = 0.042
# Optional remap fields: the question asked about every document. Unset
# fields default to a generic relevance question.
[[virtual_models]]
id = "jev-rerank"
capability = "rerank"
strategy = "single"
[[virtual_models.targets]]
model = "jev"
[virtual_models.targets.remap]
strategy = "predicate"
instructions = "Could `document` be the precedent cited in the query?"
criteria.true = "The document states the specific rule the query cites."
criteria.false = "The document is only on a similar topic."
- Besides
predicate, the remap strategies arescore,composite(weighted criteria) andchoice, and a staticcontextcan be added; see Virtual models.strategy = "noul"is still accepted as an alias ofpredicate, andlumen config migraterewrites it. - Clients call plain
/v1/rerank; ordering,top_n,return_documents,rank_fieldsand fallbacks (afallbackvirtual model whose second target iscohere/rerank-english, say) work as for any reranker. - Documents are packed into as few upstream calls as the target allows. The
default is at most 100 documents and about 48k estimated tokens per call,
4 calls in flight. A target’s own limits tighten that: Cloudflare packs at
most 64 documents per call; Ollama packs about 16k tokens per call with one
call in flight (a local GPU). A listwise
choiceover more documents than the target’s option limit (Ollama 26, otherwise 255) isLM-1001. A document longer than about 4,096 tokens is truncated first, like Cohere’s defaultmax_tokens_per_doc. - Refusals: OpenAI can refuse a question. A refused
predicateorscorequestion scores that document (or that composite criterion) 0.0; a refused listwisechoicefails the attempt ascontent_filter, so a virtual model withfallback_on = ["content_filter"]moves to its next target. Every refusal is counted inlumen_decision_refusals_total{model}, including those of achoicethat then falls back. - Because scores are calibrated probabilities, they are comparable across requests: a cut-off such as 0.5 means the same thing everywhere.
- Usage: the upstream
input_tokensisusage.total_tokens(unflagged when the upstream reports it); search units are derived. The decision model’scost_per_1m_inputbills per input token. - The remap belongs to a target of a virtual model. For per-tenant relevance
rules, put a
switchon the budget group in front of several such virtual models.
Providers
Which provider kinds serve rerank and their setup is in
Providers.