--- name: obsidian-workflow-pkm description: Obsidian PKM 端到端编排层——专为"多步骤复合需求"设计,组合调用 obsidian-* 子技能。覆盖 Inbox→Zettelkasten 原子化、MOC 主题地图、PARA 项目归档、Karpathy LLM-Wiki、周报/月报汇总、季度知识库体检、文献批量导入、Web Clip→永久笔记。**优先匹配**:当用户说"整理 inbox/构建 MOC/做季度体检/汇总周报/clip 这篇文章"等多步骤指令时,先进入本技能(编排层)再下发子技能;单一原子操作(搜一篇笔记、改一个属性)请直接用 obsidian-search/meta 等专项子技能。触发词:整理 inbox、原子化笔记、构建 MOC、PARA 归档、LLM wiki、周报、月报、知识库体检、Zettelkasten 流程、web clip、网页剪藏、批量导入文献。 --- # Obsidian Workflow · PKM 编排工作流 > 参照 `lark-workflow-*` 的命名与定位——这是**编排层**技能,调用各 `obsidian-*` 子技能完成端到端 PKM 流程。不用于单一原子操作,那些请用对应专项技能。 > **设计哲学**:每个工作流都是"**步骤序列 + 决策点 + 审计记录**"。AI agent 按步骤执行、在决策点等待用户确认(按项目 CLAUDE.md 规则)、所有写入记录到 daily note。 --- ## 何时使用 | 场景 | 工作流 | |------|--------| | 清理 Inbox,把闪念变成永久笔记 | **Workflow 1: Inbox → Atomic → Permanent** | | 从零构建一个主题的 MOC | **Workflow 2: MOC Builder** | | 已完成项目归档到 Archive | **Workflow 3: PARA 归档** | | 用 LLM 构建一个可维护的主题 Wiki | **Workflow 4: Karpathy LLM-Wiki** | | 生成周报/月报 | **Workflow 5: 周报 / 月报汇总** | | 季度知识库健康度体检 | **Workflow 6: 季度体检** | | 从网页/PDF 批量导入并原子化 | **Workflow 7: 文献批量导入** | | 单篇网页剪藏 → 永久笔记 | **Workflow 8: Web Clip → Permanent** | --- ## Workflow 1 · Inbox → Atomic → Permanent(Zettelkasten 核心流程) **目标**:把 `00-Inbox/` 中的零散捕获,重写为 `50-Zettel/` 下的原子永久笔记,并自动补双向链接。 ### 步骤 ``` ┌─────────────────┐ │ 1. 扫描 Inbox │ obsidian-search 列出 00-Inbox/ 所有文件 └────────┬────────┘ ↓ ┌─────────────────┐ │ 2. 逐篇读取 │ obsidian (read) 读原文 └────────┬────────┘ ↓ ┌─────────────────┐ │ 3. AI 原子化改写 │ 一个概念一篇笔记,标题 = 概念主干 └────────┬────────┘ ↓ ┌─────────────────┐ ┌ 决策点 ┐ │ 4. 用户确认 │ ───→│ 继续? │ └────────┬────────┘ └───┬────┘ ↓ ↓ ┌─────────────────┐ │ 5. 找相关永久笔记 │ obsidian-search (search + backlinks) └────────┬────────┘ ↓ ┌─────────────────┐ │ 6. 创建新笔记 │ obsidian (create) 到 50-Zettel/ │ + 补反链 │ obsidian-meta (property:set refs) └────────┬────────┘ ↓ ┌─────────────────┐ │ 7. 移除原 inbox │ obsidian (delete) 或 move 到 40-Archive └────────┬────────┘ ↓ ┌─────────────────┐ │ 8. 审计日志 │ obsidian-daily (daily:append) └─────────────────┘ ``` ### Bash 实现骨架 ```bash #!/bin/bash # workflow_inbox_to_permanent.sh set -e # 审计函数 log() { obsidian daily:append inline content=" - \`$(date +%H:%M)\` **inbox→permanent** $1" } # Step 1: 列 Inbox INBOX_FILES=$(obsidian files folder="00-Inbox" ext=md format=json) COUNT=$(echo "$INBOX_FILES" | jq 'length') log "扫描 Inbox:共 ${COUNT} 个待处理文件" # Step 2-6: 逐篇处理(由 agent 驱动) echo "$INBOX_FILES" | jq -r '.[] | .path' | while read -r path; do # Step 2: 读原文 ORIG=$(obsidian read path="$path") # Step 3: AI 原子化(由 agent 完成,此处伪代码) # - 分析 ORIG 内容,抽取 1~N 个原子概念 # - 为每个概念生成 ZID、标题、正文、建议标签 # Step 4: 展示拆解结果给用户,等待确认 echo "原文: $path" echo "拆解为:" echo " 1. 概念A - <标题>" echo " 2. 概念B - <标题>" read -p "继续? (y/N) " confirm [ "$confirm" != "y" ] && continue # Step 5: 搜索相关永久笔记 for concept in "$CONCEPTS"; do RELATED=$(obsidian search query="$concept" path="50-Zettel" limit=5 format=json) # agent 挑出 top-3 作为 refs done # Step 6: 创建永久笔记 ZID=$(date +%Y%m%d%H%M%S) TITLE="" CONTENT="--- zettel_id: ${ZID} title: ${TITLE} created: $(date +%Y-%m-%d) source: ${path} refs: [[[相关笔记1]], [[相关笔记2]]] tags: [concept, ] --- # ${TITLE} ## 相关 - [[相关笔记1]] - [[相关笔记2]] " obsidian create path="50-Zettel/${ZID} - ${TITLE}.md" content="$CONTENT" # Step 7: 清理 Inbox 原文 obsidian move path="$path" to="40-Archive/inbox-$(date +%Y-%m)/$(basename "$path")" log "处理完成:$path → 50-Zettel/${ZID}" done ``` --- ## Workflow 2 · MOC Builder(主题地图构建) **目标**:给定一个主题关键词,自动从 vault 中召回相关笔记,组织成一个 MOC(Map of Content)入口。 ### 步骤 ``` 1. 输入主题关键词(如"云原生运行时经济学") 2. 多关键词扩展 → 由 agent 生成 3-5 个相关词 3. 对每个词跑 obsidian-search(限定到 50-Zettel/) 4. 合并去重 → 候选列表 5. 按笔记的 created 日期排序 → 时间线 6. 按 tags 聚类 → 主题分组 7. AI 生成 MOC 结构: ## 核心概念 ## 实践案例 ## 相关研究 ## 时间线 8. 用户确认结构 9. 创建 60-MOC/<主题>.md 10. 为每篇被引用的笔记补反链(可选) ``` ### 关键命令链 ```bash TOPIC="云原生运行时经济学" KEYWORDS=("云原生" "运行时" "GraalVM" "虚拟线程" "冷启动") # Step 3-4: 召回 RESULTS="" for kw in "${KEYWORDS[@]}"; do RESULTS+=$(obsidian search query="$kw" path="50-Zettel" limit=20 format=json) done # Step 5-6: 由 agent 合并/排序/聚类 # Step 9: 创建 MOC obsidian create path="60-MOC/${TOPIC}.md" content="# MOC · ${TOPIC} > 本主题地图由 AI 于 $(date +%Y-%m-%d) 构建 ## 核心概念 - [[笔记1]] - [[笔记2]] ## 实践案例 - [[笔记3]] ## 相关研究 - [[笔记4]] ## 时间线 - 2024-01 [[早期笔记]] - 2025-06 [[中期笔记]] - 2026-04 [[最新笔记]] " ``` --- ## Workflow 3 · PARA 归档 **目标**:扫描 `10-Projects/`,找出 `status: done` 且超过 14 天无更新的项目,批量移到 `40-Archive/`。 ### 步骤 ```bash #!/bin/bash # workflow_para_archive.sh # 1. 找 done 状态项目 obsidian files folder="10-Projects" format=json | \ jq -r '.[] | .path' | while read -r path; do # 2. 读 status STATUS=$(obsidian property:read name=status path="$path" 2>/dev/null) UPDATED=$(obsidian property:read name=updated path="$path" 2>/dev/null) # 3. 判断是否符合归档条件 if [ "$STATUS" = "done" ]; then DAYS_AGO=$(( ($(date +%s) - $(date -d "$UPDATED" +%s)) / 86400 )) if [ "$DAYS_AGO" -gt 14 ]; then # 4. 先检查反链(确保没有活跃项目仍在引用) BACKLINKS=$(obsidian backlinks path="$path" total) if [ "$BACKLINKS" -gt 0 ]; then echo "⚠ 跳过(有 ${BACKLINKS} 个反链):$path" continue fi # 5. 用户确认(按项目 CLAUDE.md 规则) read -p "归档 $path ? (y/N) " confirm [ "$confirm" != "y" ] && continue # 6. 移到 Archive NEW_PATH="40-Archive/$(basename $(dirname $path))/$(basename $path)" obsidian move path="$path" to="$NEW_PATH" # 7. 审计 obsidian daily:append inline content=" - 📦 归档项目:$path → $NEW_PATH" fi fi done ``` --- ## Workflow 4 · Karpathy LLM-Wiki(AI 驱动主题 Wiki) **目标**:针对一个研究主题,用 LLM 自动收集 → 综合 → 结构化成一份可维护的 Wiki。 > 参考:Karpathy《LLM Knowledge Bases in Obsidian》 ### 步骤 ``` 1. 输入主题 + 10~20 个初始源(URL / PDF / 论文) 2. 对每个源: - 下载/读取内容 - AI 提炼:核心观点 + 关键事实 + 术语表 - 写入 20-Literature/.md 3. 综合阶段: - AI 读所有 Literature 笔记 - 生成 Wiki 大纲(章节结构) - 用户确认大纲 4. 写作阶段: - 按大纲逐章生成内容 - 每个事实标注来源([[20-Literature/xxx]]) - 写入 30-Resources/wiki-.md 5. 迭代: - 用户提新问题 → AI 查 Literature 补答 - 用户贡献新源 → Step 2~4 增量更新 6. 维护: - 每次更新在 frontmatter 记录 `last_updated` - 每月跑一次"过期源检测"(URL 404 / 事实过时) ``` ### SCHEMA.md 片段(告诉 agent 如何维护 Wiki) ```markdown ## Wiki 维护约定 - Wiki 文件位于 `30-Resources/wiki-.md` - 每个事实必须有 `[[20-Literature/xxx]]` 来源标注 - Frontmatter 必须包含: - `topic: <主题>` - `last_updated: <日期>` - `sources_count: <数字>` - `open_questions: ` - 更新 Wiki 时,只追加或修订,不删除旧段落(保留版本演化) ``` --- ## Workflow 5 · 周报 / 月报汇总 **目标**:自动从每日笔记、完成任务、git log、PR 列表中生成周报。 ```bash #!/bin/bash # workflow_weekly_report.sh WEEK=$(date +%Y-W%V) LAST_MONDAY=$(date -d "last monday" +%Y-%m-%d 2>/dev/null || date -v -mon +%Y-%m-%d) # 1. 收集本周每日笔记内容 DAILY_CONTENT="" for i in {0..6}; do DATE=$(date -d "${LAST_MONDAY} +${i} days" +%Y-%m-%d 2>/dev/null) CONTENT=$(obsidian read path="90-Daily/${DATE}.md" 2>/dev/null) DAILY_CONTENT+="$CONTENT\n\n" done # 2. 收集已完成任务 DONE=$(obsidian tasks done verbose format=json) # 3. 收集搜索关键词(AI 写作/代码/会议/学习) WRITING=$(obsidian search:context query="写作" limit=10 format=json) MEETINGS=$(obsidian search:context query="会议" limit=10 format=json) # 4. AI 生成周报 REPORT="# 周报 · ${WEEK} ## ✅ 本周完成 ## 📝 主要产出 ## 🧠 学习与思考 ## 📅 下周计划 " # 5. 写入 vault obsidian create path="99-Log/weekly-${WEEK}.md" content="$REPORT" open ``` --- ## Workflow 6 · 季度知识库体检 **目标**:三件套 + 元数据一致性检查 + 归档建议。 ### 检查项 ```bash # 1. 图谱健康三件套 obsidian orphans format=json > /tmp/q-orphans.json obsidian deadends format=json > /tmp/q-deadends.json obsidian unresolved verbose format=json > /tmp/q-unresolved.json # 2. 元数据一致性 obsidian files format=json | jq -r '.[] | .path' | while read -r p; do # 检查每篇是否有 created 字段 obsidian property:read name=created path="$p" 2>/dev/null || echo "MISSING_CREATED: $p" # 检查每篇是否有 tags obsidian property:read name=tags path="$p" 2>/dev/null || echo "MISSING_TAGS: $p" done > /tmp/q-metadata.txt # 3. Tag 体系审计 obsidian tags counts sort=count format=json > /tmp/q-tags.json # 由 agent 找出:低频 tag、命名不一致、未层级化 # 4. 归档建议 obsidian files folder="10-Projects" format=json | \ jq -r '.[] | .path' > /tmp/q-projects.txt # 由 agent 读每个项目的 status + updated,提 done + stale 归档建议 # 5. 生成体检报告 obsidian create path="99-Log/health-$(date +%Y-Q$((($(date +%m)-1)/3+1))).md" content="$REPORT" ``` ### 输出报告模板 ```markdown # 知识库季度体检 · 2026-Q2 ## 🧪 体检结论 - 总笔记数:X - 孤立笔记:X(占 Y%) - 断头笔记:X - 未解析链接:X - 元数据缺失:X ## 🔴 高危问题 - ... ## 🟡 优化建议 - ... ## 🟢 健康指标 - ... ## 行动项(自动生成 task) - [ ] 清理 N 篇孤立笔记 - [ ] 修复 N 个未解析链接 - [ ] 合并 N 个低频 tag ``` --- ## Workflow 7 · 文献批量导入 **目标**:从网页/PDF 批量导入到 `20-Literature/`,每篇自动生成:摘要、关键词、与现有知识库的关联。 ```bash # 依赖:Web Clipper 或 obsidian-advanced-uri 插件 # 简化流程: URLS=("https://..." "https://..." "https://...") for url in "${URLS[@]}"; do # 1. 下载原文(用 Bash curl 或 Clipper) CONTENT=$(curl -s "$url" | ) # 2. AI 提炼 SUMMARY="" KEYWORDS="" # 3. 找已有相关笔记 RELATED="" for kw in $KEYWORDS; do RELATED+=$(obsidian search query="$kw" limit=5 format=json) done # 4. 创建 Literature 笔记 TS=$(date +%Y%m%d%H%M%S) obsidian create path="20-Literature/${TS}-$(slugify).md" content="--- type: literature title: <原文标题> source: ${url} created: $(date +%Y-%m-%d) tags: [literature, ${KEYWORDS}] related: [$(agent 填充)] --- ## 摘要 ${SUMMARY} ## 关键词 ${KEYWORDS} ## 原文要点 ## 与现有知识库的关联 - [[相关笔记 1]] - [[相关笔记 2]] ## 原文链接 ${url} " done ``` --- ## Workflow 8 · Web Clip → Permanent(单篇网页剪藏) **目标**:用户给一个 URL(或一段文字),AI 抓取→清洗→提炼→落 `30-Resources/` 或 `50-Zettel/`,比 Workflow 7(批量文献)更轻量、即时。 ### 与 Workflow 7 的区别 | 维度 | Workflow 7 | Workflow 8 | |------|-----------|-----------| | 触发 | 一批 URL/PDF | 单条 URL/选文 | | 目录 | `20-Literature/` | `30-Resources/` 或 `50-Zettel/` | | 时机 | 批处理 | 即时单次 | | 决策点 | 一次全批确认 | 每次都确认 | ### 步骤 ``` ┌──────────────────┐ │ 1. 抓取网页正文 │ defuddle(社区标准)/ WebFetch / curl + readability └────────┬─────────┘ ↓ ┌──────────────────┐ │ 2. 清洗为 Markdown│ 去广告/导航/评论;保留正文 + 图链 + 代码块 └────────┬─────────┘ ↓ ┌──────────────────┐ ┌ 决策点 ┐ │ 3. 用户预览原文 │ ───→│ 落库? │ └────────┬─────────┘ └───┬────┘ ↓ ↓ ┌──────────────────┐ │ 4. AI 提炼摘要+关键词│ └────────┬─────────┘ ↓ ┌──────────────────┐ │ 5. obsidian-search│ 找已有相关笔记 │ 关联召回 │ └────────┬─────────┘ ↓ ┌──────────────────┐ │ 6. 创建笔记 │ frontmatter: source=url, type=clip │ + 双向链接 │ └────────┬─────────┘ ↓ ┌──────────────────┐ │ 7. daily:append │ 审计:URL + 落位路径 └──────────────────┘ ``` ### Bash 实现骨架 ```bash #!/bin/bash # workflow_web_clip.sh URL="$1" TARGET_DIR="${2:-30-Resources}" # 默认 30-Resources,可指定 50-Zettel # 1. 抓取 + 清洗(按可用性优先级回退) if command -v defuddle &>/dev/null; then # 社区首选:defuddle 专门为 LLM 设计,去 chrome CLEAN=$(defuddle "$URL" --markdown) elif command -v readability-cli &>/dev/null; then CLEAN=$(readability-cli "$URL" --output md) else # 兜底:让 AI agent 走 WebFetch + 手工清洗 CLEAN=$(echo "USE WebFetch tool with prompt: extract main content as clean markdown") fi # 2. AI 提炼 TITLE=$(echo "$CLEAN" | head -1 | sed 's/^#\s*//') SUMMARY="" KEYWORDS="" # 3. 关联召回 RELATED=$(obsidian search query="$KEYWORDS" limit=5 format=json | jq -r '.[].path') # 4. 落库 SLUG=$(echo "$TITLE" | tr ' ' '-' | tr -dc 'a-zA-Z0-9-_一-龥') DATE=$(date +%Y-%m-%d) PATH_NEW="${TARGET_DIR}/${DATE}-${SLUG}.md" obsidian create path="$PATH_NEW" content="--- type: clip title: ${TITLE} source: ${URL} created: ${DATE} tags: [clip] related: [${RELATED}] --- ## TL;DR ${SUMMARY} ## 关键词 ${KEYWORDS} ## 正文(清洗后) ${CLEAN} ## 与现有知识库 - 见 frontmatter related 字段 " # 5. 审计 obsidian daily:append content="\n- [web-clip] ${URL} → [[${PATH_NEW}]]" ``` ### 注意 - `defuddle` 是 Obsidian 团队官方维护的 web→markdown 清洗工具([github.com/kepano/defuddle](https://github.com/kepano/defuddle)),比 readability-cli 更专为 LLM 优化(去 token 浪费) - 没装 defuddle 时,AI agent 应主动用 **WebFetch 工具** 抓取并 prompt 模型"清洗为正文 markdown" - **去重检查**:落库前先 `obsidian search query="source: ${URL}"`,避免同一篇 clip 两次 --- ## 通用工作流约定 ### 1. 决策点 × 步骤 × 审计 每个工作流都是 `执行 → 决策点 → 审计`: - **执行**:由 agent 自动调用各 obsidian-* 技能 - **决策点**:在"写入前"、"删除前"、"移动前"三类操作必须等待用户确认(项目 CLAUDE.md 规则 4) - **审计**:每个写入操作在 `obsidian-daily`(日志)+ `99-Log/ai-actions-.md`(结构化记录) ### 2. 安全栏杆 - 批量操作前 **git checkpoint**(或 `obsidian-history` 手动快照) - 批量操作前 **`obsidian sync off`**(避免同步抖动) - Agent 一次只能动 1 个工作流;不能并发两个写入 workflow ### 3. 命名约定 - 工作流脚本:`workflow_.sh`,放在 vault 根的 `99-Log/scripts/` 或用户 `~/.claude/scripts/` - 工作流日志:`99-Log/workflow--YYYYMMDD.md` - 工作流模板:`70-Templates/workflow-.md` --- ## 与其他 obsidian-* 技能的调用关系 ```mermaid graph TD WF[obsidian-workflow-pkm] CORE[obsidian 核心] SEARCH[obsidian-search] META[obsidian-meta] TASKS[obsidian-tasks] DAILY[obsidian-daily] BASES[obsidian-bases] HIST[obsidian-history] WF --> CORE WF --> SEARCH WF --> META WF --> TASKS WF --> DAILY WF --> BASES WF --> HIST DAILY -.审计日志.-> WF HIST -.检查点.-> WF ``` --- ## 常见陷阱 | 现象 | 原因 | 对策 | |------|------|------| | 工作流中途失败导致状态不一致 | 没有事务 | 先 git checkpoint;失败后从 checkpoint 恢复 | | Agent 在决策点没等用户 | 没实现交互 | 脚本用 `read -p`,Claude Code 用 AskUserQuestion | | 批量处理把同一笔记处理两次 | 没用 idempotent 标记 | 处理完在 frontmatter 加 `processed_by: inbox_workflow` | | MOC 构建召回漏掉笔记 | 关键词单一 | 用 3~5 个扩展词 + 标签 + 出/反链三路召回 | | 周报漏数据 | daily note 没写 | 先跑 `obsidian files folder=90-Daily` 检查覆盖 | | 归档误移有反链的项目 | 没检查 backlinks | 归档前必须 `backlinks total == 0` 断言 | | Literature 导入重复 | 未去重 | 用 URL hash 做 ID,frontmatter `source_hash` | | LLM-Wiki 越改越乱 | 没版本化 | 每次大改前 git commit + `last_updated` 更新 | --- ## 参考 - **Andrej Karpathy** · LLM-Powered Knowledge Bases in Obsidian - **Addo Zhang** · Obsidian Skills for AI Agents(Medium 2026.2) - **Tiago Forte** · PARA Method - **Niklas Luhmann** · Zettelkasten - **Nick Milo** · Linking Your Thinking (LYT) + Maps of Content - **dsebastien** · 16 Practical AI Use Cases with Obsidian