fix(rag): the legacy search route honours the session BM25/RRF tuning (#1128)
What
RAGBackend::search → search_with_embedding → fuse_results is a second retrieval route that ignored the tuning added in #1017:
- BM25 was searched with no
k1/b. fuse_resultshardcoded the RRF constant to 60, and its normaliser to2/61.
It now passes the session config through: bm25_k1 and bm25_b to the BM25 search, and rrf_k to fuse_results. The normaliser follows the RRF constant, since the best achievable fused score is 2/(k+1). With the default config the values are unchanged.
No SDK reaches this route today, so this removes a trap rather than fixing a live bug.
I took the issue's first option (honour the tuning) rather than deleting the route, because rag_backend_thread_safety_test.cpp still calls it.
Verification
Not compiled locally. The local MinGW configure fails on a missing onnxruntime source checkout in this environment, so I could not run the build or the tests here. Please treat CI as the first real check. The change is small (three call sites, one signature, one constant), but it has not been run.
Stacking
Stacked on #1017 (the bm25_k1 / bm25_b / rrf_k config fields come from there). The diff includes its commits until it merges.
Closes #1128
Summary by cubic
The legacy RAG search route (RAGBackend::search → search_with_embedding → fuse_results) previously ignored the session BM25/RRF tuning: BM25 ran with fixed k1/b and fuse_results hardcoded the RRF constant to 60 with a matching normaliser. The route now passes the session config (bm25_k1, bm25_b, rrf_k) all the way through, and the normaliser follows the configured RRF constant. Defaults are unchanged.
The same tuning knobs, plus vector_store, are now also validated and forwarded through the engine-backed retrieve operator and the rag.search / rag.query ABI paths. The VectorStore enum moved from solutions.proto into rag.proto.
Validation and operator hardening
- BM25/RRF params are validated at the ABI boundary: non-finite
bm25_k1,bm25_boutside [0, 1], and negativerrf_kare rejected instead of silently dropping hits. - Vector store values other than UNSPECIFIED/USEARCH are rejected; PGVECTOR returns NOT_SUPPORTED.
- The retrieve operator parses numeric params strictly (full-consumption, finite, classic locale) and rejects malformed values instead of falling back to defaults.
- Float params travel between the solution converter and retrieve operator as classic-locale text that round-trips exactly.
- RRF scoring accumulates in double and ties break on id, so a large
rrf_kcan't produce accidental ties.
Summary by CodeRabbit
- New Features
- RAG retrieval settings now let you tune BM25 ranking and reciprocal-rank fusion for a session or an individual query.
- Retrieval options support selecting a vector store; currently, only the in-process USEARCH option is supported.
- Bug Fixes
- Invalid or unsupported retrieval settings are rejected with clear errors rather than silently falling back to defaults.
- Fusion scoring uses improved numeric precision and consistent ordering for results with tied scores.