Skip to content

QMD 引擎让 OpenClaw 获得高级本地搜索能力:BM25、向量搜索和重排序合并在一个二进制中,还能索引项目文档、笔记和历史会话。配置只需将 memory.backend 设为 "qmd",并确保 qmd 命令在 gateway 的 PATH 中;首次搜索会自动下载约 2 GB 的 GGUF 模型。QMD 不可用时自动回退到内置引擎。

OpenClaw QMD 记忆引擎配置:本地向量搜索、重排序与额外路径索引

QMD 是运行在 OpenClaw 旁边的本地优先搜索 sidecar,在一个二进制里集成了 BM25、向量搜索和重排序,并且能索引 workspace memory 文件以外的内容。

与内置引擎对比的优势

  • 重排序与查询扩展 —— 更精准的召回
  • 索引额外目录 —— 项目文档、团队笔记,磁盘上任意位置
  • 索引会话记录 —— 召回历史对话
  • 完全本地 —— 通过可选 node-llama-cpp 运行,自动下载 GGUF 模型
  • 自动回退 —— QMD 不可用时无缝降级到内置引擎

启用 QMD 记忆引擎的步骤

前置条件

  1. 安装 QMD 二进制:
    bash
    npm install -g @tobilu/qmd
    # 或
    bun install -g @tobilu/qmd
  2. 确保 SQLite 构建支持扩展(macOS 用 brew install sqlite)。
  3. QMD 必须在 gateway 进程的 PATH 环境变量中。
  4. 操作系统:macOS 和 Linux 开箱即用,Windows 建议通过 WSL2。

配置启用

在 OpenClaw 配置中添加或修改 memory 部分:

json5
{
  memory: {
    backend: "qmd",
  },
}

OpenClaw 会在 ~/.openclaw/agents/<agentId>/qmd/ 下自动创建独立的 QMD home 目录,自动管理 sidecar 生命周期(集合创建、更新、embedding 运行)。启动时不会默认初始化 QMD,直到首次使用 memory 时才加载。

若希望 gateway 启动时就刷新索引,可设置 memory.qmd.update.startup"idle""immediate"

Sidecar 工作原理

  • OpenClaw 从 workspace 的 MEMORY.mdmemory/ 目录以及 memory.qmd.paths 中配置的额外路径创建 QMD 集合,并在 QMD 管理器打开后及之后每隔 5 分钟运行 qmd update
  • 搜索模式由 memory.qmd.searchMode 控制,默认 "search"(纯 BM25)。也支持 "vsearch""query"。特定模式失败时会自动用 qmd query 重试。
  • QMD 完全失败时回退到内置 SQLite 引擎。连续失败时会有退避机制,避免因二进制缺失或依赖问题造成重试风暴。
  • 启动时默认不初始化 QMD,冷启动不会导入记忆运行时或创建长驻 watcher。

第一次搜索可能较慢 —— QMD 会在首次 qmd query 时自动下载 GGUF 模型(约 2 GB)用于重排序和查询扩展。

搜索性能与兼容性

OpenClaw 启动时会检查已安装 QMD 的帮助文本。如果二进制支持多个集合过滤(多个 -c 参数),会将同源的集合合并到一次 qmd search 调用中;否则按集合分别搜索再合并去重,以保证兼容旧版本。

手动检查版本兼容性:

bash
qmd --help | grep -i collection

当前 QMD 帮助表明多个 -c 是支持的,旧版通常只接受一个集合。

模型覆盖

通过环境变量替换 QMD 使用的模型,无需修改 OpenClaw 配置:

bash
export QMD_EMBED_MODEL="hf:Qwen/Qwen3-Embedding-0.6B-GGUF/Qwen3-Embedding-0.6B-Q8_0.gguf"
export QMD_RERANK_MODEL="/absolute/path/to/reranker.gguf"
export QMD_GENERATE_MODEL="/absolute/path/to/generator.gguf"

更改 embedding 模型后必须重新运行 embedding 以使索引与新向量空间匹配。

索引额外路径

json5
{
  memory: {
    backend: "qmd",
    qmd: {
      paths: [{ name: "docs", path: "~/notes", pattern: "**/*.md" }],
    },
  },
}

搜索额外路径的结果以 qmd/&lt;collection&gt;/&lt;relative-path&gt; 形式返回。memory_get 能识别此前缀并从对应集合根目录读取文件。

索引会话记录

json5
{
  memory: {
    backend: "qmd",
    qmd: {
      sessions: { enabled: true },
    },
  },
}

会话记录作为 User/Assistant 对话轮次导出到 ~/.openclaw/agents/&lt;id&gt;/qmd/sessions/ 下的专属 QMD 集合。

搜索范围

默认 QMD 搜索结果仅在私信和 channel 会话中显示,群组不显示。通过 memory.qmd.scope 定制:

json5
{
  memory: {
    qmd: {
      scope: {
        default: "deny",
        rules: [{ action: "allow", match: { chatType: "direct" } }],
      },
    },
  },
}

scope 拒绝某次搜索时,OpenClaw 会记录警告并附上推导出的 channel 和 chat type,便于排查空结果。

引用来源

memory.citations"auto""on" 时,搜索片段包含 Source: <path#line> 页脚。设为 "off" 可隐藏页脚,但内部仍将路径传递给 agent。

什么时候选择 QMD

  • 需要重排序以获得更高质量的结果
  • 需要搜索 workspace 外的项目文档或笔记
  • 需要召回历史会话
  • 需要完全本地搜索且无需 API key

简单场景可使用内置引擎,无需额外依赖。

常见问题排查

QMD 找不到 / spawn qmd ENOENT
确保 qmd 在 gateway 进程的 PATH 中。若作为服务运行,可建立软链接:

bash
sudo ln -s ~/.bun/bin/qmd /usr/local/bin/qmd

或显式指定二进制路径:

json5
{
  memory: {
    backend: "qmd",
    qmd: {
      command: "/absolute/path/to/qmd",
    },
  },
}

然后用 openclaw memory status --deep 验证。

第一次搜索非常慢
QMD 首次使用时需下载 GGUF 模型(约 2 GB)。可用 qmd query "test" 预先填充缓存(使用 OpenClaw 相同的 XDG 目录)。

搜索超时
增大 memory.qmd.limits.timeoutMs(默认 4000ms)。慢硬件建议设为 120000

群聊返回空结果
检查 memory.qmd.scope —— 默认只允许私信和 channel。需添加群组匹配规则。

临时仓库目录导致 ENAMETOOLONG 或索引异常
将临时 monorepo 置于 .tmp/ 等隐藏目录内,或移到 QMD 索引根之外。

常见问题

如何在 OpenClaw 中单独为某个智能体启用 QMD?

agents.list[<agentId>] 下配置 memory.backend: "qmd",其他智能体仍可使用内置引擎或不同后端。

QMD 与内置引擎可以同时使用吗?

不能。memory.backend 互斥,QMD 作为后端启用后,内置引擎仅作为回退(当 QMD 不可用时自动切换),不会同时运行。

Windows 上使用 QMD 有什么限制?

Windows 原生对 SQLite 扩展支持不完整,建议通过 WSL2 运行。如果必须使用原生 Windows,需自行确保 SQLite 加载 .dll 扩展的能力。

完整配置参考

完整的 memory.qmd.* 可配置项、搜索模式列表、更新间隔、scope 规则等,请参阅 Memory 配置参考