Skip to content
Forward Deployed

Forward Deployed
Lessons and contents
Retrievers & Hybrid SearchLesson 7 of 8
8 lessons
Learn

Retriever patterns compared; hybrid + rerank in a managed vector store

Source
From the RAG & Agents Engineering course
By
Sourav Banerjee
Last updated
9 Nov 2026

Report an issue

Choosing a retriever pattern

What you'll learn

  • Match four retriever patterns to the failure each one fixes.
  • Count the LLM calls a nested retriever spends per question.
  • Compare hybrid search inside the vector store with an ensemble in the application.
  • Judge a vendor's quality claim for a reranker before paying its latency.

Lessons 1 to 5 of T6.1 each fixed one retrieval failure: forced top-k, the dense miss on exact codes, the merge of two lists, redundant chunks, chunks that should never be allowed. This lesson puts the fixes side by side as patterns a team can pick from.

Larkspur's team wants better answers and adds every pattern they have heard of: multi-query in front, compression behind, an ensemble underneath. Answers improve a little, and the cost per question rises several times over. Nobody counted the calls before stacking them.

Notebook 06a runs four patterns over the same eight topic-tagged documents in Chroma. Each fixes a different failure and costs something different:

Pattern Fixes Extra cost per question 06a setup
Multi-query Wording that misses the documents 1 LLM call, then one search per variant Base retriever k = 2, temperature 0.3
Contextual compression Chunks full of text the question does not need 1 LLM call per retrieved chunk Base retriever k = 4
Ensemble (BM25 + dense) Exact terms the dense retriever misses One more search; no LLM call k = 3 each, weights 0.4 BM25 and 0.6 dense
Parent document Small chunks that match well but lack context A docstore lookup 200-character children (20 overlap) inside 800-character parents (100 overlap)

Table 1: Four patterns, the failure each fixes, and its price.

Choosing starts from the failure seen on the golden set, not from the pattern list. Here is that diagnosis as a chain of checks:

Diagram: Evidence missing from the top k?; Right chunk, but too much text?; Question quotes a code or name?; Ensemble BM25 + dense; Multi-query; Compression; Parent document if context is cutDiagram: Evidence missing from the top k?; Right chunk, but too much text?; Question quotes a code or name?; Ensemble BM25 + dense; Multi-query; Compression; Parent document if context is cut

Figure 1: Pick the pattern from the failure, one check at a time.

06a's ensemble demo uses three questions chosen to separate the halves: ACID transactions (keyword-heavy, BM25 should help), How do I store AI model outputs for later retrieval? (worded unlike any document, dense should help), and fast similarity lookup for embeddings (mixed). It prints the top result from BM25, dense and the ensemble for each, side by side. That is the shape a team's own comparison should take: golden questions of each kind, every retriever's answer next to the others.

Nesting patterns

Because every pattern is a retriever, they nest. 06a's last demo wraps multi-query inside compression and feeds the result to a prompt:

Diagram: Question; MultiQueryRetriever LLM writes variants; Chroma k = 3 per variant; LLMChainExtractor keeps relevant text; Prompt + gpt-4o-mini; AnswerDiagram: Question; MultiQueryRetriever LLM writes variants; Chroma k = 3 per variant; LLMChainExtractor keeps relevant text; Prompt + gpt-4o-mini; Answer

Figure 2: Multi-query inside compression, as 06a builds it.

Multi-query widens the pool for recall and compression narrows each chunk for precision, so the two pull in opposite directions on purpose. The calls add up, and the middle term grows with the union of results:

Stage LLM calls Assumption
Write variants 1 One call returns 3 variants
Search 0 4 searches (question plus 3 variants), k = 3 each
Compress 7 12 results, 7 unique after de-duplication, one call each
Answer 1
Total 9 Against 1 for plain retrieval plus an answer

Table 2: LLM calls per question in the nested pipeline (illustrative: the union size depends on how much the variants overlap).

We call this call stacking: each wrapper's cost is reasonable alone, and the product of them is what the bill shows. Nine calls in sequence also means nine round trips of latency before the user sees a word.

Pitfall: call stacking. Count calls per question before nesting, and measure each layer's gain on the golden set separately. A layer that adds two calls and no recall comes out.

Hybrid in the store

Notebook 06b, an optional notebook, moves hybrid search and reranking into a managed vector store. It embeds the question with BAAI/bge-large-en-v1.5 (1,024 dimensions, normalised) and makes one call per mode, returning 5 results:

Mode What the call adds
Vector only The query vector
Hybrid The query text and a hybrid query type
Hybrid + rerank A reranker over the text column

Table 3: Three search modes in 06b.

Hybrid in the store and an ensemble in the application do the same job in different places:

Hybrid in the store Ensemble in the application
Keyword index lives Next to the vectors, kept in sync by the store In application memory, built from the full document list
Corpus changes Indexed with the rest The BM25 index is rebuilt
Fusion On the server, one round trip In code you can read and log
Suits Scale and many writers Inspection, tuning, small corpora

Table 4: Two places to run hybrid search.

06b describes the reranker as about 15% better in quality for 1 to 1.5 seconds of extra latency. The notebook states those figures without measuring them. Treat a number like that as a hypothesis: measure the gain and the latency on your own golden set before paying for it. T6.3 covers rerankers and the retrieve-wide, rerank-narrow design.

In practice: Larkspur's retriever stack

  1. Diagnose first. Run the golden set, and sort misses into Figure 1's boxes.
  2. Ensemble for codes. Error codes and plan names were the dense misses in lesson 2 of T6.1; BM25 plus dense with RRF fixes them for one extra search and no LLM call.
  3. Hold multi-query until paraphrase misses remain after the ensemble, and count its calls when it goes in.
  4. Choose the location by scale. An application ensemble while the handbook is small and changing; the store's hybrid mode once many teams write to it.

T6.2 picks up where multi-query leaves off, with the full family of query rewrites.

Run the notebooks

The code for this lesson is in these notebooks. Colab runs one in your browser: install the packages its first cell imports and set the API keys it reads. To run every notebook as written, clone the repository and use its uv environment.

Notebook GitHub Colab
Advanced retriever patterns Open on GitHub Open in Colab

Key Takeaways

  • Each pattern fixes one failure at its own price: multi-query fixes wording, compression trims noisy chunks at one LLM call each, an ensemble catches exact terms, and parent documents restore missing context.
  • Patterns nest because each is a retriever, but calls multiply (call stacking): multi-query inside compression can spend about 9 LLM calls where plain retrieval spends 1.
  • Hybrid in the store fuses on the server and stays in sync; an application ensemble is easier to inspect. Measure any reranker's gain and latency on your golden set before enabling it.

Check yourself

1. In the nested pipeline, why do multi-query and compression pull in opposite directions, and what drives their LLM call count?

Multi-query widens the pool for recall; compression narrows each chunk for precision. They cost one call for the variants, one per unique chunk in the union for extraction, and one for the answer, so the count grows with the size of the union.

2. Small 200-character chunks match Larkspur questions well, but the passages that reach the model lack context. Which pattern fixes that, and at what cost?

The parent document retriever. It searches the small child chunks and returns the larger parents that contain them (800 characters in 06a). The extra cost is a docstore lookup, with no LLM call.

3. Notebook 06b says the store's reranker is about 15% better for 1 to 1.5 seconds of extra latency. Should Larkspur turn it on on that basis?

Not on that basis. The notebook states the figures without measuring them. Measure the quality gain and the added latency on Larkspur's own golden set first, and keep the reranker only if the gain is worth the latency.

Rate your confidence and keep notes on the module page.