feat(brain): hybrid BM25+vector search via Qdrant + nomic-embed-text #8
Closed
opened 2026-05-12 15:34:32 +00:00 by mathias
·
3 comments
No Branch/Tag Specified
main
fix/pipeline-writes-158
fix/edit-path-io-192
fix/create-regular-188
fix/guard-special-179
fix/linkcheck-keeps-write-178
fix/write-dir-redirect-173
fix/tunnel-detect-174
fix/pipeline-root-157
w3/154-mcp-auth-wiring
fix/tunnel-traversal
test/in-brain-targets-171
fix/brain-scan-root-157
fix/graph-wiki-root-157
fix/vectorstore-root-157
fix/notes-root-157
fix/search-root-157
fix/brainwide-root-157
fix/raw-symlinks-153
feat/symlink-tripwire-157
fix/rest-auth-149
fix/123-brain-edit-envelope-check
feat/106-page-aware-extraction
fix/105-source-drift-on-main
fix/104-surface-merge-conflicts-on-main
agent/b1-compile-on-ingest
agent/104-surface-merge-conflicts
agent/105-source-drift
agent/107-loud-unconfigured-alerting
feat/brain-read-edit
fix/capture-i1-refusal-names-target
renovate/configure
feat/consolidate-single-harness
icebox/cmd-routing
feat/brain-pending-promote
fix/close-session-classification-refresh
fix/capture-summarywriter
v0.24.0
v0.23.1
v0.23.0
v0.22.0
v0.21.1
v0.21.0
v0.20.1
v0.20.0
v0.19.1
v0.19.0
v0.18.4
v0.18.3
v0.18.2
v0.18.1
v0.18.0
v0.17.0
v0.16.1
v0.16.0
v0.15.0
v0.14.0
v0.13.2
v0.13.1
v0.13.0
v0.12.1
v0.12.0
v0.11.2
icebox/cmd-routing-2026-07-01
v0.11.1
v0.11.0
v0.10.0
v0.9.0
v0.8.0
v0.7.0
v0.6.0
v0.5.0
v0.4.1
v0.4.0
v0.3.0
v0.2.0
v0.1.0
Labels
Clear labels
agent/ready
blocked/client
blocked/supplier
blocked/upstream
risk/high
risk/low
risk/medium
size/l
size/m
size/s
size/xs
status:dispatch
status:dispatched
status:review
status:reviewing
type/chore
type/decision
type/docs
type/feat
type/fix
type/ops
type/research
type/test
Meets the agent-ready contract; authorizes unattended execution
Waiting on the client
Waiting on a supplier
Waiting on an upstream project or vendor
Irreversible, security-relevant, or control plane
Reversible, local, test-covered
Touches shared state, deploys or data
Too big - split it
Under two days
Under half a day
Under an hour
Maintenance, no behaviour change
Human decision required; never agent/ready
Documentation only
New capability
Corrects broken behaviour
Infrastructure, deploy, runtime
Investigate; output is a finding, not code
Test coverage only
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: mathias/hyperguild#8
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Context
Brain search is BM25-only (keyword frequency). Semantic similarity search would catch synonyms and paraphrases that BM25 misses. Qdrant is already the chosen vector store (see DECISIONS.md). nomic-embed-text runs on iguana via Ollama.
mem0 stack on koala was down when this was last checked — verify before building.
Proposed change
brain_write/brain_ingest: embed chunk with nomic-embed-text → upsert into Qdrant collectionbrainbrain_query/brain_answer: run BM25 + Qdrant vector search in parallel, merge results (RRF or score threshold), deduplicate by pathBRAIN_QDRANT_URL,BRAIN_EMBED_URL(both opt-in)/backfill-refsor new/backfill-embeddings) to embed existing brain docsPrerequisites
braincollection or per-type collectionsAcceptance criteria
task checkpassesScope clarification: this issue is now the single source of truth for embedding-based brain retrieval. The embedding portion of #2 (flat-JSON sidecar at
brain/.embeddings/index.json) was a parallel design that conflicted with DECISIONS.md (Qdrant). #2 has been closed and split — Tunnels live in #16, embeddings live here.When picking this up, the scope to keep from #2's design notes:
α) — not strictly required, but nice for tuningBRAIN_QDRANT_URL+BRAIN_EMBED_URL) — already in this issueDepends on #1 (Hall taxonomy) for path-scoped queries to be meaningful.
Scope update (2026-05-18): backend switched from Qdrant → pgvector on the existing postgres18 in
databasesnamespace.Reason: Qdrant has never been deployed — no pod, no service, no manifest. Postgres18+pgvector is already running and shared across the project; CLAUDE.md lists pgvector as the default vector store anyway. Spinning up a new engine for one consumer is friction the 2026-04-08 ADR didn't weigh. Recorded in DECISIONS.md 2026-05-18 (supersedes 2026-04-08).
Revised target shape:
brain_embeddings(path TEXT PRIMARY KEY, embedding VECTOR(768), updated_at TIMESTAMPTZ)(768 = nomic-embed-text dimension)<=>operatorαafter measuringnomic-embed-texton iguana ollama (confirmed loaded)BRAIN_EMBED_URLfor embedder, plus aBRAIN_PG_DSNfor the brain postgres connection)brain_queryruns BM25 + cosine in parallel and merges resultsOut of scope unchanged: Qdrant retained as documented fallback for >1M vectors in CLAUDE.md.
Shipped in
57462b5. Backend pivoted to pgvector (see DECISIONS.md 2026-05-18).Surface:
embed.Client(Ollama embed),vectorstore.PGStore(pgxpool+pgvector HNSW),vectorstore.Sync(walk wiki/, upsert deltas, delete vanished).search.Querygains optionalVector+Embedder; when both set, BM25 + pgvector merge via Reciprocal Rank Fusion (k=60). MCP wired viaWithHybridRetrieval. New RESTPOST /backfill-embeddings.Env:
BRAIN_PG_DSN+BRAIN_EMBED_URLmust be set together (one alone → exit 1). Defaults: nomic-embed-text:latest (768d), 300s sync interval. Backfill: post to/backfill-embeddings.DB bootstrap:
scripts/brain-embeddings-init.sql— one-time DBA setup.Acceptance criteria all met,
task checkclean. CI deploys image automatically; live verification gated on SOPS secret update.