Hybrid Search (BM25 + Vector)
Theme
Palette
Download
Caption (tap to copy)
📖 Deep dive (full written explanation)
The motivation post exists because hybrid search has a real cost — two indexes, a fusion step, more to monitor — and you should only pay that cost for a reason. The reason is that production query traffic is messy in a very specific way: it mixes exact-token queries and semantic queries, often within the same query, and a single retriever is structurally bad at one of those.
This post lays out the stakes concretely. We look at the exact-match failure of pure vectors, the synonym failure of pure keywords, why recall is the metric that actually pays off downstream, why hybrid is more robust to unexpected queries, and how to judge when the extra machinery is worth it.
The exact-token failure of pure vector search is the most common nasty surprise teams hit after migrating to embeddings. Identifiers — order numbers, SKUs, part numbers, error codes — are almost pure signal in their literal form and almost zero signal semantically. The embedding model never learned a meaningful representation for 'GTX-1660' or '#88231,' so it places them somewhere generic in the space.
The result is that a query containing a precise ID often returns a vaguely-related passage ranked above the one document that literally contains that ID. The system looks confident and is simply wrong. BM25, which scores on literal term overlap weighted by rarity, treats that rare exact token as a strong signal and nails the match — which is exactly why you keep it around.
The mirror-image failure belongs to pure keyword search. BM25 fundamentally needs shared words; it has no notion that 'cancel my plan' and 'terminating your subscription' mean the same thing. With no overlapping terms, BM25 scores the perfect target document near zero and buries it.
This is not an edge case — it is most of how humans actually phrase questions. People describe their intent in their own words, not in the vocabulary of your documentation. Vector search closes this gap effortlessly because the two phrasings land near each other in the learned space. So pure keyword search systematically loses the large fraction of queries that are paraphrases of your content.
The bar chart captures the empirical punchline that motivates the whole technique: on mixed traffic, hybrid recall typically beats either retriever alone, often by a wide margin. The illustrative numbers — BM25 around 68%, vectors around 74%, hybrid around 88% — reflect the common pattern where each single retriever misses a different slice of queries, and fusion recovers most of both slices.
The exact numbers vary by corpus, but the shape is remarkably consistent across public benchmarks and internal evaluations: the union of two complementary retrievers' successes is larger than either one's. That gap is the entire business case for hybrid.
Recall deserves its own slide because it is the metric that directly translates into answer quality in a RAG system. The generator can only reason over the chunks retrieval surfaced; anything that didn't make the candidate list is invisible to the model, no matter how good the prompt is. So every query that fails on one retriever but succeeds on the other is a query hybrid literally rescues from failure.
At the scale of thousands of daily queries, those rescued cases are the difference between a system users describe as 'usually right' and one they describe as 'reliable.' Precision and reranking matter too, but they operate on the candidate set — and if recall never put the right document in that set, no amount of downstream cleverness helps.
Robustness is the under-appreciated benefit. A single retriever has exactly one failure mode, and adversarial-feeling real-world queries — pasted log lines, half-remembered phrases, internal codenames, typo-ridden questions — tend to fall squarely into it. With two retrievers that fail in different ways, a weird query that breaks one path often still lands on the other.
This redundancy is structurally similar to defense in depth: you are not relying on any single component being perfect. The system degrades gracefully, because the probability that a query breaks both BM25 and vectors simultaneously is much lower than the probability it breaks either one alone.
The compare diagram is deliberately honest about cost, because hybrid is not free. On the gains side: higher recall on mixed traffic, an exact-match safety net, full synonym and intent coverage, and graceful handling of odd queries. On the cost side: two indexes to build and keep in sync, a fusion step to implement and tune, slightly higher query latency from running two retrievers, and more surface area to monitor and debug.
The point is not to scare you off — for most real corpora the gains dominate — but to set the expectation that you're adding an extra subsystem. Posts 3 and 5 are largely about making sure that subsystem actually helps rather than quietly hurting.
The 'when it's worth it' slide gives a practical heuristic. Hybrid earns its keep when your corpus mixes natural-language prose with literal identifiers: technical docs with part numbers, knowledge bases with error codes, codebases, legal text with citations, anything with names and IDs. Those are exactly the corpora where pure vectors leak on exact tokens and pure keywords leak on phrasing.
If, on the other hand, your content is pure prose and your queries are pure prose — say, a corpus of essays answered by conversational questions — plain vector search may already be enough, and hybrid adds complexity for marginal gain. The honest answer is that most production corpora are not that clean, which is why hybrid has become a default rather than an exotic choice.
This code-as-illustration slide makes the abstract 'mixed query' concrete. 'Why is invoice INV-7741 still unpaid' is the canonical hybrid query: it contains a precise identifier (INV-7741) and a clear semantic intent (understand an unpaid status). Pure vector search tends to return generic billing-cycle content and miss the specific invoice; pure BM25 nails the invoice document via the exact code but might miss broader billing context.
Hybrid fuses both, so the exact invoice surfaces AND the surrounding billing context comes along for the LLM to reason over. The comment annotations show the divergent top-1 results from each retriever, which is the clearest possible argument for keeping both.
The takeaways slide distills the stakes into five lines: pure vectors break on IDs and codes, pure keywords break on synonyms, hybrid recall beats either alone, the two blind spots cancel out, and it's worth it when your content mixes prose with tokens.
The through-line is complementarity again, now expressed as a cost-benefit judgment rather than a concept. You accept extra plumbing in exchange for covering a query space that no single retriever covers well. For most real systems that's a trade worth making.
The bottom-line slide states the thesis plainly: hybrid matters because production queries aren't tidy. They are exact and fuzzy, technical and casual, in the same stream — sometimes in the same query. Running both retrievers and fusing them converts two partial solutions into one that covers the space.
The price is a little extra plumbing, which the remaining posts will help you get right. With the stakes established, Post 3 opens the hood on the actual mechanics — the BM25 formula, the ANN lookup, and the fusion strategies that make the combination work.
This was the 'why it matters' post in the five-part day. We covered the complementary failure modes of pure vector and pure keyword search, why recall is the metric that pays in RAG, the robustness benefit of redundant retrievers, and a heuristic for when hybrid is worth its cost.
Next, Post 3 goes under the hood: the BM25 scoring formula demystified, how dense ANN retrieval finds neighbors, and the two dominant ways to fuse two ranked lists into one.