Retrieval currently asks the model to choose between vector and full-text search. It has now been observed choosing wrong in both directions, and each mistake was expensive. Fusing both and ranking the union removes the decision instead of trying to instruct it better.
Current state
ToolishRag exposes vectorSearch and textSearch as separate tools, and the tool descriptions tell the model when to use each. On a 40-question benchmark corpus:
- With one wording, the model called full-text 22 times against vector's 1 — including for pure prose questions with no identifier in them. It then required every word, matching zero chunks, and retrieval returned empty.
- With the corrected wording it inverted to 1 against 7, barely using full-text at all — including for questions where an exact-wording match is what would answer them.
Both are routing failures. Neither is obviously fixable by better instructions: the categories the guidance uses ("semantic queries", "exact-keyword matches") are not ones a model can reliably recognise, because every question has keywords in it.
Why fusion rather than better routing
The two retrievers fail on different inputs and succeed on different inputs, which is the textbook case for running both. The obstacle has always been that their scores are not comparable — BM25 sums per-term contributions and is unbounded before normalization; cosine is bounded and calibrated differently. Measured on one real corpus, query-to-chunk cosine tops out around 0.75 while normalized BM25 for the same corpus reaches 0.62–0.79 for questions and 0.29–0.55 for exact identifier matches. Merging those by score means whichever retriever happens to produce bigger numbers wins, regardless of relevance.
Reciprocal rank fusion sidesteps that entirely: it combines on Σ 1/(k + rank) and uses only ordering, which is the one thing the two retrievers genuinely share. It is what Elasticsearch, Vespa and Weaviate do for hybrid retrieval, for this reason.
Direction
One search tool that runs both retrievers and returns the fused ranking, replacing the routing choice rather than supplementing it. Keep it behind a switch so the routed surface remains available and the two can be compared on the same corpus.
Worth measuring, not assuming: fusion has a cost — two retrievals per call — and it may lose to a well-routed vector-only search on a corpus where full-text rarely helps. The benchmark is the arbiter.
Outcome
Either evidence that fusion beats routing on a real corpus, and a default worth changing, or a recorded result that routing is good enough and the extra retrieval is not worth paying for.
Retrieval currently asks the model to choose between vector and full-text search. It has now been observed choosing wrong in both directions, and each mistake was expensive. Fusing both and ranking the union removes the decision instead of trying to instruct it better.
Current state
ToolishRagexposesvectorSearchandtextSearchas separate tools, and the tool descriptions tell the model when to use each. On a 40-question benchmark corpus:Both are routing failures. Neither is obviously fixable by better instructions: the categories the guidance uses ("semantic queries", "exact-keyword matches") are not ones a model can reliably recognise, because every question has keywords in it.
Why fusion rather than better routing
The two retrievers fail on different inputs and succeed on different inputs, which is the textbook case for running both. The obstacle has always been that their scores are not comparable — BM25 sums per-term contributions and is unbounded before normalization; cosine is bounded and calibrated differently. Measured on one real corpus, query-to-chunk cosine tops out around 0.75 while normalized BM25 for the same corpus reaches 0.62–0.79 for questions and 0.29–0.55 for exact identifier matches. Merging those by score means whichever retriever happens to produce bigger numbers wins, regardless of relevance.
Reciprocal rank fusion sidesteps that entirely: it combines on
Σ 1/(k + rank)and uses only ordering, which is the one thing the two retrievers genuinely share. It is what Elasticsearch, Vespa and Weaviate do for hybrid retrieval, for this reason.Direction
One search tool that runs both retrievers and returns the fused ranking, replacing the routing choice rather than supplementing it. Keep it behind a switch so the routed surface remains available and the two can be compared on the same corpus.
Worth measuring, not assuming: fusion has a cost — two retrievals per call — and it may lose to a well-routed vector-only search on a corpus where full-text rarely helps. The benchmark is the arbiter.
Outcome
Either evidence that fusion beats routing on a real corpus, and a default worth changing, or a recorded result that routing is good enough and the extra retrieval is not worth paying for.