jina-reranker-m0 - a reranking-only provider for a self-hosted server.
provider = ExAgent.Providers.JinaRerankerM0.new(base_url: System.fetch_env!("RERANKER_URL"))
{:ok, result} = ExAgent.rerank(provider, "who restarts processes?", chunks, top_n: 5)
best = ExAgent.Reranking.take(result, chunks)It implements ExAgent.Provider.rerank/4 only. chat/3 returns
{:error, %ExAgent.Error{type: :unsupported}}, and there is no embed/3 - a
reranker scores query/document pairs and has no single-text vector to give.
Where it belongs in retrieval
Reranking is the second stage, not a replacement for the first:
{:ok, hits} = ExAgent.embed(embedder, [query], task: :retrieval, args: [prompt_name: :query])
shortlist = vector_search(hits, limit: 100)
{:ok, ranked} = ExAgent.rerank(reranker, query, shortlist, top_n: 10)Embeddings compare vectors computed independently, which is what makes them fast enough for a corpus. A cross-encoder reads the query and one document together - more accurate, and far too slow to run over everything. Batches are capped at 512 documents, which is the shape of the intended use.
Behind Modal's proxy auth
ExAgent.Providers.JinaRerankerM0.new(
base_url: System.fetch_env!("MODAL_RERANKER_URL"),
api_key: System.fetch_env!("MODAL_API_KEY"),
headers: [
{"Modal-Key", System.fetch_env!("MODAL_KEY")},
{"Modal-Secret", System.fetch_env!("MODAL_SECRET")}
]
)Scores
Higher is more relevant, and that is the only guarantee - see
ExAgent.Reranking on why an absolute cutoff does not port between models.
The server contract
Verified against a running deployment. POST {base_url}/v1/rerank:
{"query": "...", "documents": ["..."], "top_n": 5, "return_documents": false}answering
{"model": "...",
"results": [{"index": 0, "relevance_score": 0.28, "document": {"text": "..."}}]}Unknown body fields are rejected by the server, so unrecognized options are
reported rather than forwarded. return_documents defaults to true there and
false here: :index already identifies each document, and sending a corpus
back to have it re-quoted is waste.
This is not the shape of Jina's hosted api.jina.ai/v1/rerank service, whose
documents accept {"text": ...} / {"image": ...} objects for multimodal
ranking. Pointing this provider there will not work.
Summary
Types
@type t() :: %ExAgent.Providers.JinaRerankerM0{ api_key: String.t() | nil, base_url: String.t(), headers: [{String.t(), String.t()}], model: String.t(), receive_timeout: pos_integer(), req: Req.Request.t() | nil }
Functions
Creates a provider with validated options and an initialized Req client.
Options
:base_url(String.t/0) - Required. Root URL of the reranker; requests go to#{base_url}/v1/rerank:api_key- Sugar for anAuthorization: Bearerheader The default value isnil.:model(String.t/0) - Sent in the request body and recorded on the result The default value is"jina-reranker-m0".:headers(list ofterm/0) - Extra request headers, e.g. Modal'sModal-Key/Modal-SecretThe default value is[].:receive_timeout(pos_integer/0) - Milliseconds to wait for the response, per call; override per request withreceive_timeout:onrerank/4The default value is300000.