Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

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

オープン
#502 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
45/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
python
領域
backend, search

調査の方向性

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.

索引モデルが issue の本文から書いたものです。

説明

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).

主要言語
Python
スター
13.3k
フォーク
926
平均マージ
17時間 40分
マージ済み PR(30日)
31

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

EverMind-AI/EverOS のほかの issue

EverMind-AI/EverOS の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。