llm: retrieval endpoints — /search, /similar #570

Closed
opened 2026-07-16 19:26:08 +00:00 by kert · 2 comments
Owner

Similarity search over the comment + corpus collections.

Scope

  • /search: query text + metadata filters (docket, rule, year, doctype, collection), pagination
  • /similar/{key}: nearest neighbors of an existing bib item
  • results cite bib item keys + chunk snippets + distances

Acceptance

  • filtered search returns correct docket-scoped results on the pilot docket; p50 latency < 300ms

Spec: docs/superpowers/specs/2026-07-16-llm-module-design.md

Similarity search over the comment + corpus collections. **Scope** - [ ] `/search`: query text + metadata filters (docket, rule, year, doctype, collection), pagination - [ ] `/similar/{key}`: nearest neighbors of an existing bib item - [ ] results cite bib item keys + chunk snippets + distances **Acceptance** - filtered search returns correct docket-scoped results on the pilot docket; p50 latency < 300ms Spec: [`docs/superpowers/specs/2026-07-16-llm-module-design.md`](https://git.fhirworx.io/homelab/stack/src/branch/main/docs/superpowers/specs/2026-07-16-llm-module-design.md)
kert added this to the P34: LLM Query — RAG API, CLI, notebook client milestone 2026-07-16 19:26:08 +00:00
kert added the apillm labels 2026-07-16 19:26:08 +00:00
Author
Owner

Status audit (2026-08-13, repo-verified): NOT DONE. api.py exposes only /health, /, /whoami, /chat. Retrieval exists internally (llm/rag.py:29 retrieve, k=6, comments collection) but no /search or /similar HTTP endpoints, no metadata filters, no pagination. Note: the rules pgvector collection added by P36 (#595) will want the same filters.

**Status audit (2026-08-13, repo-verified):** NOT DONE. api.py exposes only /health, /, /whoami, /chat. Retrieval exists internally ([`llm/rag.py:29`](https://git.fhirworx.io/homelab/stack/src/branch/main/src/llm/rag.py#L29) retrieve, k=6, comments collection) but no /search or /similar HTTP endpoints, no metadata filters, no pagination. Note: the `rules` pgvector collection added by P36 (#595) will want the same filters.
Author
Owner

Done (192274e, merged to main): GET /search?q=&collection=all|comments|rules|corpus&docket=&item_key=&year=&kind=&limit=&offset= and GET /similar/{key} on the llm service (src/llm/search.py). One embedding per request, per-collection overfetch with docket/item_key/kind pushed into the pgvector store filter and year applied on the chunk date, merged by distance, paginated; /similar averages up to three of the item's own chunk vectors and excludes the item; results are the chat's source dicts (label, kind, url, title, date, docket, item_key, p_id/seq, snippet) plus distance. Acceptance: docket-scoped search on CMS-2023-0121 returned only that docket; p50 ≈ 120 ms over 5 in-process calls (first call 2.8 s includes model warm-up). 57 tests. Note: total is the page length (no COUNT query). Needs the llm image rolled to reach the live service.

Done (192274e, merged to main): GET /search?q=&collection=all|comments|rules|corpus&docket=&item_key=&year=&kind=&limit=&offset= and GET /similar/{key} on the llm service (src/llm/search.py). One embedding per request, per-collection overfetch with docket/item_key/kind pushed into the pgvector store filter and year applied on the chunk date, merged by distance, paginated; /similar averages up to three of the item's own chunk vectors and excludes the item; results are the chat's source dicts (label, kind, url, title, date, docket, item_key, p_id/seq, snippet) plus distance. Acceptance: docket-scoped search on CMS-2023-0121 returned only that docket; p50 ≈ 120 ms over 5 in-process calls (first call 2.8 s includes model warm-up). 57 tests. Note: total is the page length (no COUNT query). Needs the llm image rolled to reach the live service.
kert closed this issue 2026-09-11 21:18:47 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: homelab/stack#570