用 CK Search 在笔记中发现意义
太长不看版
CK Search 为任何目录添加本地语义搜索功能,并内置 MCP 服务器用于 AI 代理集成。语义搜索通过基于含义而非字符串匹配来克服关键词搜索的局限。本文将介绍极其简单的安装和配置过程,并解释语义搜索如何找到关键词搜索找不到的内容。这不是什么魔法,我也会坦诚地说说它的不足之处。
当搜索看不懂你的意思
在第一篇文章中,我描述了一个时刻——即使组织得再好也不够用。你可以把标签打得完美无缺,但仍然找不到你需要的东西,因为你搜索的是一个概念,而你的笔记用了不同的词。这就是关键词搜索的天花板。
我在三个 Obsidian 库中大约有 1,900 个 markdown 文件。如果你不是 Obsidian 用户,可以简单地把它理解为三个不同文件夹中的 1,900 个文本文件。它们有标签、链接,并且用 frontmatter(或者更简单地说,页面属性)来结构化。组织做得很扎实。但当我搜索"authentication"时,我找不到那篇关于"session token management"的笔记。当我搜索"AI assistant"时,我错过了那篇关于"Claude Desktop"的笔记。信息就在那里。只是搜索看不到它。
Obsidian 的内置搜索,以及大多数扩展它的插件,都基于同一个原理:将你输入的字符与文件中的字符进行匹配。有些会增加一些功能来改善关键词匹配效果,但它们仍然只是在搜索文本,而不是含义。
语义搜索(Semantic Search)的工作方式不同。它不是匹配字符串,而是将你的查询和笔记都转换为数值表示(Numerical Representations),然后衡量它们在含义上的接近程度。"Authentication"和"session token management"在这个数值空间中最终会彼此靠近,因为它们讲的是同一个概念。搜索理解的是你的意思,而不仅仅是你打的字。
为什么选择 CK Search
有好几款工具可以为 Obsidian 添加语义搜索。我在评估了几款之后选定了 CK Search。CK Search 并非 Obsidian 专用。它可以搜索任何包含文本文件的目录。
对我来说最重要的两点是:CK Search 无需运行 Obsidian 即可工作,而且它内置了 MCP 服务器。前者意味着我可以从命令行、从脚本、从任何地方进行搜索。后者意味着 Claude Code 可以直接将其作为工具使用,无需额外的依赖、配置或设置。它还是用 Rust 构建的,这是一门以速度著称的语言。
有一点需要提前说明:CK Search 没有图形界面。没有带搜索栏的 Obsidian 插件。它是一个命令行工具,而且这是有意为之——它的设计目的是被 AI 代理和脚本使用,而不是手动点击操作。如果你想要在 Obsidian 中获得可视化的语义搜索体验,Smart Connections 或 Copilot 可能更适合你。如果你正在构建一个 AI 代理以编程方式查询你笔记的系统,CK Search 是更好的工具。
工具对比
| CK Search | Smart Connections | Copilot for Obsidian | |
|---|---|---|---|
| 搜索类型 | 语义 + 混合 | 语义 | 语义 |
| MCP 支持 | 内置服务器 | 插件 | 无 |
| 多库支持 | 任意目录 | 单库 | 单库 |
| 需要 Obsidian | 否 | 是 | 是 |
| 本地优先 | 是 | 是 | 视情况而定 |
安装
CK Search 通过 Cargo(Rust 包管理器)安装。如果你还没有安装 Rust,需要先安装它。
# Install Rust (if you don't have it)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
# Install CK Search
cargo install ck-search
# Verify
ck --version
就这样。不需要 Node.js 运行时,不需要 Python 环境,不需要 Docker 容器。一条命令,一个工具。
你的第一次语义搜索
在配置其他任何东西之前,先从命令行测试一下:
# Semantic search — finds by meaning
ck --sem "ideas for improving workflow" /path/to/your/vault
第一次运行时,CK Search 会构建索引。它会读取目录中的每个 markdown 文件,并将它们的数值表示存储在一个 .ck/ 文件夹中。之后的每次搜索几乎都是即时的——它只会重新索引发生变化的文件。没有后台进程,没有守护进程,没有文件监视器。CK Search 只在你搜索时运行。其余时间零资源开销。
试几个查询,然后和 Obsidian 内置搜索返回的结果做个比较。这就是你能感受到差异的地方。搜索一个你知道存在于笔记中的概念,但用和你写的时候不同的词。语义搜索会找到它。关键词搜索不会。
CK Search 还支持关键词搜索和混合模式(语义 + 关键词组合),但我主要用它做语义搜索。我的工具栈中已经有关键词工具了:grep、Obsidian 内置搜索、Omnisearch 插件。CK Search 的独特价值在于它理解含义。我的工具栈中没有其他东西能做到这一点。
将它连接到 AI 代理
如果你正在使用 Claude Code 或任何其他 AI 代理,CK Search 作为 MCP 服务器会变得更加有用。MCP(Model Context Protocol)是一个将 AI 工具连接到外部数据源和功能的开放标准。Claude Code 原生支持它。
最简单的设置方式是使用一个 .mcp.json 文件:
{
"mcpServers": {
"ck-search": {
"command": "/Users/yourname/.cargo/bin/ck",
"args": ["--serve"]
}
}
}
用 which ck 找到你的实际路径,然后相应替换 command。
连接后,Claude Code 就能访问以下工具:
semantic_search— 最主要的。基于概念的、含义驱动的搜索。hybrid_search— 语义 + 关键词组合搜索。
实际使用中,当我问 Claude Code 关于我笔记的问题时,它会用自然语言查询调用 semantic_search,获取带有文件路径和片段的排序结果,然后阅读排名靠前的匹配内容来综合出一个答案。
索引什么(以及不索引什么)
CK Search 会索引你指向的目录中的所有内容,减去你排除的部分。你应该跳过任何不是有意义文本内容的东西。关键原则是:只索引那些你希望按含义搜索的文件。应用配置和媒体文件不属于这类。它们是会稀释索引质量的噪音。
要排除文件,请在你要搜索的目录根目录下创建一个 .ckignore 文件。
CK Search 索引基于文本的文件,如 markdown、代码和纯文本。如果你有 PDF、含文字的图片或 Office 文档,你需要使用其他工具。我使用 Omnisearch Obsidian 插件,它通过文本提取处理 PDF,通过 OCR 处理图片。但那是另一篇文章的内容了。
语义搜索不好用的时候
我想对此坦诚相告,因为太多关于 AI 工具的文章过度夸大了它的神奇之处。
语义搜索不擅长的场景:
- 精确字符串。 搜索一个错误信息、一个函数名、一个特定标签?用 grep 或 Obsidian 内置搜索。语义搜索会给你概念上相关的结果,但当你需要找到包含
ERROR_CODE_4032的那个确切文件时,这不是你想要的。 - 短且常见的查询。 搜索"meeting"会返回所有与会议模糊相关的内容。没什么帮助。
- 歧义消除。 "Apple"公司和"apple"水果在数值表示上是一样的。上下文有所帮助,但并不完美。
- Frontmatter(页面属性)查询。 搜索具有特定标签或日期的笔记?那是结构化数据。用 grep 加正则表达式,而不是语义搜索。
- 最近添加的内容。 如果你刚创建了一个笔记,它在下一次搜索触发变更文件重新索引之前不会出现在索引中。这通常不是问题,但值得了解。
坦诚的看法是:语义搜索是一种工具,而不是唯一的工具。它填补了关键词搜索无法覆盖的特定空白。但关键词搜索也填补了语义搜索无法覆盖的空白。最佳配置是两者兼用。
更宏观的视角
CK Search 是我为知识库构建的更大搜索系统中的一部分。
完整的工具栈简要概述:
- CK Search:对 markdown 文件进行语义搜索(本文所介绍的)
- Grep:精确文本和正则表达式匹配(内置工具,零配置)
- Omnisearch:跨所有文件类型的关键词搜索,包括 PDF 和带 OCR 的图片
- Sift:一个自定义的 RAG 和时序知识图谱系统,用于一个外部但相关的知识库(独立于 Obsidian)
当我的 AI 代理处理搜索查询时,它会并行运行所有这些工具,然后综合合并后的结果。但那是后续文章的内容了。就目前而言,仅 CK Search 本身就已经是对纯关键词搜索的一次重大升级。
下一步
下一篇文章将介绍我如何使用 Sift 构建一个外部知识库。Sift 是一个开源系统,它结合了向量搜索、RAG 和时序知识图谱,超越了任何单一库内搜索工具的能力。你的知识不全都存在 markdown 文件里。研究论文、网络文章、YouTube 视频、播客、参考文档——那些你从库外收集的资料——也需要一个归处。一旦有了归处,你就可以开始跨所有这些资料提问,并获得带有来源引用的答案。
本文是 AI 驱动的知识管理系列的一部分。上一篇:从文件夹到知识库。下一篇:超越 Obsidian —— 用 Sift 构建外部知识库。