SearchLab

An offline relevance lab for hybrid search — BM25, dense vectors, RRF fusion, and cross-encoder reranking, measured against public BEIR benchmarks instead of vibes.

Kind

Search

Stack

Python, Elasticsearch, pgvector

Status

stable

RETRIEVER PROTOCOL SWAPPABLE BACKENDS elasticsearch postgres query BM25 · inverted index dense kNN · HNSW RRF fusion OPTIONAL cross-encoder rerank eval harness ir_measures nDCG@10 · R@100 · MRR BEIR qrels
Fig 6.1 — Query → two arms → RRF → rerank → metrics

The Problem

Everyone ships search; almost nobody measures it. Teams bolt vectors onto an index, eyeball a few queries, and call it "semantic search" — with no way to know whether relevance got better, worse, or just different. The questions that actually matter are empirical: does hybrid retrieval beat lexical alone? Does a reranker earn its latency? Is Elasticsearch worth running when Postgres is already on the stack?

Every retrieval opinion here had to survive contact with hand-labeled relevance judgments.

The Approach

SearchLab is a relevance-engineering harness built around one discipline: every change is a hypothesis scored offline against a public benchmark (BEIR SciFact — 5k scientific abstracts, 300 queries, expert qrels) using standard IR metrics from ir_measures, so the numbers stay comparable to published baselines.

The Scoreboard

BackendModenDCG@10Recall@100MRRp50 ms
ElasticBM250.65370.88460.623621
ElasticBM25 + rerank0.67430.88460.6539*
Elasticvector0.64840.92500.612334
Elastichybrid (RRF)0.68960.95430.661258
Elastichybrid + rerank0.68620.95430.6611*
PostgresFTS0.29750.74590.260321
Postgresvector0.64840.92500.612331
Postgreshybrid (RRF)0.57630.92600.548762

* Rerank p50 is ≈ 2–3 s on CPU — two orders of magnitude above the retrieval rows and off-scale for this column. The cross-encoder cost is measured and discussed in the notebook's reranking section.

What the Numbers Said

The Outcome

A defensible recommendation — hybrid RRF on Elasticsearch, reranking only where a per-workload experiment earns it — plus a harness where the next question (a better encoder, a learned-sparse arm, another dataset) is one CLI flag and one afternoon away. The notebook walks the per-query evidence behind every claim above.

+3.6 nDCG@10 Hybrid RRF over the BM25 baseline
0.954 R@100 Recall with the dense arm fused in
ir_measures BEIR-comparable offline evaluation