A day to make memory searchable again

记忆不只要存下来。
得在你需要时,及时出现。

10·02 的主线不是“调快一个搜索框”,而是把一条停滞的记忆链路重新接上:索引追上真实文件、查询走完端到端提速、结果质量有可重复的基准。从前一晚还在搜旧页、漏新页,到会话内 P50 约 1 秒。

4.29 → 1.68s热搜 searchMs · P5048 条真实查询,同口径
32.6 → 6.7s完全冷搜 · P50刻意清空页缓存的严苛场景
3.31 → 1.07sGateway 端到端 · P50真实 memory_search 工具路径
~3s记忆变更可检索新建 / 编辑 / 删除的实时同步
01 / THE REAL PROBLEM

开始时,坏掉的不只是速度。

索引自 9·28 起停更:旧文件仍被搜到,新写的页面搜不到,改过的项目页返回旧内容。与此同时,搜索每次都在重复付启动、串行等待和无关扫描的固定成本。

ROOT CAUSE

索引停在 9·28

搜索服务只读;没有任何进程把文件变化同步进索引。归档页仍会命中,新页面搜不到,修改过的页还是旧内容。

ROOT CAUSE

KNN 每次冷启动

子进程导入了用不到的模块,启动约 1.37s;老向量布局把 1,280 个候选反复从大块中取出计算。

ROOT CAUSE

串行等待 + 无关扫描

关键词搜完才发 embedding;即使只查记忆,也同步扫描数千个 session 目录做可见性过滤。

落差有多大:索引里 949 个已归档文件还会冒出来;90 个新文件完全搜不到;207 个修改过的文件(含 175 个项目页)仍然是旧内容。9/11 后搜索变只读,却没有配套的索引同步服务。
02 / THREE FIXES

不是一刀优化,
是把三段链路分别修好。

把索引的新鲜度、查询关键路径、工具层多余工作拆开。否则单看“快了”,会把搜得快但结果过时也算成功。

01 · v-memory-indexer

把索引同步移出 Gateway

常驻 watcher 在 Gateway 外跟踪 memory/;按原生索引逻辑增量同步。副本稳态单页约 3 秒;V 上线后首次写入 6.2 秒,后续编辑 2.8 秒、删除 2.2 秒。几百文件副本约 1 分钟。每小时全量对账兜底,不让写索引卡住 Gateway 主线程。

02 · memory-search-fast

缩短搜索关键路径

KNN 子进程去掉 3 个无用裸 import;embedding 与关键词搜索并发;索引重建采用 64 条/块布局,减少向量取块开销。搜索结果逐条保持一致。

03 · PR #143

删掉与记忆无关的工作

没有 session 记录的命中就直接返回,不再为每次记忆查询同步加载整份 session 目录;提前启动待命的向量子进程。48/48 查询结果一致。

记忆文件变更memory/ 下新建、编辑、删除;不会把 Gateway 卡在同步工作上
→
Gateway 外实时索引原生 watcher 增量更新;单页数秒内可搜,批量约一分钟
→
下一次查询读到新事实每小时全量对账,补上可能漏掉的文件系统事件
关键词搜索与查询向量化并发开始,不再排队等前一步
+
待命 KNN 向量子进程精简启动依赖、读新布局索引;无会话命中时跳过全量 session 可见性扫描
→
合并排序后返回真实 Gateway memory_search 路径一起计时;不拿 CLI 启动时间冒充用户体感
03 / MEASURED, NOT GUESSED

三种计时口径,
各回答一个不同问题。

同一批 48 条真实查询用于搜索链路测试;Gateway 工具端到端单独测。清空全部页缓存的冷搜是压力场景,不等同日常冷查询。

BEFORE · SEARCHMS P50
热 4.29s · 冷 32.6s
完全冷搜 P50;冷的向量阶段一度要 29 秒。
AFTER · SEARCHMS P50
热 1.68s · 冷 6.7s
热搜 P90 2.36s;完全冷搜最慢 8.9s。searchMs 不含 manager 打开。
BEFORE · GATEWAY TOOL END-TO-END
3.31s P50
提速前走真实工具调用的中位数;比独立 probe 多出工具层开销。
AFTER · GATEWAY TOOL END-TO-END
1.07s P50
同一组 48 条,结果 48/48 一致;41/48 在 1.5 秒内。P90 仍有 3.60 秒。
不能混的口径:CLI 脚本路径仍约 6–7 秒,因为命令行启动就占约 2 秒,而且 PATH 里的 openclaw 与 Gateway 的构建并不相同。这个报告的“约 1 秒”说的是 V 会话内的 Gateway 工具路径,不是 CLI 全链路,也不是每一次搜索都低于 1 秒。
04 / RETRIEVAL QUALITY

搜得快之外,
第一条也更像答案。

索引追平后,用 48 条真实线上问题做盲评。匹配的新结构让结果不再指向已搬走的旧页;后来再用 54 题基准迭代排序。

48 条真实查询 · 盲评指标索引停更时同步后变化
第一条有用(盲评)50%73%+23 pp
nDCG@80.5430.641+0.098
死链结果4%0%清零
晚间 54 题排序回归(20:22):hit@1 53.7% · hit@3 64.8% · hit@5 70.4% · MRR 0.603 · 前五噪音占比 8.9%。相较 20:09,MRR 0.569 → 0.603、噪音 13.7% → 8.9%,但 hit@5 72.2% → 70.4% 有回落。此轮还挪走了 240 个 dreaming 文件与 11 个导入副本;这是不同于 48 题盲评的另一组测量。
05 / ITERATION & INTEGRITY

一天里反复测,
不把第一次变好当成终点。

真正的工作包括失败轮次、口径校正和基准防污染。每一轮都保留分歧,不只记最后一张漂亮成绩单。

上午 · 10/02

恢复新鲜度

实时索引上线;新建、修改、删除都能很快反映到搜索结果。

中午 · 10/02

拆掉固定耗时

KNN 冷启动、串行 embedding、session 扫描逐项定位;V 的真实工具路径中位数降到约 1 秒。

下午 · 10/02

修关键词召回

#153 / #157 多轮排序修复:中文切词、IDF 和保守的三字候选回退。每轮都跑 54 题基准。

晚上 · 10/02

清理噪音并复测

54 题防污染、噪音目录软归档,再跑最后一轮;提升集中在首位质量和噪音率,仍留有真实问题。

真实提问仍是短板

最新 54 题里,real 组 hit@3 / hit@5 都约 46%,仍有 13/24 条进不了前五。还不能说“记忆已经都能找准”。

S12 语料敏感问题

软归档噪音目录后,S12 的正确页掉出前五;A/B 表明这是词组候选受语料统计影响,已转开发侧。不是为了刷分就把噪音目录塞回索引。

重启后的冷启动待补

重启后首次搜索曾慢到 13 秒,并触发一分钟暂停重试;自动预热还没做。常态 P50 提速不等于重启体验已收口。

评测也要防自己作弊:早期记录把基准题原文写进 memory/,实时索引会把题目本身当答案,抬高下一轮分数。后来 54 题统一使用 S01–S30 / R01–R24 编号,题目和结果移到 memory/ 之外;报告只写题号。
06 / ALSO ON OCT 02

主线之外,
只留下几件值得记的。

这些不和 Memory Search 的延迟/质量数据混成一个成绩。

Universal Memory

另一个检索面:归档 374 份旧导入内容,查明默认 0.35 分数门槛会挡掉纯关键词结果;按批准把查询改为 --min-score 0。与 V 的 memory_search 基准分开统计。

Memory Librarian

24 条当日 draft 完成编译;继续把日志压成项目页、人物卡与工程教训,不把搬运原文当成知识沉淀。

V Browser 口径更正

不是“停用了”。10/1 上午曾临时改走 Mac;v0.4.7 当天 12:49 修复、13:25 跨 harness 复验。此刻设备列表仍显示 Tianyi Mac Chrome online;修复后默认优先走哪条路仍需按任务确认。

THE TAKEAWAY

今天真正加速的,是“记忆能参与下一次回答”的闭环。

索引新鲜、检索够快、结果更准缺一不可:实时索引让新事实及时进来;查询路径把会话内中位数压到约一秒;分题基准让每次排序修改都能被证伪。还剩 real 组召回和重启预热等尾项——所以这不是“搜索大功告成”,而是从停更、陈旧、慢,迈进了可测、可迭代的运行状态。

V × OpenClaw · Field Notes · 2026-10-02Sources: docs/memory-search-latency-quality-20261002.md · memory/projects/memory-librarian/history.md / main.md · scripts/memory-bench/results/2026-10-02-2022-after-dreaming-move.json · V Browser device status