Install
openclaw skills install kg-note-method-obsidianObsidian笔记库按KG笔记法整理——四种笔记类型、链接权限、关系中转、命名规范、新旧分离。自动纠错+建关系+去重+补缺+无关内容分离+分层加载
openclaw skills install kg-note-method-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 加载):
checklist-generator.py — 自动生成执行清单+检查清单。用法:python <script> <任务名> <步1> [步2...]yaml-validator.py — 编辑后验证 YAML 结构。用法:python <script> <文件.md>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 单字符 0→1(只改对应位,不改全文)。失败步记步号到末尾: | 失败: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 搜索时自动加载(匹配到即读 frontmatter)。L1/L2 需要时手动加载。
| 层级 | 概念笔记 | 某物笔记 | Skill笔记 | 何时加载 |
|---|---|---|---|---|
| L0 | abstract: YAML | abstract: YAML | abstract: 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 端是否已有主体笔记
├─ 一端有、一端没有:
│ └─ 判断缺失端:
│ ├─ 缺失端是概念 → 生成时写入清单:新建概念笔记 + 两端建关系
│ └─ 缺失端不是概念 → 生成时写入清单:把关系笔记内容移入已有主体(转纯文本)+ 删除关系笔记
├─ 两端都没有:
│ └─ 判断两端:
│ ├─ 两端都是概念 → 生成时写入清单:新建两端概念笔记 + 两端建关系
│ ├─ 一端是概念 → 生成时写入清单:新建概念笔记 + 把关系笔记内容移入已有主体(转纯文本)+ 删除关系笔记
│ └─ 两端都不是概念 → 不改动
└─ 两端都有 → 生成时写入清单:跳过(已有主体,关系笔记正常即可)
└─ 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 是 某物笔记:
└─ 查询具体属性信息(位置/参数/数据等)并填写
Skill笔记=步骤清单/技巧/能执行/经验/攻略的集合,必须有完整的可执行技能块(步骤+陷阱+验证),信息密度够大才能让 agent 直接用。任何可执行的流程、经验、技巧、攻略都归入 skill。
标准结构(L1):
---
name: 技能名
description: 一句话描述
version: x.x.x
---
# 标题
## 步骤
1. ...
2. ...
## 陷阱
- ...
笔记中已有图片禁止删除。图片嵌入见①步(同步图片嵌入)。
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_filetags: [关系],禁止 created/source/标题行(⑥关联处理校验)kg 开头必须先加载本 skill,再走清单强制建单。跳过会丢失格式校验和流程控制kg 检查 的分析阶段只读不写。read_file 后产生"这里要改"的冲动是正常的,但必须先列变更清单→问用户→等确认→再动手。分析阶段的假设是"没有写操作"--- 编辑。frontmatter 和正文分开 patch。每次 patch 后 read_file 验证 frontmatter 闭合和结构完整tag: 而非 tags: → 库里有多个笔记误写 tag:(缺 s)。yaml-validator 会报 TAG_VS_TAGS 错误。修 frontmatter 时注意该字段是 tags: 不是 tag:search_files 验证文件存在