Skip to content
bits
Retrieval without tears · Lesson 6 of 9

Reranking

Tutor:

Embedding search is fast because it does the hard work ahead of time. Every chunk was turned into a vector once; at question time you only embed the question and compare numbers. The price: the model never reads the question and the chunk together. It's matching two summaries.

A reranker does read them together. You give it the question and a list of candidate chunks, and it scores each pair, with the whole question in view. That's more accurate, and much slower per chunk, so you can't run it over your whole library. You run it on a shortlist.

Tutor:

The pattern is retrieve wide, then rerank narrow. Anthropic's setup pulled the top 150 chunks with hybrid search, reranked them, and kept the top 20 for Claude. Adding that step took the miss rate from 2.9% to 1.9%. All together, contextual retrieval plus reranking cut misses by two thirds from where plain embeddings started.

Hybrid search order vs After rerankingillustrative: made-up numbers that show the idea, not output from a real modelcompare

promptCan I claim on a battery that's 18 months old?

Hybrid search order

1. Frames: lifetime warranty for the first owner. 2. Battery care: store at 40–60% charge in winter. 3. E-bike batteries: 2-year warranty from delivery, covering capacity below 70%.

After reranking

1. E-bike batteries: 2-year warranty from delivery, covering capacity below 70%. 2. Claims must be filed within 30 days of noticing the fault. 3. Battery care: store at 40–60% charge in winter.

Tutor:

The first list matched the words “battery” and “warranty”. The reranker read the question, saw it was about age and eligibility, and moved the 2-year rule to the top.

As of October 2026, Voyage's current rerankers are rerank-3 (most accurate) and rerank-3-lite (faster and cheaper). It's one HTTP call:

// Rerank candidate chunks against the question. Needs VOYAGE_API_KEY.
export async function rerank(query: string, documents: string[], topK = 20) {
const res = await fetch("https://ai.mongodb.com/v1/rerank", {
method: "POST",
headers: {
"content-type": "application/json",
authorization: `Bearer ${process.env.VOYAGE_API_KEY}`,
},
body: JSON.stringify({ query, documents, model: "rerank-3", top_k: topK }),
});
if (!res.ok) throw new Error(`Voyage: ${res.status} ${await res.text()}`);
const json = (await res.json()) as { data: { index: number; relevance_score: number }[] };
return json.data; // best first; index points into `documents`
}
TypeScriptUTF-8● lines 9–9: the request
Tutor:

Example output for the question above (your scores will differ):

OUTPUT
npx tsx try-rerank.ts
0.91 #2 E-bike batteries: 2-year warranty from delivery…
0.62 #4 Claims must be filed within 30 days…
0.38 #1 Battery care: store at 40–60% charge…
example output, not a live run
Tutor:

Reranking adds a network call to every question, and the bill grows with the number of chunks you send it. Anthropic's advice: try a few shortlist sizes on your own questions and pick the best trade-off.

quick check+20 neurons
Tutor:

A reranker is more accurate than embedding search. Why not skip embeddings and rerank your whole library for every question?

    Type your answer or tap an option · Enter checks

    quick check+20 neurons
    Tutor:

    Put the steps in order for one question.

      Type your answer or tap an option · Enter checks