对标社区基准(kepano/obsidian-skills 31.8k★、AgriciDaniel/claude-obsidian
15 技能完整体系)后的 P1-P6 优化合集:
- P1: 8 个子技能 description 末尾去"伴随激活"冗余句(路由不识别该声明)
- P5: obsidian-plugins 描述聚焦环境层(插件/主题/CSS/Templates/快捷键/命令)
- P6: obsidian-workflow-pkm 描述加"多步骤复合需求优先匹配"前置引导
- P3: 核心 obsidian skill 增补 OFM 语法速查章节
(wikilinks/embeds/callouts/block refs/highlight/math 全表)
- P4: workflow-pkm 新增 Workflow 8 Web Clip → Permanent
(引用 defuddle 社区标准,WebFetch 兜底)
186 lines
6.8 KiB
Markdown
186 lines
6.8 KiB
Markdown
---
|
||
name: obsidian-search
|
||
description: Obsidian vault 全文搜索与链接图谱分析。触发场景:搜索笔记内容、查反链/出链、体检图谱健康度(孤立笔记 orphans、断头笔记 deadends、未解析链接 unresolved)、AI 回答前做语义召回(RAG)。触发词:搜索笔记、找笔记、反链、出链、孤立笔记、图谱体检、知识库体检。不用于 tag 查询(obsidian-meta)或 Bases 结构化查询(obsidian-bases)。
|
||
---
|
||
|
||
# Obsidian Search · 搜索与图谱分析
|
||
|
||
> 官方 `obsidian` CLI 的搜索与链接分析子集。让 AI agent 能像读取一个知识图谱数据库一样理解你的 vault。
|
||
|
||
---
|
||
|
||
## 何时使用
|
||
|
||
- 全文搜索笔记内容(关键词、正则、限定文件夹)
|
||
- 找到一篇笔记的**反链**(谁引用了我)或**出链**(我引用了谁)
|
||
- **图谱健康度体检**:找出孤立笔记、没有出链的断头、未解析的坏链
|
||
- 在 AI agent 做问答/总结前,**先做语义召回**,把最相关的几篇文章喂给模型
|
||
|
||
## 不用于
|
||
|
||
- 查找含某 **tag** 的笔记 → **obsidian-meta** (`tags`, `tag name=<tag> verbose`)
|
||
- 查询 frontmatter **property** → **obsidian-meta** (`properties`, `property:read`)
|
||
- 按 Bases 视图结构化查询 → **obsidian-bases**
|
||
|
||
---
|
||
|
||
## 命令速查
|
||
|
||
### 全文搜索
|
||
|
||
```bash
|
||
obsidian search query="云原生" # 基础全文搜索
|
||
obsidian search query="云原生" path="10-Projects" # 限定文件夹
|
||
obsidian search query="云原生" limit=20 # 限制结果数
|
||
obsidian search query="云原生" case # 区分大小写
|
||
obsidian search query="云原生" total # 只返回匹配计数
|
||
obsidian search query="云原生" format=json # JSON 输出(agent 友好)
|
||
|
||
obsidian search:context query="云原生" # 搜索 + 显示匹配行上下文
|
||
obsidian search:context query="云原生" format=json
|
||
|
||
obsidian search:open query="云原生" # 在 Obsidian 中打开搜索面板
|
||
```
|
||
|
||
### 出链 / 反链
|
||
|
||
```bash
|
||
obsidian links file="云原生运行时经济学" # 当前笔记出链
|
||
obsidian links file=<name> total # 只返回出链数
|
||
|
||
obsidian backlinks file=<name> # 反链(tsv 默认)
|
||
obsidian backlinks file=<name> counts # 含每个反链的引用次数
|
||
obsidian backlinks file=<name> format=json # JSON 输出
|
||
obsidian backlinks file=<name> total # 反链总数
|
||
```
|
||
|
||
### 图谱健康度(三件套)
|
||
|
||
```bash
|
||
obsidian orphans # 孤立笔记(没有任何反链 = 没人引用我)
|
||
obsidian orphans total # 仅返回数量
|
||
obsidian orphans all # 含非 markdown 文件
|
||
|
||
obsidian deadends # 断头笔记(没有任何出链 = 我没引用任何人)
|
||
obsidian deadends total
|
||
|
||
obsidian unresolved # 未解析链接(链接指向不存在的笔记)
|
||
obsidian unresolved counts # 含每个坏链的引用次数
|
||
obsidian unresolved verbose # 含源文件
|
||
obsidian unresolved format=json
|
||
```
|
||
|
||
---
|
||
|
||
## AI Agent 最佳实践
|
||
|
||
### 场景 1 · 做问答前的语义召回
|
||
|
||
AI agent 回答用户问题时,不要只凭记忆编造,而要先做召回:
|
||
|
||
```bash
|
||
# Step 1: 全文搜索,拿到 top-20 候选
|
||
obsidian search:context query="<用户问题关键词>" limit=20 format=json
|
||
|
||
# Step 2: 根据匹配摘要挑 3~5 篇最相关的,逐篇 read
|
||
obsidian read file="<候选 1>"
|
||
obsidian read file="<候选 2>"
|
||
|
||
# Step 3: 基于检索到的内容回答,并标注来源
|
||
```
|
||
|
||
这是 **RAG(Retrieval-Augmented Generation)的 CLI 实现**,无需向量数据库。
|
||
|
||
### 场景 2 · 知识库季度体检
|
||
|
||
每季度跑一次"三件套"健康检查,清理知识库:
|
||
|
||
```bash
|
||
# 孤立笔记(可能是废稿,或需要补反链)
|
||
obsidian orphans format=json > /tmp/orphans.json
|
||
|
||
# 断头笔记(需要补充关联阅读)
|
||
obsidian deadends > /tmp/deadends.txt
|
||
|
||
# 未解析链接(笔记被删除或重命名导致的坏链)
|
||
obsidian unresolved verbose format=json > /tmp/unresolved.json
|
||
```
|
||
|
||
**处理建议**(交给 AI agent 分类):
|
||
|
||
| 类型 | 判定 | 处理 |
|
||
|------|------|------|
|
||
| 孤立笔记 | 正文 > 200 字 | 读内容,找相关主题补反链 |
|
||
| 孤立笔记 | 正文 ≤ 200 字 | 可能是废稿,移到 `00-Inbox/` 待清理 |
|
||
| 断头笔记 | 永久笔记(`50-Zettel/`) | 违反 Zettelkasten 原则,**必须补出链** |
|
||
| 断头笔记 | 日常笔记 | 一般可接受 |
|
||
| 未解析链接 | 指向已删除笔记 | 删除或修复链接 |
|
||
| 未解析链接 | 指向未来笔记(占位) | 保留,或创建占位笔记 |
|
||
|
||
### 场景 3 · 重命名前的安全检查
|
||
|
||
```bash
|
||
# 准备把 "旧标题" 改名为 "新标题"
|
||
obsidian backlinks file="旧标题" format=json # 先看谁引用我
|
||
|
||
# 如果反链数 > 0,且文件是 markdown 链接而非 wikilink,需要手动修复
|
||
# wikilink [[旧标题]] 会被 obsidian move 自动更新
|
||
# markdown [链接](旧标题.md) 需要手动替换
|
||
|
||
obsidian move path="50-Zettel/旧标题.md" to="50-Zettel/新标题.md"
|
||
```
|
||
|
||
### 场景 4 · 为新笔记找"相关阅读"
|
||
|
||
```bash
|
||
# 写完一篇新笔记后,自动找出 vault 中相关的旧笔记
|
||
TITLE="云原生运行时经济学"
|
||
KEYWORDS=("云原生" "运行时" "成本" "密度")
|
||
|
||
for kw in "${KEYWORDS[@]}"; do
|
||
obsidian search query="$kw" limit=5 format=json
|
||
done
|
||
# 由 agent 合并去重,挑出 top-3 ~ 5 篇,在新笔记末尾插入 "## 相关阅读" 区块
|
||
```
|
||
|
||
---
|
||
|
||
## Agent 写入模式:把搜索结果转成笔记
|
||
|
||
```bash
|
||
# 搜索 + 写入结果到一篇"检索报告"
|
||
QUERY="虚拟线程"
|
||
obsidian create path="99-Log/search-${QUERY}-$(date +%Y%m%d).md" content="# 检索报告: ${QUERY}
|
||
|
||
生成时间: $(date '+%Y-%m-%d %H:%M')
|
||
|
||
## 全文匹配
|
||
$(obsidian search:context query=\"${QUERY}\" limit=20)
|
||
|
||
## 反链分析
|
||
(针对 top-3 笔记的反链分析)
|
||
"
|
||
```
|
||
|
||
---
|
||
|
||
## 与其他技能的协作
|
||
|
||
| 前置 → 当前 → 后继 | 典型链路 |
|
||
|------------------|---------|
|
||
| **obsidian** → obsidian-search → **obsidian-meta** | 先发现 vault,再搜索定位,再读 frontmatter |
|
||
| **obsidian-search** → **obsidian-meta** | 搜索后用 tags 做二次筛选 |
|
||
| **obsidian-search** → **obsidian-workflow-pkm** | 搜索结果作为 Zettelkasten 补链、MOC 构建的输入 |
|
||
| **obsidian-search** → **obsidian** (`read`) | 搜索召回 → 逐篇精读 |
|
||
|
||
---
|
||
|
||
## 常见陷阱
|
||
|
||
| 现象 | 原因 | 对策 |
|
||
|------|------|------|
|
||
| `search` 结果太多 | 未加 `limit` | `limit=20 path=<folder>` 双重限定 |
|
||
| `backlinks` 为空但确实有引用 | 用的是 markdown 链接而非 wikilink | `search query="[文件名]"` 兜底 |
|
||
| `orphans` 把每日笔记也列进来 | daily note 一般无人引用 | 在 agent 逻辑里过滤 `90-Daily/` 路径 |
|
||
| `unresolved` 出现"未来占位" | 预先写了 `[[未创建的笔记]]` | 占位是 Zettelkasten 合法模式,不要自动删 |
|