AI / MLMarch 15, 20265 min read
Hybrid Search: BM25 + pgvector for RAG Retrieval
Combining Elasticsearch BM25 keyword search with pgvector semantic search for better RAG retrieval quality.
Two retrieval methods, one RAG pipeline
RAG retrieval quality depends on the search layer beneath it. BM25 via Elasticsearch handles exact matches: city names, hotel brands, attraction titles. pgvector handles semantic similarity: "romantic getaway" matching "honeymoon destination."
async def hybrid_search(query: str, top_k: int = 10):
# BM25 keyword retrieval
keyword_hits = await elasticsearch.search(query, top_k=top_k)
# Vector semantic retrieval
vector_hits = await pgvector.search(query, top_k=top_k)
# Merge ranked results
return reciprocal_rank_fusion(keyword_hits, vector_hits)[:top_k]Better retrieval means better RAG context, which means better LLM answers. The search layer is where RAG quality is won or lost before the model ever sees a prompt.