Skip to content

feat(search): RRF re-rank + junk/coverage/geo filter + query cleaning for answer path - #68

Merged
us merged 1 commit into
mainfrom
feat/search-rerank
May 31, 2026
Merged

feat(search): RRF re-rank + junk/coverage/geo filter + query cleaning for answer path#68
us merged 1 commit into
mainfrom
feat/search-rerank

Conversation

@us

@us us commented May 31, 2026

Copy link
Copy Markdown
Owner

Bring SearXNG-backed answer search toward Tavily-grade

The LLM answer/summarize search path fed the synthesizer whatever SearXNG's raw
.score ranked first — which is rank-inverse and content-blind. SearXNG's bing
engine keyword-matches stopwords ("top"/"best"/"fix") and returns dictionary
definitions (merriam-webster), retailer homepages (bestbuy/zara) and homonym
pages at a flat score 1.0 that tie/outrank real results. Measured: Junk@5 = 54
across a 56-query corpus; "top restaurants in belgrad" returned Belgrad-Forest
(Istanbul) / Belgrade-Lakes (Maine) noise.

What changed (answer/summarize path only; plain search unchanged)

  • rerank.rs (new): RRF fusion over per-engine ranks (k=60) + hard junk
    filter (dictionary/shopping/captcha/asset-leak) + BM25-lite relevance + query
    term-coverage guard + geo disambiguation (region vs competing toponyms) +
    per-registrable-domain dedupe.
  • client.rs: capture SearXNG's engines[]/positions[] (needed for RRF).
  • params.rs: clean_query strips a leading ranking stopword
    (top/best/good/greatest/finest/cheapest) when ≥3 tokens and not quoted — this
    removes the bing "best→dictionary/bestbuy" bait at the source — plus pins
    language=en when the request omits it (explicit per-request language honored).
  • transform.rs: new transform_flat_reranked; transform_flat kept for the
    plain (non-LLM) path for SaaS byte-parity.
  • search.rs: answer/summarize builds the pool via the reranked transform,
    gated by new rerank_enabled config (default true).

Results (frozen-fixture cargo test, reproducible)

  • Junk@5: 54 → 0 (corpus-wide assert).
  • "top restaurants in belgrad" → tripadvisor / michelin / lepetitchef, no
    Istanbul/Maine competing tokens.
  • "python snake habitat" → excludes python.org/codecademy (homonym).
  • CleanRel@5 (snippet term-coverage fraction) 0.47 → 0.52; the dominant win is
    junk elimination + geo/homonym correctness, not the coverage fraction (which is
    bounded by snippet text in the fixtures).

cargo test -p crw-search 44 pass (5 new rerank gates), cargo test -p crw-server
89 pass, clippy -D warnings + fmt clean. CPU-only, no new network/deps.

Pairs with the deployed SearXNG config change (down-weight bing, weight google,
language pin) and is independent of the proxy-reliability work.

Copilot AI review requested due to automatic review settings May 31, 2026 14:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@us
us merged commit 32efee6 into main May 31, 2026
1 of 2 checks passed
us added a commit that referenced this pull request Jun 1, 2026
#68's answer-path reranker ran the FULL composite (RRF + BM25 + geo-score) on
every query. On the frozen benchmark that composite REGRESSES the raw-score
baseline because our cross-engine overlap is near-zero (positions median = 1),
making RRF the single worst variant.

Default to the lexical core — the only variant that beats baseline: junk filter
(structural + host blocklist) + coverage guard + competing-region filter, then
order survivors by SearXNG's raw score and dedupe by registrable domain.
Measured vs the raw-score baseline on the Tavily oracle: CleanRel 0.296->0.571,
Junk@5 70->0, Recall 0.182->0.271, nDCG@5 0.144->0.224.

- remove the composite RRF/BM25/geo-score from the default path
- retain rrf/bm25_lite/geo_score (#[allow(dead_code)]) for a future
  config-gated experiment; the benchmark is the gate
- drop "2025"/"2026" year literals from STOPWORDS (corpus-specific, they rot)
- #68's rerank_tests.rs (geo-correct, junk@5==0, dedupe) stay green
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.

2 participants