fix(search): over-fetch vector candidates so the sidechain filter can't starve results#115
Open
iceinvein wants to merge 1 commit into
Open
fix(search): over-fetch vector candidates so the sidechain filter can't starve results#115iceinvein wants to merge 1 commit into
iceinvein wants to merge 1 commit into
Conversation
…'t starve results vec0 applies the KNN `k` cutoff before the WHERE clause, so the always-on `is_sidechain = 0` filter (and any metadata filters) can shrink the result set below `limit`. With subagent (sidechain) exchanges crowding the nearest neighbours, requesting exactly `limit` candidates returns far fewer than `limit` real hits, often zero at small limits, while text search is unaffected. Over-fetch candidates with headroom for the always-on sidechain filter (`limit + 100`, or `limit * 3` when metadata filters are also active) and trim to `limit` after filtering. The sidechain filter was introduced in obra#42. Adds a regression test that indexes one real exchange among many sidechain neighbours and asserts vector search still returns it at a small limit; the test fails on the previous `k = limit` behaviour.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Vector/semantic search returns far fewer results than
limit, often zero at small limits, while text search works fine. On a ~31k-exchange index (~13% sidechain),mode: "vector"returned: limit 3 -> 0, limit 10 -> 2, limit 25 -> 11.Cause
In
searchConversations, the vec0 KNN query is:vec0 applies the
kcutoff before theWHERE, butkis only inflated (limit * 3) when metadata filters are present, never for the always-onis_sidechain = 0filter. Subagent (sidechain) exchanges crowd the nearest neighbours and get removed after the cut, leaving fewer thanlimitresults (often none at small limits). Text search is unaffected because it does not usek.The
is_sidechain = 0filter was added in #42; this is the latent recall regression introduced alongside it.Related: #111 (skip indexing sidechains) would hide this for fresh installs, but its stated assumption that search results are identical before and after does not hold for the vector path, and it does not fix the query for any index that still contains sidechain rows.
Fix
Over-fetch candidates with headroom for the always-on sidechain filter (
limit + 100, orlimit * 3when metadata filters are also active) and trim tolimitafter filtering (the existing trim handles the upper bound). This matches the existinglimit * 3idiom; a fully guaranteedlimitwould require iterativekexpansion, which could be a follow-up.Test
Adds
test/search-sidechain-recall.test.ts: indexes one real exchange among 20 sidechain neighbours on the query topic, then asserts vector search still returns it atlimit: 3and never returns sidechain rows. The test fails on the previousk = limitbehaviour and passes with the fix.Verification
show.test.tsdate-format assertion) that also fails on cleanmain, unrelated to this change.npm run buildclean.