完整解析LLM Wiki Lint结构检查器:矛盾、孤儿、缺失全揪出来的源码拆解
【免费下载链接】llm_wikiLLM Wiki is a cross-platform desktop application that turns your documents into an organized, interlinked knowledge base — automatically. Instead of traditional RAG (retrieve-and-answer from scratch every time), the LLM incrementally builds and maintains a persistent wiki from your sources。项目地址: https://gitcode.com/GitHub_Trending/ll/llm_wiki
LLM Wiki 是一款跨平台桌面应用,能自动把文档变成互相链接的知识库。它的Lint 结构检查器就像给知识库做"体检":孤立页面(Orphan)、失效链接(Broken Link)、无出链页面,乃至 LLM 才能发现的内容矛盾,一次全揪出来,还能一键修复。本文带你从源码层面看懂这套检查器是怎么工作的。
Lint 检查器能查出哪些问题?
LLM Wiki 的检查分为两层,对应四类问题:
| 层级 | 问题类型 | 说明 | 严重度 |
|---|---|---|---|
| 结构层 | orphan孤立页面 | 没有任何其他页面链接到它 | 提示 |
| 结构层 | broken-link失效链接 | [[wikilink]]指向的页面不存在 | 警告 |
| 结构层 | no-outlinks无出链 | 页面本身没有引用任何其他页面 | 提示 |
| 语义层 | semantic语义问题 | 矛盾(contradiction)、过时(stale)、缺失页面(missing-page)、建议 | 由 LLM 判定 |
结果统一用LintResult结构承载,包含类型、严重度、涉及页面、描述,以及自动修复所需的建议目标页(src/lib/lint.ts):
结构检查:三步扫描 Wiki 目录
入口是runStructuralLint,流程很直接(src/lib/lint.ts):
- 读文件:递归遍历
wiki/目录,只处理.md文件,且排除index.md和log.md(它们本就不参与互链); - 抽取信息:每页解析出标题(frontmatter 的
title或第一个#标题)、所有[[wikilink]]出链、以及用于推荐候选的 token 集合(标题 + 正文前 4000 字符); - 后台计算:把数据丢给 Web Worker 执行核心算法 src/lib/lint-structural.worker.ts,避免大库检查时卡死界面。
核心算法computeStructuralLint在 src/lib/lint-structural-core.ts 中:
- 孤立检测:统计每页的"入链次数"(
inboundCounts),零入链即孤儿——但它同时给出suggestedSource,推荐"最该链接到它"的页面; - 失效链接检测:每个出链先归一化(去掉
wiki/前缀、.md后缀、统一小写),查不到目标即告警,并附上suggestedTarget候选页; - 无出链检测:
outlinks为空即标记,附suggestedTarget推荐该链接谁。
亮点:断链修复建议是怎么"猜"出来的
失效链接最有价值的不是报错,而是推荐正确目标。源码里藏着一套相似度引擎(src/lib/lint-structural-core.ts):
- 二元片段索引:把每个页面名拆成相邻双字串(bigram)建倒排索引,
transfomer能通过片段命中transformer,而不必逐页全量比对; - 编辑距离兜底:对候选用 Levenshtein 距离 + 归一化算相似度,同基名得分 0.96、包含关系 0.82,超过 0.74 才给出建议;
- 中文友好:NFKC 归一化让全角/简体变体等价匹配,单字 CJK token 降权 0.35,防止常见字误伤。
对应场景的测试也很有趣——attention页里写错成transfomer,检查器能精准推荐transformer.md(src/lib/lint-structural-core.test.ts)。
性能上同样下过功夫:5000 个页面要求 5 秒内完成,防止"所有页对彼此全扫描"的写法回潮(src/lib/lint-structural-core.test.ts)。
语义检查:让 LLM 找出结构层看不见的矛盾
结构层只能看"链接图",而内容矛盾需要理解力。勾选"语义检查 (LLM)"后,runSemanticLint会把每页的摘要(frontmatter + 前 500 字符)拼进 Prompt,让 LLM 以固定格式输出问题块(src/lib/lint.ts):
---LINT: contradiction | warning | 两个页面的版本描述冲突--- entities/a.md 声称 X,而 concepts/b.md 声称 Y…… PAGES: entities/a.md, concepts/b.md ---END LINT---用正则LINT_BLOCK_REGEX解析回LintResult,并做了一道防误报过滤:LLM 常把已经存在的页面误报为"缺失",missingPageAlreadyExists会对名称做 NFKC 归一化后精确比对,命中即丢弃(src/lib/lint.ts)——这是针对非英文 Wiki 的实战修正。
修复:从"发现"到"一键落地"
检查结果不是终点。在 src/components/lint/lint-view.tsx 中,每类问题都有对应修复动作,实际文本变换由 src/lib/lint-fixes.ts 完成:
| 问题 | 一键修复动作 |
|---|---|
| 孤立页面 | appendWikilink:在推荐页面的## Related下自动插入[[该页]] |
| 失效链接 | rewriteWikilinkTarget:把断链改写为候选页;找不到候选时ensureBrokenLinkStub自动建一个占位 stub 页 |
| 无出链 | appendWikilink:给页面补上最相关页面的链接 |
| 语义问题 | 转入"待审阅"队列,由人工决策 |
批量修复还有一个细节:多项问题若命中同一页面,会先在内存中依次应用所有文本变换,只写盘一次,避免互相覆盖(src/components/lint/lint-view.tsx)。删除孤儿页则走级联删除,连带清理向量块和全站引用。
检查规则可配置,按项目保存
点界面左上角的齿轮可打开规则面板,支持三个开关(src/lib/lint-config.ts):
- 不报告孤立页面
ignoreOrphan - 不报告无出链页面
ignoreNoOutlinks - 忽略页面清单
ignorePages:每行一个 slug 或路径,如archive/legacy-page
配置以 JSON 保存在项目内.llm-wiki/lint-config.json,随项目走。注意忽略清单按完整路径匹配:忽略顶层foo不会误伤archive/foo——这个边界在测试中有专门覆盖(src/lib/lint-structural-core.test.ts)。
上手建议
- 新建 Wiki 后先跑一次纯结构检查(不开语义),快速清理断链和孤儿,界面进度条可随时取消;
- 页面多起来后勾选语义检查,重点看
contradiction和stale警告; - 把确实不要管的页面加进忽略清单,保持结果列表干净;
- 善用"转入待审阅",把批量操作交给 Review 队列逐条确认,避免误改。
整套 Lint 源码集中在几个文件:检查主流程 src/lib/lint.ts、结构算法 src/lib/lint-structural-core.ts、界面与修复 src/components/lint/lint-view.tsx、状态管理 src/stores/lint-store.ts。读懂它们,你就掌握了 LLM Wiki 维持"互联知识库"健康的关键一环。
【免费下载链接】llm_wikiLLM Wiki is a cross-platform desktop application that turns your documents into an organized, interlinked knowledge base — automatically. Instead of traditional RAG (retrieve-and-answer from scratch every time), the LLM incrementally builds and maintains a persistent wiki from your sources。项目地址: https://gitcode.com/GitHub_Trending/ll/llm_wiki
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考