黑曜石混合搜索
](https://www.npmjs.com/package/obsidian-hybrid-search)  ](https://www.npmjs.com/package/obsidian-hybrid-search)
一 MCP服务器 以及CLI工具,使AI助手可以查询您的黑曜石保险库。使用FTS5全文搜索、三元组模糊匹配和 sqlite-vec 向量相似性——结果与互易秩融合(RRF)合并,得分为0-1。
一旦连接,任何兼容MCP的人工智能助手都可以回答基于您实际笔记的问题:通过含义、确切短语或标题查找知识;遍历维基链接图;按标签或文件夹过滤;总是引用来源说明。无需从训练数据中猜测,无需手动复制粘贴。
不需要外部服务。一捆 @huggingface/transformers 默认情况下,模型在本地处理嵌入。任何与OpenAI兼容的API(OpenRouter、Ollama、LM Studio)都可以作为一种插入式替换。
搜索质量
评估依据 黑曜石帮助保险库 (171个注释,58个查询,本地模型):
| 职业健康安全 (本项目) | 量子分子动力学 | |
|---|---|---|
| nDCG@5 | 0.733 | 0.659 |
| MRR | 0.788 | 0.665 |
| Hit@1 | 0.724 | 0.500 |
| 平均查询时间 | 571毫秒 ¹ | 754平方米 |
| 模型下载 | 约117 MB | 约2.2 GB |
¹CPU(苹果硅),混合模式,无需重新存储。²GPU(苹果硅金属),LLM查询扩展+重新排名。
职业健康安全使用 Xenova/multilingual-e5-small. 如何复现→ · 完整基准测试→
特性
- 混合搜索
- BM25+模糊标题+语义嵌入,与RRF融合
- 别名搜索
- 笔记与 aliases: 在frontmatter中,可以通过任何别名进行索引和搜索;别名匹配在BM25(权重5×)和模糊标题评分中得到提升
- 四种搜索模式
- hybrid, semantic, fulltext, title (用于文本查询)
- 类似的笔记查找
- 通过 --path 查找语义相关的注释(始终是语义的,使用标题+内容)
- 图遍历
- --path --related 以可配置的深度显示链接的笔记;筛选依据 --direction outgoing|backlinks|both
- 链接和反向链接
- 每个结果都包括输出链接和反向链接
- 范围筛选
- 仅限于子文件夹;支持多个值和排除项(-notes/dev/)
- 标签过滤
- 按标签过滤;支持多个值和排除项(-category/cs)
- 片段控制
- --snippet-length 设置上下文窗口;空片段总是回退到笔记内容
- 扩展输出
- --extended 在CLI表中添加一个TAGS/ALIASES列,显示frontmatter标签(#tag)和别名
- 增量索引
- 仅重新索引更改的文件;实时监视编辑
- 多查询扇出
- 一次传递多个查询(ohs "q1" "q2" 或 queries[] 在MCP中);结果通过RRF合并——一个在任何一个查询中排名靠前的注释浮到顶部;当注释可能使用与查询不同的词汇时很有用
- 交叉编码器重新排序
- --rerank 对结果进行重新评分 bge-reranker-v2-m3 (ONNX int8,下载一次约570 MB);提高概念查询和多语言查询的精度;在多查询合并后应用
- 本地嵌入
- 通过以下方式脱机工作 @huggingface/transformers (不需要API密钥);默认型号:Xenova/多语言e5-small,100多种语言
- 远程嵌入
- 与OpenAI兼容的API(OpenRouter、Ollama等)
- 笔记阅读
- read 按金库相对路径取出一张或多张钞票;返回包含标题、别名、标签、链接和反向链接的完整内容;路径失误返回前3个模糊建议
- 忽略模式
- 排除文件夹、扩展名或特定文件
- 黑曜石插件
- Obsidian内部的原生搜索模式由相同的CLI提供支持——请参阅 黑曜石混合搜索插件
安装
npm install -g obsidian-hybrid-search
# or run directly without installing:
npx obsidian-hybrid-searchCLI使用情况
快速启动
选项A——推荐:设置 OBSIDIAN_VAULT_PATH 一旦进入你的shell配置文件。
这使您可以从任何目录运行该工具。添加 ~/.zshrc 或 ~/.bashrc:
export OBSIDIAN_VAULT_PATH="/path/to/your/vault"然后重新加载(source ~/.zshrc)并索引您的保险库一次:
obsidian-hybrid-search reindex之后,您可以从任何目录进行搜索:
obsidian-hybrid-search "zettelkasten"______________________________________________________________________
选项B——无环境变量:从vault内部运行。
该工具通过查找 .obsidian/ 文件夹,从当前目录向上走。 cd 进入vault(或任何子文件夹)并运行:
cd /path/to/your/vault
obsidian-hybrid-search reindex # detects vault root, creates DB, indexes everything
obsidian-hybrid-search "zettelkasten"命令可以在vault树中的任何目录中工作。从保险库外部(例如通过从调用的shell别名 ~),使用选项A或通行证 --db /path/to/vault/.obsidian-hybrid-search.db 明确地。
______________________________________________________________________
可选:远程嵌入API,而不是本地模型。
默认情况下,本地 Xenova/multilingual-e5-small 模型被使用-离线工作,不需要API密钥。首次运行时下载约117 MB。支持100多种语言,包括俄语、中文、日语等。
若要改用远程API,请将添加到您的外壳配置文件中:
export OPENAI_API_KEY="sk-..."
# Default API base is https://api.openai.com/v1 — override for other providers:
# export OPENAI_BASE_URL="https://openrouter.ai/api/v1" # OpenRouter
# export OPENAI_BASE_URL="http://localhost:11434/v1" # Ollama (no key needed)
# export OPENAI_BASE_URL="http://localhost:1234/v1" # LM Studio (no key needed)
# Optional: override the embedding model (default: text-embedding-3-small)
# export OPENAI_EMBEDDING_MODEL="text-embedding-3-small"搜索模式
| 场景 | 方式 | 模式 |
|---|---|---|
| 文本查询 | obsidian-hybrid-search "some topic" | hybrid (默认), semantic, fulltext, title |
| 类似注释 | obsidian-hybrid-search --path notes/pkm/zettelkasten.md | 始终语义化(标题+内容) |
| 图遍历 | obsidian-hybrid-search --path notes/pkm/zettelkasten.md --related | 通过BFS链接和反向链接 |
--mode 仅影响文本查询。当 --path 如果给定,则搜索始终是语义性的,无论 --mode.
# Hybrid search (default)
obsidian-hybrid-search "zettelkasten atomic notes"
# Fulltext BM25 search
obsidian-hybrid-search "permanent notes" --mode fulltext
# Fuzzy title search (fast, typo-tolerant)
obsidian-hybrid-search "zettleksten" --mode title
# Semantic / vector search
obsidian-hybrid-search "how to build a knowledge graph" --mode semantic
# Limit results and set a score threshold
obsidian-hybrid-search "productivity systems" --limit 5 --threshold 0.3
# Restrict to a subfolder
obsidian-hybrid-search "daily review" --scope notes/periodic/
obsidian-hybrid-search "daily review" --folder notes/periodic/ # alias for --scope
# Restrict to multiple subfolders (OR)
obsidian-hybrid-search "productivity" --scope notes/pkm/ --scope notes/2024/
# Exclude a subfolder
obsidian-hybrid-search "programming" --scope notes/ --scope -notes/archive/
# Filter by tag
obsidian-hybrid-search "productivity" --tag pkm
obsidian-hybrid-search "machine learning" --tag note/basic/primary
# Filter by multiple tags (AND include, exclude with -)
obsidian-hybrid-search "learning" --tag pkm --tag work
# Filter by frontmatter / properties (exact match, case-insensitive)
obsidian-hybrid-search "notes" --frontmatter status:todo
obsidian-hybrid-search "notes" --prop priority:high # --prop is alias for --frontmatter
# Filter by multiple frontmatter fields (AND)
obsidian-hybrid-search "notes" --frontmatter status:todo --frontmatter priority:high
# Exclude by frontmatter value
obsidian-hybrid-search "notes" --frontmatter -status:done
# Filter-only mode: no query, just filters (returns all matching notes sorted by title)
obsidian-hybrid-search --frontmatter status:todo
obsidian-hybrid-search --folder notes/2024/
obsidian-hybrid-search --tag pkm
obsidian-hybrid-search --frontmatter status:done --tag archived
# Unlimited results in filter-only mode (default limit is 10)
obsidian-hybrid-search --folder notes/ --limit 0
# Find semantically similar notes
obsidian-hybrid-search --path notes/pkm/zettelkasten.md
# Graph traversal: show notes linked to/from this note
# Results show depth: -1/-2 = backlinks, 0 = source, +1/+2 = outgoing links
obsidian-hybrid-search --path notes/pkm/zettelkasten.md --related
obsidian-hybrid-search --path notes/pkm/zettelkasten.md --related --depth 2
# Only outgoing links (what this note references)
obsidian-hybrid-search --path notes/pkm/zettelkasten.md --related --direction outgoing
# Only backlinks (who references this note)
obsidian-hybrid-search --path notes/pkm/zettelkasten.md --related --direction backlinks
# Longer context around each link
obsidian-hybrid-search --path notes/pkm/zettelkasten.md --related --snippet-length 500
# Rerank results with a cross-encoder model (improves precision, ~1-3s extra latency)
# Downloads bge-reranker-v2-m3 ONNX (~570 MB) on first use, cached in ~/.cache/huggingface/
obsidian-hybrid-search "zettelkasten atomic notes" --rerank
# Show tags and aliases alongside results
obsidian-hybrid-search "zettelkasten" --extended
# JSON output (for scripting)
obsidian-hybrid-search "spaced repetition" --json
# Output only paths (one per line) — useful for piping into read
obsidian-hybrid-search --frontmatter id:OHS-4 --only-paths
ohs read ${(f)"$(ohs search --frontmatter status:todo --only-paths)"} # zsh: read all matching notes
# Output absolute filesystem paths
obsidian-hybrid-search "zettelkasten" --only-absolute-paths
# Open results in Obsidian (each in a new tab)
obsidian-hybrid-search "zettelkasten" --open
# Reindex the vault
obsidian-hybrid-search reindex
# Force full reindex
obsidian-hybrid-search reindex --force
# Reindex a single file
obsidian-hybrid-search reindex notes/pkm/zettelkasten.md
# Show indexing status
obsidian-hybrid-search status
# Read a note by path (outputs body content without frontmatter)
obsidian-hybrid-search read notes/pkm/zettelkasten.md
# Read raw file from vault (with frontmatter, like cat)
obsidian-hybrid-search read notes/pkm/zettelkasten.md --raw
# Read multiple notes (separator between each)
obsidian-hybrid-search read notes/pkm/zettelkasten.md notes/pkm/evergreen-notes.md
# Cap content length
obsidian-hybrid-search read notes/pkm/zettelkasten.md --snippet-length 2000
# Structured output with all metadata
obsidian-hybrid-search read notes/pkm/zettelkasten.md --jsonShell别名
添加到您的 ~/.zshrc 或 ~/.bashrc 为了快速访问:
alias ohs='obsidian-hybrid-search'
alias ohss='obsidian-hybrid-search --mode semantic'
alias ohst='obsidian-hybrid-search --mode title'
alias ohsf='obsidian-hybrid-search --mode fulltext'
alias ohsr='obsidian-hybrid-search read'
alias ohsi='obsidian-hybrid-search reindex'
alias ohsst='obsidian-hybrid-search status'然后重新加载(source ~/.zshrc)并使用:
ohs "zettelkasten" # hybrid search
ohss "how to build a knowledge graph" # semantic
ohst "zettelkasten" # fuzzy title (typo-tolerant)
ohsf "permanent notes" # fulltext BM25
ohsr "notes/pkm/zettelkasten.md" # read note by path
ohsi # reindex vault
ohsst # show status输出示例
混合搜索返回一个包含分数和片段的表。分数按相关性进行颜色编码:
| 分数 | 颜色 | 含义 |
|---|---|---|
| 0.8-1.0 | 绿色 | 高度相关 |
| 0.5–0.8 | 黄色 | 相关性中等 |
| 0.2-0.5 | 普通 | 有点相关 |
| 0.0–0.2 | 暗淡 | 相关性低 |
┌───────┬───────────────────────────────┬────────────────────────────────────────────┐
│ SCORE │ PATH │ SNIPPET │
├───────┼───────────────────────────────┼────────────────────────────────────────────┤
│ 0.98 │ notes/pkm/zettelkasten.md │ A note-taking method developed by Niklas │
│ │ │ Luhmann. Each note contains one atomic... │
├───────┼───────────────────────────────┼────────────────────────────────────────────┤
│ 0.72 │ notes/pkm/evergreen-notes.md │ Evergreen notes are written to evolve over │
│ │ │ time. Unlike fleeting notes, they are... │
└───────┴───────────────────────────────┴────────────────────────────────────────────┘随着 --extended,添加了标签/别名列。标签前缀为 #,别名显示如下:
┌───────┬───────────────────────────────┬──────────────────┬──────────────────────────────┐
│ SCORE │ PATH │ TAGS/ALIASES │ SNIPPET │
├───────┼───────────────────────────────┼──────────────────┼──────────────────────────────┤
│ 0.98 │ notes/pkm/zettelkasten.md │ #pkm │ A note-taking method... │
│ │ │ ЗК │ │
│ │ │ slip-box │ │
├───────┼───────────────────────────────┼──────────────────┼──────────────────────────────┤
│ 0.72 │ notes/pkm/evergreen-notes.md │ #pkm │ Evergreen notes are written │
│ │ │ #writing │ to evolve over time... │
└───────┴───────────────────────────────┴──────────────────┴──────────────────────────────┘标题模式会自动省略代码段列。
MCP服务器
大多数人工智能助手在操作时无法访问您的个人知识——它们只能处理您粘贴到对话中的内容。添加此服务器可以为任何兼容MCP的助手提供整个保险库的持久、可搜索的索引。它变成了一个工具调用,而不是复制粘贴会话:助手以调用任何其他工具的方式查询你的笔记,获得带有片段和链接的排名结果,并可以根据要求浏览你的知识图谱。
添加到MCP配置(.mcp.json, claude_desktop_config.json,或为您的客户提供同等服务)。
最小配置(本地嵌入,无API密钥)
使用内置 Xenova/multilingual-e5-small model——完全离线工作,支持100多种语言。首次运行时下载约117 MB。
{
"mcpServers": {
"obsidian-hybrid-search": {
"command": "npx",
"args": ["-y", "-p", "obsidian-hybrid-search@latest", "obsidian-hybrid-search-mcp"],
"env": {
"OBSIDIAN_VAULT_PATH": "/path/to/your/vault"
}
}
}
}完整配置(OpenRouter)
{
"mcpServers": {
"obsidian-hybrid-search": {
"command": "npx",
"args": ["-y", "-p", "obsidian-hybrid-search@latest", "obsidian-hybrid-search-mcp"],
"env": {
"OBSIDIAN_VAULT_PATH": "/path/to/your/vault",
"OBSIDIAN_PREFIX": "myvault_",
"OBSIDIAN_IGNORE_PATTERNS": ".obsidian/**,templates/**,*.canvas",
"OPENAI_API_KEY": "sk-or-v1-...",
"OPENAI_BASE_URL": "https://openrouter.ai/api/v1",
"OPENAI_EMBEDDING_MODEL": "openai/text-embedding-3-small"
}
}
}
}注: 在第一次运行时, npx 将自动安装该软件包。忽略模式在数据库中持久化,并在每次后续启动时恢复,即使缺少env var。服务器公开了四个工具:
| 工具 | 说明 |
|---|---|
search | 搜索保险库。使用 query 用于文本搜索(mode:混合/语义/全文/标题)或 path 为了语义相似性。合并 path 和 related: true 用于图遍历。通过 queries[] 用于多查询扇出(并行搜索、RRF合并)。支持 scope, tag, limit, threshold, depth, direction, snippet_length, rerank |
read | 按vault相对路径获取一个或多个笔记。返回完整内容、标题、别名、标签、链接和反向链接。途中错过:返回 found: false 前三个模糊建议。接受单个路径或数组。使用 snippet_length 限制内容大小 |
reindex | 重新索引vault或特定文件 |
status | 显示总笔记、索引计数、上次索引时间 |
如果 OBSIDIAN_PREFIX 如果已设置,工具名称将在MCP列表中作为前缀(例如 myvault_search, myvault_read).默认情况下 OBSIDIAN_PREFIX 为空,因此工具名称保持不变 search, read, reindex, status.
配置
| 环境变量 | 默认值 | 描述 |
|---|---|---|
OBSIDIAN_VAULT_PATH | MCP要求;CLI自动检测 | vault的绝对路径 |
OBSIDIAN_PREFIX | "" | 可选MCP工具前缀,例如。 myvault_ → myvault_search, myvault_read |
OBSIDIAN_IGNORE_PATTERNS | .obsidian/**,templates/**,*.canvas | 逗号分隔的忽略模式 |
OPENAI_API_KEY | - | API密钥;省略使用本地模型嵌入或无密钥服务器(Ollama、LM Studio) |
OPENAI_BASE_URL | https://api.openai.com/v1 | API基本URL |
OPENAI_EMBEDDING_MODEL | text-embedding-3-small | 嵌入模型名称 |
忽略模式
folder/**--忽略目录及其所有内容*.canvas--通过扩展忽略exact/path.md--忽略特定文件
忽略配置保留在数据库中,因此即使重新启动时缺少环境变量,也会自动还原。
运作原理
- 索引 --笔记按标题分块(带滑动窗口回退),嵌入并存储在带有FTS5和FTS5的SQLite中
sqlite-vec. - 搜索 --BM25(列权重:标题10×,别名5×,内容1×)、模糊三元组标题/别名搜索和向量KNN搜索并行运行;结果与RRF融合,得分为0-1(较高=相关性更高)。
- 链接 --维基链接(
[[note]])被解析为记录路径并存储;每个搜索结果包括links和backlinks阵列。 - 观察者 —
chokidar监视文件更改并在后台逐步重新索引。
发展
npm install
npm test # run test suite
npm run build # compile TypeScript测试使用伪嵌入(不需要API密钥),并针对临时保管库运行。所有测试都涵盖了分块、BM25评分、模糊搜索、链接/反向链接、标签过滤、范围过滤、相关模式遍历、方向/评分逻辑、代码段回退和忽略模式匹配。
许可证
麻省理工学院
