[控场AI]
· 10 分钟阅读· 5,012 字

用知识图谱管理900+条Obsidian笔记

用知识图谱管理900+条Obsidian笔记

用固定结构、OKF 元数据、知识图谱和 MCP 把 900 条笔记变成可提问的知识库

文章讲述一位咨询顾问如何让 900 多条 Obsidian 笔记从「可搜索」升级为「可提问」。方案分四层:固定且一致的文件夹结构提供可预测性;OKF frontmatter 为每条笔记附加机器可读的元数据,并用脚本定期清扫补全;基于自建本体的 Graphiti 知识图谱把笔记中的关系抽成带类型、带来源的事实边;小型 MCP 服务器以七个只读工具把图谱接入 Claude 的日常对话。每日 Cowork 定时任务只处理变更内容,新关系需在三条笔记中出现才晋升进本体,并依据 expires_after 清理过期事实。作者同时提醒模型步骤会把笔记文本发往云端,受监管环境需先确认数据流向,并正测试本地 Qwen 3 替代云端模型。

笔记太多,搜索不够用

一位咨询顾问在 Obsidian 里积累了 900 多个 Markdown 文件——会议记录、客户对话、研究报告,全都按自建结构存放。问题不在于找不到文件,而在于文件夹结构无法回答真正重要的问题:谁负责某个客户的数据合同?

据作者描述,搜索「Northwind」会返回所有提及该客户的笔记,但无法告诉你合同负责人是谁。答案其实藏在某次季度回顾笔记的一句话里——涉及 Dana Whitfield。他想要的是用自己的话提问、直接得到答案、并附上来源笔记的能力。

知识图谱示意

四层架构:从笔记到可查询的知识

作者的方案可以拆成四层:固定的文件夹结构、带 OKF 元数据的 Markdown 笔记、基于自建本体(ontology)的 Graphiti 知识图谱、以及每天运行的 Cowork 任务和 MCP 服务器。

关键在于,他认为「搭建」反而是最容易的部分。真正难的是长期维护数据,这个约束塑造了后面每一个设计选择。

结构一致性是地基

整个系统依赖一个简单原则:文件夹结构必须固定且一致。作者的 vault 按客户分文件夹,每个客户下再分人物子目录,同时有一个顶层 People 文件夹。他用一个虚构客户展示了大致形态:

Obsidian Vault/
  Clients/
    northwind/
      Northwind.md
      2026-09-14 quarterly review.md
      people/
        Dana Whitfield/
          Dana Whitfield.md
  People/
  Blog Posts/
  Strategy/

他特别强调,结构要符合你自己的语言习惯,因为你会用自己的称呼和别名去查询它,别人的结构未必适合你。但无论选什么结构,都必须一致遵循——这是后续所有环节的依赖。

OKF 给每条笔记加元数据

Markdown 是基础:LLM 熟悉它,任何文本工具都能读取,笔记不会被绑定到单一应用。但纯 Markdown 缺少状态信息——没有任何东西验证过它,也没有足够元数据来构建图谱。

作者选择了 Google Cloud 发布的 Open Knowledge Format(OKF)。吸引他的点是轻量:只要求在笔记顶部加一段 frontmatter,即键值对集合;同时可扩展,可以随时间叠加新键值。一个示例:

---
type: Meeting Notes
title: "Northwind quarterly review"
description: "Migration scope, timeline pressure, and who owns the data contract."
tags: [meeting, northwind, migration]
generated: { by: claude/haiku-4-5, at: 2026-09-14T11:10:37Z }
---

OKF 的设计目标与这个需求契合:agent 所需的上下文应该存在于开放格式中,而非专有服务或无结构文本里。它故意保持最小意见——type 是唯一必填字段,其余全部可选,自定义键会被保留。这意味着你可以发明 expires_after 这样的键来标记笔记过期时间,LLM 和确定性脚本都能读取并据此行动。

元数据还改变了 agent 读取笔记的成本。脚本可以只取一个属性而不碰正文;大多数时候 agent 只需要判断相关性,标题、描述和标签就够了。作者的做法是在系统的常驻指令里要求 agent 先看 frontmatter,只对看起来相关的笔记打开正文,同时为每个顶层文件夹重建索引,每行一条笔记。

OKF 与 frontmatter 的关系:frontmatter 是 Markdown 文件顶部由 --- 包裹的 YAML 区块,广泛用于静态站点生成器(如 Hugo、Jekyll)和笔记工具,用来声明标题、日期、标签等元数据。OKF 并非新文件格式,而是在 frontmatter 约定之上定义了一套最小、可扩展的键值规范,目标是让 agent 和自动化脚本以统一方式理解文档状态。它与 schema.org、OpenGraph 等元数据标准的思路一致,但更轻量,且刻意不规定过多的字段语义,从而避免绑定特定工具链。理解这一点有助于把握作者为何选择 OKF 而非自建元数据格式:开放格式意味着笔记长期可迁移,不会因某个应用停运而失效。

元数据靠脚本维护

元数据只有在每条笔记都有时才有用,所以作者用脚本做定期清扫:等待 vault 安静下来,逐条检查、补全缺失元数据、修复可机械修复的问题、链接已知名称、重建索引、扫描密钥并提交。唯一需要模型的是分类步骤——读取新笔记并写出类型、标题、描述和标签,其余全是普通代码。

他给分类器设了一个约 30 个值的批准类型列表,但分类器只从中选 8 个。原因很实际:给模型开放列表,它会为任何不匹配的笔记发明一个看似合理的新类型,而没有任何查询知道这个类型存在。不匹配的笔记会被标记出来供人工查看。

本体让关系变得可查询

笔记的核心是关系——笔记之间、以及它们描述的事物之间。Obsidian 的 wikilink 本身就是一种知识图谱。作者展示的图谱视图中,边缘的小点代表尚未与主体连接的知识;点越大说明链接越多,能看出谁真正处在他工作的中心。

但图谱视图不能查询关系。咨询工作的价值恰恰在于关系:公司、客户、人物、组织、协议、标准。于是作者引入本体来描述存在哪些类型的事物、它们之间如何关联。

一条笔记变成事实的过程是这样的:从季度回顾笔记中抽取两个实体和它们之间的关系:

Dana Whitfield (Person)  --ACCOUNTABLE_FOR-->  Northwind data contract (Contract)
  fact:   "Dana Whitfield owns the Northwind data contract and signs off changes to it."
  source: Clients/northwind/2026-09-14 quarterly review.md

关系携带一句自然语言事实和来源笔记路径,所以图谱给出的每个答案都能指回出处。这里也体现了前面强调的一致性:实体身份由类型和名称决定,不做模糊匹配。两条笔记都写 Northwind 就合并为一个节点,无需模型调用;写成 Northwind Trading 则产生第二个节点,直到有人手动映射。

为什么选 Graphiti

作者选择 Graphiti 作为图框架,因为它允许用 Python 定义实体和边类型,自带 schema、类型化边和混合搜索。更大的原因是速度——建图和底层数据库技术很耗时,Graphiti 让他快速迭代,把精力放在本体、数据结构和分类体系上。底层跑 FalkorDB 单容器,嵌入用本地模型 nomic-embed-text,图管线中唯二调用外部模型的地方是 Claude Haiku 4.5,选它是因为成本够低,可以每天跑遍所有变更笔记。

知识图谱与本体:知识图谱以「实体—关系—实体」的三元组组织信息,实体是节点,关系是带方向的边。本体(ontology)则是对图谱的「元描述」——它规定允许出现哪些实体类型(如 Person、Contract)、哪些关系类型(如 ACCOUNTABLE_FOR),以及类型之间的约束。没有本体,图谱只能存任意三元组,查询时无法区分「汇报给」和「负责」这类语义相近但含义不同的边;有了本体,系统才能按类型做精确检索与校验。作者强调实体身份由类型和名称严格决定,正是本体赋予的一致性约束,这与模糊匹配的实体消歧策略形成对比,也解释了为何 Northwind 与 Northwind Trading 会被视为两个节点。

FalkorDB 与本地嵌入模型:FalkorDB 是一个基于稀疏矩阵的图数据库,以 Redis 模块形式交付,可单容器部署,支持 Cypher 查询,适合在个人笔记本上轻量运行图工作负载。相比需要独立集群的 Neo4j,它降低了运维门槛。nomic-embed-text 是 Nomic 发布的开源文本嵌入模型,可在本地运行,把笔记文本转成向量用于语义搜索。作者让嵌入在本地完成,意味着原始笔记内容在检索环节不出本机,只有关系抽取和分类等模型步骤才调用云端 Claude Haiku 4.5。理解这两个组件的分工,就能看清作者数据边界设计的实际含义:向量化与存储留在本地,语义理解部分外包给云端。

每天自动维护图谱

数据持续变化,所以需要每日流程:导入新笔记,发现本体中尚无名称的关系。作者用 Claude Cowork 的定时任务完成这件事,每天 17:00 运行,只把上次运行后变更的内容发给模型——安静的一天不会产生任何模型调用。

关系命名至关重要。如果「Dana 向 Northwind 数据负责人汇报」和「合同出问题时升级给另一个人」被赋予同一个关系名,LLM 就无法区分,可能给出错误的人。所以新关系名需要「挣得位置」:同一个名字在三条不同笔记中出现后,才会自动晋升进本体。

同一个任务也负责清理。回到 expires_after 键:定时任务读取日期,对过期笔记做不同处理——从图谱中退役其事实,或标记待审。作者认为这个思路远超本体范畴:任何告诉模型「当前状况」的文档都会过时,而文档本身不会告诉模型它已过时,这正是元数据要解决的问题。

MCP 服务器把图谱接入日常工作

最后一块是一个通过 stdio 通信的小型 Python MCP 服务器,无需 API key,搜索走本地嵌入,查询直连 FalkorDB。它给 Claude 提供七个只读工具,其中 entity_profile 返回命名实体的摘要,find_relations 帮 Claude 在不知道关系名时判断哪种关系匹配问题。

服务器还携带指令,Claude 连接时读取。作者的指令要求:当问题涉及自己的笔记时,先查图谱再查 Slack 或网页搜索;当 Slack 与图谱冲突时,两个来源都要点名。这一点很重要——图谱只知道笔记记录了什么,如果 Claude 从网页补了缺口却不说明,答案会读起来像来自笔记,而作者会以同样的信心复述它。

实际效果:问「谁拥有 Northwind 数据合同?」,Claude 返回 Dana Whitfield,依据 9 月 14 日的季度回顾,并附上笔记链接。

数据边界需要提前想清楚

作者坦率指出:图谱、数据库和嵌入都在本地笔记本上,但图管线的每个模型步骤都会把笔记文本发给 Claude Haiku 4.5,定时任务本身跑在 Cowork 里,答案发往提问的 Claude 应用。他的工作很多在受监管环境中,因此提醒读者在把笔记接入之前确认这些数据流向可接受。服务器只在笔记本运行,网页或手机会话只能通过桌面应用间接使用。

下一步:本地模型接管

作者已经在 Apple MLX 框架上本地测试了 Qwen 3 的 14B 4-bit 量化版本,目标是看本地模型能否接管模型步骤。目前每个模型步骤都把笔记文本发往云端;本地模型能让文本留在笔记本上,这对笔记来自受监管工作的人来说意义重大。

整个方案的可借鉴之处不在于某个具体工具,而在于它的分层思路:结构一致性提供可预测性,轻量元数据提供机器可读的状态,本体提供语义,定时任务提供持续性,MCP 提供日常可用性。每一层单独都不新鲜,组合起来才让 900 条笔记从「可搜索」变成「可提问」。

#Obsidian 知识图谱#OKF 元数据#Graphiti#MCP 服务器#个人知识管理#Claude Cowork#笔记自动化
分享:

相关推荐