Skip to content

Default hybrid fusion to relative_score (instead of RRF)#112

Merged
raphaelsty merged 1 commit into
mainfrom
feat/api-default-relative-fusion
May 28, 2026
Merged

Default hybrid fusion to relative_score (instead of RRF)#112
raphaelsty merged 1 commit into
mainfrom
feat/api-default-relative-fusion

Conversation

@raphaelsty
Copy link
Copy Markdown
Collaborator

What

Changes the default hybrid-search fusion in next-plaid-api from RRF to relative_score. Requests that omit fusion now use relative-score fusion (min-max normalize each score list to [0,1], then alpha-weight) instead of reciprocal rank fusion.

Why

Relative-score fusion uses the actual ColBERT and BM25 score magnitudes, not just rank positions, which fuses better given FTS5's high recall. It also aligns the API default with what colgrep already uses.

Changes

  • handlers/search.rs: fusion defaults to "relative_score"; the fusion match now treats rrf as the explicit-only branch and falls back to relative_score.
  • models.rs: field docs + OpenAPI schema example updated to relative_score.
  • README.md: hybrid examples + parameter table updated (fusion default is now "relative_score").

alpha default is unchanged (0.75). Explicit fusion: "rrf" is fully supported.

Compatibility note

This is a behavior change: hybrid searches that don't pass fusion will rank differently (and return [0,1]-normalized scores instead of RRF's small 1/(K+rank) values). Clients that want the old behavior pass "fusion": "rrf".

Verification

  • Build + clippy -D warnings + fmt + full make ci-quick green.
  • End-to-end: a hybrid search with no fusion field returns scores [1.0, 0.845, 0.647] — the relative-score signature (top normalized to 1.0), vs RRF's ~1/(60+rank). Explicit rrf and relative_score both return 200; invalid values → 400.

Hybrid search requests that omit `fusion` now use relative-score fusion
(min-max normalize each score list to [0,1], then alpha-weight) rather
than reciprocal rank fusion. Relative-score uses the actual ColBERT/BM25
score magnitudes instead of only rank positions, which fuses better given
FTS5's high recall, and aligns the API default with colgrep's.

- search.rs: default fusion_mode to "relative_score"; make the fusion match
  fall back to relative_score (rrf is now the explicit-only branch).
- models.rs: update field docs + schema example to relative_score.
- README: update hybrid examples and the parameter table.

Explicit `fusion: "rrf"` is unchanged and still supported. Verified e2e:
a hybrid search without `fusion` returns [0,1]-normalized scores (top=1.0),
the relative-score signature, vs RRF's ~1/(60+rank) values.
@raphaelsty raphaelsty force-pushed the feat/api-default-relative-fusion branch from 7405820 to 2b421c9 Compare May 28, 2026 23:37
@raphaelsty raphaelsty merged commit bc2daf1 into main May 28, 2026
20 checks passed
@raphaelsty raphaelsty deleted the feat/api-default-relative-fusion branch May 28, 2026 23:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant