Skill: realpda/kg-note-method-obsidian (version 3.23.0)

--- name: kg-note-method-obsidian description: Obsidian笔记库按KG笔记法整理——四种笔记类型、链接权限、关系中转、命名规范、新旧分离。自动纠错+建关系+去重+补缺+无关内容分离+分层加载 version: 3.23.0 author: Hermes Agent license: MIT metadata: hermes: tags: [obsidian, kg-notes, knowledge-graph, token-saving] --- # 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` | 追踪每步完成/失败状态 | 每步完成后立即更新 | ### 执行清单格式 **执行时照做，不重复分析。** ```markdown # {任务名} — 执行清单 ## 步骤 ### 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/L1/L2 分层加载 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 端是否已有主体笔记 ├─ 一端有、一端没有： │ └─ 判断缺失端： │ ├─ 缺失端是概念 → 生成时写入清单：新建概念笔记 + 两端建关系 │ └─ 缺失端不是概念 → 生成时写入清单：把关系笔记内容移入已有主体（转纯文本）+ 删除关系笔记 ├─ 两端都没有： │ └─ 判断两端： │ ├─ 两端都是概念 → 生成时写入清单：新建两端概念笔记 + 两端建关系 │ ├─ 一端是概念 → 生成时写入清单：新建概念笔记 + 把关系笔记内容移入已有主体（转纯文本）+ 删除关系笔记 │ └─ 两端都不是概念 → 不改动 └─ 两端都有 → 生成时写入清单：跳过（已有主体，关系笔记正常即可） ``` ### ⑦ 查重（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。正文在闭合 `---` 之后，闭合不可省略。 **概念：** ```yaml --- tags: [概念] abstract: 一句话核心定义 --- ``` 正文结构（L1）： ``` ## 核心规则 ... ## 来源 ... ``` **某物：** ```yaml --- tags: [某物] abstract: 一句话简介 --- ``` 正文结构（L1）： ``` ## 基本信息 ... ``` **Skill：** ```yaml --- tags: [skill] name: 技能名 abstract: 一句话描述 version: x.x.x --- ``` 正文结构（L1）： ``` ## 步骤（技能块/技巧/经验/攻略/执行清单） ... ## 陷阱 ... ``` **关系：** ```yaml --- 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` 验证文件存在


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)