Skip to content
C.W.K.
Stream
Lesson 03 of 04 · published

Fusion Without False Certainty

~11 min · rrf, ranking, scores, explainability

Level 0Trace
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

Score scales disagree

FTS bm25 and vector cosine have different shapes and directions. One may be better when lower while another increases with similarity. Normalizing and adding them produces query-dependent numbers with no stable meaning.

RRF uses rank instead of raw score. It rewards items near the top of several lists without calibrating incompatible scales. The method is simple, robust, and easy to extend with another lane.

A fusion score is not probability

RRF at 0.03 is not three-percent truth, and 0.08 is not eighty-percent merge confidence. It is only an ordering signal from rank positions. A percent or confidence label claims more meaning than the math provides.

Use Hybrid rank or combined order, and show lane ranks plus match reasons in detail. Hiding a score may be fine; hiding provenance is not.

A missing lane is a state

When embeddings fail, lexical results may continue. Label them lexical-only and show Meaning unavailable instead of pretending fusion remains complete. Otherwise users read relevance change as content change.

Vector-only service may likewise continue during FTS rebuild. Degradation policy should preserve lane independence and distinguish zero results from zero available lanes.

Evaluate with a query set

One pleasing result cannot validate fusion. Build a fixed set spanning exact names, Korean paraphrases, acronyms, and long conceptual questions, then compare lexical, vector, and fused top-k.

Use relevance judgments from people who read source. Clicks contain position bias, and opening a curation candidate may mean it looks wrong rather than relevant. Behavioral proxies are not ground truth.

Rank fusion orders evidence; it does not invent confidence. Do not mix incompatible scales. Expose rank, availability, and match reason.

Code

A small Reciprocal Rank Fusion implementation·python
def rrf(rankings, k=60):
    scores = {}
    for ranking in rankings:
        for rank, item in enumerate(ranking, start=1):
            scores[item] = scores.get(item, 0) + 1 / (k + rank)
    return sorted(scores, key=scores.get, reverse=True)

text = ["a", "b", "c"]
meaning = ["b", "d", "a"]
assert rrf([text, meaning])[0] in {"a", "b"}

External links

Exercise

Inspect a hybrid-search UI and remove percentages or bars that imply probability. Show lane rank, match reason, and degraded availability instead.
Hint
A number between zero and one is not automatically a probability. Explain its formula in user language.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.