docs: v1.3 - 记录 BM25 迁移决策与向量搜索禁用原因

- 测试结果:embeddinggemma-300M 向量质量不足,精确召回差于 BM25
- 变更:qmd-wrapper.sh vsearch→search,禁用内置 embedding 模型
- 对比分析表格 + 后续恢复语义搜索的建议路径
This commit is contained in:
mini
2026-02-17 17:17:25 +08:00
parent 388585f30f
commit e8adf8cfc5

View File

@@ -298,7 +298,7 @@ Before doing anything else:
---
*本文档由 Ami + 阿米狗共同研究整理2026-02-17v1.1 更新于同日v1.2 QMD 修复记录追加于同日*
*本文档由 Ami + 阿米狗共同研究整理2026-02-17v1.1 更新于同日v1.2 QMD 修复记录追加于同日v1.3 BM25 迁移记录追加于同日*
---
@@ -524,3 +524,83 @@ ln -sf ~/.cache/qmd/models/hf_tobil_qmd-query-expansion-1.7B-q4_k_m.gguf \
2. **QMD 的两个 XDG 环境完全隔离**CLI 工具用 `~/.cache/qmd/`OpenClaw 用 `~/.openclaw/agents/main/qmd/xdg-cache/`,模型需要手动同步。
3. **`qmd query` 不适合长文档**session 对话记录会产生超大 chunk直接用 reranker 会崩溃,`qmd vsearch` 是更安全的替代。
4. **OpenClaw 的降级机制会掩盖真实错误**QMD 崩溃 → 回退内置 SQLite → 内置失败 → 显示 `disabled: true`,看起来像是"没配置",实际是 QMD 崩了。
---
## 附录:从向量搜索迁移到 BM25v1.3
> 记录于 2026-02-17基于实际测试结果
### 背景
v1.2 的方案使用 `qmd vsearch`(向量搜索)绕过了 reranker 崩溃问题,但随即发现 vsearch 本身的精确召回效果也存在问题。
### 测试结果
**测试案例**:搜索暗语关键词"自食其力大爆发"、"暗语"
| 搜索方式 | 结果 |
|----------|------|
| `qmd vsearch`(向量搜索) | 返回 session 开头片段score 0.55~0.64,未命中目标内容 |
| `qmd search`BM25 | 直接命中snippet 精准显示上下文 |
直接用 SQLite FTS5 验证:
```sql
SELECT filepath, snippet(documents_fts, 2, '>>>', '<<<', '...', 60)
FROM documents_fts WHERE documents_fts MATCH '暗语' LIMIT 5;
-- 输出sessions/0e957dfc-....md | ...记住了。 **>>>暗语<<<**:柳暗花明又一村 ...
```
### 根本原因
当前使用的本地 embedding 模型为 `embeddinggemma-300M`(仅 **3 亿参数**),向量质量严重不足:
- 对精确短语(人名、暗语、项目名)的语义距离计算基本等同于噪声
- 返回结果随机性高,无法可靠用于记忆召回
- 还需要额外加载 ~300MB 模型占用内存
### 对比分析
| 方案 | 精确召回 | 语义召回 | 资源消耗 |
|------|---------|---------|---------|
| BM25 alone | ✅ 强 | ❌ 无 | 极低(纯 SQLite FTS5 |
| 300M 向量模型 | ❌ 差 | ❌ 也差 | 高(需加载大模型) |
| BM25 + 好模型(未来) | ✅ 强 | ✅ 强 | 中(需 API 或大本地模型) |
**结论**:用 300M 模型做向量搜索,丧失了 BM25 的精确匹配优势,却没有获得任何有效的语义搜索能力。两头都不讨好。
### 变更内容
1. **`scripts/qmd-wrapper.sh`**:搜索命令从 `vsearch` 改为 `search`BM25/FTS5
```bash
# 修改前
ARGS+=("vsearch")
# 修改后
ARGS+=("search")
```
2. **`openclaw.json`**:禁用内置 embedding 模型加载
```json
{
"agents": {
"defaults": {
"memorySearch": {
"enabled": false
}
}
}
}
```
### 当前遗留配置说明
`memorySearch` 下仍保留了 `provider: "local"` 等字段,但由于 `enabled: false`,实际不会加载 embedding 模型。未来清理时可完整删除 `memorySearch` 块。
### 后续方向
如果未来要恢复语义搜索能力,推荐方案:
- 接入 OpenAI `text-embedding-3-large` API
- 或使用 1B+ 参数的本地 GGUF embedding 模型
- 届时恢复混合搜索BM25 + 向量),调整 `vectorWeight` / `textWeight`