折腾 一段时间RAGFlow、Dify、LangChain RAG 后,我发现,在中小型项目或者个人知识库的角度来看,用 Karpathy 提的 LLM Wiki 方案远比RAG的效率高:不做查询时检索,而是在摄入时就让 LLM 把知识编译进一组持久演化的 markdown 页面,配合 Obsidian 做前端,又方便直观的整理和阅读知识,还有着ClaudeCode同款的检索机制,绕过RAG不可控也无法衡量边界的黑盒子(当然企业级大规模超大规模的知识库还是RAG加知识图谱上限更高)。
测试跑了两个仓库:
- DESI 暗能量光谱仪论文 wiki(约 30 份论文 + ICD)。
- OCS 望远镜观测控制系统代码 wiki(约 50 个 Python 文件 → 45 个解析页)。
这套思路对单领域、有边界、需要长期维护的知识库明显比 RAG 更顺手。下面把两种范式的差别、各自的适用边界、以及 Obsidian 上的具体配法整理一遍。
灵感来源是 Karpathy 的 gist:https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f,我在这个基础上加了 schema、frontmatter 漂移追踪、Obsidian 显示约定三块工程化补充。
1. 两种范式的本质差别
| 维度 | RAGFlow(RAG 流派) | LLM Wiki |
|---|---|---|
| 知识入库时机 | 查询时检索 chunk → 拼 prompt | 摄入时 LLM 写成 markdown |
| 知识载体 | 向量库 + 知识图谱(不透明) | 一组人能读的 md 文件 |
| 跨页引用 | 嵌入相似度 + 图算法 | [[wikilink]] 显式硬链 |
| 演化方式 | 重建索引 | git diff,逐页 patch |
| 检索质量上限 | 受 chunking + embedding 限制 | 受 LLM 摄入时的提炼判断限制 |
| 谁来"理解" | 查询时由 LLM 现场拼 | 摄入时已由 LLM 写定 |
| 失败模式 | 召回错或缺,答非所问 | 漂移:代码/论文改了 wiki 没跟上 |
一句话:RAG 是搜索引擎 + LLM;LLM Wiki 是 LLM 替你提前写好的、互相超链的笔记。 


如图为 RAGFlow 知识图谱页面,还有非专业根本看不懂的一堆参数,根本不会调,出错了也不知道哪里可以改进
2. LLM Wiki 的优势
2.1 知识是显式的、可审计的、可改的
每一条知识都对应一个肉眼就能读得懂的 markdown 段落。错了直接改,不用重训嵌入、不用 reindex。
比如我在 OCS 代码 wiki 里深读时发现 4 个源码 bug(如 Server.add_timer 漏写 self),直接写进 known-issues.md,几秒钟搞定。RAG 里"我希望知识库标记某段代码有 bug"基本不可能。
2.2 没有召回不准的问题
LLM 答问时读的是它自己之前写的 wiki,不是RAG切碎再嵌入的 chunk。术语、缩写、跨文档关联都在 [[wikilink]] 里硬连好。"召回失败"这个失败模式几乎消失不存在。
2.3 git 原生友好
每页一个文件,文本可读,diff 干净。多人协作可以走 PR review。RAGFlow 里改一条知识操作太复杂了,而我们熟悉的git 仓库里只是 vim + git commit。
2.4 知识自组织、自累积
每次摄入新资料,LLM 不仅写新的 source 页,还会合并进相关的 concept / subsystem 页。半年下来,concept 页就成了"团队对这个概念的共识沉淀"。RAG 是查一次拼一次,下次还得重拼(真特么费token啊)。
2.5 Obsidian 免费给你一个 GUI
Graph view、反链、全文搜索、frontmatter 过滤、Dataview 表格------这些 RAGFlow 要专门做产品才能提供,Obsidian 装个插件就有,而且非常漂亮直观。
2.6 调试容易
LLM 答错了?直接看它引用的页,改那一段。RAG 答错了?查 chunk → 看 embedding → 怀疑 reranker → 怀疑 prompt 模板,绕一大圈,还找不到问题,对我这种只会一点的初学者太不友好了。
2.7 同一份内容人和 LLM 都能用
我自己直接在 Obsidian 里翻 wiki 当复习材料甚至学习资料,LLM 把同样的文件当 context。一份内容两个消费者,没有冗余
2.8 作为学习助手
我可以把llmwiki作为学习助手,我能知道他的能力边界,可以主动的学习,可以和自己学习百科全书一样,具体可参考后文obsidian的界面配图,一目了然,对项目或者对过往经验有个大概的梳理,胸有成竹。RAG像一个黑盒子,纯靠自己摸索和提问,效率太差了
3. LLM Wiki 的短板
3.1 不适合规模化文档
经验上界大约 1000 个 md。超过这个量级,单个对话塞不下索引、维护成本爆炸、漂移检测跑不动。要做万级文档库,还是得用 RAG。
3.2 摄入成本会高一点
每份新资料都需要 LLM 跑一遍:读、提炼、写 source 页、更新相关页、改 index。一篇 30 页论文够烧几万 token。RAGFlow 那边就一次 embedding 调用。
3.3 没有"模糊语义检索"
如果某个概念你(或 LLM)摄入时没写,下次查就是死链。RAG 至少能从原文片段里翻出来。LLM Wiki 的覆盖率完全取决于摄入时的判断力。不过可以打标签,深读我觉得可以弥补一点
3.4 多人并发写容易冲突
git 合并冲突的老问题。如果团队里五个人同时改同一个 concept 页,需要规矩。RAGFlow 那边是中心化数据库,没有这层麻烦。
3.5 需要纪律
没 schema 的 LLM Wiki 半年就变成一堆杂草。必须强制模板(frontmatter / 标准页结构 / 命名约定),并定期 lint。我两个仓库的 CLAUDE.md 都用一整章定义 schema,就是这个原因。
3.6 不擅长流式更新
每天有新数据涌入的场景(日志、票务、客服记录)显然该用 RAG。LLM Wiki 适合有边界的、增长缓慢的知识域:论文集、代码库、产品手册、研究笔记。
3.7 漂移是头号风险
代码改了 wiki 没跟上,wiki 就在骗人。我用 frontmatter 里写 synced_commit: <短哈希>,lint 时用 git log <synced_commit>..HEAD --oneline -- <source_paths> 检测过期页。但这套机制需要纪律才跑得起来。
4. 什么时候选哪个
| 场景 | 选 |
|---|---|
| 个人读论文/代码笔记 | LLM Wiki |
| 小团队(≤10 人)的项目交接文档 | LLM Wiki |
| 单个开源项目的代码知识库 | LLM Wiki |
| 万级以上客服记录、企业内文档检索 | RAGFlow |
| 需要按用户角色做权限隔离 | RAGFlow |
| 日更/小时更的内容流 | RAGFlow |
| 知识来源是"我自己读过想沉淀的东西" | LLM Wiki |
| 知识来源是"未知的、需要被搜出来的" | RAGFlow |
混合也行:拿 RAG 做粗筛召回 → 召回结果触发一次 LLM Wiki 摄入 → 之后查问就走 wiki。但很多场景里这一步是过度设计。
5. 实战搭建:四步走
下面以代码知识库为例(论文版几乎一样,只是模板字段不同)。
5.1 目录骨架
my_wiki/
├── CLAUDE.md ← schema + 工作流定义(核心)
├── index.md ← 顶层入口
├── code-map.md ← 代码速查(要找 X 看哪里)
├── decisions.md ← 设计决策记录(ADR)
├── known-issues.md ← 已知问题与技术债
├── roadmap.md ← 路线
├── data/ ← 原始资料(论文 PDF / 代码快照),只读
└── wiki/ ← 所有 LLM 生成的页面
├── architecture.md
├── figures/ ← matplotlib 出的架构图
├── components/ ← 框架核心抽象(一类一页)
├── modules/ ← 每个目录/包一页
├── flows/ ← 关键执行流程时序
├── guides/ ← 使用 / 移植 / 部署
├── interfaces/ ← 模块间契约
└── glossary.md ← 术语表
5.2 CLAUDE.md:schema 是灵魂
CLAUDE.md 是给 LLM 看的工作指令,里面定义:
- 铁律 :
data/不可改,衍生内容只能写到wiki/。 - 页面模板:source/component/module/flow/guide 每类页的 frontmatter 字段与正文骨架。
- 跨页引用约定 :
[[wikilink]]用什么 slug。 - 摄入工作流:用户说"摄入 xxx" 时按 Step 1~6 怎么执行。
- 查询工作流:用户问问题时怎么定位、怎么避免直接 grep PDF。
- lint 工作流:定期检查孤立页、断链、漂移、frontmatter 缺失。
- 风格规则:中文为主、数字带单位、不写 emoji、不为对称凑字数。
没有这份 schema,LLM 每次摄入风格漂移,半年后 wiki 内部不自洽。
5.3 摄入工作流(最关键的一步)
比如我们指定说"摄入 data/paper/xxx.pdf"时,LLM 按顺序:
- 定深度:skim(前 3 页+结论)/ summarized(默认)/ deep(精读)。巨型 ICD 用 skim,核心论文用 deep。
- 读取 :PDF 超过 10 页必须分页读(
Read工具的pages: "1-5"等参数),按 abstract/intro/conclusion 分阶段。 - 写 source 页:严格按模板,关键参数、CID、规格必须带数字和单位。
- 更新相关页 :扫所有
[[wikilink]],已存在的合并新事实,不存在的建 stub。 - 更新索引 :
index.md加引用、glossary.md加新缩写。 - 写摄入备注:诚实记录"读了哪几章、哪些跳过、哪里没看懂",给未来 lint 用。
5.4 查询工作流
我们问问题时,LLM 的优先级:
- 先读
index.md和glossary.md定位主题。 - 顺
[[wikilink]]跳到 subsystem / concept / interface 页。 - 必要时回到 source 页看是从哪份资料提炼的。
- wiki 没覆盖时 才回去读
data/里的原始资料------此时本质是触发新一轮摄入,答完顺手把事实补进 wiki。
最后这条其实是核心:每次回答都能顺手积累知识,wiki 跟着对话越用越完整。
5.5 lint 工作流
定期跑(或用户说 "lint"),列表报告不擅自改:
- 漂移:source_paths 里有改动而 synced_commit 没更新。
- 断链 :
[[xxx]]但xxx.md不存在。 - 孤立页:没人链入。
- 矛盾:同一参数在不同页给出不同数字。
- frontmatter 缺失:source 页缺 type/year/source_path。
6. 配 Obsidian:必装三件套
6.1 Front Matter Title(必装)
Obsidian 默认侧栏显示文件名(slug),但我们 frontmatter 里写了 name: English (中文),希望侧栏显示中文。这个插件就干这事。
装法:Settings → Community plugins → Browse → 搜 "Front Matter Title" → Install + Enable。
启用后所有 frontmatter 里有 name: 字段的页,侧栏会显示 English (中文),没写的(如 CLAUDE.md)保持原文件名。
如果改了 frontmatter 后侧栏没刷新:Ctrl+P → 输入 Front Matter Title: Delete cache,或干脆重载库(Ctrl+P → Reload app without saving)。这是这个插件唯一的痛点。
6.2 Graph view(自带)
图谱视图是 LLM Wiki 的杀手锏:能一眼看出哪些页是中心节点(被很多页链入)、哪些是孤立的(没人链入)。
鼠标放到那个节点,清楚地看到都有那些关系(当然这更方便机器去寻找)
孤立点是 lint 的重点对象------要么链到主图谱里去,要么直接删掉。
比如我随便建了一个其他的文档,跟内容毫无关系就叫未命名

6.3 Dataview(推荐)
用 SQL 风格语法在页内动态生成表格,比手写 index 列表灵活。
例:在 index.md 里写
markdown
```dataview
TABLE year, status
FROM "wiki/sources"
WHERE type = "paper"
SORT year DESC
```
自动列出所有论文的摄入状态、年份,新增 source 页自动入表。
6.4 可选:Templates、Git、Excalidraw
- Templates:新建页时自动套用 source/concept 模板,省手敲 frontmatter。
- Git:在 Obsidian 内提交 / 拉取,不用切到终端。
- Excalidraw:偶尔手画架构草图比 matplotlib 快。
7. 风格规则(避免 wiki 变废稿)
总结我两个分别记录文档仓库和代码仓库个人感觉的一点经验:
- 中文为主,专有名词保留英文 :
BAO、focal-plane、NetworkNode这类不翻译,避免歧义。 - 数字必带单位 + 来源 :
焦距 3.2 m [[sources/desi-instrument-overview-2022]],不写"焦距大约三米"。 - 不复述源码/论文里显然的东西 :目标是提炼意图与架构,不是翻译摘要。
def __init__(self): pass不需要写"这是构造函数"。 - 区分"是什么"和"应该怎样" :解析页只记现状,改进建议放 guide 或
known-issues.md,不要混进解析。 - 不为对称凑内容:某节没东西就留空或删掉,不要编。"暂无"比编的强。
- 未实现的功能标注清楚:状态机里配了但代码没写的子系统,标"已规划未实现",不要假装解析过。
- 不写 emoji:博客可以,wiki 不行------干扰 grep、刺眼、显业余。
8. 两个仓库的实测
8.1 DESI 论文 wiki
-
原始资料:约 60 份论文 + 一批 ICD。
-
产出:sources 30 页 + concepts/subsystems/interfaces 约 40 页。
-
用法:我问"DESI 的焦面有几个 positioner、定位精度多少",LLM 直接读
subsystems/focal-plane.md答完,并附上[[sources/desi-overview-2022]]引用。如果该页缺这事实,它会回去翻 PDF 并把答案补进 wiki,下次直接命中。 并且,最主要的是他给了我学习的路径,比如我是项目经理或者小白的角色,我可以从路径A开始看起,

如果我是科学家,我可以从路线B开始看

如果是项目总工,可以看路径C

作为软件的具体开发者,我直接看D

还有多条路线,预览完知道自己怎么看效率最高,真的帮助很大
- 反例对比:之前用 RAGFlow 跑同样的资料,每次都得 chunk 召回,跨论文的概念关联(如"BAO 与 RSD 的差别")经常召回不全。
8.2 OCS 代码 wiki
- 原始资料:MUST 团队的望远镜控制系统代码
- 产出:8 components + 10 modules + 5 flows + 5 interfaces + 8 guides + 5 项目级文档 + 5 张架构图 = 45 个 md 文件。
- 用法:好长时间忘记代码了或者交接给同事可以直接读 wiki,不用啃源码。我深读时还发现 4 个未提交的 bug,全部记入
known-issues.md。有类似问题AI会直接提醒你类似的错误! - 漂移控制:每个解析页 frontmatter 里写
synced_commit: c317381,下次代码改了用 git log 检测哪些页 stale。
如图同一份 wiki 在 Obsidian Graph view 里的拓扑(能看出 architecture / network-node / messagebus 是高连接度核心节点)。
9. 常见问题
Q:摄入一次烧多少 token?
A:经验值:summarized 一篇 20 页论文约 5-10 万 token;deep 模式翻倍。代码模块按文件量算,OCS 一个 module(约 500 行)大约 2 万。Claude 配 Sonnet/Opus 跑都 OK,走订阅我感觉还行。
Q:能不能完全无人值守?
A:不建议。lint 报告必须人看一眼,摄入完最好抽检 source 页的关键数字。LLM 偶尔会写错数(尤其是 PDF 数字识别错位)不然后面会变屎山
Q:能多个 wiki 共用一份 CLAUDE.md 吗?
A:能,但建议每个 wiki 独立 schema。我 DESI 和 OCS 两个仓库的 CLAUDE.md 80% 一样,但模板字段差很多(论文有 arxiv/authors,代码有 synced_commit/source_paths),混用反而绕。
Q:Obsidian 必须用吗?
A:不是。底层就是一堆 md,VS Code / Typora / 直接 GitHub Web 都能看。Obsidian 只是体验最好的前端,特别是 graph view 和反链面板对 wiki 类内容增益最大。
Q:能跑在 Linux 服务器上让 LLM 自己摄入吗?
A:可以。我自己用 Claude Code CLI 跑本地摄入,但中央化部署一个"摄入 worker"完全可行------本质就是 LLM 调 Read/Write/Glob 那几个工具。
10. 总结
- LLM Wiki 不是 RAG 的升级,是另一种问题域的方案:有边界、需提炼、长期维护、人和 LLM 共用。
- 它把"理解"从查询时移到摄入时,换来透明度、可审计、git 友好。
- 代价是规模天花板(约 1000 页)和摄入成本。
- 配 Obsidian 是最省事的搭建路径:Front Matter Title + Graph view + Dataview,三件套足够。
- 特别注意:schema 必须先写、frontmatter 必须强制、lint 必须定期、漂移必须追踪。
如果你也在被 RAGFlow 的"图谱混乱、调试黑盒、改一条事实要点十下"折磨,建议拿一个小项目(不超过 50 份文档)试一试 LLM Wiki。真的太香了!!!





