# What is hybrid search, and why combine keyword search with vector search?

Running a keyword search (usually BM25) and a vector search for the same query and merging the 2 ranked lists, so exact terms like a product code and loose wording like "money back" are both found.

- Page: https://tecyfy.com/concepts/hybrid-search
- Subject: Data engineering in the AI era (https://tecyfy.com/concepts)
- Level: intermediate
- Also called: Hybrid Retrieval, BM25 Plus Vector Search, Keyword and Semantic Search

Hybrid search runs 2 searches for the same question, one by keyword and one by meaning, and merges what they find. Each catches what the other misses.

**Search by meaning** compares [embeddings](https://tecyfy.com/concepts/embedding). It knows that "How long until I get my money back?" asks about refunds, though the help page never says "money back". But an embedding model squeezes a passage into a few hundred numbers, and a code like `E04` or `AST-28` barely moves them. Ask "my mixer shows E04" and a page about error E07 can come first, because it is about the same thing.

**Search by keyword** matches words. It finds `E04` exactly, and an order number, a person's name or a part number. But it has no idea that "money back" means refund, and common words like "how long" can pull in the wrong page.

Real questions mix both kinds, so a system that answers them uses both.

## How keyword search ranks: BM25

The usual keyword method is BM25, from the Okapi search system built at City University London. It scores a passage for each word of the query it contains, and 3 ideas set the score:

- **Rare words count more.** A word in 2 passages out of 1,000 says much more than a word in 900 of them.
- **Repeats count less and less.** The fifth "refund" in a passage adds far less than the first.
- **Long passages are evened out,** so a page does not win only by being long. 2 settings tune this: `k1`, usually 1.2 to 2.0, and `b`, usually 0.75.

Most search engines and databases have it built in, and it takes about 20 lines of Python to write yourself.

## Merging the 2 lists

The 2 searches score on different scales, so their scores cannot be added. The common fix ignores the scores and uses the positions. **Reciprocal rank fusion** gives each passage 1 / (60 + its rank) in every list it appears in, and adds them up. A passage ranked 1st by both gets 1/61 + 1/61. A passage only one search found still gets something, but less. The 60 comes from the paper that proposed the method in 2009, where it worked well and the exact value mattered little.

Some systems weight the 2 lists instead, for example 70% meaning and 30% keyword. That needs tuning on your own questions, and fusion by rank does not.

## Does it help?

In Anthropic's tests on several kinds of documents, adding BM25 to embeddings cut failed searches more than embeddings alone: 49% fewer failures against 35%, both with context added to each chunk. On a small, simple collection meaning search may already find everything, and fusion can even push the best passage down a place. That is why hybrid search is usually followed by [Reranking](https://tecyfy.com/concepts/reranking), which reads each candidate with the question and puts them in order, and why you check any change with [recall at k](https://tecyfy.com/concepts/retrieval-evaluation) on real questions.

## Related

- [Reranking](https://tecyfy.com/concepts/reranking): A second search step that reads each candidate passage together with the question and scores how well it answers, so the best few of a fast first search go to the model in the right order.
- [Embedding](https://tecyfy.com/concepts/embedding): A list of numbers that stands for the meaning of a piece of text, an image or other data. Things with similar meaning get similar numbers, so a computer can find them.
- [RAG](https://tecyfy.com/concepts/rag): A way to answer from your own documents. A search finds the passages that match the question, and they are added to the prompt before the model writes.
- [Retrieval Evaluation](https://tecyfy.com/concepts/retrieval-evaluation): Testing the search step of a RAG system on its own, with questions whose answering passages you know, and scoring it with recall at k, the share of those passages found in the top k results.
- [Chunking](https://tecyfy.com/concepts/chunking): Cutting documents into smaller passages before they are embedded for retrieval, so a search returns the part that answers a question rather than a whole file.

## Sources

- [Introducing Contextual Retrieval](https://www.anthropic.com/news/contextual-retrieval)
- [Reciprocal Rank Fusion outperforms Condorcet and individual Rank Learning Methods](https://plg.uwaterloo.ca/~gvcormac/cormacksigir09-rrf.pdf)
- [Okapi BM25](https://en.wikipedia.org/wiki/Okapi_BM25)
- [Databricks AI Search](https://docs.databricks.com/aws/en/vector-search/vector-search)
