Hybrid search, explained without the buzzwords
Why blending vector similarity with keyword search consistently outperforms either method alone, and how to implement it.
Vector search gets a lot of the press in modern retrieval, and for good reason. It handles paraphrasing, synonyms, and messy human phrasing in a way that plain keyword search never could. But if you have ever watched a visitor ask a question that includes an internal product code, a version number, or an acronym, you have also seen vector search miss badly. Hybrid search exists because both methods have blind spots, and their blind spots barely overlap.
What each method is actually good at
Vector search compares meaning. It turns text into a dense numerical representation and looks for chunks whose meaning is close to the query. That is exactly what you want when a visitor asks about "cancelling my plan" and the docs use the phrase "ending your subscription".
Keyword search, in the form of BM25 or a Postgres TSVECTOR index, compares literal tokens. It is exactly what you want when a visitor pastes the string "ERR_TIMEOUT_1044" and needs the doc that mentions that exact code. No embedding model is going to reliably guess that a specific error code should map to a specific troubleshooting page.
How to combine the two
The simplest and most reliable technique is reciprocal rank fusion. Run both searches, get two ranked lists, and combine them by rank rather than by raw score. A chunk that shows up near the top of either list gets credit. A chunk that shows up near the top of both lists gets a lot of credit.
def rrf(vector_hits, keyword_hits, k=60):
scores = {}
for rank, doc_id in enumerate(vector_hits):
scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank)
for rank, doc_id in enumerate(keyword_hits):
scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank)
return sorted(scores.items(), key=lambda x: x[1], reverse=True)The k parameter is a smoothing constant. A value around 60 works well in practice. Larger values flatten the contribution of top ranked results. Smaller values sharpen it.
The failure modes hybrid quietly fixes
- Rare terminology like SKUs, error codes, and legal clause references start returning the right page again.
- Paraphrased questions still land on the right chunk even when the vocabulary does not match.
- A single embedding model bug no longer takes down retrieval entirely, because keyword search continues to work.
What to measure
A good hybrid rollout is boring by design. Track recall at ten for a fixed evaluation set of real questions, and compare vector only, keyword only, and hybrid. In our internal evaluation, hybrid beat vector alone on roughly nineteen of twenty question types, and beat keyword alone on all of them. The exceptions were queries where a single perfect keyword match should completely dominate the result.
You do not need a research team to ship hybrid search. You need one vector index, one keyword index, one small function to fuse them, and a habit of measuring against real questions. Everything else is polish.
See it on your own site
OyeChats answers every visitor from your own docs, scores their intent as they chat, and routes the buyers to your team. Free to start — live in under 10 minutes.
Keep reading
How much does an AI chatbot actually cost? A 2026 breakdown in ₹ and $
A transparent teardown of what an AI chatbot for your website really costs each month — the pricing models, the hidden usage fees, and real numbers for a small team.
The best AI chatbot for Indian SMBs in 2026 (pricing in ₹, WhatsApp, and Hindi)
What Indian small businesses should look for in an AI support and lead-gen chatbot — rupee pricing, WhatsApp reach, regional languages, and a practical shortlist.
How to train an AI chatbot on your own website, step by step
A practical, no-jargon guide to turning your existing website and docs into an AI chatbot that answers in your voice and only from your content.
