ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

QMD 查询语法深度指南:结构化多路检索、Intent 消歧与本地混合搜索实战

2026/9/10 8:23:17 拓冰建站 浏览量
QMD 查询语法深度指南:结构化多路检索、Intent 消歧与本地混合搜索实战 QMD 查询语法深度指南结构化多路检索、Intent 消歧与本地混合搜索实战【免费下载链接】qmdmini cli search engine for your docs, knowledge bases, meeting notes, whatever. Tracking current sota approaches while being all local项目地址: https://gitcode.com/GitHub_Trending/qmd1/qmdQMDQuick Markdown Database是一个完全本地运行的 mini CLI 搜索引擎面向文档、知识库、会议纪要等纯文本语料。本文以 docs/SYNTAX.md 为骨架系统讲解 QMD 的结构化查询语言从 EBNF 文法、lex/vec/hyde三种子查询类型、expand:隐式展开、intent:消歧到多行查询文档、集合作用域scoping以及 CLI 与 MCP/HTTP 两种调用方式的完整参数细节。读完本文你将掌握如何写出高召回、高精度的 QMD 查询理解底层 BM25、向量检索、HyDE 与 RRF 融合的配合方式并能在命令行与 MCP/HTTP 接口中灵活运用intent、collections等关键参数。QMD 查询的核心理念结构化文档 类型化子查询QMD 查询不是普通的关键词字符串而是结构化文档structured document每一行都声明一个搜索类型lex、vec、hyde和对应的查询文本。查询解析器会按行拆分、trim、丢弃空行然后根据行首前缀将各子查询分派到不同的检索后端。顶层文法如下源自 docs/SYNTAX.md 的 EBNF 定义query expand_query | query_document ; expand_query text | explicit_expand ; explicit_expand expand: text ; query_document [ intent_line ] { typed_line } ; intent_line intent: text newline ; typed_line type : text newline ; type lex | vec | hyde ; text quoted_phrase | plain_text ; quoted_phrase { character } ; plain_text { character } ; newline \n ;从文法可以读出一个关键约束顶层查询只有两种合法形态——要么是一个独立的 expand 查询单行要么是一个多行查询文档由可选的intent:行和若干lex:/vec:/hyde:类型行组成。不存在多个裸文本行这种中间形态。这个约束在源码中得到严格验证src/cli/qmd.ts中的parseStructuredQuery见 src/cli/qmd.ts逐行扫描遇到无前缀的多行文本会直接抛出错误Line N is missing a lex:/vec:/hyde:/intent: prefix. Each line in a query document must start with one.expand:行如果出现在多行文档中也会报错query documents cannot mix expand with typed lines. Submit a single expand query instead.同时intent:单独出现没有任何搜索行也会被拒绝intent: cannot appear alone. Add at least one lex:, vec:, or hyde: line.三种查询类型lex、vec 与 hyde类型检索方法描述lexBM25精确关键词匹配的关键词搜索vecVector语义相似度搜索hydeVector假设文档嵌入Hypothetical Document Embedding这三种类型对应源码中src/llm.ts定义的QueryType lex | vec | hyde它们分别驱动不同的检索后端lex走 BM25 关键词检索对应searchLex基于 SQLite FTS速度最快适合精确匹配已知术语、专有名词和代码标识符。vec走向量相似度检索对应searchVector适合用自然语言表达意图、词汇未知的场景。hyde也是向量检索但查询本身是一段假设性答案hypothetical answer passage。先把期望答案的样子写出来再做向量匹配从而拉近查询与文档在语义空间中的距离。QMD 的完整检索管线search会串联查询展开 → 多信号检索 → RRF 融合 → LLM 重排。src/bench/bench.ts的注释清楚地列出了四种后端对比bm25纯关键词、vector纯向量、hybridBM25 向量 RRF 融合、无重排、full完整混合管线 LLM 重排。默认行为单行裸查询自动走 expand任何单行、无前缀的查询都会被当作 expand 查询处理交给本地查询展开模型自动生成lex、vec、hyde三种变体# 下面两种写法等价且都不能与类型化行混用 how does authentication work expand: how does authentication work展开模型生成了哪些子查询CLI 会以树形结构打印到 stderr 用于进度反馈——logExpansionTree见 src/cli/qmd.ts输出类似├─ how does authentication work ├─ lex: authentication ├─ vec: how does authentication work └─ hyde: The authentication flow typically involves...注意展开模型的调用在src/llm.ts中以expandQuery(query, options)接口暴露SDK 层面对应qmd.expandQuery()展开所需的上下文大小可通过expandContextSize或环境变量QMD_EXPAND_CONTEXT_SIZE配置默认 2048必须是正整数见 src/llm.ts。Lex 查询语法前缀匹配、短语与否定Lex 查询支持专门语法用于精确关键词匹配lex_query { lex_term } ; lex_term negation | phrase | word ; negation - ( phrase | word ) ; phrase { character } ; word { letter | digit | } ;语法含义示例word前缀匹配perf匹配 performancephrase精确短语rate limiter-word排除该词-sports-phrase排除该短语-test data注意几个实现细节word是前缀匹配perf能命中performance、perfmon等词这是设计行为而非模糊匹配否定只对单个词或短语生效形如-foo bar会整体按前缀词处理-term与phrase语法只在lex行内有效vec与hyde行按纯文本处理。实际示例lex: CAP theorem consistency lex: machine learning -deep learning lex: auth -oauth -samlVec 与 HyDE 查询自然语言与假设答案Vec 查询没有特殊语法——直接写下你想找的内容即可vec: how does the rate limiter handle burst traffic vec: what is the tradeoff between consistency and availabilityHyde 查询是 50–100 词的假设答案段落——写出你期望答案长什么样子hyde: The rate limiter uses a sliding window algorithm with a 60-second window. When a client exceeds 100 requests per minute, subsequent requests return 429 Too Many Requests.HyDE 的价值在于把提问变成作答让向量匹配更贴近文档正文的表达方式。写 hyde 段落时尽量模仿目标文档的语气与术语例如提到具体的算法名、状态码、参数名效果会更好。多行查询文档混合检索 首行 2 倍权重把多种查询类型组合在一个文档里是 QMD 获得最佳效果的标准姿势。第一条查询在融合fusion中享有 2 倍权重因此应把最强的信号放在第一行lex: rate limiter algorithm vec: how does rate limiting work in the API hyde: The API implements rate limiting using a token bucket algorithm...融合机制对应源码中的 RRFReciprocal Rank Fusion实现各子查询分别检索后按排名取倒数分融合hybrid 模式即BM25 vector RRF fusion见 src/bench/bench.ts。MCP 服务端的策略文档也明确写着 First sub-query gets 2× weight — put your strongest signal first见 src/mcp/server.ts。针对不同目标MCP 服务端给出的选型建议目标做法通用搜索推荐传query自动展开为类型化变体并融合、重排已知精确术语/名称只用lex概念搜索只用vec最佳召回lexvec复杂/微妙问题lexvechyde词汇未知用自然语言传query让服务端自动展开Expand 查询显式与隐式两种写法Expand 查询必须独立存在不能与类型化行混用。既可以依赖默认的无前缀形式也可以显式加expand:前缀expand: error handling best practices # 等价于 error handling best practices两种形式都会调用本地查询展开模型自动生成lex、vec、hyde变体。源码验证parseStructuredQuery识别到expand:前缀且文档只有一行时直接返回null表示这是一条独立展开查询见 src/cli/qmd.ts后续交给 LLM 展开流程处理。Intent 行给歧义查询提供背景语境可选的intent:行用于为歧义查询提供背景语境指导查询展开、重排reranking和摘要snippet抽取但它本身不参与检索。规则如下每个查询文档最多一条intent:行intent:不能单独出现——至少需要一条lex:、vec:或hyde:行intent 还可以通过 CLI 的--intent参数或 MCP 的intent参数传入。典型示例intent: web page load times and Core Web Vitals lex: performance vec: how to improve performance没有 intent 时performance 是歧义的网页性能团队健康度体能带上 intent 后检索管线会优先选取并排序与网页性能相关的内容。源码层面intent 的消歧作用体现在多处src/index.ts的SearchOptions中intent字段注释为 Domain intent hint — steers reranking and snippet/chunk selection见 src/index.tsextractSnippet(row.body, query, ...)在生成摘要时接收opts.intent参与上下文选择见 src/cli/qmd.ts。专门的 test/intent.test.ts 覆盖了extractSnippet结合 intent 的跨文档片段消歧、chunk 选择打分、以及 intent 存在时绕过强信号strong-signal bypass等行为。一个值得注意的演进细节ExpandQueryOptions.intent字段已被标记为deprecated——意图信息不再喂给展开模型因为模型会把它当作元语言原样复制成子查询而是改为通过SearchOptions.intent传给重排与摘要阶段见 src/index.ts。也就是说intent 的正确用法是作为检索后处理重排/摘要的上下文而不是查询展开的输入。约束汇总顶层查询必须是独立的 expand 查询或多行查询文档二选一查询文档只允许lex、vec、hyde、intent类型行内部不允许出现expand:lex语法-term、phrase只在 lex 查询中生效每个查询文档最多一条intent:行且不能单独出现空行会被忽略行首/行尾空白会被裁剪。这些规则全部可以在parseStructuredQuerysrc/cli/qmd.ts中找到对应的报错分支与容错逻辑例如空lex:/vec:/hyde:行会报must include text.行内出现换行会报Keep each query on a single line.。Scoping用集合限定检索范围默认情况下 QMD 会检索所有默认包含的集合collection。通过-cCLI或collectionsMCP/SDK可以把查询限定到特定集合# CLI —— 按集合名过滤集合列表见 qmd collection list qmd query -c docs how does auth work qmd query -c docs -c notes $lex: auth\nvec: authentication flowMCP / HTTP 侧传入复数collections数组OR 匹配{ searches: [ { type: lex, query: auth } ], collections: [docs, notes] }关键语义-c/collections按集合名匹配且从任意目录下都生效多个值之间是OR 合并未指定时搜索所有默认包含的集合被标记为排除的集合qmd collection exclude name默认跳过除非显式指名MCP 侧参数必须是复数collections数组——单数collection会被静默忽略见 docs/SYNTAX.md 与 src/mcp/server.ts 的工具描述。MCP / HTTP API结构化 searches 数组MCP 的query工具以及 REST/query端点接受结构化查询核心是searches数组。没有q字符串参数——searches是必需的{ searches: [ { type: lex, query: CAP theorem }, { type: vec, query: consistency vs availability } ], collections: [docs], limit: 10 }带 intent 的请求{ searches: [ { type: lex, query: performance } ], intent: web page load times and Core Web Vitals }在 src/mcp/server.ts 的 schema 定义中query与searches是互斥的query是纯文本查询由 SDK 自动展开为 lex/vec/hyde 变体、RRF 融合并重排推荐默认searches是类型化子查询数组最多 10 个第一条享有 2 倍权重用于精确控制检索策略。intent在每次搜索调用中都被建议提供以消歧并改善摘要服务端系统提示明确写道 Always provideintenton every search call to disambiguate and improve snippets.。CLI 用法速查# 单行隐式 expand qmd query how does auth work # 多行带类型 qmd query $lex: auth token\nvec: how does authentication work # 结构化 qmd query $lex: keywords\nvec: question\nhyde: hypothetical answer... # 带 intent内联 qmd query $intent: web performance and latency\nlex: performance\nvec: how to improve performance # 带 intent参数 qmd query --intent web performance and latency performanceCLI 侧search()的实现会先解析结构化查询再解析集合过滤resolveCollectionFilter支持多个-c然后走 FTS 检索并用extractSnippet生成带 intent 上下文的摘要见 src/cli/qmd.ts。小结与最佳实践能用一句自然语言表达就写一句单行裸查询自动 expand是最省心也最通用的入口需要精确控制时用查询文档把最强的信号放第一行2 倍融合权重lex抓精确词、vec抓语义、hyde抓答案形态三者互补达到最佳召回歧义查询务必给 intent一行intent:就能让重排与摘要阶段聚焦到正确领域善用集合作用域通过-c/collections缩小检索面既提速又降噪注意 MCP 参数是复数形式了解底层管线lex走 BM25、vec/hyde走向量、多路结果经 RRF 融合、LLM 重排收尾——理解了这条链路才能写出真正贴合检索器特性的查询。更多实现细节可继续阅读 src/cli/qmd.ts、src/index.ts、src/llm.ts、src/mcp/server.ts 以及 test/intent.test.ts。【免费下载链接】qmdmini cli search engine for your docs, knowledge bases, meeting notes, whatever. Tracking current sota approaches while being all local项目地址: https://gitcode.com/GitHub_Trending/qmd1/qmd创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考