Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

method=vector over episodes never reads the episode vector column — it depends entirely on atomic_fact

Aperta
#502 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
45/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
python
Ambito
backend, search

Direzione di ricerca

Start in memory/search/manager.py at the single-route branch where fusion_mode is None: KEYWORD goes to sparse_recall, while VECTOR goes to _maxsim_atomic_recall and never reaches EpisodeRecaller.dense_recall. Reproduce by running method=vector against a store with episodes but an empty atomic_fact table and confirming zero results. Done when the maintainers settle whether to fall back to dense_recall or log the empty case, and the chosen behaviour is covered by a test.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug

Summary

POST /api/v2/memory/search with method="vector" does not run a dense search over the episode table. It routes through _maxsim_atomic_recall, which does ANN over atomic_fact, max-pools by memcell, and fetches the parent episodes. So when atomic_fact is empty or stale, method=vector returns zero episodes with HTTP 200 — while every episode carries a perfectly usable 1024-dim body vector that is never consulted, and method=keyword over the same store answers normally.

Where

memory/search/manager.py, the single-route branch (fusion_mode is None, around line 405):

if req.method == SearchMethod.KEYWORD:
    cands = await self._ep.sparse_recall(...)
else:
    cands = await self._maxsim_atomic_recall(req, where, top_k)   # VECTOR lands here

EpisodeRecaller.dense_recall (the method that does query episode.vector) exists and is wired, but nothing on the method=vector path calls it for the episode kind.

Observed

EverOS 1.4.1 at a345d08, isolated root, 106 daily-log Markdown files / 1060 episode entries, all indexed, embeddings healthy.

episode      rows = 1060   (vector: non-null, dim=1024; subject_vector: non-null, dim=1024)
atomic_fact  rows = 0

Same query, three methods:

method episodes returned
keyword 5
vector 0
hybrid 5

No error, no log line, HTTP 200 with an empty array. Replaying dense_search's own query chain against the live table — nearest_to(v).column("vector").distance_type("cosine").nprobes(32) — returns 5 rows with _distance=0.2726, so the data, the index and the repo layer are all fine. hybrid returning 5 is not reassurance: its sparse leg carries those hits, so the dead dense leg is masked.

To be explicit about my setup: my atomic_fact table was empty because the corpus was materialised with EverOS's own EpisodeWriter rather than by running the OME extraction strategy. A store built normally through /add + /flush will have facts. The defect is not that I got 0 — it is that this configuration of a healthy index yields a silent 0 at all.

Why it matters beyond the test setup

Any store whose atomic_fact table is empty, lagging or broken loses vector search silently, while keyword keeps working — so the deployment looks half-alive rather than broken. Reachable states include:

  • #434 — a sub-1024-dim embedding provider makes atomic_fact writes fail terminally (retryable=FALSE) while /health still reports embed: true. That lands exactly here.
  • A root re-indexed from Markdown where episodes are present but fact extraction has not caught up (facts are derived by an OME strategy, asynchronously, after the episode lands).
  • Any deployment running with the extraction strategy disabled.

In each case the user-visible result is "vector recall quietly returns nothing", which in a memory system is indistinguishable from "nothing matched".

Questions for a maintainer

  1. Is the atomic-fact-only route intended for method=vector? The docstring describes it as trading an extra ANN scan for finer-grained semantic match, which is a reasonable ranking choice — but it reads as an enrichment, not as the sole source of dense recall.
  2. If intended, should it fall back? An empty or short atomic_fact pool could fall through to EpisodeRecaller.dense_recall rather than returning nothing.
  3. Either way, it should not be silent. A dense route that recalls zero candidates because its backing table is empty deserves a log line at minimum, and arguably a reasons entry on /health once the fact table is empty while episodes exist.

Related: #434 (the most likely way to reach this state in production), #394 (the other case of a documented dense-search knob not doing what the docs say).

Lingua principale
Python
Stelle
13.3k
Fork
926
Merge medio
17h 40m
PR unite (30g)
31

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di EverMind-AI/EverOS

Tutte le issue di EverMind-AI/EverOS

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.