本文是「LLM Wiki 实战」系列第 2 篇。
上一篇:新手入门全流程 ------ 跑通了安装到问答的完整闭环。
本篇用一批真实的行业报告,演示如何从「一堆 PDF」变成「一个能跨文档问答、能看图谱聚类的知识库」。
一、为什么用真实数据演示
入门篇用的是抽象步骤,真正检验一个知识库工具的价值,要看它在真实、专业、跨文档的资料上表现如何。本篇的案例数据是一组火电机组深度调峰的技术报告(共 6 份 PDF):
| # | 文件 | 主题 |
|---|---|---|
| 0 | 项目技术报告 | 总体综述 |
| 1 | 锅炉水动力安全监控系统专项研究报告 | 水冷壁水动力稳定性 |
| 2 | 汽轮机及热力系统调峰安全监控系统专项研究报告 | 转子热应力 / 寿命损耗 |
| 3 | 锅炉低负荷稳燃监控系统专题研究报告 | 燃烧稳定性 / 投油助燃 |
| 4 | 深度调峰机组寿命影响研究 | 疲劳 / 蠕变 / 寿命评估 |
| 5 | 机组调峰多目标综合评估系统专题研究报告 | 经济性+安全性+环保性多目标 |
这批数据很适合拿来压测 LLM Wiki,原因有三:
- 跨文档关联强 ------ 「深度调峰」这个概念同时出现在锅炉、汽轮机、寿命三份报告里,且各有侧重。RAG 会每次重新检索拼接;LLM Wiki 应该把它们汇成一个
deep-peak-shaving概念页,并标注各来源。 - 专业术语 + 公式 + 表格密集 ------ 能检验 PDF 解析(pdfium)、KaTeX 公式渲染、表格结构化提取的真实表现。
- 存在天然知识空白 ------ 比如这批报告偏「安全/寿命」,对「调峰对环保排放的影响」着墨很少,正好演示「知识空白检测 → 深度研究补全」。
二、第一步:写 purpose.md ------ 给知识库一个灵魂
创建项目时选「研究」模板,然后认真填写 purpose.md。这个文件会被 LLM 在每次摄入和查询时读取,直接决定它怎么归类、怎么取舍。一个填得好的 purpose:
markdown
# Project Purpose
## Goal
构建火电机组深度调峰运行的安全性、寿命与综合评估知识库,
支撑调峰运行方案优化与风险评估。
## Key Questions
1. 深度调峰下锅炉水动力失稳的诱因与边界条件是什么?
2. 汽轮机转子在频繁启停/变负荷下的寿命损耗如何量化?
3. 低负荷稳燃的关键约束与投油策略如何权衡经济性?
4. 如何对调峰运行进行多目标(安全/寿命/经济/环保)综合评估?
## Scope
**In scope:** 锅炉、汽轮机、寿命、综合评估
**Out of scope:** 电网调度策略、新能源耦合
## Thesis
> 深度调峰的安全性瓶颈在「水动力稳定性 + 转子热应力」,
> 寿命瓶颈在「低周疲劳」,经济性受「投油成本」主导。
关键点:
purpose.md是「为什么」,schema.md是「怎么组织」。前者给方向,后者给规则。很多人只用 schema 不写 purpose,LLM 就缺少判断「哪些该深挖、哪些该略过」的依据。
三、第二步:让 schema 映射到这个领域
默认 schema 提供了 7 种页面类型。在这个火电案例里,它们自然落地为:
| 页面类型 | 在本案例中的含义 | 示例文件 |
|---|---|---|
| entity | 设备 / 系统 / 机构 | water-wall.md(水冷壁)、steam-turbine-rotor.md(汽轮机转子) |
| concept | 技术机理 / 方法 | deep-peak-shaving.md、low-cycle-fatigue.md(低周疲劳) |
| source | 每份报告的摘要 | boiler-hydrodynamic-safety-report.md |
| comparison | 并列对比 | peak-shaving-cost-comparison.md |
| synthesis | 跨报告综合 | life-assessment-synthesis.md |
| query | 开放问题 | does-low-load-combustion-limit-depth.md |
命名遵循 schema 的 kebab-case.md 规范,实体尽量贴合专业术语,概念用描述性名词短语。这一步不用手动建,只是理解 LLM 会按这个结构生成。
四、第三步:导入 6 份报告
把 6 份 PDF 放进一个文件夹(建议按 火电调峰/锅炉、火电调峰/汽轮机 这样分子目录),然后在 资料源 面板用「导入文件夹」。
这里有几个值得知道的技术细节:
- 文件夹路径会作为分类上下文传给 LLM 。比如
火电调峰/锅炉/水动力报告.pdf这个路径,LLM 会拿到papers > energy > boiler这样的层级提示,帮助它把摘要归到锅炉主题下。这是比「扁平导入」更聪明的做法。 - SHA256 增量缓存:摄入前先算源文件内容哈希,没变过就跳过,省 token 也省时间。第二次导入同一批文件几乎是秒过。
- 串行 + 持久化队列:摄入是严格串行的,避免并发 LLM 调用互相覆盖 wiki 文件。队列落盘,崩溃/重启后自动恢复,失败任务重试最多 3 次。
- 15 分钟超时:长 PDF 的两步摄入可能要几分钟,超时设得宽,不会过早判失败。
解析层面:PDF 用内置的 pdfium(Rust 侧 pdfium-render),表格/公式密集的可选 MinerU 云端解析;失败会自动回退本地解析。
五、第四步:解剖摄入产物
摄入完成后,你的项目目录会长成这样(基于 schema 规则的预期结构):
my-wiki/
├── purpose.md
├── schema.md
├── raw/
│ └── sources/ # 6 份原始 PDF(不可变)
├── wiki/
│ ├── index.md # 内容目录(LLM 每次摄入更新)
│ ├── log.md # 操作时序日志
│ ├── overview.md # 全局概要(每次摄入后重生成)
│ ├── entities/
│ │ ├── water-wall.md # 水冷壁
│ │ ├── steam-turbine-rotor.md # 汽轮机转子
│ │ └── economizer.md
│ ├── concepts/
│ │ ├── deep-peak-shaving.md # 深度调峰(横跨多份报告)
│ │ ├── low-cycle-fatigue.md # 低周疲劳
│ │ └── hydrodynamic-instability.md
│ ├── sources/ # 6 份报告各一个摘要页
│ ├── queries/
│ └── synthesis/
└── .llm-wiki/ # 聊天历史、审核项、配置
每一个生成页都带可追溯的 frontmatter。一份报告摘要页(source)长这样:
yaml
---
type: source
title: 锅炉水动力安全监控系统专项研究报告
authors: []
year: 2024
url: ""
venue: ""
tags: [锅炉, 水动力, 调峰, 安全]
related: [[hydrodynamic-instability], [water-wall], [deep-peak-shaving]]
sources: [raw/sources/锅炉水动力安全监控系统专项研究报告.pdf]
created: 2026-07-07
updated: 2026-07-07
---
sources: [] 字段是来源可追溯的关键------删除某份原始 PDF 时,系统靠它做级联清理(见系列第 4 篇)。
index.md 会按类型分组汇总,每条一行带 [[wikilink]]:
markdown
## Entities
- [[water-wall]] --- 水冷壁,水动力稳定性关键受热面
- [[steam-turbine-rotor]] --- 汽轮机转子,热应力与寿命核心
## Concepts
- [[deep-peak-shaving]] --- 机组出力降至额定 30%~40% 以下的运行方式
- [[low-cycle-fatigue]] --- 启停循环导致的转子疲劳损耗
log.md 是可解析的时序记录,前缀统一格式,用 grep "^## \[" log.md | tail -5 就能取最近 5 条操作------这是个为脚本化设计的细节:
markdown
## [2026-07-07] ingest | 锅炉水动力安全监控系统专项研究报告
- 新增 source: boiler-hydrodynamic-safety-report
- 新增 entity: [[water-wall]]
- 更新 concept: [[hydrodynamic-instability]](补充了质量流速边界)
- 标记审核项:水动力失稳阈值与报告3表述存在张力
注意最后一行------LLM 在摄入时就主动标记了两份报告间的矛盾,丢进审核队列等你判断。这是两步摄入的「分析步」产出,下一篇会展开。
六、第五步:跨文档问答
现在来问几个真正需要综合多份报告的问题。
问题 1:深度调峰对锅炉和汽轮机的安全影响,分别有哪些关键约束?
LLM Wiki 的回答会带 [1] [2] [3] 编号引用,分别指向 deep-peak-shaving、锅炉水动力报告摘要、汽轮机报告摘要,并在引用面板里按类型分组展示用到了哪些页面。关键是------这些页面在摄入时已经建好并交叉引用了,查询时是「读取 + 综合」,不是「现检索现拼」。
问题 2:频繁启停导致的转子寿命损耗,主要机理是什么?如何量化?
这个问题横跨报告 2(汽轮机)和报告 4(寿命研究)。LLM 会命中 low-cycle-fatigue 概念页(它本身就被两份报告共同贡献),给出带公式(低周疲劳寿命公式,L-M 或 Manson-Coffin)的综合回答,KaTeX 渲染 $$...$$。
问题 3:把这批报告里提到的所有「调峰运行约束」整理成一张对比表。
LLM 可以直接生成 Markdown 表格,你也可以把这类高价值回答保存到 Wiki (wiki/queries/),它会进一步抽取其中的实体/概念进知识网络------一次问答的成果就此沉淀,下次能被复用。
七、第六步:图谱聚类与知识空白
切到知识图谱面板。6 份报告 + 抽取出的实体/概念,会自然聚成几个社区(Louvain 算法按链接拓扑自动聚类):
- 一个「锅炉侧」社区:水冷壁、水动力稳定性、低负荷稳燃、投油策略
- 一个「汽轮机侧」社区:转子、热应力、低周疲劳、寿命评估
- 一个「综合评估」社区:多目标评估、经济性、安全性指标
社区按内聚度评分,内部交叉引用薄弱的(< 0.15)会被标警告------提示你这块知识还没被充分串联。
知识空白检测会主动指出:
- 孤立页面:某个被提取出的实体(如「省煤器」)只有 1 个连接,说明它被提到但没展开
- 桥接节点 :
deep-peak-shaving连接了 3+ 个集群,是关键枢纽 - 稀疏社区:综合评估社区内聚度低,方法之间缺交叉引用
八、第七步:用深度研究补全空白
发现「调峰对环保排放的影响」这块在这批报告里几乎空白时,点知识空白卡片上的 Deep Research 按钮。LLM 会读取 overview.md + purpose.md,生成领域精准的研究主题和搜索查询(不是泛泛的「调峰 环保」),弹出一个可编辑确认框:
研究主题:深度调峰对 NOx/SO₂ 排放的影响及低负荷脱硝瓶颈
搜索查询:
1. "deep peak shaving" NOx emission low-load SCR
2. 燃煤机组低负荷 脱硝 催化剂 温度
3. ...
你确认后,它通过 Tavily / SerpApi / SearXNG 联网搜索,把结果综合成新的 Wiki 研究页,并交叉引用已有的 deep-peak-shaving 等页面,最后自动走一遍两步摄入,把新实体/概念吸进知识网络。知识库就这样自我补全。
九、小结
走完这一遍,你应该能体会到 LLM Wiki 相对 RAG 的本质优势:
- 知识是编译好的,不是现检索的 ------ 跨文档综合在摄入时就完成了
- 矛盾被主动标记 ------ 不用你逐份比对
- 图谱暴露结构 ------ 哪块串联了、哪块空白,一目了然
- 能自我补全 ------ 发现空白 → 联网研究 → 自动入库
purpose.md 写得多认真,LLM 的归类和取舍就有多准------这是本篇最想强调的一点。
下一篇我们深入四个杀手锏的实现:知识图谱的四信号关联度与 Louvain 社区检测、MCP Server 如何把 Claude Code 接进你的知识库、深度研究的主题生成机制、两步思维链摄入的内部流程。
案例数据 :
shuju/目录下的 6 份火电深度调峰报告 PDF系列下一篇:[亮点功能深挖 ------ 图谱 / MCP / 深度研究 / 两步摄入](#亮点功能深挖 —— 图谱 / MCP / 深度研究 / 两步摄入)