Why raw dense and sparse scores should not be added directly
Talqora Vector uses regional S3 Vectors for dense search and Quickwit BM25 for sparse search. These systems produce rankings from different retrieval models. A dense-search similarity score reflects the relationship between embedding vectors, while a BM25 score is driven by term frequency, document frequency, and field-length effects.
Adding those scores together with a fixed weight can be fragile. Score ranges may differ across queries, embedding models, index configurations, or corpus changes. A query containing a rare error code, for example, can produce a sharply peaked BM25 ranking, while a broad natural-language question may have a flatter dense ranking. Rank positions are usually more comparable than the underlying score values.
- Dense retrieval helps with paraphrases and conceptual similarity.
- BM25 helps with exact terms, product names, codes, and quoted phrases.
- Raw score scales are model- and query-dependent.
- A fusion method should tolerate differing score distributions.
Fuse two ranked lists with RRF
RRF assigns each document a contribution based on its position in each result list. For a document d, calculate RRF(d) = Σ 1 / (k + rank_i(d)), where rank_i is the one-based rank in retrieval list i and k is a positive constant. Documents that appear near the top of either list receive useful credit, while documents supported by both lists rise further.
A common starting value for k is 60, but it is a tuning parameter rather than a universal rule. Retrieve a bounded candidate set from the S3 Vectors dense path and another from the Quickwit BM25 path, deduplicate by a stable document or chunk identifier, compute the fused score, then sort descending. If a document appears in only one list, it still participates using its contribution from that list.
- Request top N candidates from dense retrieval.
- Request top N candidates from BM25 retrieval.
- Use one stable ID to deduplicate documents or chunks.
- Sum reciprocal-rank contributions and return the highest fused results.
Evaluate fusion with query slices, not a single average
Start with a small evaluation set that reflects how people search your corpus. Include exact-identifier queries, short keyword queries, natural-language questions, acronym-heavy requests, and queries whose wording differs from the expected answer. For each query, record whether a relevant item appears in the top results for dense-only, sparse-only, and fused retrieval.
RRF is a strong baseline because it avoids score calibration, but it is still a retrieval policy that should be checked as content and query behavior change. Inspect failures by slice. If exact matches regress, increase the sparse candidate depth or verify tokenization and indexed fields. If semantic queries regress, inspect chunk boundaries, embedding inputs, and dense candidate depth before changing fusion logic.
- Compare dense-only, sparse-only, and fused rankings on the same queries.
- Track recall-oriented measures at the result depth your application uses.
- Review failures by query type rather than relying only on an aggregate metric.
- Keep candidate depths and the RRF k value explicit in configuration.
