This repository has been archived on 2026-07-19. You can view files and clone it. You cannot open issues or pull requests or push a commit.
chaim 1441a41d45 feat(kb/search): LLM-powered query expansion in /kb/search
Single-shot search ranks the source whose title literally contains the
query terms way above everything else, so "מהי תקנה 37" returns 6 hits
from the תקנה 37 circular + 2 from the law and zero from ספר הליקויים
— even though the latter is the canonical medical reference for that
regulation. The ask agent already worked around this by issuing several
search_insurance_kb calls with different phrasings; that intelligence is
now also available to the public /kb/search endpoint.

Implementation:
- _retrieve_rrf extracts vector + lexical retrieval (RRF fused, no
  rerank) into a reusable async helper. Each candidate now carries
  chunk_id so callers can dedup when merging multiple sub-searches.
- _expand_query asks the configured Claude model (via ai-gateway) for
  up to 3 alternative phrasings, with a 12s timeout. On any failure the
  caller silently falls back to single-query mode.
- search() gains an `expand: bool` parameter. When true, runs the
  original query plus all variants through _retrieve_rrf in parallel,
  merges by chunk_id keeping the best RRF score, and reranks the union
  against the ORIGINAL query so the final order reflects what the user
  asked, not the variants.
- /kb/search defaults to expand=true.

Cost per call: 1 extra LLM round-trip (~1-2s on Sonnet) and 3 extra
Voyage embeds (~150ms each, parallel). Latency budget grows from ~700ms
to ~3s, acceptable for a search the user explicitly triggered.

Refs Task Master #1
2026-04-25 10:09:47 +00:00
2026-04-13 17:29:35 +00:00
S
Description
Archived from gitea.marcus1.com
287 KiB
Languages
Python 96.3%
PLpgSQL 3.5%
Dockerfile 0.2%