Kg Note Method Obsidian

Obsidian笔记库按KG笔记法整理——四种笔记类型、链接权限、关系中转、命名规范、新旧分离。自动纠错+建关系+去重+补缺+无关内容分离+分层加载

Audits

Pass

Install

openclaw skills install kg-note-method-obsidian

KG笔记法 — Obsidian 笔记整理

<!-- 速查: 内容检查+拆分→分类匹配→名称匹配→图片保护→直链检查→查相关笔记→查重→更改清单→补完计划→收尾 -->

⚠️ 不主动改写笔记:所有命令(除 kg 完善),尽量保留原文原貌。

⚡ 手动调用命令

所有命令第一步:skill_view(name='kg-note-method-obsidian') 加载本 skill。不可跳过。

kg start

加载本 skill。

kg "笔记名.md"/"关键词"

kg start → 建执行清单+检查清单到 _working/(清单强制)→ 查找笔记逐条跑 ①-⑥ → ⑦ → 按清单执行 → ⑧,无笔记则新建再跑

kg 完善 "笔记名.md"

kg start → 建执行清单+检查清单到 _working/(清单强制)→ 逐条跑 ①-⑥ → ⑦ → ⑨ → 按清单执行 → ⑧

kg 检查 "笔记名.md" / kg 检查 "关键词"

与其他命令相同的清单(清单名=笔记名),区别仅在于:分析完成后询问是否执行,等用户确认后才动手。

kg 查看 "笔记名.md"

加载 L0(frontmatter)。相关则加载 L1(对应段落)。仍不足加载 L2(全文)。

用户消息以 kg 开头 → 必须先加载本 skill。路径含 vault → 自动触发,用上述命令更可靠。

| _working/ | 当前任务清单目录 |

📦 内置脚本和参考(skill_view + file_path 加载):

  1. checklist-generator.py — 自动生成执行清单+检查清单。用法:python <script> <任务名> <步1> [步2...]
  2. yaml-validator.py — 编辑后验证 YAML 结构。用法:python <script> <文件.md>
  3. enrichment.py — 补完计划:将搜索结果格式化为 KG 标准段落追加到笔记。用法:echo "内容" | python <script> <文件.md> --stdout--text "..."

清单目录: vault 根目录下的 _working/

两个清单文件

文件用途更新时机
{任务名}_执行清单.md预判所有步骤的详细操作任务开始前一次性生成
{任务名}_检查清单.md追踪每步完成/失败状态每步完成后立即更新

执行清单格式

执行时照做,不重复分析。

# {任务名} — 执行清单
## 步骤
### 1. 重命名「美食-青岛.md」→「青岛美食.md」(②名称检查:主体名禁` - `)
- 操作类型:mv
### 2. 修改「笔记A.md」tag
- 操作类型:patch
- tags: [旧tag] → tags: [某物]
### 3. 新建「笔记A - 关系 - 笔记B.md」
- 操作类型:新建文件
- 内容:[[笔记A]]关系描述[[笔记B]]。
### 4. 检查两端残留链接 + 查重
- 操作类型:检查验证
### N. 删除本任务的2个清单文件
- 操作类型:删除文件

检查清单格式

极度精简一行状态码。执行清单已含完整描述,这里只记进度。每步一个位:0=未做,1=完成。 文件内容仅一行:

0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0

步数 = 冒号分隔的位数。更新时 patch 单字符 01(只改对应位,不改全文)。失败步记步号到末尾: | 失败:3,7完整标识:检查清单全 1 + 执行清单最后一步≥"删除本任务2个清单文件"。

格式示例(17步,第1、3步已完成,第7步失败):

1:0:1:0:0:0:0:0:0:0:0:0:0:0:0:0:0 | 失败:7

执行流程

步0 和步5 不可跳过。跳过步0 → 同名任务已有清单却被覆盖。跳过步5 → 用户不知道还有其他任务。

0. 任务开始前(不可跳过):
   search_files target=content, pattern='检查清单', path=_working/
   ├─ 有同名任务的清单 → read_file 检查清单+执行清单 → 检查是否可续接
   │  (有未完成位 且 最后一步不是"删除本任务")→ 从未完成步开始
   │  否则(全1或最后一步是删除)→ 删除清单文件,重新建
   ├─ 有其他任务的清单(不同名)→ 当前任务执行完后步5再提示
   └─ 无清单 → **清理同名残留:先 `search_files` 搜 `_working/` 下所有包含该笔记名的清单文件并删除**(防止之前建错的 `笔记名+命令名` 形式残留)。
      然后生成执行清单+检查清单。**清单名=笔记名(用户给的参数),不加任何命令前缀/后缀。**
      **参数映射:** `kg 检查 苏州` → checklist-generator.py 第一个参数传 `苏州`,不传 `苏州检查`
      `kg "青岛美食.md"` → 传 `青岛美食`
      `kg 完善 资本收益.md` → 传 `资本收益`
      优先用脚本(需设环境变量):
      `OBSIDIAN_VAULT="<vault绝对路径>" python scripts/checklist-generator.py <任务名> <步1> [步2...]`
      或用完整路径:`python <script_full_path> <任务名> <步1> [步2...]`(此时仅打印到终端,需手动保存)
      ⚠️ 脚本在终端输出清单不等于文件已保存到 _working/。
      **必须验证:** 脚本执行后立即 `search_files path=_working/ pattern=<任务名>` 确认清单文件存在:
      ├─ 不存在 → 重跑(检查环境变量或手动 copy 内容建文件)
      └─ 存在 → 继续
      无脚本环境 → 手动建(格式见上)

1. **命令流程分支:**
   ├─ **`kg 检查` → 分析阶段(只读不写):**
   │   ├─ 逐条跑 ①-⑥ → ⑦ → ⑨,**此阶段禁止任何 patch/write_file/mv**
   │   ├─ **⑧(生成变更清单)两个动作:**
   │   │   ① 在回复中向用户列出所有变更
   │   │   ② **同时用 `write_file` 覆盖执行清单,把具体的操作步骤写进去**(每条操作含:文件、操作类型、具体内容)
   │   │      ⚠️ 清单源自初始脚本,但分析后才产生具体内容。不能只列在回复里,必须写回清单文件。
   │   ├─ **同步更新检查清单 bitmask 步数** — 执行清单步骤数变化后,检查清单的位也要对应
   │   ├─ → **询问用户「是否执行?」**
   │   │     「📋 分析完成,发现以下问题:\n        · 傻瓜.md: tags为空→[概念], 删除无关行\n     是否执行这些修改?」
   │   │     等用户回复"执行/动手/是" → 进入执行阶段
   │   │     用户说"不/算了" → 删除清单,结束
   │   └─ **⚠️ 分析阶段动手修改是最高频错误** — read_file 后会产生"这里要改"的冲动,必须克制。只更新执行清单,不动笔记文件。分析阶段的假设是"没有写操作"。
   │
   └─ **`kg "笔记名"` / `kg 完善` → 直接执行(不询问):**
        逐条跑 ①-⑥ → ⑦ → ⑨(仅完善),分析和执行合一。发现一个问题就把操作记入执行清单(write_file 追加或覆盖)→ 立即执行 → 更新 bitmask。不等待用户确认。
        完成后 → ⑧(列出所有变更)

2. 每步完成后 → 立即 `patch` 检查清单,将该步对应的 `0` 改为 `1`(单字符替换,不得用 `write_file` 重写全文)。失败则追加 `| 失败:N`。
   **patch 操作安全规则(适用所有文件编辑):**
   - `patch` 的 old_text 必须足够短且唯一,**禁止跨 frontmatter 边界**(`---` 之间 vs `---` 之外分开编辑)
   - 编辑笔记文件后,立即调用 `python scripts/yaml-validator.py <文件>` 验证 frontmatter 闭合
   - 涉及 YAML 字段(tags/abstract/aliases)用单行 patch,不要大段替换
3. 全部完成 → read_file 检查清单+执行清单,确认检查清单所有位均为 `1` 且执行清单最后一步为"删除本任务2个清单文件"。是则删除两个清单文件;否则说明执行不完整,删除清单并通知用户。
4. 中途中止 → 清单文件保留,下次会话恢复

**5. 任务完成后(不可跳过):**
   search_files target=files, pattern=*检查清单*, path=_working/
   ├─ 有 OTHER 清单文件 → 逐条 read_file 读取 → 列给用户:
   │     「📋 还有未完成任务:
   │       · 小村庄 — 完成度 0/14(14步未完成)
   │       · 美食-青岛 — 完成度 0/17」
   │     → clarify 询问:「是否继续完成某个?」
   │     → 用户选是 / 指定某个 → 开始执行
   │     → 用户选否 → 结束
   └─ 无 → 结束

清单文件不在 KG 图谱内,禁止用 [[链接]]。纯文本跟踪用。

四种类型

所有主体笔记(概念/某物/skill)统一 L0 为 abstract,一句让人看明白的核心简介。

类型tag[[链接]]?文件名含-?内容
概念笔记概念抽象概念
某物笔记某物具体人/物/地点
Skill笔记skill技能块/技巧/经验/攻略/操作步骤/执行清单
关系笔记关系✅唯一✅ 格式:A - 关系 - B一句话+两个[[链接]],禁表格/段落/标题

主体笔记=概念+某物+skill。关系笔记=线。攻略类文件→归入 skill 笔记

L0/L1/L2 分层加载

L0 搜索时自动加载(匹配到即读 frontmatter)。L1/L2 需要时手动加载。

层级概念笔记某物笔记Skill笔记何时加载
L0abstract: YAMLabstract: YAMLabstract: YAML搜到即加载
L1## 核心规则 段落## 基本信息 段落## 步骤 / 技能块L0相关后加载
L2全文+来源全文+来源全文+来源需要细节时

操作流程

两阶段模型: kg 检查 的分析阶段只读不写(read_file/search_files 可以,patch/write_file/mv 禁止),分析完写回执行清单→问用户→等确认再执行。 kg 完善 / kg "笔记名" 无分析阶段——分析和执行合一,发现即动手。不询问。

逐条跑 ①-⑥ → ⑦ → 按清单执行 → ⑧


① 内容检查 + 拆分

read_file 先读。内容 > tag > 名称。
└─ 内容有混入/分属多主题(表格/段落/无关信息混在主体或关系里)
   └─ 搜库判断:
      ├─ 已有主体且缺此信息 → 生成时写入清单:patch 移入该主体
      ├─ 已有更完整 → 生成时写入清单:patch 删除混入内容
      └─ 无主体 → 生成时写入清单:新建文件(保留原笔记,只拆分不改写)

② 分类匹配

└─ 内容与当前 tag 不匹配:
   └─ 抽象定义+规则 → 生成时写入清单:patch tags 为 [概念]
   └─ 描述具体人/物/地点属性 → 生成时写入清单:patch tags 为 [某物]
   └─ 步骤清单/技巧/能执行/经验 → 生成时写入清单:patch tags 为 [skill]
   └─ 一句话+俩 [[链接]] → 生成时写入清单:patch tags 为 [关系]

③ 名称匹配

└─ 主体笔记名含 ` - `(误认为关系笔记)→ 生成时写入清单:重命名 mv
└─ 文件名 与 核心内容 不匹配 → 生成时写入清单:重命名 mv(以核心内容为准)

④ 图片保护

└─ 已有 ![]() 图片:
   ├─ 有效(HTTP 200)→ 不动
   └─ 失效(404/403)→ 生成时写入清单:搜有效替代链接
└─ 没有图片 → 跳过

⑤ 直链检查

read_file 检查正文 [[链接]]:
└─ tag 是 概念/某物/skill(主体笔记)且有 [[链接]]:
   └─ 检查 [[链接]] 目标是否存在:
      ├─ 存在 → 生成时写入清单:新建关系笔记(A - 关系 - B)+ 删原直链(先补关系再删链)
      └─ 不存在 → 生成时写入清单:[[链接]] 转为纯文本(删除 [[ ]] 保留字词)
└─ tag 是 关系 → [[链接]] 合法,不动

⑥ 查相关笔记 + 关联处理

按以下顺序检查 tag 类型,在清单生成时写入:

└─ tag 是 概念/某物/skill(主体笔记):
   └─ search_files 搜库中有关联的其他主体笔记
   └─ 每找到一条有效关联 → 生成时写入清单:新建关系笔记(A - 关系 - B)
──────────────────────────────────────
└─ tag 是 概念(特殊处理——概念之间常需连线成网):
   └─ 列出本概念相关的其他概念
   └─ 搜库查找:
      ├─ 已有 → 生成时写入清单:新建关系笔记(A - 关系 - B)
      └─ 没有 → 生成时写入清单:新建概念笔记 + 建关系
──────────────────────────────────────
└─ tag 是 关系(检查两端主体是否存在):
   └─ search_files 查 A 端和 B 端是否已有主体笔记
      ├─ 一端有、一端没有:
      │  └─ 判断缺失端:
      │     ├─ 缺失端是概念 → 生成时写入清单:新建概念笔记 + 两端建关系
      │     └─ 缺失端不是概念 → 生成时写入清单:把关系笔记内容移入已有主体(转纯文本)+ 删除关系笔记
      ├─ 两端都没有:
      │  └─ 判断两端:
      │     ├─ 两端都是概念 → 生成时写入清单:新建两端概念笔记 + 两端建关系
      │     ├─ 一端是概念 → 生成时写入清单:新建概念笔记 + 把关系笔记内容移入已有主体(转纯文本)+ 删除关系笔记
      │     └─ 两端都不是概念 → 不改动
      └─ 两端都有 → 生成时写入清单:跳过(已有主体,关系笔记正常即可)

⑦ 查重(R7)

└─ search_files 通过关系笔记连接的目标主体笔记(反向追踪):
   └─ 检查两个主体之间是否有多条关系笔记:
      ├─ 多条同向(A→B 多条)→ 生成时写入清单:选最佳名称保留,其余删除
      ├─ 双向(A→B + B→A)→ 生成时写入清单:保留不冲突
      └─ 同语义覆盖(一条含归属+类型+位置等,另一条只是子集)→ 生成时写入清单:保留语义更全的一条,删子集
   └─ 每条被保留的关系笔记 → 生成时写入清单:校验文件名最佳匹配

⑧ 更改清单

操作完成后在回复中列出所有更改:新建/修改/删除的文件清单。 分析阶段的⑧不同: 分析完成后的⑧不仅要列出变更,还必须用 write_file 覆盖 _working/ 下的执行清单, 把具体的操作步骤写入(替换初始模板),同时更新检查清单 bitmask 步数。然后等用户确认后才进入执行。

⑨ 补完计划

优先用脚本:python scripts/enrichment.py <笔记.md> --stdout 预览格式化的补充内容,确认后再追加。 无脚本环境 → 手动写:

└─ tag 是 概念/skill 笔记:
   └─ 网络搜索 What、Why、Who、When、Where、How、How much、Effectiveness
   └─ 搜到有用信息 → 写入笔记对应段落并标明出处
   └─ 需改写原文 → clarify 询问用户确认后再改
└─ tag 是 某物笔记:
   └─ 查询具体属性信息(位置/参数/数据等)并填写

规则

R4:Skill 结构

Skill笔记=步骤清单/技巧/能执行/经验/攻略的集合,必须有完整的可执行技能块(步骤+陷阱+验证),信息密度够大才能让 agent 直接用。任何可执行的流程、经验、技巧、攻略都归入 skill。

标准结构(L1):

---
name: 技能名
description: 一句话描述
version: x.x.x
---

# 标题

## 步骤
1. ...
2. ...

## 陷阱
- ...

R5:图片保护

笔记中已有图片禁止删除。图片嵌入见①步(同步图片嵌入)。

模板

abstract 只放 YAML frontmatter。正文在闭合 --- 之后,闭合不可省略。

概念:

---
tags: [概念]
abstract: 一句话核心定义
---

正文结构(L1):

## 核心规则
...
## 来源
...

某物:

---
tags: [某物]
abstract: 一句话简介
---

正文结构(L1):

## 基本信息
...

Skill:

---
tags: [skill]
name: 技能名
abstract: 一句话描述
version: x.x.x
---

正文结构(L1):

## 步骤(技能块/技巧/经验/攻略/执行清单)
...
## 陷阱
...

关系:

---
tags: [关系]
---

正文:[[A]]关系描述[[B]]。 一句完整句子(含动词+句号),禁止 created/source/标题行。

速查

内容检查+拆分→分类匹配→名称匹配→图片保护→直链检查→查相关笔记→查重→更改清单→补完计划→收尾

陷阱(按频率排序)

  • 不看内容就动手 → 涉文件操作必须先 read_file
  • 见链接就动手/多链/复合句 → 先看tag→关系链接合法;正文只允许2链;复合因果拆多条(⑥关联处理自动校验)
  • 建完主体停手/忘查另一端/直链先删后补 → 同轮次搜关联建关系(⑥);直链先补关系再删
  • 多主体不扫/缺端直接删/关系重复 → ⑥已覆盖缺端处理;⑦查重覆盖关系冗余和语义覆盖
  • 清单相关 → 任务开始必须建清单;步0必搜同名清单检查完整标识;步5必查其他清单
  • 全图空白/skill写一半 → ①-⑤检查阶段图片保护;skill缺abstract或缺技能块
  • 关系笔记前部冗余 → frontmatter 只能 tags: [关系],禁止 created/source/标题行(⑥关联处理校验)
  • ⚠️ 未加载skill直接操作 → 用户消息以 kg 开头必须先加载本 skill,再走清单强制建单。跳过会丢失格式校验和流程控制
  • ⚠️ 跳过清单直接动手 → 每条命令第一动作就是建清单。不建清单不允许任何文件操作
  • ⚠️ 分析阶段动手修改kg 检查 的分析阶段只读不写。read_file 后产生"这里要改"的冲动是正常的,但必须先列变更清单→问用户→等确认→再动手。分析阶段的假设是"没有写操作"
  • ⚠️ 执行中修改清单 → 清单生成后禁止追加/删除步骤。发现新问题记下来→执行完当前→删清单→建新清单处理
  • ⚠️ patch 跨 YAML 边界 → old_text 禁止跨 --- 编辑。frontmatter 和正文分开 patch。每次 patch 后 read_file 验证 frontmatter 闭合和结构完整
  • ⚠️ 字段名写错 tag: 而非 tags: → 库里有多个笔记误写 tag:(缺 s)。yaml-validator 会报 TAG_VS_TAGS 错误。修 frontmatter 时注意该字段是 tags: 不是 tag:
  • ⚠️ 脚本输出≠文件保存 → 在终端跑 checklist-generator.py 只打印到 stdout,文件未必写入 _working/。必须设 OBSIDIAN_VAULT 环境变量或手动保存。执行后立即 search_files 验证文件存在