Reranker Stage · SOP
Third-person analytical view of how a mature RAG pipeline thinks about the
reranker. The skill is for an LLM agent that writes / reviews / debugs
retrieval code — it teaches the cross-framework reranking discipline, not one
vendor's API. For the per-framework API, descend to [[llamaindex]]
(node postprocessors) or [[agentsop-hybrid-retrieval]] (the recall stage that feeds
the reranker).
This is the C4 gap skill in the Phase-D enhance pass. The reranker SOP
existed only buried inside [[llamaindex]] (OP-03 AddReranker, Stage 3 step 7,
anti-pattern A6). It is the highest-ROI single addition to a naive RAG
pipeline, so it earns a standalone overlay.
1 · 何时激活 (Activation Rules)
Activate when any holds:
- A RAG pipeline's answer quality has plateaued after the cheap knobs
(prompt, embedding model, chunk size) are exhausted —
[[llamaindex]] Stage 3
lists reranking as the last optimization step, deliberately.
- Diagnostics show the relevant document is in top-k but buried — high
hit-rate, low MRR, wrong top-1. This is LlamaIndex failure modes #1 / #10
([[llamaindex]]
OP-03).
- The LLM context window is under pressure — too many marginal chunks
inflate cost, latency, and "lost-in-the-middle" degradation. A reranker lets
you retrieve 50 and feed 5.
- A user asks where to add a reranker, how to tune N vs k, or API vs local.
Do not activate (boundary — see §6):
- Recall is the bottleneck: the right doc is not in top-N at all. A
reranker can only reorder what retrieval already found — fix retrieval,
hybrid (
[[agentsop-hybrid-retrieval]]), or chunking first.
- top-k is already small (≤5) and answers are correct — no plateau.
- A hard sub-100ms path where the extra round-trip is unaffordable and quality
is already acceptable.
2 · 核心心智模型 (Core Mental Model)
The one sentence
Retrieve wide for recall with a cheap bi-encoder; rerank narrow for
precision with an expensive cross-encoder that sees query + document
together — something the bi-encoder structurally could not do.
Why two stages exist at all
The retriever (bi-encoder / vector search) embeds the query and every document
separately, offline. Similarity is a dot product of two vectors that never
met. This is fast (vectors are precomputed; ANN search is sub-linear) but
lossy: the document's vector is a single "topic average" computed without
knowledge of the query.
A cross-encoder takes [query, document] as a single joint input and
runs full attention across both, emitting one relevance score. It sees exactly
which query token matches which document token. This is far more accurate — and
far more expensive: it cannot be precomputed, so it runs once per
(query, candidate) pair at query time. Scoring 1M docs this way is infeasible;
scoring 20-50 is cheap.
query ─┐ query ─┐
├─ dot product (precomputed) ├─► [CROSS-ENCODER] ─► score
doc ─┘ ← bi-encoder, FAST, lossy doc ─┘ joint attention, SLOW, sharp
RECALL stage (retrieve top-50) PRECISION stage (rerank → top-5)
The reranker is the bridge: it spends cross-encoder accuracy on a small
candidate set the bi-encoder produced cheaply. Wide net, sharp knife.
The order law (inherited from [[llamaindex]] Stage 3)
Prompts first, reranking last. Reranking is high-impact but expensive —
exhaust the cheap knobs (prompt, embed model, chunk size, hybrid) before
spending per-query cross-encoder latency. But once those are spent, the
reranker is usually the single biggest remaining lever (5-15pp
faithfulness lift on noisy corpora — [[llamaindex]] OP-03).
What a reranker is NOT
- Not a recall fix — it reorders, never retrieves (§6).
- Not a chunking fix — it scores whole candidates, it does not resize them.
- Not free — every reranked candidate is an inference (local) or a billed unit
(API).
3 · SOP 工作流 (Agentic Protocol)
Each stage gates the next. Never skip the baseline measurement.
Stage 0 — Confirm the lever is real
Before adding anything, prove the symptom is precision, not recall:
- Run the existing pipeline against ~30-50 labeled QA pairs.
- Record hit-rate@N (is the gold doc in top-N?) and MRR (how high?).
- If hit-rate is low → recall problem → STOP, fix retrieval / hybrid
(
[[agentsop-hybrid-retrieval]]) / chunking. A reranker will not help.
- If hit-rate is high but MRR is low → precision problem → the gold doc is
buried → a reranker is the right lever. Proceed.
Stage 1 — Retrieve wide
Raise the retriever's top_k (or top_n) to 20-50. This is the "recall"
stage: cast a wide net so the reranker has the gold doc to find. Hybrid
retrieval ([[agentsop-hybrid-retrieval]]) feeds the reranker an even better candidate
pool because it adds lexical recall the dense retriever misses.
Stage 2 — Insert the reranker
Add a reranker as a post-retrieval step (LlamaIndex node postprocessor;
LangChain ContextualCompressionRetriever — §7). Pick the model per §4 OP-03.
It consumes the wide candidate list and re-scores every candidate against the
query with a cross-encoder.
Stage 3 — Keep narrow
Truncate to top-k = 3-5 after rerank. This is what reaches the synthesizer.
The whole point: the LLM now sees a small, high-precision context instead of a
large noisy one.
Stage 4 — Measure the lift, gate the change
Re-run the same eval set. Compare before vs after on {MRR, faithfulness,
relevancy, p95 latency, per-query cost}. Keep the reranker only if
the precision lift justifies the added latency/cost (§5). A reranker that adds
300ms for +1pp is not always worth shipping. Pin N and k as tuned constants.
4 · 操作模型 (Operation Models)
Each operation: Trigger / Action / Output / Evidence. Full machine-readable
list in intermediate/operation_candidates.json.
OP-01 ConfirmPrecisionNotRecall
- Trigger: Considering a reranker; haven't proven the symptom is precision.
- Action: Measure hit-rate@N and MRR on labeled QA. High hit-rate + low MRR
⇒ precision problem ⇒ reranker is right. Low hit-rate ⇒ recall problem ⇒ STOP.
- Output: Go/no-go decision backed by a number, not a hunch.
- Evidence: [[llamaindex]]
OP-03 (#1/#10 = right doc in top-k, wrong top-1);
[[agentsop-hybrid-retrieval]] for the recall path.
OP-02 WidenThenNarrow
- Trigger: Reranker confirmed; pipeline still on naive
top_k=4.
- Action: Retrieve top-N = 20-50, rerank, keep top-k = 3-5. Embed the
two numbers as named, evaluated constants.
- Output: A two-stage retrieve→rerank pipeline with a high-precision tail.
- Evidence: [[llamaindex]] Stage 3 step 7 ("widen top_k to 20-50, rerank to
3-5");
OP-03.
OP-03 ChooseRerankerModel
- Trigger: Reranker stage exists; model not yet chosen.
- Action: Pick by constraint:
- Cohere Rerank / Voyage rerank (API) — fastest to ship, no GPU, strong
multilingual; cost per 1k searches, data leaves your boundary.
- bge-reranker (bge-reranker-v2-m3 / large) — local — open-weights,
self-hosted, no per-call fee, strong on multilingual; needs a GPU for low
latency, you own ops.
- SentenceTransformer cross-encoder (e.g. ms-marco-MiniLM) — light,
CPU-runnable for small N, the lowest-dependency local option; weaker than
bge-large but cheap.
- ColBERT (late-interaction) — middle ground: token-level interaction,
precomputable, scales to larger N than a full cross-encoder.
- Output: A model justified by latency budget, cost ceiling, data-residency,
and language mix.
- Evidence: [[llamaindex]]
OP-03 (CohereRerank / SentenceTransformerRerank /
ColBERT named); external: "cohere rerank", "bge-reranker", "cross-encoder
rerank RAG".
OP-04 BudgetLatencyAndCost
- Trigger: Before shipping; reranker adds a per-query inference/billing unit.
- Action: Measure p95 added by the rerank call at the chosen N. API rerankers
add a network round-trip (~tens-hundreds ms) + per-search cost; local models
add GPU/CPU inference time. Latency scales with N, not k — so over-large N
is the latency killer (§6).
- Output: p95 and $/query deltas attached to the change; ship only if the
precision lift clears the bar.
- Evidence: [[llamaindex]] Stage 3 ("high-impact but expensive — exhaust
cheap knobs first"); §5 Dilemma 1.
OP-05 TuneNvsK
- Trigger: Reranker live; N/k still at defaults; want to optimize the
precision/latency frontier.
- Action: Sweep N ∈ {20, 30, 50} holding k fixed (recall ceiling of the
candidate pool), then sweep k ∈ {3, 5, 8} holding N fixed (how much
context the LLM sees). Pick the smallest N that saturates hit-rate and the
smallest k that saturates faithfulness.
- Output: Tuned (N, k) on the cost/quality frontier, not guessed.
- Evidence: [[llamaindex]]
OP-02 TuneChunkSize (same sweep-and-pin
discipline applied to N/k); Stage 3 step 7.
OP-06 RerankAfterHybrid
- Trigger: Traffic has lexical-identity queries (codes, SKUs, symbols) AND a
precision plateau.
- Action: Use hybrid retrieval (
[[agentsop-hybrid-retrieval]], BM25 + dense) for the
wide stage, then rerank its fused candidate list. Hybrid maximizes recall into
the pool; rerank maximizes precision out of it. They compose.
- Output: Best-of-both — lexical recall + cross-encoder precision.
- Evidence: [[agentsop-hybrid-retrieval]] (recall stage); [[llamaindex]]
OP-04
AddHybridBM25 + OP-03 AddReranker (sequential in Stage 3).
OP-07 GateOnEval
- Trigger: Any reranker add/change.
- Action: Compare before/after on {MRR, faithfulness, relevancy, p95,
$/query}. Keep only on net-positive. Treat as a regression test for future
retriever changes.
- Output: Quantitative justification; the reranker is now eval-gated.
- Evidence: [[llamaindex]]
OP-10 EvalLoop, Stage 2 ("eval loop before
optimizing anything"), Stage 4.
5 · 困境决策案例 (Dilemma Cases)
Dilemma 1 — Rerank latency vs answer quality
困境: A reranker reliably lifts precision but adds a per-query stage:
network round-trip (API) or GPU inference (local). On a latency-sensitive
surface (chat, autocomplete) the added p95 may violate the SLA even when quality
improves.
约束: Cross-encoder cost is per (query, candidate) pair and scales with N
([[llamaindex]] Stage 3: reranking is "high-impact but expensive"). Latency is
dominated by N, not k. The bi-encoder stage was chosen precisely because it is
fast; the reranker reintroduces query-time compute.
决策步骤:
- Measure baseline p95 and the SLA headroom.
- Measure rerank-stage p95 at the smallest viable N (start N=20).
- If it fits headroom and quality lifts ≥ a meaningful threshold → ship.
- If it does not fit → shrink N (OP-05), switch to a lighter model
(MiniLM cross-encoder, ColBERT), or rerank async/cache for repeat queries.
- If still over budget and quality is already acceptable → do not rerank
(§6 boundary).
结果: Reranking is the highest-ROI lever only when latency headroom exists.
The decision is SLA-driven, not quality-driven in isolation. Smaller N often
recovers most of the lift at a fraction of the latency.
可提取的操作: OP-04, OP-05. Anti-pattern A3 (over-large N).
Dilemma 2 — API reranker (Cohere/Voyage) vs local model (bge / cross-encoder)
困境: The hosted API ships in an afternoon, needs no GPU, and tracks SOTA —
but bills per search and sends query + candidates to a third party. A local
bge-reranker has zero per-call fee and keeps data in-boundary — but needs a GPU,
ops ownership, and model-update discipline.
约束: Per-query cost (API) vs fixed infra cost + ops (local); data-residency
/ compliance; latency (API adds network hop, local adds inference); team's
GPU/MLOps capacity.
决策步骤:
- Data residency hard constraint (PII, regulated)? → local (bge / ColBERT),
decision over.
- Estimate query volume × API price vs GPU rental. Low/spiky volume → API
usually cheaper; high steady volume → local amortizes.
- No GPU and no MLOps appetite? → API (or CPU MiniLM for tiny N).
- Multilingual corpus? Both Cohere and bge-reranker-v2-m3 are strong — let
cost/residency decide.
- Whichever: wrap the call behind a single
rerank(query, nodes) -> nodes
seam so swapping API↔local is a one-line change.
结果: Default to the API to validate the lift cheaply (prove the reranker
helps before investing in infra), then migrate to local once volume,
cost, or residency justify it. The abstraction seam makes the migration safe.
可提取的操作: OP-03, OP-04. Anti-pattern A5 (vendor lock-in, no seam).
6 · 反模式与边界 (Anti-patterns & Boundaries)
Anti-patterns
| # |
Anti-pattern |
Correct move |
| A1 |
Reranking to fix recall — gold doc isn't in top-N |
Fix retrieval / hybrid ([[agentsop-hybrid-retrieval]]) / chunking; a reranker only reorders what's already retrieved |
| A2 |
Naive similarity_top_k=N then feed all N to the LLM, no rerank |
Widen N and rerank to top-3-5 ([[llamaindex]] A6) |
| A3 |
Over-large N (rerank 200+ candidates) |
Latency scales with N; pick the smallest N that saturates hit-rate (OP-05) |
| A4 |
Add reranker first, before prompt/embed/chunk/hybrid |
Order law: reranking is last ([[llamaindex]] Stage 3); cheapest knobs first |
| A5 |
Hard-wire one vendor SDK throughout the pipeline |
Hide behind a rerank(query, nodes) seam so API↔local swaps in one line (Dilemma 2) |
| A6 |
Ship reranker without before/after eval |
Gate on {MRR, faithfulness, p95, $/query} (OP-07); a reranker that costs latency for no lift is removed |
| A7 |
Keep N=k (rerank n candidates, return n) |
Reranking only helps when k < N — you must discard the low-scored tail |
| A8 |
Re-embed / re-chunk hoping to fix "wrong top-1" |
If the right doc is present but buried, that's a rerank job, not a re-ingest |
Boundaries — when not to add a reranker
- B1 — Recall is the bottleneck: hit-rate@N low ⇒ the answer isn't in the
pool. Reranking is a no-op. Fix retrieval first (OP-01,
[[agentsop-hybrid-retrieval]]).
- B2 — Already narrow & correct: top-k ≤ 5 and answers right ⇒ no plateau,
no lever.
- B3 — Hard real-time / sub-100ms: the extra round-trip blows the budget and
quality is acceptable ⇒ skip (Dilemma 1).
- B4 — Tiny static corpus (prompt-stuffable, <100k tokens): no retrieval
stage to rerank ([[llamaindex]] B1).
PR-review smells (instant red flags)
index.as_query_engine(similarity_top_k=20) with no node postprocessor →
A2 ([[llamaindex]] PR-smell).
- Reranker added but
top_k still 4 → A7 (N=k, reranker is a no-op).
- A vendor rerank SDK imported in >1 module → A5 (no seam).
- A reranker PR with no eval delta in the description → A6.
- "Added reranker to improve recall" in a commit message → A1 (category error).
7 · 跨框架对照 (Cross-framework Mapping)
The reranker is one stage with the same shape everywhere: consume a wide
candidate list, re-score with a cross-encoder, truncate to top-k.
| Framework / vendor |
Reranker primitive |
Notes |
LlamaIndex ([[llamaindex]]) |
Node postprocessor: CohereRerank, SentenceTransformerRerank, ColbertRerank, LLMRerank passed as node_postprocessors=[...] to the query engine; widen similarity_top_k, set top_n on the reranker |
The canonical reference; OP-03 AddReranker, Stage 3 step 7, A6 |
| LangChain |
ContextualCompressionRetriever wrapping a base retriever with a CohereRerank / CrossEncoderReranker / LLMChainExtractor compressor |
Base retriever returns N, compressor reranks/filters to k |
| Cohere Rerank API |
cohere.rerank(query, documents, top_n, model="rerank-v3.5") |
Hosted cross-encoder; multilingual; per-search billing |
| Voyage rerank API |
voyageai.rerank(query, documents, model="rerank-2", top_k) |
Hosted; pairs well with Voyage embeddings |
| bge-reranker (local) |
FlagReranker("BAAI/bge-reranker-v2-m3") / via sentence-transformers CrossEncoder |
Open-weights, self-hosted, no per-call fee, GPU recommended |
| SentenceTransformers cross-encoder |
CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2").predict([(q, d), ...]) |
Lightest local option; CPU-viable for small N |
| ColBERT / RAGatouille |
Late-interaction reranker; token-level scoring, precomputable |
Scales to larger N than a full cross-encoder |
| Haystack |
TransformersSimilarityRanker / CohereRanker component in the pipeline |
Same wide→narrow shape, pipeline-component form |
Activate this skill for the reranking decision (whether, where, how wide,
which model, what it costs). Descend to [[llamaindex]] for node-postprocessor
wiring, and to [[agentsop-hybrid-retrieval]] for the recall stage that feeds it.
References
references/R1-source-evidence.md — every cited claim resolved to a source line.
intermediate/operation_candidates.json — machine-readable operation list.
Primary sources (cited inline above)
[[llamaindex]] SKILL — OP-03 AddReranker, OP-02 TuneChunkSize,
OP-04 AddHybridBM25, OP-10 EvalLoop; Stage 2/3/4; anti-patterns A6/A3;
failure modes #1/#10; the "prompts first, reranking last" order law.
[[agentsop-hybrid-retrieval]] — the wide/recall stage (BM25 + dense) that feeds the
reranker; lexical-identity recall.
- External: "cohere rerank" (rerank-v3.5, hosted cross-encoder, per-search
billing, multilingual); "bge-reranker" (BAAI bge-reranker-v2-m3 / large,
open-weights local cross-encoder); "cross-encoder rerank RAG" (bi-encoder
retrieve → cross-encoder rerank, joint query+doc attention, the two-stage
recall→precision pattern).
1---2name: agentsop-reranker-stage3description: Adds and tunes a reranker stage for RAG using the retrieve-wide, rerank-narrow pattern. Use when relevant documents appear in the initial top-N but are buried by noise, top-1 precision or MRR is low despite adequate recall, or too many marginal chunks consume context. Covers cross-encoder, API, and local rerankers; N-to-k selection; and latency/cost tradeoffs. Do not use when retrieval recall itself is failing.4---56# Reranker Stage · SOP78> Third-person analytical view of how a mature RAG pipeline *thinks* about the9> reranker. The skill is for an LLM agent that writes / reviews / debugs10> retrieval code — it teaches the cross-framework reranking discipline, not one11> vendor's API. For the per-framework API, descend to `[[llamaindex]]`12> (node postprocessors) or `[[agentsop-hybrid-retrieval]]` (the recall stage that feeds13> the reranker).1415This is the **C4 gap skill** in the Phase-D enhance pass. The reranker SOP16existed only buried inside `[[llamaindex]]` (`OP-03 AddReranker`, Stage 3 step 7,17anti-pattern A6). It is the **highest-ROI single addition** to a naive RAG18pipeline, so it earns a standalone overlay.1920---2122## 1 · 何时激活 (Activation Rules)2324Activate when **any** holds:25261. A RAG pipeline's answer quality has **plateaued** after the cheap knobs27 (prompt, embedding model, chunk size) are exhausted — `[[llamaindex]]` Stage 328 lists reranking as the **last** optimization step, deliberately.292. Diagnostics show the **relevant document is in top-k but buried** — high30 hit-rate, low MRR, wrong top-1. This is LlamaIndex failure modes **#1 / #10**31 ([[llamaindex]] `OP-03`).323. The LLM **context window is under pressure** — too many marginal chunks33 inflate cost, latency, and "lost-in-the-middle" degradation. A reranker lets34 you retrieve 50 and feed 5.354. A user asks **where to add a reranker, how to tune N vs k, or API vs local**.3637Do **not** activate (boundary — see §6):3839- **Recall is the bottleneck**: the right doc is *not in top-N at all*. A40 reranker can only reorder what retrieval already found — fix retrieval,41 hybrid (`[[agentsop-hybrid-retrieval]]`), or chunking first.42- top-k is already small (≤5) and answers are correct — no plateau.43- A hard sub-100ms path where the extra round-trip is unaffordable and quality44 is already acceptable.4546---4748## 2 · 核心心智模型 (Core Mental Model)4950### The one sentence5152> **Retrieve wide for recall with a cheap bi-encoder; rerank narrow for53> precision with an expensive cross-encoder that sees query + document54> together — something the bi-encoder structurally could not do.**5556### Why two stages exist at all5758The retriever (bi-encoder / vector search) embeds the query and every document59**separately, offline**. Similarity is a dot product of two vectors that never60met. This is *fast* (vectors are precomputed; ANN search is sub-linear) but61*lossy*: the document's vector is a single "topic average" computed without62knowledge of the query.6364A **cross-encoder** takes `[query, document]` as a **single joint input** and65runs full attention across both, emitting one relevance score. It sees exactly66which query token matches which document token. This is far more accurate — and67far more expensive: it cannot be precomputed, so it runs **once per68(query, candidate) pair at query time**. Scoring 1M docs this way is infeasible;69scoring **20-50** is cheap.7071```72 query ─┐ query ─┐73 ├─ dot product (precomputed) ├─► [CROSS-ENCODER] ─► score74 doc ─┘ ← bi-encoder, FAST, lossy doc ─┘ joint attention, SLOW, sharp75 RECALL stage (retrieve top-50) PRECISION stage (rerank → top-5)76```7778The reranker is the bridge: it spends cross-encoder accuracy on a small79candidate set the bi-encoder produced cheaply. **Wide net, sharp knife.**8081### The order law (inherited from `[[llamaindex]]` Stage 3)8283> Prompts first, reranking last. Reranking is high-impact but expensive —84> exhaust the cheap knobs (prompt, embed model, chunk size, hybrid) before85> spending per-query cross-encoder latency. But once those are spent, the86> reranker is usually the **single biggest remaining lever** (5-15pp87> faithfulness lift on noisy corpora — [[llamaindex]] `OP-03`).8889### What a reranker is NOT9091- Not a recall fix — it reorders, never retrieves (§6).92- Not a chunking fix — it scores whole candidates, it does not resize them.93- Not free — every reranked candidate is an inference (local) or a billed unit94 (API).9596---9798## 3 · SOP 工作流 (Agentic Protocol)99100Each stage gates the next. Never skip the baseline measurement.101102### Stage 0 — Confirm the lever is real103104Before adding anything, prove the symptom is *precision*, not *recall*:1051061. Run the existing pipeline against ~30-50 labeled QA pairs.1072. Record **hit-rate@N** (is the gold doc in top-N?) and **MRR** (how high?).1083. **If hit-rate is low** → recall problem → STOP, fix retrieval / hybrid109 (`[[agentsop-hybrid-retrieval]]`) / chunking. A reranker will not help.1104. **If hit-rate is high but MRR is low** → precision problem → the gold doc is111 buried → a reranker is the right lever. Proceed.112113### Stage 1 — Retrieve wide114115Raise the retriever's `top_k` (or `top_n`) to **20-50**. This is the "recall"116stage: cast a wide net so the reranker has the gold doc to find. Hybrid117retrieval (`[[agentsop-hybrid-retrieval]]`) feeds the reranker an even better candidate118pool because it adds lexical recall the dense retriever misses.119120### Stage 2 — Insert the reranker121122Add a reranker as a post-retrieval step (LlamaIndex node postprocessor;123LangChain `ContextualCompressionRetriever` — §7). Pick the model per §4 OP-03.124It consumes the wide candidate list and re-scores every candidate against the125query with a cross-encoder.126127### Stage 3 — Keep narrow128129Truncate to **top-k = 3-5** after rerank. This is what reaches the synthesizer.130The whole point: the LLM now sees a *small, high-precision* context instead of a131large noisy one.132133### Stage 4 — Measure the lift, gate the change134135Re-run the same eval set. Compare **before vs after** on {MRR, faithfulness,136relevancy, **p95 latency**, **per-query cost**}. Keep the reranker **only if**137the precision lift justifies the added latency/cost (§5). A reranker that adds138300ms for +1pp is not always worth shipping. Pin N and k as tuned constants.139140---141142## 4 · 操作模型 (Operation Models)143144Each operation: **Trigger / Action / Output / Evidence**. Full machine-readable145list in `intermediate/operation_candidates.json`.146147### OP-01 ConfirmPrecisionNotRecall148- **Trigger**: Considering a reranker; haven't proven the symptom is precision.149- **Action**: Measure hit-rate@N and MRR on labeled QA. High hit-rate + low MRR150 ⇒ precision problem ⇒ reranker is right. Low hit-rate ⇒ recall problem ⇒ STOP.151- **Output**: Go/no-go decision backed by a number, not a hunch.152- **Evidence**: [[llamaindex]] `OP-03` (#1/#10 = right doc in top-k, wrong top-1);153 [[agentsop-hybrid-retrieval]] for the recall path.154155### OP-02 WidenThenNarrow156- **Trigger**: Reranker confirmed; pipeline still on naive `top_k=4`.157- **Action**: Retrieve **top-N = 20-50**, rerank, keep **top-k = 3-5**. Embed the158 two numbers as named, evaluated constants.159- **Output**: A two-stage retrieve→rerank pipeline with a high-precision tail.160- **Evidence**: [[llamaindex]] Stage 3 step 7 ("widen top_k to 20-50, rerank to161 3-5"); `OP-03`.162163### OP-03 ChooseRerankerModel164- **Trigger**: Reranker stage exists; model not yet chosen.165- **Action**: Pick by constraint:166 - **Cohere Rerank / Voyage rerank (API)** — fastest to ship, no GPU, strong167 multilingual; cost per 1k searches, data leaves your boundary.168 - **bge-reranker (bge-reranker-v2-m3 / large) — local** — open-weights,169 self-hosted, no per-call fee, strong on multilingual; needs a GPU for low170 latency, you own ops.171 - **SentenceTransformer cross-encoder (e.g. ms-marco-MiniLM)** — light,172 CPU-runnable for small N, the lowest-dependency local option; weaker than173 bge-large but cheap.174 - **ColBERT (late-interaction)** — middle ground: token-level interaction,175 precomputable, scales to larger N than a full cross-encoder.176- **Output**: A model justified by latency budget, cost ceiling, data-residency,177 and language mix.178- **Evidence**: [[llamaindex]] `OP-03` (CohereRerank / SentenceTransformerRerank /179 ColBERT named); external: "cohere rerank", "bge-reranker", "cross-encoder180 rerank RAG".181182### OP-04 BudgetLatencyAndCost183- **Trigger**: Before shipping; reranker adds a per-query inference/billing unit.184- **Action**: Measure p95 added by the rerank call at the chosen N. API rerankers185 add a network round-trip (~tens-hundreds ms) + per-search cost; local models186 add GPU/CPU inference time. Latency scales with **N**, not k — so over-large N187 is the latency killer (§6).188- **Output**: p95 and $/query deltas attached to the change; ship only if the189 precision lift clears the bar.190- **Evidence**: [[llamaindex]] Stage 3 ("high-impact but expensive — exhaust191 cheap knobs first"); §5 Dilemma 1.192193### OP-05 TuneNvsK194- **Trigger**: Reranker live; N/k still at defaults; want to optimize the195 precision/latency frontier.196- **Action**: Sweep **N ∈ {20, 30, 50}** holding k fixed (recall ceiling of the197 candidate pool), then sweep **k ∈ {3, 5, 8}** holding N fixed (how much198 context the LLM sees). Pick the smallest N that saturates hit-rate and the199 smallest k that saturates faithfulness.200- **Output**: Tuned (N, k) on the cost/quality frontier, not guessed.201- **Evidence**: [[llamaindex]] `OP-02 TuneChunkSize` (same sweep-and-pin202 discipline applied to N/k); Stage 3 step 7.203204### OP-06 RerankAfterHybrid205- **Trigger**: Traffic has lexical-identity queries (codes, SKUs, symbols) AND a206 precision plateau.207- **Action**: Use hybrid retrieval (`[[agentsop-hybrid-retrieval]]`, BM25 + dense) for the208 wide stage, then rerank its fused candidate list. Hybrid maximizes recall into209 the pool; rerank maximizes precision out of it. They **compose**.210- **Output**: Best-of-both — lexical recall + cross-encoder precision.211- **Evidence**: [[agentsop-hybrid-retrieval]] (recall stage); [[llamaindex]] `OP-04`212 AddHybridBM25 + `OP-03` AddReranker (sequential in Stage 3).213214### OP-07 GateOnEval215- **Trigger**: Any reranker add/change.216- **Action**: Compare before/after on {MRR, faithfulness, relevancy, p95,217 $/query}. Keep only on net-positive. Treat as a regression test for future218 retriever changes.219- **Output**: Quantitative justification; the reranker is now eval-gated.220- **Evidence**: [[llamaindex]] `OP-10 EvalLoop`, Stage 2 ("eval loop before221 optimizing anything"), Stage 4.222223---224225## 5 · 困境决策案例 (Dilemma Cases)226227### Dilemma 1 — Rerank latency vs answer quality228229**困境**: A reranker reliably lifts precision but adds a per-query stage:230network round-trip (API) or GPU inference (local). On a latency-sensitive231surface (chat, autocomplete) the added p95 may violate the SLA even when quality232improves.233234**约束**: Cross-encoder cost is **per (query, candidate) pair** and scales with N235([[llamaindex]] Stage 3: reranking is "high-impact but expensive"). Latency is236dominated by N, not k. The bi-encoder stage was chosen precisely because it is237fast; the reranker reintroduces query-time compute.238239**决策步骤**:2401. Measure baseline p95 and the SLA headroom.2412. Measure rerank-stage p95 at the smallest viable N (start N=20).2423. If it fits headroom and quality lifts ≥ a meaningful threshold → ship.2434. If it does not fit → shrink N (OP-05), switch to a lighter model244 (MiniLM cross-encoder, ColBERT), or rerank async/cache for repeat queries.2455. If still over budget and quality is already acceptable → **do not rerank**246 (§6 boundary).247248**结果**: Reranking is the highest-ROI lever *only when latency headroom exists*.249The decision is SLA-driven, not quality-driven in isolation. Smaller N often250recovers most of the lift at a fraction of the latency.251252**可提取的操作**: `OP-04`, `OP-05`. Anti-pattern A3 (over-large N).253254### Dilemma 2 — API reranker (Cohere/Voyage) vs local model (bge / cross-encoder)255256**困境**: The hosted API ships in an afternoon, needs no GPU, and tracks SOTA —257but bills per search and sends query + candidates to a third party. A local258bge-reranker has zero per-call fee and keeps data in-boundary — but needs a GPU,259ops ownership, and model-update discipline.260261**约束**: Per-query cost (API) vs fixed infra cost + ops (local); data-residency262/ compliance; latency (API adds network hop, local adds inference); team's263GPU/MLOps capacity.264265**决策步骤**:2661. **Data residency** hard constraint (PII, regulated)? → local (bge / ColBERT),267 decision over.2682. Estimate query volume × API price vs GPU rental. Low/spiky volume → API269 usually cheaper; high steady volume → local amortizes.2703. No GPU and no MLOps appetite? → API (or CPU MiniLM for tiny N).2714. Multilingual corpus? Both Cohere and bge-reranker-v2-m3 are strong — let272 cost/residency decide.2735. Whichever: wrap the call behind a single `rerank(query, nodes) -> nodes`274 seam so swapping API↔local is a one-line change.275276**结果**: Default to the **API to validate the lift cheaply** (prove the reranker277helps before investing in infra), then migrate to **local** once volume,278cost, or residency justify it. The abstraction seam makes the migration safe.279280**可提取的操作**: `OP-03`, `OP-04`. Anti-pattern A5 (vendor lock-in, no seam).281282---283284## 6 · 反模式与边界 (Anti-patterns & Boundaries)285286### Anti-patterns287288| # | Anti-pattern | Correct move |289|---|---|---|290| A1 | Reranking to fix **recall** — gold doc isn't in top-N | Fix retrieval / hybrid (`[[agentsop-hybrid-retrieval]]`) / chunking; a reranker only reorders what's already retrieved |291| A2 | Naive `similarity_top_k=N` then feed all N to the LLM, no rerank | Widen N **and** rerank to top-3-5 ([[llamaindex]] A6) |292| A3 | Over-large N (rerank 200+ candidates) | Latency scales with N; pick the smallest N that saturates hit-rate (OP-05) |293| A4 | Add reranker first, before prompt/embed/chunk/hybrid | Order law: reranking is **last** ([[llamaindex]] Stage 3); cheapest knobs first |294| A5 | Hard-wire one vendor SDK throughout the pipeline | Hide behind a `rerank(query, nodes)` seam so API↔local swaps in one line (Dilemma 2) |295| A6 | Ship reranker without before/after eval | Gate on {MRR, faithfulness, p95, $/query} (OP-07); a reranker that costs latency for no lift is removed |296| A7 | Keep N=k (rerank n candidates, return n) | Reranking only helps when k < N — you must discard the low-scored tail |297| A8 | Re-embed / re-chunk hoping to fix "wrong top-1" | If the right doc is *present but buried*, that's a rerank job, not a re-ingest |298299### Boundaries — when **not** to add a reranker300301- **B1 — Recall is the bottleneck**: hit-rate@N low ⇒ the answer isn't in the302 pool. Reranking is a no-op. Fix retrieval first (OP-01, `[[agentsop-hybrid-retrieval]]`).303- **B2 — Already narrow & correct**: top-k ≤ 5 and answers right ⇒ no plateau,304 no lever.305- **B3 — Hard real-time / sub-100ms**: the extra round-trip blows the budget and306 quality is acceptable ⇒ skip (Dilemma 1).307- **B4 — Tiny static corpus** (prompt-stuffable, <100k tokens): no retrieval308 stage to rerank ([[llamaindex]] B1).309310### PR-review smells (instant red flags)311312- `index.as_query_engine(similarity_top_k=20)` with **no** node postprocessor →313 A2 ([[llamaindex]] PR-smell).314- Reranker added but `top_k` still 4 → A7 (N=k, reranker is a no-op).315- A vendor rerank SDK imported in >1 module → A5 (no seam).316- A reranker PR with no eval delta in the description → A6.317- "Added reranker to improve recall" in a commit message → A1 (category error).318319---320321## 7 · 跨框架对照 (Cross-framework Mapping)322323The reranker is **one stage** with the same shape everywhere: consume a wide324candidate list, re-score with a cross-encoder, truncate to top-k.325326| Framework / vendor | Reranker primitive | Notes |327|---|---|---|328| **LlamaIndex** (`[[llamaindex]]`) | **Node postprocessor**: `CohereRerank`, `SentenceTransformerRerank`, `ColbertRerank`, `LLMRerank` passed as `node_postprocessors=[...]` to the query engine; widen `similarity_top_k`, set `top_n` on the reranker | The canonical reference; `OP-03 AddReranker`, Stage 3 step 7, A6 |329| **LangChain** | **`ContextualCompressionRetriever`** wrapping a base retriever with a `CohereRerank` / `CrossEncoderReranker` / `LLMChainExtractor` compressor | Base retriever returns N, compressor reranks/filters to k |330| **Cohere Rerank API** | `cohere.rerank(query, documents, top_n, model="rerank-v3.5")` | Hosted cross-encoder; multilingual; per-search billing |331| **Voyage rerank API** | `voyageai.rerank(query, documents, model="rerank-2", top_k)` | Hosted; pairs well with Voyage embeddings |332| **bge-reranker (local)** | `FlagReranker("BAAI/bge-reranker-v2-m3")` / via `sentence-transformers` `CrossEncoder` | Open-weights, self-hosted, no per-call fee, GPU recommended |333| **SentenceTransformers cross-encoder** | `CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2").predict([(q, d), ...])` | Lightest local option; CPU-viable for small N |334| **ColBERT / RAGatouille** | Late-interaction reranker; token-level scoring, precomputable | Scales to larger N than a full cross-encoder |335| **Haystack** | `TransformersSimilarityRanker` / `CohereRanker` component in the pipeline | Same wide→narrow shape, pipeline-component form |336337> Activate **this skill** for the *reranking decision* (whether, where, how wide,338> which model, what it costs). Descend to `[[llamaindex]]` for node-postprocessor339> wiring, and to `[[agentsop-hybrid-retrieval]]` for the recall stage that feeds it.340341---342343## References344345- `references/R1-source-evidence.md` — every cited claim resolved to a source line.346- `intermediate/operation_candidates.json` — machine-readable operation list.347348### Primary sources (cited inline above)349350- `[[llamaindex]]` SKILL — `OP-03 AddReranker`, `OP-02 TuneChunkSize`,351 `OP-04 AddHybridBM25`, `OP-10 EvalLoop`; Stage 2/3/4; anti-patterns A6/A3;352 failure modes #1/#10; the "prompts first, reranking last" order law.353- `[[agentsop-hybrid-retrieval]]` — the wide/recall stage (BM25 + dense) that feeds the354 reranker; lexical-identity recall.355- External: "cohere rerank" (rerank-v3.5, hosted cross-encoder, per-search356 billing, multilingual); "bge-reranker" (BAAI bge-reranker-v2-m3 / large,357 open-weights local cross-encoder); "cross-encoder rerank RAG" (bi-encoder358 retrieve → cross-encoder rerank, joint query+doc attention, the two-stage359 recall→precision pattern).