背景 链接到标题

在 OpenClaw 的对话系统中,每次回复前的上下文由以下几个部分组成:

  • 静态文件——AGENTS.mdMEMORY.mdSOUL.md 等 workspace bootstrap 文件在会话开始时注入
  • Active Memory——可选的子 agent,在每次回复前自动运行 memory_search / memory_get,将检索到的记忆以隐藏前缀注入 prompt
  • memory_search / memory_get 工具——Agent 可以在对话中主动调用这些工具搜索历史记忆

其中 memory_search 的检索能力由 memory-core 插件提供。

Memory-Core 的检索架构 链接到标题

memory-core 的默认后端是 builtin(SQLite 引擎),采用混合检索(hybrid search)策略:向量搜索和 BM25 关键词搜索两路并行执行后按权重合并。

检索路径 技术 权重
Vector search bge-m3 embedding, 1024 维 0.7
BM25 keyword search SQLite FTS5 0.3

向量搜索负责语义匹配,BM25 负责字面关键词匹配。

flowchart LR Q["Query"] --> E["Embedding (bge-m3)"] Q --> T["Tokenize"] E --> VS["Vector Search"] T --> BM["BM25 Search (FTS5)"] VS --> M["Weighted Merge"] BM --> M M --> R["Top Results"]

问题:中文 BM25 检索效果差 链接到标题

根因 链接到标题

SQLite FTS5 默认的 unicode61 tokenizer 在处理 CJK(中文/日文/韩文)文本时,会将连续的中文字符合并成单个 token。例如 "混合检索配置说明" 这 7 个字在 FTS5 索引中是一个 token,搜索 "检索配置" 无法匹配。

官方文档提到了 CJK 支持 via trigram tokenizer,但 trigram 方案也有实现 bug,导致中文查询的 BM25 分数始终为 0。

相关 Issue 链接到标题

当前应对 链接到标题

保持现状,调整混合检索权重 链接到标题

当前配置的 vectorWeight=0.7textWeight=0.3 已经偏向向量搜索。bge-m3 embedding 模型对中文语义理解质量良好,向量检索基本不受影响。BM25 部分即使贡献低,整体检索效果仍在可接受范围。

如果需要进一步规避 BM25 问题,可以调高 vectorWeight

{
  agents: {
    defaults: {
      memorySearch: {
        query: {
          hybrid: {
            vectorWeight: 0.9,
            textWeight: 0.1,
          },
        },
      },
    },
  },
}

暂不切换 QMD 链接到标题

QMD 项目同样使用 SQLite FTS5 做 BM25,存在完全一样的中文 tokenizer 问题。虽有几个修复 PR(bigram、n-gram),但均未合入。

自定义插件补充中文 BM25 检索 链接到标题

如果未来需要更好的中文 BM25 检索,OpenClaw 插件 SDK 提供了 registerMemoryCorpusSupplement 接口,可以将自定义检索结果合并到 memory_search 的返回中。memory-wiki 插件就是用这个接口把自己的 wiki 数据注入到混合检索结果中的。

实现思路:

  1. 编写一个 OpenClaw 插件,内部使用 nodejieba 对中文内容分词
  2. 分词后以空格分隔写入 SQLite FTS5(此时 unicode61 可以正确按词分割)
  3. 检索时同样对中文 query 做 jieba 分词后走 BM25
  4. 通过 registerMemoryCorpusSupplement 注册为 memory_search 的补充 corpus
  5. memory-core 原有的向量检索和 dreaming 不受影响,BM25 结果合并返回

这种方式是增量补充,不需要替换 memory-core,复杂度可控。

后续 链接到标题

上游 PR #92164 修复了 trigram 下的两个 bug(CJK token 拆分 + MATCH 空结果回退 LIKE),合入后升级即可恢复正常的混合搜索权重。届时可以将 vectorWeight 调回默认比例。

如果需要更精准的中文字面检索,自定义插件补充 jieba 分词 BM25 是中期可行的方向。