recall.scoreThreshold applied across incommensurable score scales (BM25/cosine 0-1 vs RRF ~0.03)
Author: kevinyuanCreated Sep 8, 2026Updated Sep 17, 2026
Summary
recall.scoreThreshold (default 0.3) is applied as a single absolute cutoff, but the scores it is compared against live on different, incommensurable scales depending on the search strategy.
Details
- keyword (FTS/BM25 via
bm25RankToScore): 0–1 scale →0.3is a plausible cutoff. - embedding (cosine,
1 - distance): 0–1 scale →0.3is plausible. - hybrid (RRF,
k=60): scores are ~0.016–0.05(RRF of two lists). An absolute0.3cutoff here would filter out essentially everything.
So the same scoreThreshold constant means very different things per strategy. In practice the hybrid path avoids the problem only because it does not apply the threshold at all (see related issue about searchHybrid ignoring _threshold). The keyword path additionally has a "document set is small → return below-threshold results anyway" fallback, which masks the scale mismatch.
Suggestion
Pick one of:
- Apply per-source thresholds before fusion (cosine ≥ x, BM25-score ≥ y) instead of one absolute value on the fused score;
- Drop the absolute threshold for fused/RRF results and rely on top-N;
- At minimum, document the per-strategy meaning of
scoreThresholdso operators do not set a value that is a no-op or over-filters depending on strategy.
Source: TencentCloud/TencentDB-Agent-Memory