Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Enhancement-overlay SOP for the reranker stage of a RAG pipeline — the "retrieve wide, rerank narrow" discipline. Activate when a calling agent owns a retrieval pipeline whose answers have plateaued: top-k contains the right document but it is buried below noise, or the context window is under pressure from too many marginal chunks. Encodes the one non- negotiable insight — a cheap bi-encoder retrieves *wide* for recall, then a more expensive cross-encoder (which reads query + document *together
.claude/skills/agentsope-agentsop-reranker-stage/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 45% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 162% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 212% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 122% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 178% | 0% |
> 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.
Activate when any holds:
(prompt, embedding model, chunk size) are exhausted — [[llamaindex]] Stage 3 lists reranking as the last optimization step, deliberately.
hit-rate, low MRR, wrong top-1. This is LlamaIndex failure modes #1 / #10 (llamaindex]] OP-03).
inflate cost, latency, and "lost-in-the-middle" degradation. A reranker lets you retrieve 50 and feed 5.
Do not activate (boundary — see §6):
reranker can only reorder what retrieval already found — fix retrieval, hybrid ([[agentsop-hybrid-retrieval]]), or chunking first.
is already acceptable.
> 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.
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.
[[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).
(API).
Each stage gates the next. Never skip the baseline measurement.
Before adding anything, prove the symptom is precision, not recall:
([[agentsop-hybrid-retrieval]]) / chunking. A reranker will not help.
buried → a reranker is the right lever. Proceed.
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.
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.
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.
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.
Each operation: Trigger / Action / Output / Evidence. Full machine-readable list in intermediate/operation_candidates.json.
⇒ precision problem ⇒ reranker is right. Low hit-rate ⇒ recall problem ⇒ STOP.
OP-03 (#1/#10 = right doc in top-k, wrong top-1);agentsop-hybrid-retrieval]] for the recall path.
top_k=4.two numbers as named, evaluated constants.
3-5"); OP-03.
multilingual; cost per 1k searches, data leaves your boundary.
self-hosted, no per-call fee, strong on multilingual; needs a GPU for low latency, you own ops.
CPU-runnable for small N, the lowest-dependency local option; weaker than bge-large but cheap.
precomputable, scales to larger N than a full cross-encoder.
and language mix.
OP-03 (CohereRerank / SentenceTransformerRerank /ColBERT named); external: "cohere rerank", "bge-reranker", "cross-encoder rerank RAG".
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).
precision lift clears the bar.
cheap knobs first"); §5 Dilemma 1.
precision/latency frontier.
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.
OP-02 TuneChunkSize (same sweep-and-pindiscipline applied to N/k); Stage 3 step 7.
precision plateau.
[[agentsop-hybrid-retrieval]], BM25 + dense) for thewide stage, then rerank its fused candidate list. Hybrid maximizes recall into the pool; rerank maximizes precision out of it. They compose.
OP-04AddHybridBM25 + OP-03 AddReranker (sequential in Stage 3).
$/query}. Keep only on net-positive. Treat as a regression test for future retriever changes.
OP-10 EvalLoop, Stage 2 ("eval loop beforeoptimizing anything"), Stage 4.
困境: 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.
决策步骤:
(MiniLM cross-encoder, ColBERT), or rerank async/cache for repeat queries.
(§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).
困境: 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.
决策步骤:
decision over.
usually cheaper; high steady volume → local amortizes.
cost/residency decide.
rerank(query, nodes) -> nodesseam 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).
| # | 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 |
pool. Reranking is a no-op. Fix retrieval first (OP-01, [[agentsop-hybrid-retrieval]]).
no lever.
quality is acceptable ⇒ skip (Dilemma 1).
stage to rerank (llamaindex]] B1).
index.as_query_engine(similarity_top_k=20) with no node postprocessor →A2 (llamaindex]] PR-smell).
top_k still 4 → A7 (N=k, reranker is a no-op).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/R1-source-evidence.md — every cited claim resolved to a source line.intermediate/operation_candidates.json — machine-readable operation list.[[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 thereranker; lexical-identity recall.
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).
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 36,027 | 21,676 | -40% | 1 | 1 | 0% | 6,202 | 9,014 | +45% | 0 | 0 | — |
case-02 | fail→fail | 36,957 | 36,983 | +0% | 1 | 1 | 0% | 6,243 | 11,575 | +85% | 0 | 0 | — |
case-03 | pass→pass | 16,823 | 12,323 | -27% | 1 | 1 | 0% | 2,650 | 7,369 | +178% | 0 | 0 | — |
case-04 | pass→pass | 13,620 | 8,945 | -34% | 1 | 1 | 0% | 2,004 | 6,650 | +232% | 0 | 0 | — |
case-05 | fail→pass | 17,858 | 14,694 | -18% | 1 | 1 | 0% | 2,955 | 7,735 | +162% | 0 | 0 | — |
case-06 | pass→pass | 18,072 | 10,889 | -40% | 1 | 1 | 0% | 2,731 | 7,085 | +159% | 0 | 0 | — |
case-12 | fail→pass | 14,810 | 12,810 | -14% | 1 | 1 | 0% | 2,367 | 7,396 | +212% | 0 | 0 | — |
case-07 | pass→pass | 15,125 | 10,005 | -34% | 1 | 1 | 0% | 2,524 | 6,867 | +172% | 0 | 0 | — |
case-08 | pass→pass | 13,084 | 10,905 | -17% | 1 | 1 | 0% | 2,234 | 7,013 | +214% | 0 | 0 | — |
case-09 | pass→pass | 18,747 | 13,696 | -27% | 1 | 1 | 0% | 2,754 | 7,498 | +172% | 0 | 0 | — |
case-10 | pass→pass | 16,784 | 15,902 | -5% | 1 | 1 | 0% | 2,579 | 8,185 | +217% | 0 | 0 | — |
case-11 | fail→pass | 21,233 | 14,235 | -33% | 1 | 1 | 0% | 3,405 | 7,544 | +122% | 0 | 0 | — |
case-13 | pass→pass | 11,158 | 10,277 | -8% | 1 | 1 | 0% | 1,878 | 7,053 | +276% | 0 | 0 | — |
case-14 | pass→pass | 15,338 | 13,780 | -10% | 1 | 1 | 0% | 2,522 | 7,568 | +200% | 0 | 0 | — |
case-15 | pass→pass | 13,417 | 10,751 | -20% | 1 | 1 | 0% | 2,210 | 7,066 | +220% | 0 | 0 | — |
case-16 | pass→pass | 11,361 | 13,185 | +16% | 1 | 1 | 0% | 1,681 | 7,425 | +342% | 0 | 0 | — |
case-17 | fail→fail | 35,069 | 16,011 | -54% | 1 | 1 | 0% | 1,381 | 8,016 | +480% | 0 | 0 | — |
case-18 | pass→pass | 12,761 | 7,573 | -41% | 1 | 1 | 0% | 2,017 | 6,469 | +221% | 0 | 0 | — |
case-19 | pass→pass | 9,825 | 8,378 | -15% | 1 | 1 | 0% | 1,529 | 6,643 | +334% | 0 | 0 | — |
case-20 | pass→pass | 16,236 | 19,070 | +17% | 1 | 1 | 0% | 2,474 | 8,219 | +232% | 0 | 0 | — |
case-21 | pass→pass | 9,274 | 10,705 | +15% | 1 | 1 | 0% | 1,560 | 7,141 | +358% | 0 | 0 | — |
case-22 | pass→pass | 15,305 | 14,189 | -7% | 1 | 1 | 0% | 2,474 | 7,641 | +209% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +18 percentage points is the difference between those two pass rates over the 21 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.