Keyword vs Semantic Search: The Same Query, Both Rankings
Runs BM25 and a vector ranking over the same documents side by side, with reciprocal rank fusion, and counts the query terms that score exactly zero on the lexical side.
BM25 scores “how”, “do”, “i”, “change”, “credential”, “safely” at exactly zero — not low, zero. Those terms cannot contribute to a lexical ranking however important they are, which is the entire case for a second retriever.
| Hybrid | BM25 | Vector | Document |
|---|---|---|---|
| #1 | #1 (0.98) | #1 (1.00) | Rate limits are applied per key, so a freshly created key starts with a clean limit window. |
| #2 | #2 (0.91) | #2 (0.98) | Credentials should be replaced on a schedule. A superseded secret stays valid throughout the overlap window so callers never see an error. |
| #3 | #3 (0.71) | #3 (0.55) | Invoices are issued monthly and can be downloaded as a PDF from the billing page at any time. |
| #4 | #4 (0.69) | #6 (0.33) | If a secret has leaked, revoke it immediately and accept the downtime. Graceful replacement is for planned changes only. |
| #5 | #7 (0.00) | #4 (0.40) | Webhook signing secrets are stored separately from API keys and are cycled on their own schedule.the two methods disagree by 3 places |
| #6 | #5 (0.00) | #7 (0.27) | Rotating an API key without downtime: create the new key, deploy it everywhere, confirm traffic has moved, then revoke the old one. |
| #7 | #8 (0.00) | #5 (0.34) | The keys page lists every key you have created, with the date it was last used and its final four characters.the two methods disagree by 3 places |
| #8 | #6 (0.00) | #8 (-0.28) | Refunds are returned to the original payment method and take five to ten working days to appear. |
- Documents
- 8
- Average document length
- 19.0 words
- Distinct query terms
- 7
- Query terms with zero document frequency
- 6
- Vector ranking produced by
- latent semantic analysis at rank 3
- BM25 puts first
- Rate limits are applied per key, so a freshly create
- The vector side puts first
- Rate limits are applied per key, so a freshly create
- Documents the two rank ≥3 places apart
- 2
- Fusion
- reciprocal rank fusion, k = 60
Why you end up running both
The two methods fail in ways that do not overlap, and that is the whole argument for hybrid search. BM25 matches terms. It is fast, needs no training, handles a corpus it has never seen, and gives you an explanation for free — the score decomposes into a contribution per query term. Its failure is total rather than graceful: a query term that appears in no document contributes exactly zero, so a user who asks about "credentials" when your documentation says "API keys" gets nothing at all from the lexical side.
Vector retrieval fails the other way. It has no notion of a term appearing or not appearing, so it always returns a full ranking — which is useful when the vocabulary differs and dangerous when there is nothing relevant to return, because the top result looks the same either way. And it is unreliable on the things BM25 is best at: product codes, error numbers, surnames, version strings. An embedding of ERR_4013 is close to the embedding of ERR_4031, which is exactly the wrong behaviour.
Fusion is how production systems get both. Reciprocal rank fusion adds 1/(60 + rank) from each ranker, deliberately ignoring the scores: a document needs to place well in one list to survive, and placing well in both wins. The number worth watching above is the count of documents the two methods rank three or more places apart. When it is high, hybrid is buying you something real. When it is near zero, your queries and your corpus share a vocabulary and the second retriever is latency you are paying for nothing.