Skip to content

Semantic-only queries return 0 results despite active vector pipeline (query embedded, index populated) — v0.9.27 #1072

Description

@verrecs

Summary

On v0.9.27 (standalone/native mode), purely-semantic queries return 0 results from smart-search (compact mode) even though the whole vector pipeline is demonstrably active: the query is embedded at search time, the vector index is populated and persisted, and doctor reports the embedding provider green. Keyword (BM25) matches over memories work fine.

Environment

  • agentmemory 0.9.27, standalone worker under systemd (user), native iii 0.11.2
  • LLM + embeddings via Ollama's OpenAI-compatible API (local GPU):
    • OPENAI_BASE_URL=http://<lan-host>:11434, OPENAI_MODEL=qwen3:4b-instruct
    • EMBEDDING_PROVIDER=openai, OPENAI_EMBEDDING_MODEL=nomic-embed-text, OPENAI_EMBEDDING_DIMENSIONS=768
  • Corpus: 52 imported Claude Code JSONL sessions → 23 780 observations, plus ~30 memories
  • doctor: LLM provider ✓, Embedding provider ✓, consolidation ✓, compression ✓

What provably works

  • Full index rebuild after purging stale index shards: 0 embed failed warnings, 39 vector shards persisted (mem:index:bm25:vectors:*)
  • Query-time embedding: every smart-search call hits the embedding endpoint (verified via Ollama /api/ps keep-alive refresh)
  • BM25: exact-keyword queries (e.g. a term present in a memory) return that memory

Bug

Semantic-only paraphrases (no shared tokens with the target text, e.g. querying in French "le noyau a assassiné une machine virtuelle faute de mémoire vive" against an OOM-incident memory that is semantically near-identical) return {"mode":"compact","results":[]} — via both the MCP tool and POST /agentmemory/smart-search.

Given HybridSearch.tripleStreamSearch() runs this.vector.search(queryEmbedding, limit*2) unconditionally once vector.size > 0, cosine top-N should always produce candidates, and RRF fusion should surface at least weak hits. It looks like either a post-fusion score threshold, or compact-mode formatting dropping observation-level (obsId) hits, hides all vector-leg results.

Two contributing traps hit on the way (worth docs/UX love)

  1. Stale persisted index blocks the lazy rebuild forever: index shards persisted before a large import reload at boot → idx.size > 0 → the if (idx.size === 0) rebuildIndex() path never fires → imported observations are never indexed. AGENTMEMORY_DROP_STALE_INDEX=true only drops the vector side on dimension mismatch; BM25 shards keep the gate closed. We had to stop the worker and delete mem:index:* bins manually to force a full rebuild.
  2. Dimensions env var naming: the OpenAI provider only reads OPENAI_EMBEDDING_DIMENSIONS; setting EMBEDDING_DIMENSIONS (a recognized var elsewhere) silently leads to Embedding dimension mismatch in openai.embedBatch[0]: expected 1536, got 768 and all rebuild batches being skipped.

Ask

  • Where can vector-leg hits get filtered out between tripleStreamSearch fusion and compact-mode output?
  • Would you accept a rebuild-index migrate step (or REST endpoint) to avoid the manual shard purge?

Happy to run any diagnostic build/flags — the setup is reproducible on demand.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions