## 环境 - dsh-mneme 0.2.10 / 0.2.11 / 0.3.0 均存在 - Windows 11,dsh web profile ## 现象 每次重启 dsh,记忆库中所有记忆的 `embedding` 列被置空(UPDATE 置 NULL), `/api/dsh-mneme/semantic` 的 `embeddedCount` 归零,语义搜索静默降级为 keyword。 手动 reindex(`/api/dsh-mneme/vector-reindex`)可恢复向量,但下次重启又全部清空。 ## 触发路径 启动时执行 mirror 合并回库(`mergeHumanEdits`,读 md 镜像 → `store.update`)→ 不带 `embedding` 字段的 update → 向量被清。 ## 根因(代码级) 1. `lib/store.js` 的 `toRow()` 刻意剥离 `embedding` 字段(避免向量经 API 外泄,合理设计); 2. 但 `update()` 与 `compareAndUpdate()` 的向量保留逻辑写的是 `existing.embedding ?? null`,而 `existing = getById(id)` → `toRow` → `existing.embedding` 恒为 `undefined` → `?? null` 兜底生效 → 向量被清成 NULL; 3. 代码意图显然是"未传 embedding 时保留旧向量"(与 `patch.content ?? existing.content` 等其他字段的保留逻辑一致),因此这是 toRow 与 update 之间的耦合缺陷。 ## 复现步骤 1. 配置 `embedProvider: local`,记忆库已有向量(embeddedCount > 0); 2. 重启 dsh(触发启动 mirror 合并 → mergeHumanEdits → store.update); 3. 重启后查库:`SELECT COUNT(*) FROM memories WHERE embedding IS NOT NULL` → 0。 ## 影响 每次重启丢失全部向量,语义搜索静默失效;需要人工 reindex 且无法持久。 ## 修复建议(两处) `update()` 和 `compareAndUpdate()` 中,改为直接从原始行读取 embedding 列: ```js // 原: const embedding = patch.embedding !== undefined ? (Array.isArray(patch.embedding) && patch.embedding.length ? JSON.stringify(patch.embedding) : null) : existing.embedding ?? null; // 改: const existingEmbedding = db.prepare("SELECT embedding FROM memories WHERE id = ?").get(id)?.embedding ?? null; const embedding = patch.embedding !== undefined ? (Array.isArray(patch.embedding) && patch.embedding.length ? JSON.stringify(patch.embedding) : null) : existingEmbedding;
Activity
Anans-Amarre commentedon Aug 16, 2026
感谢这么详尽的 bug 报告!@heptaspirit 你定位得非常准——
toRow()剥离 embedding 与update()的existing.embedding ?? null兜底确实是耦合缺陷。我们已核实并确认:
update()/compareAndUpdate()现在只在patch.embedding !== undefined时才写该列,否则保留现有向量(不会清空)mergeHumanEdits(启动 mirror 合并回库)更新记忆后没有触发 re-embed,所以人工编辑过的记忆向量与内容可能不一致修复方向:mergeHumanEdits 的 update 后补一次
scheduleEmbed,与 saveWithDedupe 路径对齐。已列入待办,会尽快修复。再次感谢严谨复现!modusensus commentedon Aug 16, 2026
已在v0.3.3修复,感谢建议!
fix: v0.6.0 会话生命周期 code-review 修复(kimi-k2.7-code 审查 #1-#4)
docs(directories): ponytail 评审瘦身——复述与设计 lore 收敛到唯一出处