feat: replace nomic-embed-text retriever with Agent-ModernColBERT #15
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/colbert-retriever"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Closes #8.
app/services/colbert_index.py: newColBERTIndex, mirrorsBM25Index's dirty-flag/rebuild-from-SQLite pattern.app/services/retriever.py:hybrid_search's semantic half now merges BM25 with Agent-ModernColBERT MaxSim scores (min-max normalized per-batch) instead of Ollama-embed + sqlite-vec cosine. BM25 merge/rank/per-doc-cap/adjacent-chunk-window logic unchanged.ColBERTIndexregistry inapp/main.py/app/deps.py, same pattern as the existing BM25 registry.pylate, no Ollama dependency, but still gated behind the same check.agent-moderncolbertregistered with apagepiper/retrieveassignment referencing this issue — someone pre-wired that side already.A note on how this was tested
pylate is intentionally not installed in the dev/test env. Installing it directly into the shared
cfconda env on Heimdall broke several other services' torch/transformers pins (vllm, xformers, chatterbox-tts, pyannote-audio) — see the cf-sysadmin skill's "Known Gotchas" for the full incident writeup and the isolated-env remediation (cf-vllm,cf-voice, and a generalsandboxenv on Sif for this kind of research going forward). Instead:sandboxenv (isolated, throwaway) — confirmed the full encode → index → retrieve workflow against the real Agent-ModernColBERT model, including a query matching this issue's own motivating example ("how do I set the IP on the AVC-X") ranking the correct document first.pylate/pylate.models/pylate.indexes/pylate.retrievemodules viasys.modulessoColBERTIndex's lazy imports resolve to mocks without pylate needing to be installed anywhere near this repo's own dev env.Known follow-up (not addressed here)
Shelve scripts still compute and store Ollama embeddings into
page_vecsat shelve time — that table is no longer read by search/chat now that retrieval uses the ColBERT index. Removing the now-redundant embedding step is separate cleanup.Test plan
pytest tests/ -q— 69 passed (12 new tests)/chatendpoint end-to-end (would needpylateactually installed in pagepiper's own Docker image/environment.yml, not yet done)When CF_ORCH_URL is set, chat now calls CFOrchClient.task_allocate("pagepiper", "rag_query") instead of routing through LLMRouter with an explicit model. The coordinator resolves the assignment (granite-4.1-8b via assignments.yaml) and returns an allocated URL; pagepiper wraps it in a minimal LLMRouter config for the Synthesizer. Falls back to LLMRouter on TaskNotFound or allocation failure, so standalone Ollama installs are unaffected. Extracts _run_chat() and _build_llm_for_alloc() helpers to keep the endpoint body readable regardless of which path fires.