[Bug]: memory.prefetch_search_topn is inert above 5 (call site omits limit), plus two docstrings state the wrong defaults

Aperta Adatta ai principianti
#6,923 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@peterzhang987723 ci sta già lavorando.

Dal 4/11/2026.

  • #6997 di @peterzhang987723 — aperta

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
70/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python

Direzione di ricerca

Inizia da session/memory/session_extract_context_provider.py: search_files (intorno alla riga 447) imposta limit a 5 di default, e la chiamata intorno alla riga 567 non lo passa, quindi lo slice prefetch_search_topn intorno alla riga 594 non può mai vedere più di 5 voci. Passa in quel punto di chiamata un limit ricavato dall'impostazione di configurazione. Poi correggi i valori di default errati in openviking_cli/utils/config/memory_config.py (righe 61-67, eager_prefetch) e in session/memory/extract_loop.py (riga 147: la docstring di max_iterations dice 5, la firma dice 3). È completato quando la chiamata passa il limit configurato e entrambe le docstring corrispondono al codice.

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

Descrizione

kernel

Summary

memory.prefetch_search_topn cannot raise the amount of memory content preloaded into the extraction prompt above 5, because the search call site omits limit while the method signature defaults to 5. The configured value only slices a list that can never exceed 5 entries. Two docstrings in the same path also state defaults that are the opposite of the code.

Both defects were measured against live traffic, not read off the source.

Environment

  • OpenViking v0.5.2.1, container ghcr.io/volcengine/openviking:v0.5.2.1
  • memory.eager_prefetch: default true (unset in ov.conf)
  • memory.prefetch_search_topn: unset, so default 5
  • Inference backend: Qwen3.8-Flash-Next served locally by oMLX 0.7.3

Defect 1: the knob is clamped by a hard-coded default

session/memory/session_extract_context_provider.py:

447:    async def search_files(
448:        self, query: str, search_uris: List[str] = None, limit: int = 5

567:            search_uris = await self.search_files(
568:                query=search_query,
569:                search_uris=dir_list,
570:            )                       # no limit passed, so limit=5 applies

594:            topn_files = files_to_read_from_search[: self._prefetch_search_topn]

prefetch_search_topn slices a list that search_files already truncated to 5. Setting it to 10 or 20 returns the same 5 files. The setting can only take effect by lowering it below 5, which is the opposite of its documented purpose.

Measured proof

URIs listed per prefetch message, counted across 49 logged extraction requests:

URIs listed requests
1 2
2 6
3 8
4 9
5 (the cap) 24

49 % of runs sit exactly on the ceiling, so the limit binds roughly half the time and headroom above 5 is unreachable.

Why it matters operationally

The preloaded set is all the extraction agent can see before it rewrites memory. Measured on our store (4517 memory files, 20.3 MB of markdown): mean 5.31 files preloaded per run, median 48565 injected characters, about 5 records out of 4517 files, roughly 0.1 % collection visibility, with no read tool available because get_tools() returns [] under eager_prefetch.

That is the dedup window. Consequences we measured:

  • 34 of 1604 trajectories plus cases files share a normalized base name (2.1 %), one name recurring 6 times.
  • One batched search covers every multi-file schema directory for self plus each peer scope, competing for the same 5 slots, so per-directory visibility is a fraction of one file.
  • _build_prefetch_search_query sends one query per commit, concatenating user text parts (1000 chars each) and assistant parts (500 chars each), truncated to _PREFETCH_SEARCH_QUERY_MAX_CHARS = 5000. On a long session that is an average-of-everything blob, so the top hits follow the session's dominant topic rather than the memory about to be written.

Raising prefetch_search_topn is the obvious lever an operator reaches for here, and it silently does nothing.

Suggested fix

Make the documented knob authoritative at the call site:

search_uris = await self.search_files(
    query=search_query,
    search_uris=dir_list,
    limit=max(5, self._prefetch_search_topn),
)

Worth considering separately: search per schema directory rather than one merged batch, so a single topic cannot consume all N slots. optimize_search_result already fetches limit + 10 and filters .abstract.md / .overview.md before cutting, so additional slots are real memory files rather than index noise.

Defect 2: two docstrings state the wrong defaults

openviking_cli/utils/config/memory_config.py:61-67:

eager_prefetch: bool = Field(
    default=True,
    description=(... "When disabled (default), LLM has read tool and reads files on-demand.")
)

The default is True, so the sentence describes the opposite of reality, including the trade-off it implies.

session/memory/extract_loop.py:

133:        max_iterations: int = 3,
147:            max_iterations: Maximum number of ReAct iterations (default: 5)

Signature default is 3, docstring says 5. This one has teeth, because the iteration budget is what caps extraction work per commit.

Suggested fix: correct both strings, and consider deriving one from the other so they cannot drift again.

Notes

  • This is independent of the Unknown tool loop reported separately, but the two share a root: the extraction phase runs with no tools advertised and a preloaded context whose size the operator cannot actually configure.
  • Minimal reproduction: a store with more than 5 topically relevant memory files, then observe the prefetch listing fewer URIs than the configured prefetch_search_topn.

Report authored by an agent under human supervision, measured against a live single-tenant installation. Made under human guidelines with free tokens from local oMLX inference server.

Lingua principale
Python
Stelle
41.8k
Fork
3.4k
Merge medio
19h 54m
PR unite (30g)
491

Preparare l'ambiente

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 volcengine/OpenViking

Tutte le issue di volcengine/OpenViking

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.