Skip to content
AI Engineering
Embeddings & Retrieval

Semantic, keyword and hybrid search

Keyword search finds exact terms. Semantic search finds meaning. Combining them catches what either alone misses.

Chapter 8: Embeddings & RetrievalLesson 7 of 13Level: CoreAbout 12 min
Words on this page (8)
BM25
: A classic keyword scoring method that ranks documents by matching terms.
chunk
: A small piece of a document, sized for indexing and retrieval.
vector
: An ordered list of numbers. Embeddings and model activations are vectors.
reciprocal rank fusion
: A way to merge two ranked result lists by adding 1 / (k + rank) for each list.
reranker
: A second model that rescores a short list of search results by reading query and passage together.
logarithm
: The power you raise a base to in order to get a number. log base 2 of 8 is 3 because 2 to the power 3 is 8.
weights
: The learned numbers that define a trained model. A model whose weights are published is called open-weight.
hybrid search
: Combining keyword search and vector search.

How each works

Keyword search with scores a document higher when it contains the query's rare words many times. It nails error codes, names and identifiers and misses synonyms. Semantic search embeds the query and finds the nearest , so "car won't start" matches "engine fails to turn over". It can miss exact strings like "ERR_4021".

Combining them

Run both, then merge the ranked lists. gives each document a score of 1 / (k + rank) in each list, with k often 60, and adds them up. Add a over the merged top 50 for further gains.

score(d)=∑lists1k+rank(d)\mathrm{score}(d) = \sum_{\text{lists}} \frac{1}{k + \mathrm{rank}(d)}

A worked example: merging two lists

Keyword results: page A (1st), B (2nd), C (3rd). Semantic results: D (1st), A (2nd), E (3rd). With reciprocal rank fusion (k = 60): A scores 1/61 + 1/62 = 0.0325, D scores 1/61 = 0.0164, B scores 1/62 = 0.0161. A rises to the top because both methods liked it. A reranker can then reorder the top 50.

When to use which

Product codes, names, error messages, legal citations: keyword helps most. Vague questions in natural language: semantic helps most. Do both and let fusion decide.

How BM25 gives a score

BM25 rests on three ideas. A rare word is worth more than a common one. A word repeated many times helps, but each repeat adds less. A very long page is slightly discounted, so it does not win just by containing more words.

Here is the rarity idea in simplified form, with invented numbers. Among 1,000 pages, "ERR_4021" appears in 2 and "the" appears in 990. Using a natural , a rarity is about ln(1000 / 2) = 6.2 for the code and ln(1000 / 990) = 0.01 for "the". The code is worth about 600 times more. Real BM25 uses a slightly different formula, but the effect is the same.

A second example: fusion going wrong

Reciprocal rank fusion uses only ranks, not scores. Suppose the semantic list puts a junk page 1st, and the keyword list does not contain it. Junk scores 1/61 = 0.0164. A good page ranked 3rd in both lists scores 1/63 + 1/63 = 0.0317, so it beats the junk. Agreement between lists protects you. But if one list is poor for a query type, its top results still get a boost, so a weak list can add noise.

What goes wrong

Keyword search fails on small spelling differences: "e-mail" against "email", or "colour" against "color". The symptom is a page you know exists that never appears for one phrasing. Semantic search fails on exact identifiers and on negations. Test both lists separately with the same query before you blame the fusion step.

Trade-offs

means two indexes to build and keep in sync, and two searches per question, so it adds time and upkeep. It pays off when your users mix exact terms and vague questions. If your corpus is all long natural prose and your users ask conversational questions, semantic search alone may be enough.

Try it yourself

Write 15 queries: five with exact codes or names, five vague, five mixed. Run keyword only, semantic only, then fusion. For each, note whether the right page is in the top five. Expect keyword to win the first group, semantic the second, and fusion to be rarely worst. If fusion adds nothing for your data, skip it.

Common mistake

Adding hybrid search without a test set, so you cannot tell if it helped.

Check yourself

Which search is better at finding the exact string ERR_4021?

A document ranks 1st in keyword and 3rd in semantic results. What does reciprocal rank fusion with k = 60 give it?

Users type "my screen is frozen" but the page says "Application not responding". Which search helps?

Go deeper

Spotted a mistake or something unclear? Report it on GitHub.

On this page