知识库健康检查器
你的知识库是活的,不是死的。让它呼吸。
核心理念
市面上的检查工具只做一件事:检测有没有坏东西。
我们做三件事:
- 检测问题(空壳、断链、孤立)
- 分析健康度(内容密度、网络连接、主题分布)
- 给出生机(可视化报告 + 修复建议 + 自动修复脚本)
不只是"告诉你哪里坏了",而是"帮你让它变好"。
适用场景
- Obsidian用户:检测断链、未连接的笔记
- Notion导出用户:检查格式一致性、空页面
- Logseq用户:分析graph密度、孤立block
- Markdown知识库:内容质量综合评估
- 知识库重构前:做一次全面体检,避免搬砖式迁移
执行流程
Phase 0: 扫描确认(用户检查点)
先确认知识库路径和预期:
扫描目录:~/.openclaw/workspace/memory/ [默认]
文件总数:预计 ~600-800个
预估时间:640个文件约20秒
确认:开始扫描?(y/n)
扫描策略:
- 递归扫描所有.md文件
- 排除隐藏文件(.开头)和系统文件(node_modules/、.git/)
- 实时进度展示:每扫描100个文件更新一次
- 支持中断恢复:从进度文件恢复上次扫描位置
进度展示:
扫描中:[████████████░░░░░░░░] 240/640 (37.5%) | 预计剩余12s
Phase 1: 空壳文件检测
定义:文件存在但内容低于阈值,或内容只有"TODO占位"。
检测标准:
- 内容长度:< 200字符 = 空壳
- 结构完整度:缺少标题(#开头的行)
- 占位符检测:内容中包含"待补充"、"TODO"、"占位"
- 图片文件数:>3个且文字<100字符 = 纯图片笔记
输出格式:
空壳文件清单:
┌─────────────────────────┬──────────┬─────────────────────────┐
│ 文件名 │ 类型 │ 建议 │
├─────────────────────────┼──────────┼─────────────────────────┤
│ theory-gap.md │ 内容过短 │ 补充定义/方法/案例 │
│ 待研究.md │ 占位符 │ 删除或开始撰写 │
│ product-sketch.png.md │ 纯图片 │ 添加图片说明文字 │
└─────────────────────────┴──────────┴─────────────────────────┘
Phase 2: 断链检测
定义:Wiki链接指向不存在的文件或锚点。
链接类型检测:
- 文件链接:
[[filename]] → 检查文件是否存在
- 锚点链接:
[[filename#heading]] → 检查文件和锚点是否存在
- 外部链接:
[text](url) → 可选检查HTTP 200(需用户确认,耗时)
- 相对路径:
../path/to/file → 检查路径有效性
检测策略:
- 逐文件扫描,提取所有链接模式
- 构建文件索引(文件名 → 完整路径)
- 验证每个链接的可达性
- 记录断链类型:文件不存在、锚点不存在、权限问题
输出格式:
断链清单:
┌─────────────────────────┬──────────┬─────────────────────────┐
│ 源文件 │ 链接类型 │ 目标(不存在) │
├─────────────────────────┼──────────┼─────────────────────────┤
│ quantum-mechanics.md │ 文件链接 │ [[wave-function]] │
│ design-system.md │ 锚点链接 │ [[#best-practices]] │
│ research-links.md │ 外部链接 │ https://broken-url │
└─────────────────────────┴──────────┴─────────────────────────┘
Phase 3: 内容密度分析
定义:分析文件的内容质量,不是简单看字数。
分析维度:
-
字数分布:
- 过短(<300字):内容单薄
- 适中(300-3000字):健康
- 过长(>3000字):建议拆分
-
结构质量:
- 标题层级(H1/H2/H3分布)
- 列表密度(有序/无序列表占比)
- 代码块数量(技术类文档)
- 表格数量(数据类文档)
-
链接密度:
- 内链数:链接到知识库内部的其他文件
- 外链数:外部引用
- 无内链 = 孤岛文件
-
更新时间:
- 最近修改时间(mtime)
- 长期未更新(>90天):标注为"待回顾"
输出格式:
内容密度分析:
┌─────────────────────────┬────────┬────────┬────────┬────────┐
│ 文件名 │ 字数 │ 结构分 │ 内链数 │ 状态 │
├─────────────────────────┼────────┼────────┼────────┼────────┤
│ machine-learning.md │ 2800 │ 85 │ 12 │ ✅健康 │
│ quick-note.md │ 120 │ 30 │ 0 │ ⚠️孤岛 │
│ legacy-theory.md │ 5400 │ 70 │ 3 │ ⚠️过长 │
└─────────────────────────┴────────┴────────┴────────┴────────┘
Phase 4: 知识网络完整性
定义:分析知识库的连接结构,发现孤岛和中心节点。
构建知识图谱:
- 节点 = 文件
- 边 = 内链关系(A→B表示A链接到B)
分析指标:
- 孤立节点:没有入边也没有出边的文件
- 中心节点:度数>10的文件(被广泛引用)
- 弱连接:单向链接(A→B但B不回链A)
- 环路检测:是否存在循环引用
- 连通分量:知识库是否是一个连通图,还是分裂成多个孤岛
输出格式:
知识网络分析:
- 总节点数:347
- 连通分量:3个(主图322节点,孤岛A 18节点,孤岛B 7节点)
- 孤立节点:5个(完全未连接)
- 中心节点:8个(被引用>10次)
- 弱连接:42对(单向链接)
孤立节点建议:
┌─────────────────────────┬─────────────────────────┐
│ 孤岛文件 │ 连接建议 │
├─────────────────────────┼─────────────────────────┤
│ draft-idea.md │ 链接到[[thinking]]或删除 │
│ temp-research.md │ 整合到主话题或归档 │
└─────────────────────────┴─────────────────────────┘
Phase 5: 可视化健康报告卡片(用户检查点)
生成前展示摘要:
检测完成!发现以下问题:
- 空壳文件:12个
- 断链:8个
- 孤立节点:15个
- 健康分:78分
是否生成完整报告?(y/n)
生成机制:使用Python脚本生成HTML报告,包含:
- 总体健康评分(0-100分)
- 各维度得分(空壳、断链、密度、网络)
- 问题分布饼图
- 修复建议清单
- 一键修复按钮(生成脚本)
报告模板:
<!-- assets/report_templates/health_report.html -->
<div class="health-card">
<div class="score-circle">
<div class="score">78</div>
<div class="label">健康分</div>
</div>
<div class="metrics">
<div class="metric">
<span class="name">空壳文件</span>
<span class="value">12个</span>
<span class="trend">↑3</span>
</div>
<!-- ... 更多指标 -->
</div>
<div class="actions">
<button onclick="generateFixScript()">生成修复脚本</button>
<button onclick="exportReport()">导出PDF</button>
</div>
</div>
输出:health-report-YYYYMMDD-HHMM.html,自动在浏览器打开。
Phase 6: 自动修复建议
修复策略:
-
空壳文件:
- 原则:删除无意义占位,补充有价值的框架
- 生成:批量删除脚本或补充模板
-
断链:
- 策略:搜索相似文件名,推荐替换目标
- 生成:sed替换脚本或交互式修复工具
-
孤岛文件:
- 判断:有内容但无链接 = 建议连接;无内容 = 建议删除
- 生成:批量添加链接脚本
-
过长文件:
输出格式:
#!/bin/bash
# auto-fix-20260418-1055.sh
# 知识库自动修复脚本(需人工审查后执行)
# 1. 删除空壳文件
rm "memory/drafts/待研究.md"
rm "memory/temp/quick-note.md"
# 2. 修复断链(搜索相似文件名)
sed -i '' 's/\[\[wave-function\]\]/[[wave-function-theory]]/g' "memory/physics/quantum-mechanics.md"
# 3. 拆分过长文件
python3 scripts/split_long_file.py "memory/legacy/theory.md" --by-h2
echo "修复完成,请review更改后commit"
使用方式
快速体检(默认)
用户:"检查一下我的知识库健康度"
→ Phase 0-5,生成HTML报告,浏览器打开
→ 展示:健康分、问题分布、修复建议
深度分析(含网络)
用户:"深度分析我的知识库网络结构"
→ Phase 0-4 + Phase 6
→ 额外输出:连通分量图、中心节点列表、弱连接清单
只检测不修复
用户:"只检测问题,不要生成修复脚本"
→ Phase 0-4,跳过Phase 5-6
→ 输出:纯文本诊断报告
生成修复脚本
用户:"生成修复脚本"
→ 基于之前的检测结果,执行Phase 6
→ 输出:auto-fix-YYYYMMDD-HHMM.sh
→ 提示用户审查后执行
定期检查(Cron集成)
用户:"每周日自动检查知识库"
→ 生成cron任务:每周日09:00执行
→ 输出:发送到飞书/邮件/控制台
工具脚本
scripts/health_check.py
核心检测引擎:
- 空壳文件检测
- 断链检测
- 内容密度分析
- 知识网络分析
scripts/report_generator.py
可视化报告生成:
- HTML模板渲染
- 评分计算
- 图表生成(可选Chart.js)
scripts/auto_fix.py
修复脚本生成:
评分标准
| 维度 | 权重 | 满分标准 |
|---|
| 空壳文件率 | 25% | 0个空壳 |
| 断链接率 | 30% | 0个断链 |
| 内容密度 | 25% | 80%文件健康 |
| 网络完整性 | 20% | 孤岛<5% |
健康分 = Σ(维度得分 × 权重)
错误处理与边界条件
超时保护
- 单个文件处理超时:跳过并记录到
skipped_files.json
- 整体扫描超时:每100个文件保存一次进度,支持中断恢复
- 大文件处理:>5MB的文件单独标记,建议手动检查
内存保护
- 流式处理:不一次性加载所有文件到内存
- 进度保存:每100个文件保存一次中间结果
- 恢复机制:从
progress.json恢复上次扫描位置
编码处理
- 优先UTF-8,失败后尝试GBK、GB2312
- 无法解码的文件记录到
encoding_errors.json
排除规则
- 隐藏文件(.开头)
- 系统目录(node_modules/、.git/、pycache/、.obsidian/)
- 用户自定义排除(支持正则表达式)
与竞品差异
| 功能 | Obsidian Linter | Logseq Linter | 我们 |
|---|
| 空壳检测 | ❌ | ❌ | ✅ |
| 断链检测 | ✅ | ✅ | ✅ |
| 内容密度 | ❌ | ❌ | ✅ |
| 知识网络 | ❌ | ❌ | ✅ |
| 可视化报告 | ❌ | ❌ | ✅ |
| 自动修复 | ❌ | ❌ | ✅ |
| 多平台支持 | 只Obsidian | 只Logseq | ✅全平台 |
性能预期
| 文件数量 | 预估时间 | 内存占用 |
|---|
| < 100 | < 3秒 | < 50MB |
| 500 | < 10秒 | < 200MB |
| 1000 | < 20秒 | < 500MB |
| > 5000 | 建议分段扫描 | 按需分配 |
实战案例
案例1:知识库全面体检
用户:"检查一下我的知识库健康度"
→ 执行:health_check.py ~/.openclaw/workspace/memory
→ 结果:640个文件,健康分56.4
→ 发现:12个空壳文件、8个断链、15个孤立节点
→ 生成:health-report-20260418.html
→ 动作:浏览器自动打开报告
案例2:修复断链
用户:"我的知识库有很多断链,帮我修复"
→ 执行:report_generator.py → auto_fix.py
→ 生成:auto-fix-20260418.sh(包含8个sed命令)
→ 动作:用户审查后执行bash auto-fix-20260418.sh
→ 结果:8个断链已修复
案例3:定期检查(Cron集成)
用户:"每周日自动检查知识库"
→ 配置cron:0 9 * * 0 /path/to/health_check.py
→ 输出:发送到飞书或邮件
→ 效果:知识库质量持续监控
常见问题FAQ
Q: 扫描很慢怎么办?
A: 可能原因:1) 文件数量太多(>5000),建议分段扫描;2) 文件很大(>5MB),建议单独处理;3) 磁盘IO瓶颈,建议用SSD。
Q: 报告打不开怎么办?
A: 1) 检查浏览器是否支持HTML5;2) 检查文件路径是否正确;3) 检查是否有权限问题;4) 尝试其他浏览器。
Q: 修复脚本执行失败怎么办?
A: 1) 检查是否在正确目录执行;2) 检查文件是否存在;3) 检查是否有权限;4) 手动review脚本内容后再执行。
Q: 如何排除某些目录?
A: 在SKILL.md的"错误处理与边界条件"章节有详细说明,可以在命令行传入exclude_dirs参数。
Q: 如何自定义空壳文件阈值?
A: 默认200字符,可以通过min_chars参数调整。例如:min_chars=100(更宽松)或min_chars=500(更严格)。
最后
你的知识库像花园。
不只是除草,还要修剪、施肥、规划新的花坛。
检查是手段,健康是目的。