How to Combine Keyword and Vector Search in RAG
Why hybrid retrieval is the production default rather than an upgrade: complementary failure modes of lexical and dense search, reciprocal rank fusion versus weighted scoring, parameter choices, and how filtering interacts with fusion.
- Lexical and dense retrieval fail on opposite cases — BM25 nails exact identifiers and misses paraphrase; embeddings handle paraphrase and blur precise strings — so running both and fusing is the production default, not an optimization to add later.
- Reciprocal rank fusion (RRF) is the robust default because it needs no score calibration: it merges ranked lists using only rank positions. Weighted score fusion gives finer control but requires normalizing incomparable score scales, which drifts as corpora evolve.
- The k-per-channel choice matters more than the fusion constant: too few candidates per channel caps achievable quality because the true best passage may never enter either list. Measure end-metric against candidate count once and pick the knee.
- Hybrid multiplies first-stage work per query. Route simple lookups past the second channel with a cheap gate, and remember that pre-filtering for permissions applies to BOTH channels before fusion — post-filtering after fusion can leave a result list that filters down to nothing.
The pillar guide declares hybrid retrieval the default; this article justifies that stance and turns it into parameters. The core argument is about failure modes, not averages: neither channel is merely "worse" than the other — each fails on different inputs, which is exactly what makes their combination powerful.
Why do keyword and vector search fail differently?
Lexical methods such as BM25 match terms with statistics — term frequency, document length, rarity. They excel where the query shares surface form with the answer: error codes, SKUs, API names, acronyms, statutes. They fail under paraphrase and vocabulary mismatch, penalizing well-written answers phrased differently from the question.
Dense retrieval embeds query and passages into one semantic space, matching meaning rather than strings. It catches paraphrase, synonyms and cross-lingual matches. It blurs exact tokens — two similar-looking identifiers embed almost identically — and it inherits whatever biases its training distribution carried.
The failure sets barely overlap. A help desk query citing an exact exception code defeats dense retrieval trivially and lexical trivially well; "how do I stop my worker dying after deploy" defeats lexical if the docs say "crash loop post-release" and falls easily to embeddings. Production traffic contains generous amounts of both kinds.
Which fusion method should you use?
Two workhorses dominate practice:
- Reciprocal Rank Fusion — merge by ranks alone: each document gains
1 / (k + rank)per list,kcommonly set around 60. No score normalization needed, no tuning beyond k, remarkably hard to break. Start here. - Weighted score fusion — normalize each channel's scores, then blend with weights. Finer control (down-weighting lexical for chatty paraphrase-heavy traffic, up-weighting it for code search) but the normalization is a maintenance liability: score distributions shift with corpus growth and model changes.
Whichever you pick, evaluate fusion as a measured decision on your golden set — the same harness used for chunking and embedding decisions — rather than a preference.
What parameters actually move the needle?
Three, in order of impact:
- Candidates per channel: how deep each channel retrieves before fusion. Too shallow caps quality — the true best passage may never enter any list. Plot final answer metric against candidate depth; choose at the knee, not the asymptote.
- Final selection size: how many fused results survive to reranking or assembly. This interacts with downstream budget (see the corpus reranking reference for the split).
- Fusion constant or weights: real but smallest effect. Tune last.
How do you prove hybrid actually helped?
Run the counterfactual rather than the vibe: the golden-set harness scores three configurations — lexical only, dense only, fused — on identical questions. The interesting output is not the average uplift but the per-question diff: which identifier-style questions flipped from miss to hit, and whether any paraphrase questions regressed. Keep that diff list; it becomes regression coverage for the fusion parameters themselves. In production, log which channel contributed each selected passage (the fusion step knows each item's origin) so per-channel contribution stays observable as your query mix drifts.
What breaks hybrid systems in production?
Four recurring failure modes deserve standing checks:
- Channel skew — one channel's index lags the other after partial ingestion failures, so fusion blends evidence from different corpus generations. Monitor document counts and newest synced versions across both indexes together.
- Score-normalization drift — weighted-fusion setups calibrated months ago silently misbehave as corpus growth shifts score distributions. RRF avoids this by construction; weighted setups need periodic recalibration against the golden set.
- Silent channel degradation — a broken lexical analyzer or an embedding API change can halve one channel while the system still looks alive overall. Track per-channel hit rates; a sudden monopoly in contribution is an alarm, not a win.
- Filter asymmetry — permissions enforced on one channel but not the other turn hybrid into a leak vector. The pre-filter rule must hold identically everywhere, verified by permission-negative test cases that run both channels.
How does this compose with filters, permissions and reranking?
Order of operations is the whole game:
- Permissions and scope filters apply pre-fusion, inside each channel, so every candidate is already legitimate
- Fusion merges the filtered lists
- Deduplication collapses near-identical passages that arrived via both channels
- Reranking then reorders survivors if budgeted
Skip the pre-fusion filtering and you invite the empty-list failure: all top fused hits from one channel, all filtered out afterward. Skip deduplication and the generator sees the same passage twice with different scores, overweighting it for no informational gain. The vector database reference matters here too — stores differ sharply in how efficiently they serve filtered vector search, and that difference lands directly on your most permission-sensitive queries.
Adopt hybrid early, measure the parameters honestly, and the system quietly stops failing on exact-string questions while keeping everything embeddings are good at.
If you take one number away, take this: log per-question channel attribution from day one. Every later decision in this article's lifecycle — fusion weights, candidate depth, whether to gate the second channel, when to suspect skew — is answered in minutes with that log and argued about for weeks without it. Hybrid retrieval is cheap to build and easy to misjudge; attribution data is what keeps the judgment honest. It also settles the most common post-launch argument before it starts: when someone proposes removing a channel for simplicity, the contribution log shows exactly which classes of questions would regress, and the decision becomes arithmetic instead of taste.
Frequently asked questions
- When is vector-only retrieval good enough?
- Rarely in production, despite demos suggesting otherwise. Vector-only systems keep missing queries hinging on exact strings — error codes, part numbers, statute citations, names — because embedding smooths away precisely those distinctions. If your corpus genuinely contains no identifier-style queries, measurement will show lexical adding nothing; verify rather than assume, because real query logs almost always contain them.
- What is reciprocal rank fusion?
- A method for merging multiple ranked lists using only rank positions: each document scores the sum over channels of 1/(k + rank), with k typically around 60. Documents near the top of several lists rise; documents high in one list alone still compete. Because it never compares raw relevance scores across channels — which live on incompatible scales — RRF avoids calibration entirely and stays stable as content evolves.
- Should hybrid retrieval run both channels always?
- Usually yes at modest scale; conditionally at cost-sensitive scale. Both channels double first-stage work, so high-volume systems gate the second channel behind a cheap signal — query shape heuristics or a small classifier — running full hybrid only where it changes outcomes. Measure the gate itself: an aggressive router that skips lexical on identifier-shaped queries inverts the entire point.
- How do metadata filters interact with fusion?
- Apply access-control and scope filters inside each channel before ranking and fusion, not afterward. Post-filtering a merged list risks ending with zero visible results when all top hits came from one channel and fail the filter — the classic empty-answer failure. Pre-filtering keeps both channels working within the allowed candidate set so fusion operates on legitimate evidence.
This guide is free and stays free. The reference corpus behind it — machine-readable contracts, verified primary sources, continuously refreshed — is the paid product: a €5 starter key unlocks every premium reference for one agent via API; a €25 corpus license delivers the full corpus as RAG / fine-tuning data with an explicit AI-use grant; the €150 enterprise license adds commercial redistribution rights.