TL;DR
There are two ways to search: vector search matches by meaning (Module 3), and keyword search matches by exact words. They fail in opposite ways, so production retrievers usually run both and merge the two rankings into one with Reciprocal Rank Fusion (RRF). That combination is called hybrid search, and it's the safe default.
The second engine: keyword search
You already have one search engine from Module 3. The two engines are good at different things:
- Vector search embeds the query and finds chunks closest in meaning. Ask "how long do refunds take?" and it finds "we refund within seven business days" — zero shared words, but the meaning matches.
- Keyword search (the kind databases have had forever) ranks by exact word
overlap. Type
"error code E-104"or"section 3.2"and it jumps straight to the line containing that literal string.
They're strong in exactly the spots the other is weak:
| Query | Vector search | Keyword search |
|---|---|---|
| "how long do refunds take?" | ✅ finds the paraphrase | ❌ no shared words |
| "error code E-104" | ⚠️ blurs to general error text | ✅ exact match |
| "cancel my plan" → "stop your subscription" | ✅ meaning matches | ❌ misses |
| "section 3.2" | ❌ numbers carry little meaning | ✅ exact word |
That middle row is the catch with meaning-only search: an exact code like E-104
barely registers as "meaning," so vector search returns paragraphs that are about
errors but miss the one line that names the code. Keyword search treats E-104 as
the whole point.
Analogy
Vector search is asking a librarian "where's the book about a wizard school?" — they understand what you mean. Keyword search is the index at the back of the book: useless for vague intent, unbeatable when you know the exact term you're hunting.
Fusing the two: hybrid search
If both engines are useful, run both — but now you have two ranked lists and can
only paste one ordered set of chunks into the prompt. You have to fuse them. The
catch: their scores aren't comparable — a meaning score of 0.74 and a keyword score
of 12.3 live on completely different scales, so you can't just add them.
Reciprocal Rank Fusion (RRF) sidesteps that by ignoring the raw scores and using only each chunk's rank (its position) in each list:
RRF score = Σ 1 / (k + rank_in_that_list) with k = 60
A chunk gets a contribution from every list it appears in; a better rank (smaller number) contributes more. Re-sort by the summed score and you have one combined ranking.
Take three chunks and their ranks in each engine (k = 60):
| Chunk | Vector rank | Keyword rank | RRF score | Result |
|---|---|---|---|---|
| A | #3 | #3 | 1/63 + 1/63 = 0.0317 | Wins — solid in both |
| B | #1 | #8 | 1/61 + 1/68 = 0.0311 | Close — great in one |
| C | #8 | (absent) | 1/68 = 0.0147 | Falls — one weak list only |
This is the checkpoint. Chunk A (#3 in both) edges out chunk B (#1 keyword, #8
vector) because RRF rewards agreement: a chunk both engines like is a safer bet
than one that's brilliant in a single engine and poor in the other. The constant
k = 60 softens the gap between top ranks so a single #1 can't completely dominate.
Analogy
It's two judges scoring a contest on different scales — one out of 10, one out of 100. Rather than reconcile the scales, you rank each judge's picks and reward the contestant who placed near the top of both ballots. Broad agreement beats one enthusiastic vote.
Choosing the mode
In the M4 lab the searchType dropdown exposes all three. Pick by how your users
phrase queries:
- Vector — answers are paraphrased; users describe intent in their own words.
- Keyword — users quote exact phrases, codes, or section numbers.
- Hybrid — both happen (the common real-world case). The safe default.
Try it yourself
Run the same query through all three modes against a small fixture corpus. Try a conceptual question, then try an exact code or phrase, and watch the rankings flip.
Common mistake
Reaching for hybrid and assuming it's strictly better, then being surprised when a pure-exact-match query gets a worse top result. Fusion blends — it can pull a perfect keyword hit down a slot if vector disagrees. Hybrid is the best default, but for a corpus that's almost entirely code lookups, pure keyword can still win.
Key takeaways
Key takeaways
- Vector search matches meaning; keyword search matches exact words.
- Vector wins on paraphrases; keyword wins on codes, IDs, and quoted phrases.
- Hybrid runs both and fuses the rankings with RRF — by rank, not raw score.
- RRF rewards chunks that rank well in both lists; hybrid is the safe default.
Optional — why fuse by rank instead of normalizing scores
An obvious alternative to RRF is to normalize both score sets (say, to a 0–1 range) and add them. RRF is usually preferred because:
- Score distributions are unstable. Meaning and keyword scores shift with query length, corpus size, and how many results come back. Normalizing a moving target adds its own noise; ranks are far more stable.
- Ranks shrug off outliers. One chunk with a freakishly high keyword score won't
swamp the fusion — it's still just "rank #1," worth
1/(k+1). kis a tunable knob. A largerkmakes presence-in-both matter more; a smallerklets top ranks dominate. The conventionalk = 60is a good default, not a law.
And the reason keyword is needed at all: a meaning vector captures the gist of a
chunk, so a rare identifier like E-104 barely moves it — two chunks that differ
only by an error code can look nearly identical to vector search. Keyword search is
literal by design, which is exactly what codes and IDs need.
