知识图谱分析Skill graph

这是一个交互式知识图谱分析工具,能够通过自然语言处理用户的问题,将其映射到相应的图谱操作,并提供具体的分析结果和行动建议。关键词包括:知识图谱、自然语言处理、图谱操作、连接分析、结构化知识。

NLP 0 次安装 0 次浏览 更新于 2/27/2026

运行时配置(第0步 — 在任何处理之前)

读取这些文件以配置特定领域的操作:

  1. ops/derivation-manifest.md — 词汇映射,平台提示

    • 使用 vocabulary.notes 作为笔记文件夹名称
    • 使用 vocabulary.note / vocabulary.note_plural 作为笔记类型引用
    • 使用 vocabulary.topic_map / vocabulary.topic_map_plural 作为MOC引用
    • 使用 vocabulary.cmd_reflect 作为连接查找命令名称
    • 使用 vocabulary.cmd_reweave 作为向后传递命令名称
  2. ops/config.yaml — 用于图阈值(MOC大小限制,孤儿阈值)

如果没有派生文件存在,则使用通用术语(笔记,MOCs等)。


立即执行

目标:$ARGUMENTS

从参数中解析操作:

  • 如果参数匹配已知操作:路由到该操作
  • 如果参数是自然语言问题:映射到最近的操作(见交互模式)
  • 如果没有参数:进入交互模式

现在开始。 路由到适当的操作。


哲学

图就是知识。这项技能使其可见。

个别{vocabulary.note_plural}有价值,但它们的连接创造了复合价值。/graph揭示了这些连接的结构属性 —— 图在哪里密集,哪里稀疏,哪里脆弱,以及合成机会隐藏在哪里。

每次操作产生两样东西:发现(分析揭示的内容)和行动(关于它的具体下一步)。永远不要转储原始数据。总是用{vocabulary.note}描述和领域上下文解释结果。总是建议具体的下一步。


操作

/graph health

完整的图健康报告:密度,孤儿,悬挂链接,覆盖率。

第1步:收集原始指标

# 计算总笔记数(不包括MOCs)
NOTES_DIR="{vocabulary.notes}"
TOTAL=$(ls -1 "$NOTES_DIR"/*.md 2>/dev/null | wc -l | tr -d ' ')
MOC_COUNT=$(grep -rl '^type: moc' "$NOTES_DIR"/*.md 2>/dev/null | wc -l | tr -d ' ')
NOTE_COUNT=$((TOTAL - MOC_COUNT))

# 计算所有wiki链接
LINK_COUNT=$(grep -ohP '\[\[[^\]]+\]\]' "$NOTES_DIR"/*.md 2>/dev/null | wc -l | tr -d ' ')

# 计算链接密度
# 密度 = 实际链接 / 可能链接
# 可能链接 = N * (N - 1) 针对有向图
echo "Density: $LINK_COUNT / ($NOTE_COUNT * ($NOTE_COUNT - 1))"

# 查找孤儿笔记(零入站链接)
for f in "$NOTES_DIR"/*.md; do
  NAME=$(basename "$f" .md)
  INCOMING=$(grep -rl "\[\[$NAME\]\]" "$NOTES_DIR"/ 2>/dev/null | grep -v "$f" | wc -l | tr -d ' ')
  [[ "$INCOMING" -eq 0 ]] && echo "ORPHAN: $NAME"
done

# 查找悬挂链接(链接到不存在的文件)
grep -ohP '\[\[([^\]]+)\]\]' "$NOTES_DIR"/*.md 2>/dev/null | sort -u | while read -r link; do
  NAME=$(echo "$link" | sed 's/\[\[//;s/\]\]//')
  [[ ! -f "$NOTES_DIR/$NAME.md" ]] && echo "DANGLING: $NAME"
done

# MOC覆盖率:至少出现在一个MOC的核心思想中的笔记的百分比
COVERED=0
for f in "$NOTES_DIR"/*.md; do
  NAME=$(basename "$f" .md)
  # 跳过MOCs本身
  grep -q '^type: moc' "$f" 2>/dev/null && continue
  # 检查是否有任何MOC链接到这个笔记
  if grep -rl '^type: moc' "$NOTES_DIR"/*.md 2>/dev/null | xargs grep -l "\[\[$NAME\]\]" >/dev/null 2>&1; then
    COVERED=$((COVERED + 1))
  fi
done
echo "Coverage: $COVERED / $NOTE_COUNT"

如果ops/scripts/graph/中存在图助手脚本,则使用它们代替内联分析:

  • ops/scripts/graph/link-density.sh用于密度指标
  • ops/scripts/graph/orphan-notes.sh用于孤儿检测
  • ops/scripts/graph/dangling-links.sh用于悬挂链接检测

第2步:解释并呈现

--=={ 图健康 }==--

  {vocabulary.note_plural}: [N](加上[M] {vocabulary.topic_map_plural})
  连接:[N](平均每{vocabulary.note} [X]个)
  图密度:[0.XX]
  {vocabulary.topic_map}覆盖率:[N]%的{vocabulary.note_plural}出现在至少一个{vocabulary.topic_map}中

  孤儿([N]):
    - [[orphan name]] — [description from YAML]
    → 建议:运行 /{vocabulary.cmd_reflect}以找到连接

  悬挂链接([N]):
    - [[missing name]] — 引用自[[source note]]
    → 建议:创建{vocabulary.note}或移除链接

  {vocabulary.topic_map}大小:
    - [[moc name]]: [N] {vocabulary.note_plural} [OK | WARN: 接近分裂阈值 | WARN: 考虑合并]

  总体:[HEALTHY | NEEDS ATTENTION | FRAGMENTED]

密度基准:

密度 解释
< 0.02 稀疏 — 存在{vocabulary.note_plural}但连接很少
0.02-0.06 健康 — 增长中的网络,有意义的连接
0.06-0.15 密集 — 连接良好,注意过度链接
> 0.15 非常密集 — 验证连接是否真实,不是噪音

/graph triangles

寻找合成机会 —— A链接到B且A链接到C,但B不链接到C的开放三元闭合。

第1步:构建邻接数据

# 对于每个笔记,提取出站wiki链接
for f in "$NOTES_DIR"/*.md; do
  NAME=$(basename "$f" .md)
  LINKS=$(grep -oP '\[\[([^\]]+)\]\]' "$f" 2>/dev/null | sed 's/\[\[//;s/\]\]//' | sort -u)
  echo "FROM:$NAME"
  echo "$LINKS" | while read -r target; do
    [[ -n "$target" ]] && echo "  TO:$target"
  done
done

如果ops/scripts/graph/find-triangles.sh存在,直接使用它。

第2步:寻找开放三角形

对于每个笔记A有出站链接到B和C:

  1. 检查B是否链接到C(任一方向)
  2. 检查C是否链接到B(任一方向)
  3. 如果两个链接都不存在:这是一个开放三角形(合成机会)

第3步:评估和排名

对于每个开放三角形:

  1. 阅读BOTH未链接{vocabulary.note_plural}的描述
  2. 评估:是否有共同父项建议的真实概念关系?
  3. 按潜在价值排名:B和C通过A的视角连接会有多么令人惊讶和有用?

第4步:呈现顶级发现

--=={ 图形三角形 }==--

  发现[N]合成机会 —— 共享
  一个共同引用但彼此不引用的{vocabulary.note_plural}对:

  1. [[note B]] 和 [[note C]]
    共同父项:[[note A]]
    B: "[description]"
    C: "[description]"
    → 这些可能因为[关于为什么B和C可能通过A的视角相关联的具体推理
       而受益于连接]
    → 行动:在[[note B]]上运行 /{vocabulary.cmd_reflect}以评估

  2. [[note D]] 和 [[note E]]
    共同父项:[[note F]]
    ...

  [如果存在更多:"[N]更多三角形被发现。显示全部?(是/否)"]

过滤掉微不足道的三角形: 跳过对:

  • 两者都在同一{vocabulary.topic_map}中(它们可能已经通过MOC相互关联,无需直接链接)
  • 一个是{vocabulary.topic_map}本身(MOCs链接到一切,与MOCs的三角形是噪音)
  • 描述表明没有概念上的重叠

/graph bridges

识别结构上关键的{vocabulary.note_plural},其移除会断开图区域。

第1步:构建邻接列表

从{vocabulary.notes}/中的所有wiki链接构建双向邻接列表。

如果ops/scripts/graph/find-bridges.sh存在,直接使用它。

第2步:寻找桥节点

桥笔记是:

  • 移除它(及其链接)会将一个连通分量分成两个或更多分量
  • 它是{vocabulary.note_plural}群集之间唯一的连接

实现:对于每个笔记,暂时移除它并检查剩余的图是否有更多连通分量。

第3步:呈现发现

--=={ 图形桥 }==--

  发现[N]桥{vocabulary.note_plural} —— 结构上关键的节点,其
  移除会断开图区域:

  1. [[bridge note]] — 连接[N] {vocabulary.note_plural}在一边到[M]在另一边
     描述:"[description]"
     群集A:[[note1]], [[note2]], ...
     群集B:[[note3]], [[note4]], ...
     → 风险:如果这个{vocabulary.note}变得陈旧,[N+M] {vocabulary.note_plural}
       失去它们的连接路径
     → 行动:考虑在群集之间添加并行连接

  [如果没有桥:"没有发现桥笔记。该图在所有连通区域之间有冗余路径。这是健康的。"]

/graph clusters

发现连通分量和主题边界。

第1步:构建邻接列表

从所有wiki链接构建双向邻接列表。

如果ops/scripts/graph/find-clusters.sh存在,直接使用它。

第2步:寻找连通分量

使用BFS/DFS找到所有连通分量:

  1. 从任何未访问的笔记开始
  2. 通过wiki链接(双向)遍历所有可达笔记
  3. 标记为一个分量
  4. 重复直到所有笔记访问完毕

第3步:分析群集

对于每个群集:

  • 大小({vocabulary.note_plural}的数量)
  • 键{vocabulary.note_plural}(群集中链接计数最高的)
  • 主题覆盖(哪些{vocabulary.topic_map_plural}被代表)
  • 隔离级别(有多少链接跨越群集边界)

第4步:呈现发现

--=={ 图形群集 }==--

  发现[N]连通分量:

  群集1:[size] {vocabulary.note_plural}
    关键节点:[[note1]] (8链接), [[note2]] (6链接)
    主题:[[topic A]], [[topic B]]
    跨群集链接:[N]
    → 这个群集是[连接良好 | 孤立 | 一个枢纽]

  群集2:[size] {vocabulary.note_plural}
    ...

  孤立{vocabulary.note_plural} ([N]):
    - [[isolated note]] — [description]
    → 行动:运行 /{vocabulary.cmd_reflect}以找到连接

  [如果1群集:"所有{vocabulary.note_plural}都在一个连通分量中。
  该图完全连接。这是健康的。"]

/graph hubs

按影响力排名{vocabulary.note_plural} —— 最多链接到(权威)和最多链接来自(枢纽)。

第1步:计算链接

# 权威得分:每个笔记的入站链接
for f in "$NOTES_DIR"/*.md; do
  NAME=$(basename "$f" .md)
  INCOMING=$(grep -rl "\[\[$NAME\]\]" "$NOTES_DIR"/ 2>/dev/null | grep -v "$f" | wc -l | tr -d ' ')
  echo "AUTH:$INCOMING:$NAME"
done | sort -t: -k2 -rn | head -10

# 枢纽得分:每个笔记的出站链接
for f in "$NOTES_DIR"/*.md; do
  NAME=$(basename "$f" .md)
  OUTGOING=$(grep -oP '\[\[[^\]]+\]\]' "$f" 2>/dev/null | wc -l | tr -d ' ')
  echo "HUB:$OUTGOING:$NAME"
done | sort -t: -k2 -rn | head -10

如果ops/scripts/graph/influence-flow.sh存在,直接使用它。

第2步:识别合成器

合成器{vocabulary.note_plural}在两个指标上都得分高 —— 它们吸收许多输入(高权威)并产生许多输出(高枢纽)。这些是图中结构上最重要的{vocabulary.note_plural}。

第3步:呈现发现

--=={ 图形枢纽 }==--

  顶级权威(最多链接到):
    1. [[note]] — [N]入站链接 — "[description]"
    2. [[note]] — [N]入站链接 — "[description]"
    ...

  顶级枢纽(最多链接来自):
    1. [[note]] — [N]出站链接 — "[description]"
    2. [[note]] — [N]出站链接 — "[description]"
    ...

  合成器(两个都高 — 结构上重要):
    1. [[note]] — [N]入 / [M]出 — "[description]"
    ...

  [如果没有明确的合成器:"没有笔记在两个指标上都得分高。
  这表明该图具有独立的输入和输出层。"]

/graph siblings [[topic]]

在主题内找到未连接的{vocabulary.note_plural} —— 共享相同{vocabulary.topic_map}但不相互链接的{vocabulary.note_plural}。

第1步:读取指定的{vocabulary.topic_map}

找到并读取与参数匹配的{vocabulary.topic_map}。提取核心思想中链接的所有{vocabulary.note_plural}。

第2步:检查成对连接

对于{vocabulary.topic_map}中的每对{vocabulary.note_plural}:

  1. A链接到B吗?(在A的文件中grep [[B]]
  2. B链接到A吗?(在B的文件中grep [[A]]
  3. 如果两者都不是:这是一对未连接的兄弟

如果ops/scripts/graph/topic-siblings.sh存在,使用主题参数。

第3步:评估对

对于每对未连接的对:

  • 阅读两个描述
  • 评估是否应该存在连接
  • 评为:可能的连接,可能的连接,适当分开

第4步:呈现发现

--=={ 图形兄弟姐妹:[[topic]] }==--

  {vocabulary.topic_map} [[topic]]有[N] {vocabulary.note_plural}。
  发现[M]未连接的兄弟姐妹对:

  可能的连接:
    1. [[note A]] 和 [[note B]]
       A: "[description]"
       B: "[description]"
       → [为什么这些可能相关]

  可能的连接:
    2. [[note C]] 和 [[note D]]
       ...

  适当分开:[N]对 —— 不需要连接

  → 行动:在"可能的"对上运行 /{vocabulary.cmd_reflect}

/graph forward [[note]] [depth]

从{vocabulary.note}开始的N跳前向遍历。默认深度:2。

第1步:从指定的{vocabulary.note}开始

读取{vocabulary.note}并提取所有出站wiki链接(第1跳)。

如果ops/scripts/graph/n-hop-forward.sh存在,使用它与笔记和深度参数。

第2步:遍历

对于每个链接的{vocabulary.note}:

  1. 阅读它并提取其出站wiki链接(第2跳)
  2. 继续到指定深度
  3. 跟踪访问过的笔记以避免循环

第3步:作为注释树呈现

--=={ 前向遍历:[[note]](深度[N]) }==--

  [[root note]] — "[description]"
    ├── [[link 1]] — "[description]"
    │   ├── [[link 1a]] — "[description]"
    │   └── [[link 1b]] — "[description]"
    ├── [[link 2]] — "[description]"
    │   └── [[link 2a]] — "[description]"
    └── [[link 3]] — "[description]"

  在[depth]跳中到达[N] {vocabulary.note_plural}。
  死胡同(没有出站链接):[[note X]], [[note Y]]
  检测到循环:[[note]] → ... → [[note]](跳过)

/graph backward [[note]] [depth]

到{vocabulary.note}的N跳后向遍历。默认深度:2。

第1步:从指定的{vocabulary.note}开始

找到所有链接到这个{vocabulary.note}的笔记(第1跳)。

NAME="[note name]"
grep -rl "\[\[$NAME\]\]" "$NOTES_DIR"/*.md 2>/dev/null

如果ops/scripts/graph/recursive-backlinks.sh存在,使用它与笔记和深度参数。

第2步:向后遍历

对于每个链接的{vocabulary.note}:

  1. 找到什么链接到它(第2跳)
  2. 继续到指定深度
  3. 跟踪访问过的笔记以避免循环

第3步:作为注释树呈现

--=={ 后向遍历:[[note]](深度[N]) }==--

  [[root note]] — "[description]"
    ├── [[referrer 1]] — "[description]"
    │   ├── [[referrer 1a]] — "[description]"
    │   └── [[referrer 1b]] — "[description]"
    ├── [[referrer 2]] — "[description]"
    │   └── [[referrer 2a]] — "[description]"
    └── [[referrer 3]] — "[description]"

  [N] {vocabulary.note_plural}在[depth]跳内导致[[root note]]。
  入口点(没有入站链接):[[note X]], [[note Y]]

/graph query [field] [value]

跨{vocabulary.note_plural}的模式级YAML查询。

第1步:解析字段和值

支持的查询模式:

查询 Ripgrep模式 目的
topics [[X]] rg '^topics:.*\[\[X\]\]' 查找主题中的笔记
type tension rg '^type: tension' 按类型查找笔记
methodology X rg '^methodology:.*X' 按传统查找笔记
status open rg '^status: open' 按状态查找笔记
created 2026-02 rg '^created: 2026-02' 按日期范围查找笔记
source [[X]] rg '^source:.*\[\[X\]\]' 从来源查找笔记

第2步:执行查询

rg "^{field}:.*{value}" "$NOTES_DIR"/*.md -l 2>/dev/null

对于每个匹配的文件,提取描述以供上下文。

第3步:呈现结果

--=={ 图形查询:{field} = {value} }==--

  发现[N] {vocabulary.note_plural}:

  1. [[note name]] — "[description]"
  2. [[note name]] — "[description]"
  ...

  分布:
    [如果查询主题:每个子主题有多少]
    [如果查询类型:按状态分解]
    [如果查询方法论:按传统分解]

交互模式

如果没有提供参数:

  1. 询问:“您想了解您的知识图谱的哪些方面?”
  2. 将自然语言映射到操作:
用户说 映射到 为什么
“我应该在哪里寻找连接?” triangles 寻找合成机会
“我最重要的笔记是什么?” hubs 权威/枢纽排名
“有孤立的区域吗?” clusters 连通分量检测
“我的图有多健康?” health 完整的健康报告
“什么连接了我的主题?” bridges 桥笔记识别
“什么连接到[[X]]?” backward [[X]] 后向遍历
“[[X]]会导致什么?” forward [[X]] 前向遍历
“向我展示关于[主题]的笔记” query topics [[topic]] 模式查询
“在[主题]中需要连接什么?” siblings [[topic]] 未连接的兄弟姐妹对
  1. 运行映射的操作
  2. 呈现结果后,提供后续:“想进一步探索这些吗?”

输出规则

  • 永远不要转储原始数据。 总是用{vocabulary.note}描述和上下文解释结果。
  • 总是建议行动。 "在这些对上运行 /{vocabulary.cmd_reflect}“或"考虑添加关于X的桥{vocabulary.note}”。
  • 使用领域词汇 对所有标签和描述 —— {vocabulary.note},{vocabulary.topic_map}等。
  • 对于大型结果集, 总结顶级发现(最多10个)并提供显示更多:“[N]更多结果。显示全部?(是/否)”
  • 包括密度基准 为上下文 —— “你的密度0.04处于健康范围。”
  • 区分结构和语义。 图形分析揭示结构属性。关于连接是否应该存在的语义判断需要 /{vocabulary.cmd_reflect}。

边缘情况

小型Vault(<10笔记)

报告指标但提供上下文:“有[N] {vocabulary.note_plural},图形分析提供有限的洞察。随着知识图谱的增长,图形操作变得更有价值。当前指标是基线测量。”

所有操作仍然运行 —— 它们只是产生较少的数据。

图脚本不可用

如果ops/scripts/graph/不存在或缺少个别脚本,使用grep,文件读取和bash循环内联实现分析,如每个操作的步骤所示。内联实现是完整的 —— 脚本是优化,不是必需的。

没有ops/derivation-manifest.md

使用通用词汇(笔记,MOCs等)。所有操作都相同。

笔记目录为空

报告:“在{vocabulary.notes}/中未发现{vocabulary.note_plural}。开始捕获内容以构建您的知识图谱。”

笔记未找到(对于forward/backward/siblings)

如果指定的{vocabulary.note}或{vocabulary.topic_map}不存在:

  1. 搜索部分匹配:ls "$NOTES_DIR"/*{query}*.md 2>/dev/null
  2. 如果找到匹配:“您是说:[[match1]],[[match2]]?”
  3. 如果没有匹配:“{vocabulary.note} '[[name]]'未找到。检查名称然后重试。”