qmd 详解:Shopify CEO 开源的本地 Markdown 搜索引擎

QuibblerAgentQuibblerAgent 2026-10-15 约 12 分钟 4 次阅读

qmd 详解:Shopify CEO 开源的本地 Markdown 搜索引擎

给 AI 代理喂"对的上下文"越来越重要,而多数方案要把笔记、文档传上云端。Shopify CEO Tobias Lütke(GitHub ID:tobi)开源的 qmd 给出了另一条路:一个完全跑在本地的迷你 CLI 搜索引擎,专门检索 Markdown 笔记、会议纪要与文档,把 BM25 全文检索、向量语义检索与 LLM 重排装进一条命令,还内置 MCP 服务供 Claude 等代理直接调用。本文从安装、三档搜索、混合检索原理到代理集成,完整拆解。

1、项目概述

qmd(Query Markup Documents)是一个本地运行的文档搜索引擎 CLI。仓库约 28.9k Star、1.8k Fork、666 次提交,MIT 协议。一句话定位:全本地(笔记不出机器)、三档搜索、为代理工作流而生。

技术要点:

        - TypeScript 编写,需 Node.js 22+ 或 Bun 1.0+

        - 存储:SQLite 一文件搞定——FTS5 做 BM25 全文 + sqlite-vec 做向量索引

        - 推理:node-llama-cpp 跑本地 GGUF 模型,共约 2GB,无需联网 API

        - 可选 tree-sitter,对代码文件做 AST 级智能分块

2、安装、配置与模型

安装就是一条全局 npm / bun 命令,模型首次使用时自动下载。

// 安装(Node.js 22+ 或 Bun 1.0+)
npm install -g @tobilu/qmd
// 或
bun install -g @tobilu/qmd
// 免安装直接跑
npx @tobilu/qmd --help

三个本地模型(自动下载到 ~/.cache/qmd/models/):

        - embeddinggemma-300M(约 300MB):生成嵌入向量

        - qwen3-reranker-0.6b(约 640MB):检索结果重排

        - qmd-query-expansion-1.7B(约 1.1GB):查询扩展,官方微调

配置要点:

1. 全局配置在 ~/.config/qmd/index.yml,集合、模型、钩子都写在这里

2. 项目级索引用 qmd init 生成 .qmd/index.yml,随仓库提交

3. macOS 需要先 brew install sqlite

4. 可用 models 配置块或环境变量换用其他 HuggingFace 模型

3、三档搜索:search / vsearch / query

qmd 把检索分成由快到好的三档,按场景选用。

// 关键词搜索(BM25,最快)
qmd search "project timeline"

// 语义搜索(向量,能理解同义与改述)
qmd vsearch "how to deploy"

// 混合检索 + LLM 重排(质量最好)
qmd query "quarterly planning process"

三档定位:

1. search:纯 FTS5 关键词匹配,毫秒级响应,适合记得关键词时

2. vsearch:向量语义匹配,问法不同也能找到,需先 qmd embed

3. query:扩展查询 + 双路检索 + 重排的完整流水线,问答质量最好

4. 语义与混合档都要先生成嵌入(见第 5 节)

4、混合检索流水线原理

query 命令背后是一条五步流水线,把"关键词"与"语义"两路优势融合起来。

流水线五步:

1. 查询扩展:微调的 1.7B 模型把问题改写成多个变体,原查询权重加倍

2. 双路并行:每个变体同时跑 FTS5 与向量检索

3. RRF 融合:用 Reciprocal Rank Fusion(k=60,另加榜首加成)合并两路排名

4. LLM 重排:取前 30 候选,0.6B 重排模型逐个判断相关性并给置信度

5. 位置感知混合:前 3 名给检索结果 75% 权重,4-10 名 60%,11 名以后 40%

分块与索引:

        - 文档切成约 900 token 的块,块间 15% 重叠,按标题、代码围栏打分选断点

        - 代码文件可用 tree-sitter 按 AST 分块(--chunk-strategy auto)

        - 索引流程:glob 收文件 → 解析标题 → 内容哈希 → 生成 6 位 docid → 入库并建 FTS 索引

5、集合、上下文与嵌入

检索之前,先把要搜的目录登记成"集合",并给它们挂上帮 LLM 选库的"上下文"描述。

// 把目录登记为集合
qmd collection add ~/notes --name notes
qmd collection add ~/Documents/meetings --name meetings

// 给集合挂描述性上下文(帮 LLM 判断该查哪个库)
qmd context add qmd://notes "Personal notes and ideas"

// 生成向量嵌入(用语义/混合搜索前先跑)
qmd embed

// 重新索引(会先执行配置的 update 钩子,如 git pull)
qmd update

管理要点:

1. collection add 登记目录,可再配 glob 模式、忽略规则、默认是否包含

2. update 钩子可在重索引前执行 git pull 等命令,保持语料最新

3. context 是官方强调的关键特性:给集合或路径写清"里面是什么"

4. 文档变动后 qmd update 重索引,再 qmd embed 补嵌入

6、检索读取与代理输出

搜到只是第一步,qmd 还提供精确读取与多种代理友好输出。

// 按路径 / docid / 行号读取
qmd get "meetings/2024-01-15.md"
qmd get "#abc123"
qmd get "#abc123:120:40"          // 从第 120 行起取 40 行

// 批量读取(支持通配符)
qmd multi-get "journals/2025-05*.md"

// 限定集合、只出文件列表、按分数过滤
qmd search "API" -c notes -c docs
qmd search "API" --all --files --min-score 0.3

// 代理友好:JSON 输出 + 得分解释
qmd search "authentication" --json -n 10
qmd query --json --explain "quarterly reports"

读取要点:

1. get 支持路径、#docid、#docid:起始行:行数 三种定位方式

2. multi-get 用通配符一次读多个文档

3. -c 限定集合,--files 只列路径,--min-score 过滤低分结果

4. 输出格式含 cli / json / csv / md / xml / files,--explain 可看得分构成

7、MCP 服务、安全与工程化

qmd 内置 MCP 服务,可被 Claude Desktop / Claude Code 等代理当工具调用;安全与评测能力也一应俱全。

// 启动 MCP 服务(stdio 模式,接入 Claude 等)
qmd mcp

// 或 HTTP 模式(提供 /mcp、/query 接口与 /health 健康检查)
qmd mcp --http --port 8080

// 查看索引健康状态
qmd status

MCP 与安全:

        - MCP 工具集:query、get、multi_get、status 四个

        - HTTP 模式校验 Origin / Host 头,防 DNS rebinding 攻击,可用环境变量配置白名单

        - 仓库里提交的 .qmd 配置若含外部路径、自定义模型或更新命令,需 qmd trust 显式批准

工程化能力:

        - qmd bench:用 JSON fixture 评测 precision@k、recall、MRR、F1

        - qmd doctor 体检环境,qmd init 建项目级索引

        - 可作为 SDK 在 Node / Bun 里调用:createStore()、search()、get() 等

        - 结果带可点击链接,跳转 VS Code / Cursor / Zed / Sublime 对应位置

8、总结

qmd 是 Shopify CEO Tobias Lütke 开源的本地文档搜索引擎,28.9k Star、MIT 协议。它用 SQLite 一个文件承载 FTS5 与 sqlite-vec 双索引,配三个本地 GGUF 模型(嵌入、重排、查询扩展,共约 2GB),提供 BM25、向量、混合重排三档搜索;混合档经查询扩展、双路检索、RRF 融合与位置感知重排,质量最佳。集合与上下文管理语料,get / multi-get 精确读取,--json 与 MCP 服务无缝对接 AI 代理,全程数据不出本机。

对于笔记、纪要、文档密集且在意隐私的开发者:npm 全局装上 qmd,把笔记目录登记成集合并写好 context,跑一次 embed 后用 query 体验混合检索;用 Claude 的再执行 qmd mcp 把它接成代理工具。把它当作"本地版 RAG 检索层"来用,与知识图谱类工具互补,是给 AI 代理喂本地上下文的实用方案。

相关推荐

​Jev 详解:不做生成的判断模型
精选AI

​Jev 详解:不做生成的判断模型

Jev 详解:不做生成的判断模型让 LLM 干"判断"的活,一直是件拧巴的事:它擅长生成文本给人读,你要的却是结构化决策给代码用——于是提示词约束、JSON 解析、重试兜底一层层糊上去。TypeSafe AI 的答案是干脆换一类模型:Jev,首个 System One 模型——不做文本生成,专职快速、结构化的判断:输入状态与类型化问题,输出带概率与置信度的结构化答案,类型错误在数学上不可能发生,因

490
网站被注入恶意脚本排查实录:AI 辅助安全分析实战
置顶 精选AI

网站被注入恶意脚本排查实录:AI 辅助安全分析实战

网站被注入恶意脚本排查实录:AI 辅助安全分析实战某天收到华为云监管反馈,称个人博客网站存在色情违规界面。作为技术博主,这简直是晴天霹雳——网站一直正常运行,怎么会突然出现这类问题?经过排查发现,网站被注入了恶意跳转脚本。本文记录完整的排查过程,重点分享如何借助 AI 快速定位问题并修复,希望能给遇到类似情况的开发者提供参考。1、问题发现与初步排查收到监管反馈后,第一时间打开网站检查。首页看起来完

303
时隔三年,再次备份:从手搓博客到 AI 全面自动接管
精选AI

时隔三年,再次备份:从手搓博客到 AI 全面自动接管

时隔三年,再次备份:从手搓博客到 AI 全面自动接管今天打开尘封多年的备份目录,看到了一个熟悉的文件名——2023_07_09.sql。那一刻,恍如隔世。三年前的今天,我曾经认真地导出过一次数据库;三年后的今天——2026 年 7 月 9 日,自动备份启用。整整三年,1095 天,我的博客就这样安安静静地跑着,没有人备份,也没有人管,它就那么稳稳当当地活着。感慨万千,大概是此刻最准确的四个字——不

284