Better retrieval

  • Intermediate
  • 30 min
  • Lesson 3 of 6 in Retrieval-augmented generation
  • Last verified

Before you start

You will be able to

  • Walk a bad RAG answer back to the failing stage using the debugging playbook.
  • Explain hybrid search with Reciprocal Rank Fusion and cross-encoder reranking, including what each costs.
  • Choose a query transformation for a given retrieval failure and state its cost.
  • Explain why metadata and permission filters are applied before or during vector search, and the trade-off of post-filtering.
  • Use chunk-level techniques (parent-child, sentence window, contextual chunks, MMR) and context assembly to improve what reaches the prompt.

The right timetable page is in the car. You can see its corner sticking out of the drawer.

Merrow has pulled two candidates and finds the second one plausible. “That’ll do,” he says, and reaches for the stamp.

From the counter, how would anyone know whether the best page was ever on the pile?

Concept

Better retrieval means getting the right chunk into the prompt more often. The tools are: searching two ways and merging (hybrid), re-scoring a shortlist (rerank), fixing the query, filtering by metadata, shaping the chunks, and assembling the final context carefully.

Why it matters

Answer quality is capped by retrieval quality. Many “the LLM hallucinated” bugs are really “the right chunk never reached the prompt”. Fixing the generator will not help if its evidence is wrong.

Each technique below has a cost in latency, money or complexity. The skill is applying the cheapest fix to the failure you have actually measured.

Mental model

Retrieval is a two-step search party. First a wide net brings in many candidates cheaply, so the right one is probably in the catch (high recall). Then a careful sorter looks closely at each candidate and keeps the best few (high precision).

Every technique in this lesson widens the net, sharpens the sorter, or cleans up what is handed over.

  • Dense (embeddings) matches meaning and paraphrase. It is weak on exact tokens such as IDs, error codes and rare names.
  • Sparse (BM25BM25A keyword ranking function that scores documents by term frequency, term rarity and length. It catches exact terms and identifiers that embeddings miss.Open the glossary entry or keyword) matches exact terms. It is weak on synonyms and paraphrase.
  • Hybrid runs both and merges the lists.

Prefer Reciprocal Rank Fusion (RRF)Reciprocal rank fusion (RRF)A way to merge ranked lists by summing 1/(k + rank) per list, with k often 60. It uses ranks only, so incompatible score scales need no calibration.Open the glossary entry: score(d) = sum over lists of 1 / (k + rank_i(d)). The default k = 60 comes from the original paper (Cormack, Clarke and Buettcher, SIGIR 2009), where it was fixed in a pilot study. RRF uses ranks only, so you never normalise incompatible score scales. The alternative is a weighted sum of normalised scores, which can do better when tuned but needs tuning and labelled data.

Worked example, k = 60. Document A is rank 1 in the dense list and rank 3 in the BM25 list: 1/61 + 1/63 is about 0.0323. Document B is rank 2 in dense and rank 1 in BM25: 1/62 + 1/61 is about 0.0325. B wins the fused list because it ranks well in both, even though A won the dense list.

Diagram: The query goes to dense search and BM25 in parallel, each returning a top 50.

Query

Dense search
top 50

BM25 search
top 50

RRF fusion

Cross-encoder rerank
top 5

Prompt

Diagram summary: The query goes to dense search and BM25 in parallel, each returning a top 50. RRF fuses the two lists, a cross-encoderCross-encoderA model that reads query and passage together and outputs a relevance score. More accurate, but one call per pair, so it reranks a shortlist.Open the glossary entry reranks the fused list down to the top 5, and those go into the prompt. The numbers 50 and 5 are illustrative.

Reranking

  • A bi-encoderBi-encoderA model that embeds query and document separately, so document vectors can be precomputed. Fast, used for first-stage retrieval.Open the glossary entry (used for retrieval) embeds query and chunk separately. It is fast and approximate, and chunk vectors can be precomputed.
  • A cross-encoder (used for reranking) reads query and chunk together. It is more accurate but needs one model call per pair, so you run it on the shortlist only.

Pattern: retrieve wide (for example 50 to 100), rerank narrow (for example 3 to 8). The cost is added latency and money in exchange for better precision in the top results. Measure it on your own question set; reranking is not free and not always worth it.

Query transformation

Fix the query instead of the index.

TechniqueWhat it doesUse whenTypical cost or risk
RewriteAn LLM turns the query into a clean standalone searchFollow-ups such as “what about the second one?”One LLM call; may change the meaning
Multi-queryGenerate several paraphrases, retrieve for each, fuseShort or ambiguous queries; recall problemsSeveral searches; may add off-topic results
DecompositionSplit a complex question into sub-questionsMulti-part or multi-hop questionsSeveral calls; sub-answers must be combined
Step-backAsk a more general question firstQuestions that need background principlesExtra call; can retrieve too broadly
HyDEHyDEHypothetical document embeddings: the model writes a plausible answer and that text is used to search. It helps when queries and documents are phrased differently, but a wrong draft can bias retrieval.Open the glossary entryEmbed an LLM-written hypothetical answer instead of the queryQuery and documents are phrased very differentlyThe invented answer can steer search toward a wrong idea
RoutingPick an index or tool by query typeSeveral corpora or mixed structured and unstructured dataMisrouting sends queries to the wrong place

Every transform adds an LLM call (latency and cost) and can drift from the user’s intent. Gate them: apply them only when a quick check says they are needed. Multi-query, for instance, hurts when the query is already precise, because the paraphrases dilute it.

Metadata filtering and permissions

  • Store source, date, document type, language, tenant and ACL as metadata.
  • Filter before or during the vector search (pre-filter), not after.
  • Post-filtering a top-k can leave you with zero results, because the best matches were the ones removed.
  • Pre-filtering can hurt recall or latency in some approximate indexes. Know how your database behaves.
  • Take the filter value (tenant, group) from the authenticated identity on the server, never from text the user supplied. Some stores offer a namespace per tenant, which makes the restriction part of the search itself.
  • Permissions are enforced in the retriever. Asking the LLM to hide things is not a control, because the text is already in the prompt.

Chunk-level improvements

  • Parent-child (small-to-big): match on small chunks, return the larger parent.
  • Sentence window: match a sentence, return it with N neighbours on each side.
  • Contextual chunks: give each chunk back its context before indexing. The cheap option prepends the document title and section. The richer option is an LLM-written note situating the chunk in its document; Anthropic calls this contextual retrieval and applies it to both the embeddings and the BM25 index (source above). The richer option costs an extra model call per chunk at ingest.
  • Structure-aware splitting: respect headings, tables and code blocks.
  • Diversity (MMR, maximal marginal relevanceMaximal marginal relevance (MMR)A selection method that balances relevance against redundancy, so the top-k results are not near-duplicates.Open the glossary entry): trade relevance against redundancy so the top-k is not five copies of the same paragraph.

Context assembly

The last step before generation:

  • De-duplicate, order by relevance, and cap by a token budget.
  • Put the strongest chunks at the start or end, because models use the middle of long contexts less reliably (Liu et al., 2023, “Lost in the Middle”).
  • Include source ids so the model can cite.
  • Optionally compress by extracting only the relevant sentences. The risk is dropping a sentence the answer needed.

Debugging playbook

Work from the symptom back through the pipeline. Ask one question at a time.

Diagram: A decision tree for a bad answer: first check the passage is indexed, then that it was retrieved, then that it survived reranking and...

No

Yes

No

Yes

No

Yes

No

Yes

Bad answer

Is the correct passage
in the corpus and indexed?

Ingestion bug:
parsing, missing doc, stale index

Is it in the retrieved
top-k?

Retrieval bug:
chunking, embedding, hybrid,
filters, query rewrite

Is it in the final prompt
after rerank and trimming?

Rerank or context-budget bug

Does the answer follow
the passage?

Generation bug:
prompt, model, too much noise

Source or question ambiguity

Diagram summary: A decision tree for a bad answer: first check the passage is indexed, then that it was retrieved, then that it survived reranking and trimming into the prompt, then whether the answer follows it. The first “no” names the failing stage.

Test to separate retrieval from generation: paste the gold passage into the prompt by hand. A correct answer means retrieval (or ingestion) failed. A wrong answer means generation or prompt.

Log the retrieved chunk ids for every request. Without them this tree cannot be walked after the fact.

Real-world application

Teams usually add these in order of cost: filters and chunk fixes first (no extra runtime calls), then hybrid search, then reranking, and query transforms last because they add an LLM call to every request. Each step is justified by a failure you have measured on a labelled set (see RAG evaluation in depth).

Interview perspective

Provenance: common industry pattern; no company-specific claim.

  • “Dense for meaning, BM25 for exact tokens, fuse with RRF, rerank the shortlist with a cross-encoder.”
  • “I log retrieved chunk ids per request so every bad answer is debuggable.”
  • “Permissions are filters in the retriever, not instructions in the prompt.”

Practice questions

Provenance: generated practice.

  • Why does RRF avoid score normalisation?
  • When would multi-query hurt?
  • Pre-filter versus post-filter: what is the trade-off?
  • Design the test that tells a retrieval failure from a generation failure.

Activity

Do, notice, apply.

  1. Do. Implement RRF over two ranked lists (a few lines of code, or by hand with k = 60). Use lists where one document is first in one list and missing from the other.
  2. Notice. Build a case where RRF beats both input lists. What property of the two lists made that possible? What happens to a document that appears in only one list? Describe each document by its rank in each list, and by the rank of a known relevant document.
  3. Apply. Take the debugging tree and a bad answer from any RAG tool you use. Write which question in the tree you would ask first, and what log you would need to answer it.

Homework

For a failing question set you invent (five questions, each with a different cause), write the first fix you would try for each, the metric you would watch, and its latency or cost price.

Quick revision

  • Quality is capped by retrieval. The right chunk must reach the prompt.
  • Hybrid = dense + BM25, fused by RRF (k = 60 default, rank-based).
  • Rerank a wide shortlist with a cross-encoder: more precision, more latency.
  • Query transforms fix the query but add a call and can drift. Gate them.
  • Filter by metadata and permissions before or during search.
  • Log retrieved chunk ids. Walk the debugging tree from the symptom back.

Check yourself

  • Checkpoint (answer aloud, no notes): Why does RRF avoid score normalisation, and when would you not use it?
  • Re-test (nearby variant): Exact SKU searches fail, but paraphrased questions work. Which technique do you reach for and which metric tells you it worked?
  • Misconception to avoid: “Reranking fixes recall.” It can only reorder what retrieval already returned.

Practice

Test what you just read. Quizzes and cards are grouped by module: Retrieval-augmented generation.

Check yourself10 questions on what this lesson set out to teach

Checking answers needs JavaScript. You can still read every question and option below.

0 of 10 answered

Keyboard: arrow keys move between options. Space or Enter selects the focused option.

ObjectiveWalk a bad RAG answer back to the failing stage using the debugging playbook.

  1. Question 1 of 10The correct passage is indexed, but a debug log shows it is not among the retrieved top-k for the failing query. Which stage do you investigate?

    Choose one answer.

  2. Question 2 of 10Following the debugging playbook, the correct passage is in the final prompt, yet the answer contradicts it. Where does the fix belong?

    Choose one answer.

ObjectiveExplain hybrid search with Reciprocal Rank Fusion and cross-encoder reranking, including what each costs.

  1. Question 3 of 10Merrow's search finds the right page at rank 12 of the first-stage results, but only the top 5 go to the prompt, so it is left out. What is the most direct fix?

    Choose one answer.

  2. Question 4 of 10With RRF at k = 60, document A is rank 1 in the dense list and absent from the BM25 list. Document B is rank 2 in both lists. Which scores higher in the fused list?

    Choose one answer.

  3. Question 5 of 10A team adds a cross-encoder reranker over the top 50 results, yet exact-ID queries still fail. Logs show the right chunk is never among those 50. Why did reranking not help?

    Choose one answer.

ObjectiveChoose a query transformation for a given retrieval failure and state its cost.

  1. Question 6 of 10A user chats with the assistant and then asks 'what about the second one?'. Retrieval on that raw text returns junk. Which transformation fits, and what does it cost?

    Choose one answer.

  2. Question 7 of 10A team applies multi-query expansion to every request. Latency rises and precise lookups such as exact policy numbers get worse. What is the most sensible change?

    Choose one answer.

ObjectiveExplain why metadata and permission filters are applied before or during vector search, and the trade-off of post-filtering.

  1. Question 8 of 10Which design enforces tenant isolation most reliably in a multi-tenant RAG service?

    Choose one answer.

ObjectiveUse chunk-level techniques (parent-child, sentence window, contextual chunks, MMR) and context assembly to improve what reaches the prompt.

  1. Question 9 of 10The top 5 chunks for a query are near-duplicate copies of the same paragraph, taken from five near-duplicate pages. Which technique addresses this directly?

    Choose one answer.

  2. Question 10 of 10You assemble ten retrieved chunks into one long prompt. Where should the most important chunk go?

    Choose one answer.

Build with this