Skip to content

feat: boost vector search weight in RRF for semantic queries#260

Merged
BYK merged 2 commits into
mainfrom
byk/weighted-rrf-vector-boost
May 12, 2026
Merged

feat: boost vector search weight in RRF for semantic queries#260
BYK merged 2 commits into
mainfrom
byk/weighted-rrf-vector-boost

Conversation

@BYK
Copy link
Copy Markdown
Owner

@BYK BYK commented May 12, 2026

Summary

  • Add optional weight parameter to reciprocalRankFusion() — changes score formula from 1/(k+rank) to weight/(k+rank), fully backward compatible
  • For recall queries with 3+ meaningful terms (after stopword removal), boost vector search lists by 1.5x in RRF fusion, improving ranking for semantic/multi-term queries where BM25 keyword dilution causes noise
  • Short queries (1-2 terms) are unchanged — BM25 excels there
  • Configurable via .lore.json: search.vectorBoostWeight (default 1.5) and search.vectorBoostMinTerms (default 3)

Motivation

Analysis of real recall queries from production logs showed that long semantic queries (e.g. "Sentry setup, logging, curator logs, debug logging configuration") return poor results because FTS5 BM25 with OR fallback matches documents containing any term — flooding results with session noise. Vector search captures semantic intent but had equal weight to each BM25 list in RRF, so it couldn't overcome the keyword noise.

At weight=1.5, a vector hit at rank 0 scores 1.5/60 = 0.025 — it still needs corroboration from at least one other list to outrank an item appearing in 2 unweighted BM25 lists (2/60 = 0.033). This is the right fusion behavior: boost semantics without letting a single vector hit dominate.

BYK added 2 commits May 12, 2026 15:49
…ation

Extract shared dataDir() into packages/core/src/data-dir.ts that
atomically renames ~/.local/share/opencode-lore/ to ~/.local/share/lore/
on first access. This eliminates the duplicated path logic between db.ts
and log.ts, and migrates existing users transparently on startup.

Migration is one-shot per process, silent on failure, and skipped in
test environments. If both old and new directories exist, the new one
wins.
Long multi-term queries suffer from FTS keyword dilution — BM25 OR
fallback matches documents containing any term, flooding results with
session noise. Vector search captures semantic intent but had equal
weight to each BM25 list in reciprocal rank fusion.

Add configurable weight parameter to RRF so vector search lists get
boosted (default 1.5x) when the query has 3+ meaningful terms. Short
keyword queries (1-2 terms) are unchanged since BM25 excels there.

Config keys: search.vectorBoostWeight (1-5, default 1.5),
search.vectorBoostMinTerms (1-10, default 3).
@BYK BYK merged commit db791b9 into main May 12, 2026
7 checks passed
@BYK BYK deleted the byk/weighted-rrf-vector-boost branch May 12, 2026 16:47
BYK added a commit that referenced this pull request May 12, 2026
…ker boilerplate (#261)

## Summary

- Add `AND m.distilled = 0` filter to all temporal FTS search queries
(`search()`, `searchScored()`, `searchLike()`) — matches what vector
search already does, uses existing compound index
- Add DB migration v20 that purges legacy worker boilerplate messages
(observer, curator, consolidation, reflector, eval system prompts) from
temporal storage

## Motivation

Temporal FTS search was hitting all 114K+ messages, but only ~14K
undistilled ones are meaningful for recall. The other 100K distilled
messages are already represented in distillation search results,
creating duplicate signal that dilutes results.

Additionally, ~355 legacy worker boilerplate messages (averaging 100KB+
each, with observer prompts up to 1.6MB containing full conversation
transcripts) were polluting keyword matches for virtually any domain
query. These came from older gateway/plugin worker calls that stored
their full system prompts in temporal storage — a pattern that has since
been fixed (no new boilerplate since May 9).

Combined with #260 (weighted RRF for vector search), this should
significantly improve recall quality for multi-term semantic queries.
This was referenced May 13, 2026
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