这个项目能做什么
# QMD - 查询标记文档
QMD 是一款设备端搜索引擎,专为个人知识库、文档、会议记录以及任何基于 Markdown 的内容而设计。它完全在本地运行,结合 BM25 全文搜索、向量语义搜索和基于 LLM 的重排序,在不将数据发送到外部服务的情况下提供高质量结果。
## 核心功能
- **混合搜索流水线**:结合 BM25 (FTS5)、向量相似度搜索和 LLM 重排序。查询扩展生成类型化子查询(`lex` 用于关键词,`vec` 用于稠密向量,`hyde` 用于假设文档嵌入),这些子查询被路由到相应的后端,通过倒数排名融合 (RRF) 进行融合,并由 LLM 进行重排序。
- **上下文树**:为集合添加分层上下文(例如,`qmd://notes` → "个人笔记和想法"),该上下文会与匹配的文档一起返回,帮助 LLM 做出更好的上下文决策。
- **本地模型**:使用从 HuggingFace 下载并缓存在本地的 GGUF 模型。默认嵌入模型是 `embeddinggemma-300M-Q8_0`(约 300MB)。可以通过 `QMD_EMBED_MODEL` 环境变量设置自定义模型(例如,用于多语言语料库)。
- **AST 感知分块**:可选的基于 tree-sitter 的分块功能,用于代码文件(TypeScript、JavaScript、Python、Go、Rust),可生成更高质量的分块;其他文件类型使用基于正则表达式的分块。
- **MCP 服务器**:公开一个模型上下文协议服务器,提供查询、检索文档、批量检索和状态检查等工具。支持 stdio 和 HTTP 传输,并具有安全功能(来源/主机验证以防止 DNS 重绑定攻击)。
- **SDK**:通过 TypeScript/JavaScript SDK 提供编程访问,包含搜索、文档检索、上下文管理和查询扩展等方法。
## 快速开始
```sh
# 全局安装(Node 或 Bun)
npm install -g @tobilu/qmd
# 或者
bun install -g @tobilu/qmd
# 创建集合
qmd collection add ~/notes --name notes
qmd collection add ~/Documents/meetings --name meetings
# 添加上下文
qmd context add qmd://notes "个人笔记和想法"
# 生成嵌入
qmd embed
# 搜索
qmd search "项目时间线" # 快速关键词搜索
qmd vsearch "如何部署" # 语义搜索
qmd query "季度规划流程" # 混合 + 重排序(最佳质量)
```
## CLI 命令
- `qmd collection add <路径> --name <名称> [--mask <glob>]` — 添加集合
- `qmd collection show <名称>` — 显示集合详情
- `qmd collection include/exclude <名称>` — 切换集合包含状态
- `qmd collection update-cmd <名称> '<命令>'` — 设置更新命令
- `qmd embed [--chunk-strategy auto]` — 生成向量嵌入
- `qmd search <查询> [-c <集合>] [--json] [--files] [--min-score <数字>]` — 关键词搜索
- `qmd vsearch <查询>` — 语义搜索
- `qmd query <查询>` — 混合搜索并重排序
- `qmd get <路径|文档ID>` — 检索文档
- `qmd multi-get <glob>` — 批量检索文档
- `qmd mcp [--http] [--port <端口>] [--host <地址>] [--daemon]` — 启动 MCP 服务器
- `qmd status` — 显示索引健康状态和 MCP 状态
## MCP 服务器
公开的工具:
- `query` — 使用类型化子查询、RRF 融合和可选重排序进行搜索
- `get` — 按路径、文档ID或行范围检索文档
- `multi_get` — 按 glob、逗号分隔列表或文档ID批量检索
- `status` — 索引健康状态和集合信息
HTTP 传输(默认端口 8181)提供:
- `POST /mcp` — MCP 流式 HTTP
- `POST /query`(别名 `/search`)— 无需 MCP 协议的结构化搜索
- `GET /health` — 存活检查
安全性:拒绝非回环 `Origin` 头的请求(403)。`Host` 验证可防止 DNS 重绑定。环境变量 `QMD_ALLOWED_ORIGINS` 和 `QMD_ALLOWED_HOSTS` 可扩展允许的来源/主机。
## SDK 用法
```js
const { QmdStore } = require('@tobilu/qmd')
const store = new QmdStore({ dbPath: './qmd.db', collections: { notes: { path: '/path/to/notes' } } })
// 简单搜索(自动扩展)
const results = await store.search({ query: 'authentication flow' })
// 使用类型化子查询的结构化查询
const results2 = await store.search({
queries: [
{ type: 'vec', query: 'why do database connections time out under load' },
{ type: 'lex', query: 'connection timeout' }
],
collections: ['docs', 'notes']
})
// 禁用重排序以提高速度
const fast = await store.search({ query: 'auth', rerank: false })
// 元数据过滤
const published = await store.search({
query: 'typescript',
filter: { key: 'topics', operator: 'all', value: ['typescript'] }
})
// 直接后端访问
const bm25Results = await store.bm25Search('auth')
const vectorResults = await store.vectorSearch('auth')
// 查询扩展
const expanded = await store.expandQuery('auth flow', { intent: 'user login' })
// 文档检索
const doc = await store.get('docs/readme.md')
const body = await store.getDocumentBody('docs/readme.md', { maxLines: 100 })
// 上下文管理
await store.addContext('docs', '/api', 'REST API reference documentation')
await store.removeContext('docs', '/api')
```
## 搜索流水线详情
1. **查询扩展**:原始查询(权重 ×2)+ 1 个 LLM 变体
2. **并行检索**:每个查询同时搜索 FTS 和向量索引
3. **顶级奖励**:任何列表中排名第一的文档获得 +0.05,排名第二至第三的获得 +0.02
4. **Top-K 选择**:取前 30 个候选进行重排序
5. **重排序**:LLM 对每个文档评分(是/否,带 logprobs 置信度)
分数范围:0.0–0.2 表示低相关性,较高值表示更好的匹配。
## 模型配置
默认模型:
- 嵌入:`embeddinggemma-300M-Q8_0`(约 300MB)
- 重排序:基于 LLM(按需下载)
自定义嵌入模型示例:
```sh
export QMD_EMBED_MODEL="hf:Qwen/Qwen3-Embedding-0.6B-GGUF/Qwen3-Embedding-0.6B-Q8_0.gguf"
```
注意:更改嵌入模型需要重新嵌入所有集合,因为向量不跨兼容。
## 要求
- Node.js 或 Bun 运行时
- 足够的本地存储空间用于模型和嵌入
- 可选:GPU/VRAM 用于更快的 LLM 推理(模型在请求间保持加载在 VRAM 中)
## 许可证
开源软件。详情请参阅仓库。
评论
0 评分人数达到10人后显示
登录后参与讨论。