1jehuang / 1jehuang/jcode

Memory retrieval gaps: near-literal search misses, stale memories stay active, Chinese embeddings degrade recall

Open
#960 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

autonomous: no bug priority: high recurring-theme triage: needs-decision
Dominant language
Rust
Stars
19.9k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
30

Description

Version: jcode v0.75.5 (994b8d3dd), Windows, memory backend = local all-MiniLM-L6-v2, sidecar enabled.

Summary

Three observed problems with the memory system, reproduced in real use:

  1. memory search returns zero hits for queries that are near-literal matches of stored memories (both Chinese and English queries).
  2. memory recall surfaces stale/contradictory memories side by side; Supersedes edges do not deactivate old entries, so the agent receives both the old and the new conclusion.
  3. Garbage memories extracted by the sidecar (e.g. an entry whose content is literally 服务) remain active forever; no pruning happens.

Reproduction

Memory store contains (among 98 entries):

[fact] 本机工具状态(2026-08-14 定稿):config.toml [tools] disabled=["webfetch","websearch"],...

memory list shows this entry. But:

  • memory search "禁用 webfetch 抓取工具 config.toml"No memories matching
  • memory search "webfetch disabled config.toml tools"No memories matching

Meanwhile memory recall (automatic context retrieval) returns, in the same result set:

  • #1 (new, correct): tools disabled = ["webfetch","websearch"], Exa is the default
  • #8 (old, superseded): "抓取固定为 Jina: Jina 优先、Exa 兜底" (Jina was later removed from mcp.json)
  • #6 (stale): "Tavily API key 无效,无法评测" (Tavily was later tested successfully)
  • plus a garbage entry [fact] 服务

All stale entries are still active: true; no superseded_by was set on any of them.

Root-cause hypotheses

  1. Embedder language mismatch. all-MiniLM-L6-v2 is English-only. Most memories here are Chinese. Chinese query/memory embeddings land with weak cosine similarity, often below the similarity_threshold = 0.4, so even literal matches score too low. This also explains why the automatic recall path (which may use looser filtering / recency) can still surface the entry while explicit search cannot.
  2. No lexical fallback. Retrieval is pure embedding similarity. A hybrid BM25 + semantic step (or a simple term-overlap boost) would catch near-literal Chinese queries at negligible cost.
  3. Supersedes is not enforced on the active set. Write-time contradiction detection creates the edge, but old memories remain active and retrievable. A superseded memory should be deactivated (or at least demoted/down-ranked at retrieval).
  4. No pruning of low-quality extractions. Sidecar extraction can emit junk (e.g. [fact] 服务). Phase 8 ambient garden (graph-wide merge, contradiction resolution, fact verification, weak pruning) is still Planned, which is understandable — these two points are the highest-leverage cheap fixes:
    • Multilingual embedding option (e.g. bge-m3 / multilingual-e5 small via ONNX) — one-time cost, zero per-turn increase, fixes the dominant failure for Chinese users.
    • Hybrid lexical+semantic retrieval — near-zero cost, fixes literal misses.

Why this matters

The memory system is marketed as human-like semantic memory. In practice, cross-session transfer of critical evolving facts (e.g. tool config changes) is currently unreliable: a new session either does not recall them at all (similarity threshold) or recalls outdated versions alongside the current one. Deterministic channels (preferred-tools.md injection) had to be used as a workaround, which defeats the purpose of the semantic layer.

The architecture direction is genuinely promising (write-time dedup/contradiction, confidence half-lives, cascade retrieval, planned offline consolidation); this issue is about the retrieval/consolidation gaps that make it unreliable for Chinese-heavy, fast-evolving facts today.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the memory search and memory recall entry points described in the report, then inspect how embedding similarity, active status, Supersedes edges, and sidecar-extracted entries affect results. Done means near-literal Chinese and English queries retrieve matching memories, superseded memories no longer compete with current ones, and garbage entries are excluded or pruned.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
ai, cli, search
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.