Llm-wiki-skill llm-wiki
git clone https://github.com/sdyckjq-lab/llm-wiki-skill
git clone --depth=1 https://github.com/sdyckjq-lab/llm-wiki-skill ~/.claude/skills/sdyckjq-lab-llm-wiki-skill-llm-wiki
SKILL.mdllm-wiki — 个人知识库构建系统
把碎片化的信息变成持续积累、互相链接的知识库。你只需要提供素材,AI 做所有的整理工作。
这个 skill 做什么
llm-wiki 帮你构建一个持续增长的个人知识库。它不是传统的笔记软件,而是一个让 AI 帮你维护的 wiki 系统:
- 你给素材(链接、文件、文本),AI 提取核心知识并整理成互相链接的 wiki 页面
- 知识库随着每次使用变得越来越丰富,而不是每次重新开始
- 所有内容都是本地 markdown 文件,用 Obsidian 或任何编辑器都能查看
核心理念
传统方式(RAG/聊天记录)的问题:每次问问题,AI 都要从头阅读原始文件,没有积累。知识库的价值在于知识被编译一次,然后持续维护,而不是每次重新推导。
快速开始
告诉用户这两步就够了:
- 初始化:说"帮我初始化一个知识库"
- 添加素材:给一个链接或文件,说"帮我消化这篇"
Script Directory
Scripts located in
scripts/ subdirectory.
Path Resolution:
= this SKILL.md's directorySKILL_DIR- Script path =
${SKILL_DIR}/scripts/<script-name>
依赖检查
核心主线(本地文件、纯文本、已有知识库操作)默认不需要这些提取依赖。
只有当用户给的是 URL 类来源,并且明确要自动提取网页 / X / 微信公众号 / YouTube / 知乎内容时,才检查以下可选依赖。
如果缺失,提示用户运行:
bash ${SKILL_DIR}/install.sh --platform <当前平台> --with-optional-adapters
可选依赖 skill / 工具:
— 普通网页、X/Twitter、部分知乎提取baoyu-url-to-markdown
— 微信公众号提取wechat-article-to-markdown
— YouTube 字幕提取youtube-transcript
即使这些依赖缺失,skill 仍可工作(用户可以直接提供本地文件、粘贴文本,或改走手动入口)。
外挂状态模型
外挂失败统一分成
not_installed / env_unavailable / runtime_failed / unsupported / empty_result 五类。
所有需要枚举来源、读取
source_label、raw_dir、adapter_name、fallback_hint 的地方,都先读来源总表:
bash ${SKILL_DIR}/scripts/source-registry.sh list
需要拿单个来源的定义时,用:
bash ${SKILL_DIR}/scripts/source-registry.sh get <source_id>
对 URL 类来源,先运行:
bash ${SKILL_DIR}/scripts/adapter-state.sh check <source_id>
adapter-state.sh check 返回 8 列:
source_id source_label state state_label detail recovery_action install_hint fallback_hint
:提示用户可补安装,同时允许改走手动入口not_installed
:说明缺少的环境条件,同时允许改走手动入口env_unavailable
:说明本次提取执行失败,允许重试一次,再改走手动入口runtime_failed
:直接给出手动入口,不尝试自动提取unsupported
:说明自动提取没拿到有效内容,请用户手动补全文本empty_result
当自动提取实际执行后,再运行:
bash ${SKILL_DIR}/scripts/adapter-state.sh classify-run <source_id> <exit_code> <output_path>
用返回的
detail、recovery_action、install_hint、fallback_hint 生成提示。核心主线不因外挂失败而中断。
工作流路由
根据用户的意图,路由到对应的工作流:
| 用户意图关键词 | 工作流 |
|---|---|
| "初始化知识库"、"新建 wiki"、"创建知识库" | → init |
| URL / 文件路径 / "添加素材"、"消化"、"整理" / 直接给链接 | → ingest |
| "批量消化"、"把这些都整理" / 给了文件夹路径 | → batch-ingest |
| "关于 XX"、"查询"、"XX 是什么"、"总结一下" | → query |
| "给我讲讲 XX"、"深度分析 XX"、"综述 XX"、"digest XX" | → digest |
| "对比一下 X 和 Y"、"比较 X 和 Y"、"整理一下时间线"、"按时间排列" | → digest(指定格式) |
| "检查知识库"、"健康检查"、"lint" | → lint |
| "知识库状态"、"现在有什么"、"有多少素材" | → status |
| "画个知识图谱"、"看看关联图"、"graph"、"知识库地图" | → graph |
| "删除素材"、"remove"、"delete source"、"移除" | → delete |
| "结晶化"、"crystallize"、"把这个记进知识库"、"总结这段对话" | → crystallize |
重要:如果用户直接给了一个 URL 或文件,但没有明确说要做什么,默认走 ingest 工作流。如果知识库还不存在,先自动走 init 再走 ingest。
通用前置检查
除
init 外,其他工作流默认先执行这段检查:
- 先检查当前工作目录是否包含
.wiki-schema.md- 如果包含 → 用当前目录作为知识库根路径
- 如果不包含 → 回退到读取
~/.llm-wiki-path
- 如果两者都没有:
/ingest
→ 先运行batch-ingestinit
/query
/lint
/status
/digest
/graph
→ 提示用户先初始化知识库delete
- 读取知识库根目录下的
.wiki-schema.md - 从
的"语言"字段判断.wiki-schema.mdWIKI_LANG
→语言:中文WIKI_LANG=zh
→语言:EnglishWIKI_LANG=en- 字段缺失 → 默认
WIKI_LANG=zh
输出语言规则
所有面向用户的输出和新写入的 wiki 内容,都按
WIKI_LANG 生成:
→ 使用下文中文示例WIKI_LANG=zh
→ 保持与中文示例相同的结构、信息量和顺序,仅改为自然英文措辞WIKI_LANG=en- 文件路径、wiki 链接、目录名保持现有约定,不因为语言切换而改动
术语对照:
- 素材 → Source
- 实体 → Entity
- 主题 → Topic
- 摘要 → Summary
- 综合 → Synthesis
- 消化 → Ingest
- 对比 → Comparison
- 深度报告 → Deep Dive Report
- 知识图谱 → Knowledge Graph
工作流 1:init(初始化知识库)
前置检查(含多知识库 CWD 检查)
- 先检查当前工作目录是否包含
.wiki-schema.md- 如果包含 → 当前目录已经是一个知识库,提示用户已存在并询问是否要重新初始化
- 如果当前目录没有 → 读取
文件~/.llm-wiki-path- 如果存在 → 提示用户已有一个知识库(显示路径),询问是要新建还是切换到那个
- 两个都没有 → 进入初始化流程
步骤
-
询问知识库主题(先向用户提问):
- "你的知识库要围绕什么主题?比如'AI 学习笔记'、'产品竞品分析'、'读书笔记'"
- 如果用户没想法,默认用"我的知识库"
-
询问知识库语言(先向用户提问):
- "知识库内容用什么语言?中文 / English(默认中文)"
- 选项:
(中文)或zh
(English)en - 如果用户没有明确说,默认
zh - 将选择记录为
(WIKI_LANG
或zh
)en
-
询问保存位置(先向用户提问):
- 默认:
(zh)或~/Documents/我的知识库/
(en)~/Documents/my-wiki/ - 用户可以自定义路径
- 默认:
-
运行初始化脚本:
bash ${SKILL_DIR}/scripts/init-wiki.sh "<路径>" "<主题>" -
补充初始化结果说明:
会同时生成init-wiki.sh
和purpose.md.wiki-cache.json
和purpose.md
同级存放,用来记录研究目标、关键问题和研究范围.wiki-schema.md- 提醒用户优先填写核心目标和关键问题;这些内容写在
里,后续 ingest 会优先参考这里的方向purpose.md
-
写入语言配置并本地化种子文件:
- 将
中的.wiki-schema.md
替换为:语言:{{LANGUAGE}}
→zh
(种子文件保持中文,无需额外处理)语言:中文
→en
,同时覆写以下种子文件为英文版:语言:English
- 如果
,读取WIKI_LANG=en
、${SKILL_DIR}/templates/index-en-template.md
、${SKILL_DIR}/templates/overview-en-template.md
,将${SKILL_DIR}/templates/log-en-template.md
和{{DATE}}
替换为实际值后,分别写入{{TOPIC}}
、index.md
、wiki/overview.mdlog.md
- 将
-
记录路径到
:~/.llm-wiki-pathecho "<路径>" > ~/.llm-wiki-path -
输出引导(根据
切换语言):WIKI_LANG中文(zh):
知识库已创建!路径:<路径> 接下来你可以: - 给我一个链接,我会自动提取并整理(网页、X/Twitter、公众号、知乎等) - 小红书内容请直接粘贴文本给我(暂不支持自动提取) - 给我一个本地文件路径(PDF、Markdown 等) - 直接粘贴文本内容 - 批量消化:给我一个文件夹路径 推荐:用 Obsidian 打开这个文件夹,可以实时看到知识库的构建效果。(英文版按「输出语言规则」生成,结构相同。)
工作流 2:ingest(消化素材)
这是最核心的工作流。用户给一个素材进来,AI 做所有的整理工作。
前置检查
执行通用前置检查(见上方定义)。
隐私自查提示(首次进入 ingest 必须执行)
在开始提取或分析任何内容之前,AI 必须先对用户说下面这句话,然后等待确认:
在开始分析这份素材前,请先快速确认里面不包含这些敏感内容:
- 手机号码(如 138xxxxxxxx)
- 身份证号(18 位数字)
- API 密钥(
、sk-...、AIzaSy...、OPENAI_API_KEY=、ANTHROPIC_API_KEY=)Bearer ...- 明文密码(
、password=)passwd=- 其他你不希望进入知识库的个人信息
如果素材里有上面任何一项,请先用文本编辑器删除或脱敏后再继续。 llm-wiki 不会自动过滤这些内容,处理后的内容会进入你的知识库。
确认无上述内容请回复
,要中止请回复y。n
流程规则:
- 用户回复
(或"可以"、"继续"、"没有"等明确肯定)→ 继续执行后续步骤y - 用户回复
(或"停"、"取消"等明确否定)→ 终止本次 ingest,提示用户清理后再来n - 其他不明确的回复 → 再问一次,最多两次;两次都不是明确 y/n 则终止
- 绕过规则:如果用户在当前对话里已经明确说过"素材里没有敏感信息,直接开始",
或者用户是在
流程中(已经在顶层确认过一次),AI 可以跳过这一步batch-ingest
为什么是自查清单而不是脚本:
- 正则在非结构化文本(聊天记录、笔记)里误报率很高,错过真的敏感词,误报无害的普通词
- 把判断权还给用户,比让脚本决定更可靠
- 对新手更友好,不会遇到看不懂的脚本报错
素材提取路由
根据素材类型自动路由到最佳提取方式:
外挂前置判断:
- URL 先调用
bash ${SKILL_DIR}/scripts/source-registry.sh match-url "<url>" - 本地文件先调用
bash ${SKILL_DIR}/scripts/source-registry.sh match-file "<path>" - 纯文本粘贴直接调用
bash ${SKILL_DIR}/scripts/source-registry.sh get plain_text
返回 10 列:source-registry.sh
、source_id
、source_label
、source_category
、input_mode
、match_rule
、raw_dir
、adapter_name
、dependency_name
、dependency_typefallback_hint- 调用
bash ${SKILL_DIR}/scripts/adapter-state.sh check <source_id> - 从
的 8 列结果里读取adapter-state.sh check
、state
、detail
、recovery_action
、install_hintfallback_hint - 如果
/state=not_installed
/env_unavailable
→ 不调用外挂,直接按unsupported
、detail
、recovery_action
、install_hint
告诉用户下一步fallback_hint - 只有返回
时,才继续自动提取available
URL 类素材(统一走来源总表,不手写域名表):
Chrome 提示(仅当
时): adapter-state.sh check 会把“提取器可用”与“是否存在 9222 可复用会话”分开表达。 如果 check 返回adapter_name=baoyu-url-to-markdown,正常调用外挂;即使 detail 提示未检测到 9222,也继续执行。baoyu-url-to-markdown 会自己处理 Chrome 启动,继续执行,不要等待用户确认。 只有在你想复用当前已登录的 Chrome 会话时,才需要手动开启 9222。 如果提取仍然失败(通常是页面需要登录态,如 X/Twitter、知乎等),可提示用户开启调试端口复用已登录会话:availableopen -na "Google Chrome" --args --remote-debugging-port=9222
- 如果
→ 不调用外挂,直接使用source_category=manual_onlyfallback_hint - 如果
→ 执行adapter_name=wechat-article-to-markdownwechat-article-to-markdown "<URL>" - 如果
→ 调用adapter_name=youtube-transcriptyoutube-transcript - 如果
→ 调用adapter_name=baoyu-url-to-markdownbaoyu-url-to-markdown
本地文件:
- 统一走
bash ${SKILL_DIR}/scripts/source-registry.sh match-file "<path>" - 命中后直接读取,不调用外挂
纯文本粘贴:
- 统一视为
plain_text - 直接使用用户提供的文本
统一回退规则:
- 对自动提取结果,统一运行
bash ${SKILL_DIR}/scripts/adapter-state.sh classify-run <source_id> <exit_code> <output_path> - 从
返回的 8 列结果里读取classify-run
、state
、detail
、recovery_actionfallback_hint - 如果返回
→ 按runtime_failed
、detail
、recovery_action
告诉用户“这次自动提取失败,可以先重试一次;如果还不行,就改走手动入口”fallback_hint - 如果返回
→ 按empty_result
、detail
、recovery_action
告诉用户“自动提取没有拿到有效正文,请手动补全文本后继续”fallback_hint - 其他状态也使用同一份返回结果,不再手写第二套回退文案
内容分级处理
根据素材长度和信息密度自动选择处理级别:
判断标准:
- 素材内容 > 1000 字 → 完整处理
- 素材内容 <= 1000 字(短推文、小红书笔记等)→ 简化处理
完整处理流程(长素材 > 1000 字)
-
提取素材内容:按上面的路由获取素材文本
-
保存原始素材到
对应目录:raw/- 根据素材类型保存到对应目录(articles/、tweets/、wechat/、xiaohongshu/、zhihu/ 等)
- 文件名格式:
{日期}-{短标题}.md - 如果是 URL 类素材,在文件头部记录原始 URL
-
读取上下文:
- 优先顺序:
>purpose.md
>.wiki-schema.mdindex.md - 如果
存在,先读取其中的核心目标、关键问题和研究范围purpose.md - 用
指导后续实体、主题、关联的取舍和权重purpose.md
- 优先顺序:
-
缓存检查:
- 在进入 LLM 处理前,先运行:
bash ${SKILL_DIR}/scripts/cache.sh check “<raw 文件路径>” - 如果返回
或HIT
→ 跳过本次 LLM 调用,直接读取已有 wiki 页面,并告诉用户这是”无变化,直接复用已有结果”HIT(repaired)
表示缓存自愈修复成功(上次 update 被跳过但 source 页面存在)HIT(repaired)
- 如果返回
→ 继续执行下面的两步流程MISS:<reason>
— 首次处理此素材(正常情况)MISS:no_entry
— 素材内容有变化,需要重新处理MISS:hash_changed
— 有缓存记录但 source 页面被删除了MISS:no_source
- 在进入 LLM 处理前,先运行:
-
Step 1:结构化分析:
- 输入:原始内容 +
+ 现有 wiki 结构(至少读取purpose.md
概要)index.md - 输出:JSON 格式的分析结果,不持久化,只在当前 ingest 流程里临时传递
- JSON 至少包含
、entities
、topicsconnections
是必需字段,缺失就视为格式异常并触发单步回退confidence
{ "source_summary": "一句话概括", "entities": [{"name": "xxx", "type": "concept", "relevance": "high", "confidence": "EXTRACTED"}], "topics": [{"name": "xxx", "importance": "high"}], "connections": [{"from": "A", "to": "B", "type": "因果", "confidence": "INFERRED"}], "contradictions": [{"claim_a": "...", "claim_b": "...", "context": "..."}], "new_vs_existing": {"new_entities": [], "updates": []} }置信度赋值规则(Claude 必须遵守):
- EXTRACTED:信息直接出现在原文里,字面可以找到
- INFERRED:信息是从多处原文推断出来的,原文没有直接说
- AMBIGUOUS:原文说法不清楚,或者有歧义
- UNVERIFIED:信息来自 Claude 的背景知识,原文没有证据
Step 1 完成后,必须执行验证:
- mkdir -p {wiki_root}/.wiki-tmp
- 将 Step 1 JSON 写入 {wiki_root}/.wiki-tmp/step1-latest.json
- 调用 bash ${SKILL_DIR}/scripts/validate-step1.sh {wiki_root}/.wiki-tmp/step1-latest.json
- 验证完成后删除 {wiki_root}/.wiki-tmp/step1-latest.json
如果脚本返回非 0,自动回退到单步 ingest(不进行 Step 2)。
- 输入:原始内容 +
-
Step 2:页面生成:
- 输入:原始内容 +
+ Step 1 的分析结果 + 现有相关 wiki 页面purpose.md - 输出:所有需要创建或更新的 wiki 页面内容
- Step 2 负责完成原流程中的素材摘要、实体页、主题页、index、log 更新
- 输入:原始内容 +
-
容错回退:
- 如果 Step 1 不是有效 JSON,或者缺少
、entities
、topics
等必需字段,自动回退到原来的单步流程confidence - 回退时,所有本次新生成内容统一加上:
<!-- confidence: UNVERIFIED --> - 同时在页面顶部加注释说明本次处理因格式问题降级,避免出现“部分标注、部分没标注”的状态
- 如果 Step 1 不是有效 JSON,或者缺少
-
生成素材摘要页(
):wiki/sources/{日期}-{短标题}.md- 参考
的格式templates/source-template.md - 包含:基本信息、核心观点、关键概念、与其他素材的关联、原文精彩摘录
- 对 Step 1 中标记为
或INFERRED
的关系,用 HTML 注释保留置信度:AMBIGUOUS<!-- confidence: INFERRED --> <!-- confidence: AMBIGUOUS --> - 写入 source 页面时,必须使用
(自动更新缓存):create-source-page.sh# 先把页面内容写到临时文件 echo "<页面内容>" > /tmp/source-content.tmp # 调用脚本原子写入 + 缓存更新 bash ${SKILL_DIR}/scripts/create-source-page.sh "<raw 文件路径>" "wiki/sources/{日期}-{短标题}.md" /tmp/source-content.tmp - 如果脚本返回
→ 写入和缓存都已更新SUCCESS - 如果脚本返回
→ 写入或缓存失败,检查报错信息后重试ERROR
- 参考
-
更新或创建实体页(
):wiki/entities/- 对每个关键概念,检查
下是否已有对应页面wiki/entities/ - 如果已有 → 追加新信息,更新"不同素材中的观点"部分
- 如果没有 → 创建新实体页,参考
templates/entity-template.md - 使用
语法做双向链接[[实体名]]
- 对每个关键概念,检查
-
更新或创建主题页(
):wiki/topics/
- 识别素材涉及的主要研究主题
- 如果已有对应主题页 → 更新素材汇总表和核心观点
- 如果没有 → 创建新主题页,参考
templates/topic-template.md
- 更新 index.md:
- 在对应分类下添加新条目
- 更新概览统计数字
- 更新 log.md:
- log.md 追加格式:
## {日期} ingest | {素材标题} - 记录新增和更新的页面列表
- 注意:缓存更新已在 Step 8 通过
自动完成,此处无需再调用create-source-page.shcache.sh update
- 向用户展示结果(按
切换语言):WIKI_LANG
中文(zh):
已消化:{素材标题} 新增页面: - {素材摘要页} - {新实体页1} - {新主题页1} 更新页面: - {已有实体页2}(追加了新信息) 发现关联: - 这篇素材和 [[已有素材]] 在 {某概念} 上有联系
(英文版按「输出语言规则」生成,结构相同。)
简化处理流程(短素材 <= 1000 字)
适用于短推文、小红书笔记、简短评论等。
-
保存原始素材到对应
目录raw/ -
读取上下文并检查缓存:
- 仍然优先读取
purpose.md - 仍然先运行
bash ${SKILL_DIR}/scripts/cache.sh check "<raw 文件路径>" - 如果缓存命中(
或HIT
),直接复用已有结果HIT(repaired)
- 仍然优先读取
-
生成简化摘要页(
):wiki/sources/- 只包含基本信息和核心观点
- 不写"原文精彩摘录"部分
- 写入 source 页面时同样使用
(自动更新缓存)create-source-page.sh
-
提取 1-3 个关键概念:
- 如果对应实体页已存在 → 追加一句话说明
- 如果不存在 → 在摘要页中用
标记[待创建: [[概念名]]]
-
更新 index.md 和 log.md(缓存已由
自动更新)create-source-page.sh -
跳过:主题页创建/更新、overview 更新
-
向用户展示简化结果(按
切换语言):WIKI_LANG中文(zh):
已消化:{素材标题}(短内容,简化处理) 新增: - 素材摘要页 待完善: - [待创建: [[概念名]]](积累更多素材后整理)(英文版按「输出语言规则」生成,结构相同。)
工作流 3:batch-ingest(批量消化)
当用户给了一个文件夹路径,或者说"把这些都整理一下"。
步骤
-
确认知识库路径:
- 执行通用前置检查(见上方定义),获取知识库根路径和
WIKI_LANG
- 执行通用前置检查(见上方定义),获取知识库根路径和
-
列出所有可处理文件:
- 支持的格式:
,.md
,.txt
,.pdf.html - 忽略:隐藏文件、
目录、.git
等node_modules
- 支持的格式:
-
展示文件列表,确认处理范围(按
切换语言):WIKI_LANGzh:
发现 {N} 个文件待处理: 1. file1.pdf 2. file2.md 3. file3.txt 预计需要 {N} 轮处理。是否开始?(英文版按「输出语言规则」生成,结构相同。)
-
逐个处理:对每个文件执行 ingest 工作流
- 每个文件先
cache check - 命中缓存的文件直接跳过,不再进入 LLM 处理
- 只有
的文件才继续执行完整或简化处理MISS
- 每个文件先
-
每 5 个文件后暂停,展示进度并询问是否继续(按
切换语言):WIKI_LANGzh:
进度:5/{N} 已完成 本批处理结果: - 新增素材摘要:5 - 新增实体页:3 - 更新已有页面:7 继续处理剩余 {M} 个文件?(英文版按「输出语言规则」生成,结构相同。)
-
全部完成后:
- 运行一次 index.md 全量更新
- 输出总结报告(按
切换语言):WIKI_LANG
zh:
批量消化完成! 处理了 {N} 个文件: - 已跳过 N 个(无变化),处理 M 个(新增/更新) - 成功:{S} - 跳过(内容为空/格式不支持):{K} - 失败:{F} 新增页面:{total_new} 更新页面:{total_updated}(英文版按「输出语言规则」生成,结构相同。)
工作流 4:query(查询知识库)
步骤
-
确认知识库路径:
- 执行通用前置检查(见上方定义),获取知识库根路径和
WIKI_LANG - 如果没有可用知识库,提示用户先初始化
- 执行通用前置检查(见上方定义),获取知识库根路径和
-
读取 index.md 了解知识库全貌
-
搜索相关页面:
- 先在 index.md 中定位相关分类和条目
- 再用 Grep 在
目录下搜索关键词wiki/ - 读取最相关的 3-5 个页面
-
综合回答:
- 按
用对应语言回答用户的问题WIKI_LANG - 标注信息来源(引用 wiki 页面,用
格式)[[页面名]] - 如果多个素材有不同观点,分别列出并标注来源
- 按
-
判断是否值得持久化:
- 如果回答引用了 3 个及以上来源的综合分析,提示用户:"是否保存此回答到知识库?"
- 少于 3 个来源时,默认只做即时回答,不主动建议持久化
-
重复检测:
- 持久化前,先在
下搜索同主题页面wiki/queries/ - 通过 frontmatter tags 和 title 匹配,判断是否已有同主题 query 页面
- 如果已有,提示用户是“更新现有页面”还是“新建一页”
- 如果用户选择更新旧页面,旧版页面增加
标记superseded-by
- 持久化前,先在
-
保存 query 页面:
- 用
生成页面templates/query-template.md - 保存路径使用
,避免同主题命名冲突wiki/queries/{date}-{short-hash}.md - frontmatter 必须包含
和type: queryderived: true
表示这是衍生内容,不是一手素材derived: true
- 用
-
自引用防护:
- query 页面在后续 ingest 分析里视为二级来源,不作为主要知识来源
- 如果后续页面引用 query 页面里的信息,相关关系统一按
处理INFERRED - ingest 不主动扫描
;只有当前问题确实需要时,才把 query 页面作为补充材料读取wiki/queries/
-
更新索引和日志:
- 保存成功后,在 index.md 中加入 query 条目
- 同时在 log.md 中追加一条 query 保存记录
工作流 5:lint(健康检查)
触发时机
- 用户主动说"检查知识库"
- 每次 ingest 后,如果素材总数是 10 的倍数,主动建议运行 lint
前置检查
执行通用前置检查(见上方定义)。如果没有可用知识库,提示用户先初始化。
-
确定检查范围:
- 最近更新的 10 个页面(按文件修改时间排序)
- 随机抽查的 10 个页面(避免遗漏旧页面的问题)
- 如果页面总数 <= 20,检查全部
-
Step 0:调用脚本做机械检查(必须先做,不要跳过):
bash ${SKILL_DIR}/scripts/lint-runner.sh <wiki_root>脚本负责三项机械检查(只需要精确匹配,不需要判断):
- 孤立页面(
下没有被其他页面引用的实体)entities/ - 断链(
链接指向的[[X]]
不存在,支持X.md
语法)[[X|别名]] - index 一致性(index.md 里有记录但文件缺失的条目)
退出码:
= 运行完成,0
= 脚本自身错误(路径不存在、index.md 缺失)。 如果 exit 1,向用户报告错误,不要继续。 如果 exit 0,把脚本 stdout 读进上下文,作为后续 AI 判断类检查的基础素材。1 - 孤立页面(
-
逐项检查(AI 判断类,脚本做不了):
矛盾信息(阅读相关页面,检查是否有互相矛盾的说法):
- 列出发现的矛盾
- 标注每处矛盾的来源页面
交叉引用缺失(检查相关主题的页面之间是否应该互相链接但没链):
- 建议添加的交叉引用
置信度报告(统计
/EXTRACTED
/INFERRED
/AMBIGUOUS
):UNVERIFIED- 高亮
条目,提醒用户优先验证AMBIGUOUS - 抽查标注为 EXTRACTED 的条目,检查是否能在原始素材里找到对应原文
- 如果发现 EXTRACTED 无法回溯到原文,提示用户回退为更低置信度或重新整理
补充建议:基于 Step 0 脚本的孤立页/断链输出,给出修复建议(脚本只列问题,不给方案)
- 孤立页面 → 建议从哪些相关页面添加
[[链接]] - 断链 → 建议为哪些概念创建新页面,或改写引用为已有页面
-
输出报告(按
切换语言,整合 Step 0 脚本输出 + Step 3 AI 判断结果):WIKI_LANGzh:
知识库健康检查报告 检查范围:最近更新 10 页 + 随机抽查 10 页(共 {N} 页) 孤立页面(没有其他页面链接到它): - [[某页面]] → 建议从 [[相关页面]] 添加链接 断链(被链接但不存在): - [[某概念]] → 建议创建新页面 矛盾信息: - 关于"XX",[[页面A]] 说是 Y,但 [[页面B]] 说是 Z 缺失索引: - {文件名} 存在但未记录在 index.md 中 置信度报告: - EXTRACTED:{N} - INFERRED:{N} - AMBIGUOUS:{N} - UNVERIFIED:{N}(英文版按「输出语言规则」生成,结构相同。)
-
询问用户:要自动修复哪些问题?(按
用对应语言提问)WIKI_LANG
工作流 6:status(查看状态)
前置检查
执行通用前置检查(见上方定义)。如果没有可用知识库,提示用户先初始化。
步骤
-
先运行
读取来源总表bash ${SKILL_DIR}/scripts/source-registry.sh list -
获取知识库路径(按上面的 CWD 检查逻辑)
-
统计:
- 按来源总表中的
和source_label
逐项统计raw_dir
文件数raw/
下的页面数wiki/entities/
下的页面数wiki/topics/
下的页面数wiki/sources/
和wiki/comparisons/
下的页面数wiki/synthesis/purpose.md 是否存在
- 按来源总表中的
-
读取
最后 5 条记录log.md -
读取
获取主题概览index.md -
运行
获取外挂状态bash ${SKILL_DIR}/scripts/adapter-state.sh summary-human -
输出报告(按
切换语言):WIKI_LANGzh:
知识库状态:{主题} 素材分布(按来源总表): - {source_label}:{N} - {source_label}:{N} ... Wiki 页面:{总数} 页 - 实体页:{N} - 主题页:{N} - 素材摘要:{N} - 对比分析:{N} - 综合分析:{N} 研究方向: - purpose.md 是否存在:{是/否} 最近活动: - {日期} ingest | {素材标题} - {日期} ingest | {素材标题} ... 外挂状态: {summary-human 原文} 建议: - 你可能想深入了解 {某主题},已有 {N} 篇相关素材 - {某实体} 被 {N} 篇素材提到,值得整理成独立页面(英文版按「输出语言规则」生成,结构相同。)
外挂状态直接使用
的输出,不要自己再重写一套来源清单。bash ${SKILL_DIR}/scripts/adapter-state.sh summary-human
工作流 7:digest(深度综合报告)
区别于 query:query 是快速问答,不生成新页面;digest 是跨素材深度综合,生成持久化报告。
触发关键词
- 默认深度报告格式:
"给我讲讲 XX"、"深度分析 XX"、"综述 XX"、"digest XX"、"全面总结一下 XX" - 对比表格式:
"对比一下 X 和 Y"、"比较 X 和 Y"、"X 和 Y 有什么区别" - 时间线格式:
"整理一下时间线"、"按时间排列"、"时间顺序"
前置检查
执行通用前置检查(见上方定义)。如果没有可用知识库,提示用户先初始化。
-
搜索相关页面:
- 用 Grep 在
下搜索主题关键词wiki/ - 列出将要综合的页面(让用户了解报告覆盖范围)
- 用 Grep 在
-
深度阅读所有相关页面 + 选择输出格式:
- 读取找到的所有相关 wiki 页面(sources/、entities/、topics/)
- 归纳每个页面的核心观点和来源信息
- 根据触发关键词决定输出格式:
- 用户说"对比"/"比较"类 → 使用对比表格式(见下方模板 B)
- 用户说"时间线"/"按时间"类 → 使用时间线格式(见下方模板 C)
- 其他默认 → 使用深度报告格式(见下方模板 A)
-
生成结构化深度报告,保存到
(按wiki/synthesis/{主题}-{格式}.md
切换语言):WIKI_LANG文件名规则:默认格式用
,对比表用{主题}-深度报告.md
,时间线用{主题}-对比.md{主题}-时间线.md模板 A:深度报告格式(默认)
zh:
# {主题} 深度报告 > 综合自 {N} 篇素材 | 生成日期:{日期} ## 背景概述 (简要说明这个主题的背景和重要性) ## 核心观点 (按重要性排列,每个观点标注来源) - 观点一(来源:[[素材A]]、[[素材B]]) - 观点二(来源:[[素材C]]) ## 不同视角对比 (如有多个素材观点不同,在此对比) | 维度 | 来源A的观点 | 来源B的观点 | |------|------------|------------| ## 知识脉络 (按时间或逻辑顺序梳理该主题的发展) ## 尚待解决的问题 (现有素材中尚未回答的问题,可作为下次搜集素材的方向) ## 相关页面 (列出所有综合来源的链接)(英文版按「输出语言规则」生成,结构相同。)
模板 B:对比表格式(触发词:对比 / 比较)
# {对比主题} 对比分析 > 对比 {N} 个对象 | 生成日期:{日期} ## 对比对象 - [[对象 A]] - [[对象 B]] - [[对象 C]](如有) ## 对比表 | 维度 | [[对象 A]] | [[对象 B]] | [[对象 C]] | |-----------|-----------|-----------|-----------| | 核心观点 | ... | ... | ... | | 适用场景 | ... | ... | ... | | 优点 | ... | ... | ... | | 缺点 / 限制 | ... | ... | ... | | 来源素材 | [[素材1]] | [[素材2]] | [[素材3]] | ## 关键差异 (用 1-2 句话说清最重要的差异点) ## 相关页面模板 C:时间线格式(触发词:时间线 / 按时间)
# {主题} 时间线 > 时间跨度:{起始年} ~ {结束年} | 生成日期:{日期} ```mermaid gantt title {主题} 时间线 dateFormat YYYY-MM-DD section 主要事件 事件 A : 2023-01-01, 1d 事件 B : 2024-03-15, 1d 事件 C : 2025-06-20, 1d事件说明
- 2023-01-01 — 事件 A:简要说明(来源:[[素材A]])
- 2024-03-15 — 事件 B:简要说明(来源:[[素材B]])
- 2025-06-20 — 事件 C:简要说明(来源:[[素材C]])
相关页面
> **时间线格式注意事项**: > - `gantt` 要求 `YYYY-MM-DD` 精度 > - 如果素材只有年份(如 "2023 年"),把日期补为该年第一天(`2023-01-01`) > - 如果连年份都不确定,改用**纯文字时间线**(无序列表按时间排序),不用 Mermaid gantt > - 如果事件超过 15 个,建议按 section 分组,避免图太长 -
更新 index.md 和 log.md:
- index.md 的"综合分析"分类下添加新报告条目
- log.md 追加:
## {日期} digest | {主题}
-
向用户展示结果(按
切换语言):WIKI_LANGzh:
已生成深度报告:{主题} 综合了 {N} 篇素材: - [[素材1]]、[[素材2]]... 报告已保存:wiki/synthesis/{主题}-深度报告.md 发现这些待解决问题,可以继续搜集素材: - {问题1} - {问题2}(英文版按「输出语言规则」生成,结构相同。)
工作流 8:graph(知识图谱 · Mermaid + 交互式 HTML)
触发关键词
"画个知识图谱"、"看看关联图"、"graph"、"知识库地图"、"展示知识关联"
前置检查
执行通用前置检查(见上方定义)。如果没有可用知识库,提示用户先初始化。
-
扫描双向链接:
- 遍历
下所有wiki/
文件.md - 提取每个文件中的
语法,建立关系列表:[[链接]]页面A → 页面B
- 遍历
-
生成 Mermaid 图表文件
:wiki/knowledge-graph.md# 知识图谱 > 自动生成 | {日期} | 共 {N} 个节点,{M} 条关联 ```mermaid graph LR A[概念1] --> B[概念2] A --> C[素材1] D[主题1] --> A D --> E[概念3] ``` 查看方式:用 Typora、VS Code(Markdown Preview Enhanced)、或直接在 GitHub 上查看。生成规则:
- 节点名用中括号
,名称太长则截断到 10 字[名称] - 只展示有双向链接关系的节点(孤立节点不纳入图谱)
- 如果关系超过 50 条,只保留被引用次数最多的 30 个节点,避免图谱过于密集
- 默认全部使用
无标注箭头,不自动判断关系类型A --> B
可选:手动美化图谱(生成后由用户自己做,AI 不自动处理):
生成的
默认只有wiki/knowledge-graph.md
箭头。如果用户希望图谱更清楚地 表达关系类型,可以:-->- 用编辑器打开
wiki/knowledge-graph.md - 参考
里的"关系类型词汇表"(实现 / 依赖 / 对比 / 矛盾 / 衍生).wiki-schema.md - 把最重要的 3-5 条箭头改写成
之类的带标注写法A -->|实现| B - 保存后用 Obsidian / VS Code / Typora 重新渲染
AI 在 graph 工作流里不自动打标——因为自动判断关系类型需要额外阅读整段上下文, 成本高且准确率难保证。人类对"哪些关系最值得打标"的判断更可靠。 用户如果明确要求 AI 给某几条边打标,可以单独说"把 A 和 B 之间的关系标成'实现'", AI 再手动修改
对应的那一行。wiki/knowledge-graph.md - 节点名用中括号
2b. 生成交互式图谱数据(
wiki/graph-data.json):
bash scripts/build-graph-data.sh "$WIKI_ROOT"
脚本会扫描
wiki/{entities,topics,sources,comparisons,synthesis,queries}/*.md,
解析同行 [[双向链接]] 与 <!-- confidence: EXTRACTED|INFERRED|AMBIGUOUS --> 注释,
做主题社区聚类,并写入 wiki/graph-data.json(>2MB 自动降级,单节点只留 500 行)。
依赖 jq(brew install jq)。
2c. 生成交互式图谱 HTML(wash 水彩卡片风):
bash scripts/build-graph-html.sh "$WIKI_ROOT"
生成
wiki/knowledge-graph.html。脚本把 graph-data.json(已做 </script> 转义)
内嵌进 <script id="graph-data" type="application/json">,使用本地 d3 + roughjs +
marked + purify,离线双击即可打开。包含搜索框、关系类型筛选、节点抽屉、
社区聚类等交互功能。
-
向用户展示结果(按
切换语言):WIKI_LANGzh:
知识图谱已生成! 共 {N} 个节点,{M} 条关联 查看方式: - 交互式(推荐):双击 wiki/knowledge-graph.html (建议 Chrome / Firefox;Safari 若提示"已阻止脚本", 可在 wiki/ 下跑 `python3 -m http.server 8000` 再访问) - Mermaid 静态图:wiki/knowledge-graph.md (Obsidian / VS Code Markdown Preview Enhanced / GitHub / Typora 均可渲染) 孤立页面(未纳入图谱): - [[某页面]](建议添加到相关实体页或主题页)(英文版按「输出语言规则」生成,结构相同。)
工作流 9:delete(删除素材)
触发关键词
"删除素材"、"remove"、"delete source"、"移除"
前置检查
执行通用前置检查(见上方定义)。如果没有可用知识库,提示用户先初始化。
步骤
-
识别目标素材:
- 在
下搜索用户提到的素材名raw/ - 如果匹配到多个候选,先列出候选文件让用户确认
- 在
-
扫描影响范围:
- 先运行:
bash ${SKILL_DIR}/scripts/delete-helper.sh scan-refs "<wiki 根目录>" "<素材文件名>" - 用脚本返回的页面列表作为引用扫描结果
- 逐页判断是“删除整页”还是“保留页面但移除该素材引用”
- 先运行:
-
安全确认:
- 如果影响超过 5 个页面时,先把受影响页面完整列给用户,再做二次确认
- 如果某个实体或主题只被这个素材引用,提示用户是否连同页面一起删除
-
执行级联清理:
- 删除
下对应原始文件raw/ - 删除
下对应素材摘要页wiki/sources/ - 对
、wiki/entities/
、wiki/topics/
、wiki/comparisons/
中仍需保留的页面,只移除该素材相关的引用段落wiki/synthesis/ - 更新
index.md - 在
追加删除记录log.md - 标记
需要重新生成wiki/overview.md
- 删除
-
清理缓存:
- 删除完成后,对对应 raw 文件运行:
bash ${SKILL_DIR}/scripts/cache.sh invalidate "<raw 文件路径>"
- 删除完成后,对对应 raw 文件运行:
-
断链检查:
- 用 grep 或
再扫一遍指向已删除页面的链接delete-helper.sh - 清理明确可判定的断链;如果归属不清,保留原文并提示用户后续人工确认
- 用 grep 或
-
向用户报告结果:
zh:
已删除: - raw/articles/2024-01-15-ai-article.md - wiki/sources/2024-01-15-ai-article.md 已更新(移除引用): - wiki/entities/AI-Agent.md - wiki/topics/大语言模型.md 需要重新生成: - wiki/overview.md(英文版按「输出语言规则」生成,结构相同。)
工作流 10:crystallize(结晶化)
触发条件: 用户说"结晶化"、"crystallize"、"把这个记进知识库"、"这段对话很有价值"
输入: 用户主动提供的内容(文字粘贴进对话,或明确引用某段上下文)。 用户必须主动提供内容,Claude 不自动提取当前会话。
处理步骤(MVP):
- 用户提供内容(文字粘贴进对话)
- Claude 从内容中提取:
- 核心洞见(3-5 条)
- 关键决策和原因
- 值得记录的结论
- 生成
,格式参考wiki/synthesis/sessions/{主题}-{日期}.mdtemplates/synthesis-template.md - 更新
(记录本次结晶化操作)log.md
MVP 版本不自动创建 entity 页面,不自动更新 index.md。
confidence 规则: 结晶化来源的内容默认标记为
INFERRED(来自推断/对话,非原始文档)。
输出示例: 已创建 wiki/synthesis/sessions/AI-agent-设计决策-20260413.md 已更新 log.md