zhuzhaoyun/molio/wiki-build
Claude Code and agent skill by zhuzhaoyun/molio
- community
Checking that the SKILL.md file is still in the repository.
构建/重建本地知识库的 Wiki。扫描 vault 中所有源文件,从中构建一个结构化的 wiki(源文件摘要、实体、概念、对比、概述页),创建分层 INDEX(根索引 + 各目录索引)/log/hot,密集交叉链接。支持超长源文件(百万字级小说等):prep.mjs 确定性预处理 + 分层 digest 构建 + 断点续传。开工前先侦察源文件:扫描版走 OCR、电子版直接抽文字,**电子版文字层被坏字体污染**(方正书版把数学斜体字母映射成不相干汉字)则先用 fontmap.py 清洗——三类管线完全不同,选错代价极大。支持含图源文件(扫描版教材、PPT、带插图的 PDF/论文):docling 抽图 → media.mjs 归置与规范化 → 页面内 ![[ ]] 嵌入 → 图版对账。也能把旧单索引库的索引重构为分层布局。Triggers on: 构建 wiki, 重建 wiki, build wiki, 扫描源文件构建, 初始构建, 重新构建知识库, start wiki build, 重构索引, 索引分层, 索引迁移, restructure index, 图片入库, 图版, 插…
Install
npx vskill@latest install zhuzhaoyun/molio/wiki-buildSKILL.md
wiki-build: 构建 Wiki
wiki 不是一次性的输出,而是一个持续增长的复利资产 — 每次构建、导入、查询都会让它更丰富。
维护注记:wiki-* 五件套(build/query/ingest/save/lint)同版本号共进——改任一 skill 时,五个version:一起 bump 到同一下一个版本;同一 PR(或一次对外发布)内的连续修订只 bump 一次。
核心原则
- 源文件不可变:源文件(notes/、docs/ 等)是用户的原始资料,只能读取,绝对不能修改或删除。
- 密集交叉链接:[[wiki 链接]] 是这个知识库的核心价值。每个页面都应大量链接到其他相关页面,形成知识网络。宁可多链接,不要少链接——但只链接最终页面集合里存在的页面:没有页面的名字在正文中一律用纯文本(或先建 stub 页再链)。收尾对账(deadcheck/linkpass,见"链接对账"节)机械保证零死链、零漏链。
- 图是内容,不是附件:源文件里的图形承载的信息常常无法用文字替代(几何关系、函数形态、解剖结构、电路拓扑)。建页时必须把图归置到 `wiki/images/`、用 `![[ ]]` 引用、并看图写准 caption;丢了图,页面就只剩空话。图版与页面受同等强度的对账门禁约束。
- 合成而非搬运:wiki 不是源文件的简单摘要集合,而是要提炼出跨源文件的综合观点、论点和洞察。
- 结构化元数据:每个页面必须带完整的 frontmatter,这是知识网络可查询、可审计的基础。
- 加粗书写规范(CJK):
**加粗**的首尾要紧贴文字,别让括号/引号/逗号等标点落在加粗边缘、外侧又紧贴汉字——**生态位(萝卜坑)**的分配(闭合侧失效)、甲**「重点」**乙(两侧都失效)这类写法会被 CommonMark 渲染器判定加粗失效、**按字面显示(中文没有空格,极易踩中)。改法:调整语序让加粗首尾都是文字;或在贴标点的那一侧补半角空格,把标点和外侧汉字隔开——闭合侧失效在闭合**后补(**生态位(萝卜坑)** 的分配),开启侧失效在开启**前补(甲 **「重点」** 乙),两侧都失效就两侧都补。
Vault 结构
vault 根目录就是当前工作目录。源文件在子目录中(如 raw/、notes/、docs/)。 wiki 相关内容的目录结构:
raw/— 未处理的原始资料目录raw/wechat/— 微信通道收到的网页、文件等原始资料统一先放在这里wiki/— 所有 wiki 页面的根目录wiki/INDEX.md— 根索引,只列目录级概览(各目录页数 + 覆盖范围)与概述入口页,不逐页罗列wiki/<dir>/INDEX.md— 每个内容目录(sources/entities/concepts/comparisons/questions)自己的索引,列全该目录页面及一句话摘要wiki/log.md— 按时间顺序记录的操作日志(最新条目在最上面)wiki/hot.md— 近期上下文缓存(~500 字,每次操作后刷新)wiki/images/— 图版根目录;每个含图源文件一个子目录(wiki/images/<源文件主名>/),图按文档顺序命名001.png、002.png…,整页兜底图为page-042.png。不参与页面索引与知识图谱(图谱只收.md),但会出现在文件树里wiki/meta/— 元数据目录(lint 报告等)wiki/sources/— 源文件摘要页,由 raw/、notes/、docs/ 等原始资料生成;不要把原始资料直接放入这里wiki/entities/— 人物、组织、工具等实体页wiki/concepts/— 概念、模式、框架等wiki/comparisons/— 对比分析页wiki/questions/— 归档的问答页
构建超长源文件时,确定性过程文件统一放 .molio/wiki-build/(文件树扫描会跳过 .molio,不污染 vault;跨会话可续传)。
页面路径规则:
- 默认使用单文件页面。文件名 = 实体/概念的规范名本身:中文内容用中文名直做文件名(如
wiki/entities/李白.md),英文内容用 kebab-case(如wiki/entities/molio.md)。[[wiki 链接]]的链接名必须与目标文件名(去掉.md)完全一致——[[李白]]对应李白.md,写成libai.md会断链 - 只有当某个实体、项目或主题需要拆成多个稳定页面时,才建立同名目录,并用
index.md作为该目录入口 - 同名目录下的子页面必须围绕该入口主题展开,例如
wiki/entities/molio/index.md、wiki/entities/molio/architecture.md - 不要把项目命名空间强行放进错误的内容类型目录;目录首先按页面类型归类,再按主题自然生长
Frontmatter 规范
每个 wiki 页面必须包含以下 YAML frontmatter:
字段说明:
type:页面类型,必须是以上值之一title:人类可读标题created/updated:创建和最后更新日期tags:领域标签列表(至少一个)related:相关页面的 [[wiki 链接]] 列表(尽量多填)sources:信息来源的 [[wiki 链接]] 列表(source 类型页面填原始文件名,其他类型填参考了哪些 source 页面)
页面类型说明
根据源文件的内容、规模和领域,自行决定最合适的页面类型。以下是参考:
- source(源文件摘要)— 每个源文件一个摘要页,提取关键信息,放在
wiki/sources/ - entity(实体)— 人物、组织、工具等命名实体,放在
wiki/entities/ - concept(概念)— 关键概念、想法、模式、框架,放在
wiki/concepts/ - comparison(对比)— 相关概念或方法之间的对比分析,放在
wiki/comparisons/ - overview(概述)— 当源文件较多(≥5 篇)且跨多个主题时创建,提炼跨源文件的核心论点
目录结构应从内容中自然生长,不要强行套用固定模板。如果源文件只有几篇且主题集中,扁平结构就够用。
建页粒度
哪些实体建页、建什么样的页,按信息落点判断,不按实体类别。判据只问三个结构量,与语料领域无关——同一套规则适用于小说、史书、技术文档、论文任何语料;不要按"某类东西该建/不该建"的领域直觉分类(人物/地点/器物/概念在各自语料中的重要度完全不同,预置类别会把管线锁死在一种语料上):
- 覆盖深度:它出现在几个独立区段/章节(跨度)。可机械统计(census/segments)。
- 独立信息量:去掉它,已有页面是否仍能完整表达同等信息。若它的全部内容可并入一句描述 → 没有独立落点。
- 引用需求:其他页面是否把它的名字当作讨论对象、而不是行文背景来提及(判法见下)。
分三档:
完整页(任一满足):
- 出现在章节标题/目录中(强信号,必有内容可写)
- 能用
grep -nF 名字取到足够上下文写出有实质内容的独立描述(首次出现 + 身份归属 + 至少一个关键事件/关系),且跨度≥2 区段。跨度=1 的内容通常不足以当独立页——除非它承载了不可并入其他页的关键信息。
stub 页(内容撑不起完整页,但有引用需求):
- 格式:完整 frontmatter +
stub: true标记 + 一句话身份定性(必须 grep 取证,不靠记忆)+ 关键关系链接,3-8 行即可 - 判据只有一个:其他页面会主动链接它(它是文本中反复被"讨论"的话题,即使篇幅小)。判断方法见下一节"讨论对象 vs 背景挂点"。
- 图谱/问答链路需要这些中间节点(别处提及时钟链到它);缺了就是死链或漏链。
不建页(噪音):
- 通用词、尊称、无名字的泛称("某某的娘""某某家的"这类)→ 收纳进相关页的一句话或概念页表格行
- 仅作行文背景、不被讨论的名字(判据见下)→ 正文出现用纯文本,禁止建页、禁止在正文中以
[[ ]]出现 - 判定启发式:跨度=1 且内容可并入其他页面的一句话 → 不建页(信息已被承载,单独立页是重复,只会产生一张空洞的 stub 图)
讨论对象 vs 背景挂点(领域无关的二元判据)
对正文里每个候选名字的每一处提及,问:它是被"讨论"还是被"用作背景"?
- 讨论对象:句子以它为主语/宾语在陈述它的属性、行为、关系("X 在 N 处做了某事,因其 Y 而被 Z 所知";读者查它是因为它本身构成话题)。此类提及即使零散,也指向实体。
- 背景挂点:它只出现在方位/工具/附属语境里,删掉或换成泛指后句子语义不变("某事发生在 P 处""用 T 完成了……""安置于 Q"——P/T/Q 是描述其他实体的背景,读者查的是句子的主体而不是它)。
同一句话里两者可并存("发生在 R 的那个事件"——R 是背景;"事件本身"是讨论对象)。逐处判定时要看这句话的语义中心,不是按候选名所属的领域类别划分。拿不准时用删除测试:把该名字从所有出现处换成纯文本/泛指,若任何页面的可读性都不受损 → 背景挂点,不建页;若某处去掉后话题悬空(读者会问"它到底是谁")→ 有引用需求,建 stub 都值得。
不同源文件的粒度不同,按各自内容特征独立判断。census 频率是排序信号,不是建页阈值。建了 stub 不代表必须留着:收尾时对入度=0 的 stub 做孤儿审计(见步骤 3),确认是背景挂点误建就删除/降级为纯文本。
索引分层结构(根 INDEX + 各目录 INDEX)
索引固定分两层:根 INDEX 只给目录级概览(与页面总数解耦,始终几十行),每个内容目录有自己的 INDEX.md 列全该目录页面。检索层层递进:根 INDEX → 相关目录 INDEX → 页面。根索引若逐页罗列,页面一多就会长到 runtime 一次读不完(Read 上限 2000 行),整个问答链路随之失效——这是分层的原因,不要因为"库还小"而退回单索引。
根 `wiki/INDEX.md` 格式:
各目录 `wiki/<dir>/INDEX.md`(sources / entities / concepts / comparisons / questions)格式:
规则:
- 概述页(通常 1-2 篇、全库入口)直接在根 INDEX 内联,不为 overview/ 单建目录索引
meta/是元数据目录(lint 报告等),不建索引、不列入根 INDEX- 目录 INDEX 列全该目录页面(wikilink + 一句话摘要);条目多时用
##子标题分组(sources 按主题、entities 按人物/组织/工具、concepts 按领域) - 目录索引统一大写
INDEX.md,与多页主题目录的小写index.md入口页区分 - 单目录索引几百行 Read 一次可读完,不做二次分片
索引分层迁移(已有 wiki)
存量库若是旧单索引布局(根 INDEX.md 直接以 - [[页面]] — 摘要 逐页罗列、内容目录无 INDEX.md),不重建页面、只重构索引:
find wiki/ -name '*.md'一次,建「页名 → 所在目录」映射- 读旧根 INDEX.md,每条页面条目按映射分流写入对应目录的 INDEX.md(保留原摘要;条目多则
##分组) - 根 INDEX.md 按上节分层格式改写(概述条目内联,其余目录各一行:目录链接 + 页数 + 覆盖范围)
- log.md 记一条
index | 索引分层迁移
触发:用户说「重构索引 / 索引分层 / 索引迁移」。过程幂等——目录索引已存在即跳过。wiki-ingest / wiki-save 在旧布局库上首次触发时也会自动执行本流程(见各自 SKILL.md)。
wiki/log.md 格式
最新条目在最上面:
超长源文件处理(prep + curation + 建页 + 对账)
源文件若无法在一次上下文内通读(通读后还要留空间规划+生成+交叉链接),不能按"读全文→语义识别"抽取实体,必须走本节的管线:确定性预处理把机械活(转码、切章、频率普查)做完,agent 只做语义工作(curation 审核、取证、撰写、链接)。
判断超长:wc -c 源文件 > 1.5MB(约 50 万中文字),或 Read 工具一次读不完(默认上限 2000 行)。未超长的源文件直接通读建页,不必走本管线。
步骤 0:断点检查 + 构建权(每次进入必做)
- 若已有
curation-<x>.tsv/batches/:这是续传——不要重跑 prep/curation,直接从断点继续建页。 - 同一 vault 一次只允许一个构建会话。label 用 "build-<源文件主名>-<日期>" 固定,整个构建过程(含断开续传)都传同一 label。异 label 锁 → exit 1,不要抢。
- 构建结束时:
build-lock.mjs release "build-<x>-<日期>" --vault .
步骤 1:预处理(确定性,零 LLM)
- profile 选择:prep 自动检测(检测到章节结构会选
novel并在 stderr warnings 注明);你若通读源文件开头后判断不同(如它其实是访谈实录/史料),用--profile default覆盖。自定义 profile 可放scripts/profiles/*.json。注意:若 prep 回退到 default 且 candidates 为 0,说明 profile 不匹配——必须定制 profile 而非继续。 - 编码:GBK/Big5 等自动探测转码;若 warnings 报有损解码或 PUA 字符,用
--charset指定后重跑。 - 产物(
.molio/wiki-build/):transcode-<x>.txt(行号稳定地址)、segments-<x>.json(分段+范围)、census-<x>.json(频率普查+别名线索)
步骤 2:L1 章节 digest(覆盖全文)
每个处理范围(segments.json 的一个 range,≤15 万字)派一个 subagent,只 Read 自己范围的行号区间,输出 digests/R###.md(实体+定性+事件+行号+别名线索)。digest 文件落地 = 该范围完成的唯一信号。主 agent 不通读全文。
步骤 3:curation(信息落点判据,脚本预填 + agent 审核)
这是整条管线的核心决策环节——决定建哪些页、什么类型、怎么分批。
批次 TSV 格式(制表符分隔,每行 5 列):
agent 审核时做什么(脚本做不了的语义判断):
- 按「建页粒度」的信息落点判据筛选:删噪音、删背景挂点、保留有引用需求的
- 按主题分组(
# cat=帝系/# cat=概念与制度页等)——批次即类型标签 - 每行标注
页类: entity或页类: concept - 补全别名(从 census.aliasHints / digest 中认领)
- 补全证据行号(代表性行号,不是全量)
3b 必须分块审核、边审边落盘(硬规则):草稿动辄数百行(长篇一次 ingest 可产出 600+ 实体行),禁止在一次回复里生成完整的 curation TSV——超大单次生成会撞 32k 输出上限,且长时间无输出会被 daemon 的 idle watchdog 判定挂起而终止 run(2026-10-22《封神演義》ingest 事故正是停在这一步:agent 试图一口气审核全部草稿,模型请求挂死 20+ 分钟)。正确做法:
- 可先通读草稿定下
# cat=分组方案(只输出分组规划,不写行) - 行落盘必须分块:每块 ~30-50 行,审完立即追加写入
curation-<x>.tsv(首块 Write 建档,后续用 Bashcat >>或 Edit 追加;组头# cat=随该组首块写入) - 每块写完即继续下一块,不要攒到"最后统一输出"
- 全部写完后核对:curation TSV 的有效行数 + 明确删除数 ≈ 草稿行数,缺口即漏审
脚本预填做什么(机械部分,agent 不需花 token):
- 按 count 排序、过滤低频噪音
- 预填唯一匹配的别名
- 预填证据行号(census 有则填,无则留空)
批次规模:留白为主(按主题自然分组),脚本兜底(单批超 15 条自动拆分)。
步骤 4:建页(每批一个 subagent)
每个批次派一个 subagent,读批次 TSV 该批行 + transcode 取证 → 写 drafts/<名字>.md。
- 一个 subagent 只做一批,即读即写,不要预先规划多个批次(防 32k 输出上限)
- prompt 按
页类给模板:concept 页写综合论述,entity 页写身份+事件+关系 - 建页 agent 只能链接批次 TSV 里出现的名字(白名单),清单外用纯文本
- 高频名取证封顶:首现 + 均匀采样,总量 ≤30 条
- 并发 ≤5-6 个 subagent(防 API 429 限流);完成度以磁盘落盘为准,不信通知
- 全部批次完成后跑落盘对账门禁(硬性,exit 1 即中止):
``bash node "<skill_dir>/scripts/verify-drafts.mjs" <x> --vault . ``
- 校验批次 TSV 声明的每个名字在
drafts/有对应文件且非空 - 治"subagent 输出超限被截断后静默缺失"和"报告写了卫青、文件实际不存在"——超限与漏写最终都表现为"批次声明了但没落盘",一个门禁统一定位
- 缺页 → 补建后重跑,直至 exit 0
步骤 5:安置(确定性,零 LLM)
- 按批次 TSV 的
页类列分发:entity →wiki/entities/,concept →wiki/concepts/ - 生成/更新对应目录的 INDEX.md(摘要自动提取)
- 幂等可重跑;中途打断后续传只需重跑 place
步骤 6:对比页策划(主 agent 创作,数量不固定)
实体/概念页安置完成后,主 agent 从已建页面中识别值得横向对比的主题,写 comparison 页到 wiki/comparisons/(由主 agent 直接写,不派 subagent——数量少、需全局视野,subagent 没有这个上下文):
- 数量由知识网络结构决定,不设固定数:有多少值得对比的主题就写多少——有天然对比关系(同类的并置、竞争、沿革、对立)才写,宁缺毋滥;没有就不写。不同语料的对比主题多寡差异很大,以实际建出的页面网络为准,不预设数量。
- 判断标准:两个及以上实体/概念之间存在可比维度(成败、风格、制度沿革、思想对立),且对比本身能产出超越单页的新洞察——单纯罗列不是对比,不写。
- 每页带完整 frontmatter(
type: comparison)+ 交叉链接到被对比的页面,并更新wiki/comparisons/INDEX.md。 - 这一环节是 agent 的收尾创作,不是从 census 候选筛出来的,所以不在批次 TSV 里。
步骤 7:链接对账(硬性门禁,exit 0 才算通过)
linkpass --batches:从批次 TSV 的别名列读取别名映射,把每个页面名/别名在其他页面正文中的首次出现包成[[ ]]。庙号/别名死链在这一步自动消解(如"项王"→[[项羽|项王]])。每次运行还会顺手机械清理旧版遗留的[[T|Y]]Y]]双重包裹残渣(→ 纯文本Y;代码块/引文/frontmatter 内的原样保留),防止残渣随页面拷贝自我复制- CJK 词中防护:≤3 字的中文名/别名前后都紧贴汉字时视为词中子串,跳过不包(宁可漏链,不可错链——"心理"在"核心理念"里不包,"网络"在"神经网络"里不包)。页面名也不例外:
[[网络]]能正常解析,包错地方 deadcheck 看不出来,是静默损坏。注意:跳过的是该名字在本页的唯一链接机会(只包真首次出现),不是只跳过这一处。要恢复旧的全量包裹行为加--no-cjk-guard - 前缀缺口 → `wiki/.linkpass-compounds.json`:上面那条要求前后都是汉字,所以当名字后面跟汉字、前面是空格或标点时会失效——
第六章 平面向量被包成[[平面]]向量、,对数学被包成[[对数]]学。这属于「名字是更长词的前缀」。通用解法需要一张汉语虚词表,而虚词表会误伤大量正常链接([[平面]]内的点是对的)。折中办法是由 vault 自报:在wiki/.linkpass-compounds.json里列出实际踩过的对——
``json { "对数": ["学"], "平面": ["向"] } ` (名字 → 其后不该切断的字)。file 存在则 linkpass 自动读取、叠加到现有防护上,零误伤;不存在则行为与从前完全一致。 **怎么知道该加什么**:收尾时扫一遍 [[X]]Y` 形态(X 是 ≤3 字中文名、Y 是汉字)逐条人工判断;或留意建页 agent 的回报——实测一轮里多个 agent 各自撞上并手工改过同一类错链
- 别名与页面名撞名:页面名优先(
[[网络]]本就解析到网络.md),撞名别名不会包成链接,会计入运行报告的collidedAliases——curate 时应把这类别名改掉 deadcheck:exit 0 才算通过。有死链 → 补页或改写链接,重跑直至 exit 0;检出包裹残渣只报告不阻断(下次 linkpass 会自动清理)。代码块里的[[...]]是字面文本,不算死链也不参与清理;代码块/引文/frontmatter 内的残渣单独标注(residueProtected),linkpass 不会动它们,需要时手工清理。引文与 frontmatter 里的死链照常拦下(这些区域渲染时链接仍然生效),而这些区域所有自动工具一个字都不能动(要供prep.mjs verify逐字节核验),所以命中时的唯一出路是补一个页面——哪怕只是占位 stub
步骤 8:引文核验(确定性,零 LLM)
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingapps/daemon/src/tools/skills/wiki-build/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/zhuzhaoyun/molio/wiki-build)