Zenaique

Pick the right way to fuse BM25 and dense scores before context assembly

MCQ·Medium·4.0 · 0·~1 min·Asked atCrestaMicrosoftServicenow
Attempt it
TL;DR

Reciprocal Rank Fusion works on ranks, not raw scores, so it sidesteps the fact that BM25 and cosine live on incompatible scales, and it is parameter-free in practice.

Memory aid
Sign in to see the mnemonic that makes this stick.
Easy to grasp

Imagine two teachers grading your essay on different scales. One gives marks out of 100, the other gives stars from 0 to 5. Adding 87 plus 4 is nonsense, different units. Averaging after a normalization is fragile because one teacher might happen to give very spread-out scores this term. The robust trick: ask each teacher to rank all the essays from best to worst. Then combine the rankings. An essay that came in first for both teachers is clearly best; an essay that came in first for one and tenth for the other is middling. Rank-based fusion does not care about the units. RRF is the standard recipe for this kind of combination.

Concept explanation~2 min read

Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.

Hybrid retrieval needs a fusion step. Two retrievers each produced a ranked list of candidates; the pipeline has to combine them into a single ranking before assembly. Three of the four options listed are wrong in instructive ways. The fourth, Reciprocal Rank Fusion, is the production default for reasons worth understanding.

Why raw-score addition fails

BM25 and cosine similarity are computed by different formulas with different bounds.

BM25 for a query against a document is roughly the sum over query terms of idf(term) × tf(term, doc) × length_norm. The raw output depends on how rare the terms are in the corpus and how long the matched document is. A query against a long-document corpus with common terms produces scores around 1-3. A query with rare terms against short documents can produce scores around 20-30.

Cosine similarity between two unit-norm embeddings is bounded in [-1, 1] and in practice clusters in narrow bands like 0.4 to 0.9 for retrieval workloads.

The consequence

Adding raw BM25 to raw cosine means the ranking is dominated by whichever retriever happens to have a larger numeric scale this query. That domination shifts per query as the BM25 score distribution changes with the term rarity profile. The ranking is unstable. A retrieval system with query-dependent dominance is not a production system.

Why concatenation and score averaging are also wrong
What RRF does and why it works
Production patterns and when RRF is not enough
Sign in to unlock the full deep dive.

Situations where this technique stops working.

Sign in to see when this approach fails.

2–4 min · Everything important, quickly.

Sign in to see the quick scan of the deep dive.
python
def rrf_fuse(rank_lists: list[list[str]], k: int = 60) -> list[tuple[str, float]]:
    """Reciprocal Rank Fusion across N ranked lists.
    Each list is doc_ids ordered best-first.
    Returns (doc_id, score) sorted by score desc.
    """
    scores: dict[str, float] = {}
    for ranks in rank_lists:
        for r, doc_id in enumerate(ranks, start=1):
            scores[doc_id] = scores.get(doc_id, 0.0) + 1.0 / (k + r)
    return sorted(scores.items(), key=lambda kv: kv[1], reverse=True)

# Example
dense_top = ["d3", "d1", "d7", "d2", "d5"]
bm25_top = ["d1", "d3", "d9", "d4", "d2"]
fused = rrf_fuse([dense_top, bm25_top])
# d1 and d3 dominate because they ranked high in both lists

Real products, models, and research that use this idea.

  • Elasticsearch 8.x and OpenSearch 2.x expose `rrf` as the documented fusion operator for hybrid queries.
  • Vespa's hybrid retrieval guide uses RRF with k=60 as the default sample configuration.
Sign in to see more production examples.

What an interviewer would ask next. Try answering before peeking at the approach.

QWhen would you reach for a weighted RRF instead of vanilla RRF?
A

When one retriever is known to be substantially better on the workload; introduce per-retriever weights as w / (k + rank) and tune on a labelled eval.

2 more follow-ups an interviewer would ask next. Sign in to reveal them.

Red flags & common mistakes

The phrases that signal junior thinking. Click to expand.

Most common mistake

Adding raw BM25 and cosine scores. BM25 can range 0 to 30+ depending on document length and term rarity; cosine is bounded around 0.4 to 0.9. The sum is meaningless and varies wildly per query.

Sign in to see all red flags and common mistakes.

60 second bullets to scan on the way to the call.

  • State the RRF score formula

  • Explain why BM25 and cosine scores are on incompatible scales

Sign in to unlock the revision sheet.

Primary sources. Browse if you want the original framing.

Similar questions

Same topic, related formats. Practice these next.

4 curated
Next question
Pick the most effective intervention when an agent's context grows by 8KB every iteration
MCQ·Medium