Karpathy LLM Wiki 实践:用“知识编译“替代 RAG,构建个人知识库
❝Andrej Karpathy 提出了 LLM Wiki 架构——一种完全不同于 RAG 的知识管理范式。本文将深入解读其核心思想,并分享我从零实现一个 LLM Wiki 系统的完整实践。
❞
一、背景:RAG 的繁荣与困境
过去两年,RAG(Retrieval-Augmented Generation)几乎成了 LLM 应用的"标配"。无论是企业知识库、智能客服还是个人笔记系统,大家的第一反应都是:把文档切块 → 向量化 → 存入向量数据库 → 查询时检索 → 拼进 Prompt。
这套流程确实有效,但用久了你会发现一些痛点:
「分块损失」:一篇结构化的论文,切成 512 token 的碎片后,上下文关系全丢了
「检索不稳定」:Embedding 相似度并不等于语义相关度,换个说法就可能检索不到
「每次重新理解」:同一份文档,每次查询时 LLM 都要重新"阅读"原文,浪费算力
「知识碎片化」:原始文档之间没有显式关联,知识只是"堆"在数据库里
这些问题并非 RAG 的 Bug,而是其设计哲学决定的——「RAG 本质上是"检索时理解"」。
而 Karpathy 提出了一个反直觉的思路:「为什么不在入库时就让 LLM 理解好?」
二、Karpathy 的核心思想:知识编译
Karpathy 的 LLM Wiki 架构,核心就一句话:
❝「"不要让 LLM 在查询时去理解原始文档,而是提前让 LLM 把文档'编译'成结构化的知识。"」
❞
这跟编程语言的编译器是同一个思路:
源代码 (.py) → 编译 → 字节码 (已优化) → 执行 → 结果 原始文档 (PDF) → Ingest → Wiki 页面 (结构化) → Query → 答案「"编译"意味着什么?」
一篇 20 页的论文,核心贡献可能只需 500 字描述
格式五花八门的原始资料(PDF、网页、笔记),统一成 Markdown
文档之间隐含的关联(同一个概念在不同论文里出现),变成显式的双向链接
查询时不再需要 LLM "临时抱佛脚",而是直接读已经整理好的知识
关键洞察在于:「如果你的知识库足够精炼,你根本不需要复杂的向量检索」。100 个 Wiki 页面,每个平均 500 tokens,总共才 50,000 tokens——现在的 LLM 动辄 128K 甚至 200K 的上下文窗口,完全可以把整个 Wiki 塞进去。
三、架构设计:三层分离 + Schema 契约
3.1 三层架构
LLM Wiki 采用清晰的三层架构:
┌─────────────────────────────────────────────┐ │ Layer 3: Wiki(已编译的知识图谱) │ │ entities/ concepts/ summaries/ synthesis/ │ │ queries/ index.md │ ├─────────────────────────────────────────────┤ │ Layer 2: Raw Sources(原始资料) │ │ IMA API / 本地文件 / 外部数据源 │ ├─────────────────────────────────────────────┤ │ Layer 1: Schema(行为契约) │ │ AGENTS.md + SCHEMA.md │ └─────────────────────────────────────────────┘「Schema 层」:定义 LLM 的工作规则、页面模板、质量标准
「Wiki 层」:LLM 维护的结构化 Markdown 知识库
「Raw Sources 层」:只读的原始资料,通过 API 访问
3.2 Schema:最核心的设计
在 Karpathy 的设计中,「Schema 是整个系统最核心的概念」。它不是数据库 Schema,而是一份「给 LLM 看的"行为契约"」。
Schema 分为两个文件:
AGENTS.md:全局行为规范,定义工作流(Ingest/Query/Lint)和通用约定SCHEMA.md:实例级约束,定义页面模板、标签分类、质量阈值
「Schema 解决的核心问题:」
问题 | 没有 Schema | 有 Schema |
|---|---|---|
格式 | 混乱不统一 | 严格模板、标准结构 |
质量 | 长短不一、详略不同 | 质量稳定、可预测 |
维护 | 知识库逐渐混乱 | 知识库持续整洁 |
更强大的是——「修改 Schema 就能修改 LLM 行为,不需要改一行代码」。想让摘要更详细?改 SCHEMA.md 里的字数限制就行。想新增一种页面类型?在模板里加一个定义即可。
3.3 五类页面
Wiki 中有五种页面类型,各司其职:
类型 | 目录 | 内容 | 示例 |
|---|---|---|---|
| 「Entities」 | entities/ | 人物、组织、项目 | geoffrey-hinton.md |
| 「Concepts」 | concepts/ | 技术概念、理论 | transformer.md |
| 「Summaries」 | summaries/ | 源文档摘要 | attention-is-all-you-need.md |
| 「Synthesis」 | synthesis/ | 跨文档综合分析 | evolution-of-nlp.md |
| 「Queries」 | queries/ | 归档的高质量问答 | query-20240115-scaling-laws.md |
每种页面都有严格的模板:YAML frontmatter 元数据 + 标准化的 Markdown 结构 +[[双向链接]]交叉引用。
四、三大核心操作
4.1 Ingest(摄入):知识的"编译"过程
Ingest 是 LLM Wiki 最关键的操作,完整流程如下:
原始文档 → 内容提取 → LLM 生成摘要 → 创建 Summary 页面 → LLM 提取实体 → 创建/更新 Entity 页面 → LLM 提取概念 → 创建/更新 Concept 页面 → 更新双向链接 → 更新 index.md → 记录 log.md以摄入一篇论文为例,代码的核心逻辑是这样的:
def _ingest_content(self, source_id, source_title, content, source_type, metadata): # 1. LLM 生成摘要 summary = self._summarize(content) # 2. 创建摘要页 summary_page = self.wiki.create_page( title=source_title, category="summaries", content=summary, frontmatter={"source_id": source_id, "tags": ["summary"]}, ) # 3. LLM 提取并创建/更新实体页 for entity in self._extract_entities(content): self._update_entity_page(entity, summary_slug) # 4. LLM 提取并创建/更新概念页 for concept in self._extract_concepts(content): self._update_concept_page(concept, summary_slug) # 5. 更新索引和日志 self.wiki.write_index_file() self.wiki.append_log("ingest", details, source=source_id)这里的设计亮点是「LLM 回调机制」:所有 LLM 相关功能(摘要、提取、问答)都通过回调函数注入,不提供回调时退化为简单实现(如截取前 500 字符做摘要)。这让系统可以灵活接入不同的 LLM 服务,也方便测试。
4.2 Query(查询):先 Wiki 后原始资料
Query 的设计哲学是——「先查已编译的知识(Wiki),再查原始资料(Raw Sources),最后综合生成答案」:
用户提问 → 搜索 Wiki(BM25 算法)→ 搜索 IMA 原始知识库 → 组装上下文 → LLM 综合生成答案 → 判断是否值得归档 → (是)创建 Query 页面搜索部分我实现了一个「轻量级 BM25 算法」,而非简单的子字符串匹配:
def search(self, query, category=None, top_k=20): query_tokens = self._tokenize(query) # BM25 参数 k1, b, title_boost = 1.5, 0.75, 3.0 # 计算每个查询词的 IDF for token in set(query_tokens): doc_freq = sum(1for doc in doc_contents if token in doc) idf_scores[token] = math.log( (n_docs - doc_freq + 0.5) / (doc_freq + 0.5) + 1.0 ) # 对每个文档计算 BM25 分数 + 标题加权 for page in candidate_pages: score = sum(idf * tf_norm for each query_token) if token in title_tokens: score += idf * title_boost # 标题匹配额外加权BM25 相比简单子字符串匹配的优势:支持多关键词分词、TF-IDF 加权、标题匹配加权。同时保持轻量——不需要外部依赖,也不需要向量数据库。
Query 还有一个精妙的设计:「有价值的问答会被自动归档成新的 Wiki 页面」。这意味着 Wiki 会通过使用不断"自我增长"——你问得越多,知识库越丰富。
4.3 Lint(健康检查):维护知识库质量
Lint 操作借鉴了代码静态分析的理念,定期检查 Wiki 的"健康度":
「孤儿页面」:没有任何入链的页面(说明知识孤立)
「断链」:指向不存在页面的链接
「过时内容」:超过 30 天未更新的页面(天数从 SCHEMA.md 读取)
「矛盾信息」:跨页面的矛盾内容(需要 LLM 检测)
最终输出一个健康分数和详细报告:
🔍 Wiki Health Report Health Score: 85.0% | Issue Type | Count | |------------------|-------| | Orphan Pages | 2 | | Broken Links | 1 | | Outdated Pages | 3 | | Contradictions | 0 |五、Schema 驱动 LLM:修改文档即修改行为
这是整个系统我最欣赏的设计。所有 LLM 调用都会自动注入 Schema 作为 System Prompt:
class WikiLLMFunctions: def _build_system_prompt(self, task_instruction=""): parts = [ "You are an intelligent wiki assistant.", "You MUST follow the rules and conventions defined below.", ] if self._agents_content: parts.append("--- AGENTS.md (Global Behavior Rules) ---") parts.append(self._agents_content) if self._schema_content: parts.append("--- SCHEMA.md (Instance-Specific Constraints) ---") parts.append(self._schema_content) if task_instruction: parts.append(f"--- Current Task ---\n{task_instruction}") return"\n\n".join(parts)这意味着:
「提取实体时」,LLM 会遵循 SCHEMA.md 中定义的 Entity 页面模板,输出符合规范的结构化数据
「生成摘要时」,LLM 会参考 Schema 里的写作风格指南和字数限制
「判断是否归档时」,LLM 会根据 Schema 里的归档标准做出判断
「想改变 LLM 的行为?修改 Markdown 文件即可,不需要动一行代码。」这在传统 RAG 系统中是不可想象的——通常你需要改 Prompt、改代码逻辑、重新部署。
六、与 RAG 的本质区别
维度 | 传统 RAG | LLM Wiki |
|---|---|---|
| 「核心思想」 | 原始数据 + 智能检索 | 预编译 + 全量上下文 |
| 「数据处理」 | 分块存储,保留原文 | LLM 预处理,提炼精华 |
| 「检索方式」 | 向量相似度搜索 | BM25 关键词匹配(或全量加载) |
| 「信息密度」 | 低(包含冗余) | 高(经过精炼) |
| 「知识关联」 | 隐式(Embedding 空间) | 显式( |
| 「查询时 LLM 负担」 | 重(需理解原文) | 轻(知识已结构化) |
| 「更新成本」 | 低(增量更新向量) | 高(需要重新编译) |
| 「适合数据量」 | 大规模(10GB+) | 中小规模(< 500 页) |
| 「行为修改」 | 改代码、改 Prompt、部署 | 改 Markdown 文件 |
「它们不是替代关系,而是互补」。Karpathy 自己也说:
❝"RAG 是用技术复杂度换取内容量。LLM Wiki 是用前期精炼换取查询时的简单与准确。"
❞
七、适用场景与局限
适合
「个人研究者」:追踪论文、建立知识体系
「技术学习者」:整理学习笔记、关联概念
「内容创作者」:管理写作素材、积累领域知识
「独立开发者」:个人技术文档、项目知识沉淀
不适合
「企业级知识库」:数据量太大,编译成本过高
「实时问答系统」:更新频繁,Wiki 的编译开销不划算
「多人协作场景」:并发编辑 Markdown 文件会有冲突
八、总结
Karpathy 的 LLM Wiki 并不是要"革 RAG 的命",而是提出了一种不同的知识管理哲学:
「编译优于检索」——提前让 LLM 理解文档,而不是查询时临时理解
「质量优于数量」——500 字精炼摘要 > 5000 字原文
「显式关联优于隐式」——
[[双向链接]]> Embedding 空间相似度「简单优于复杂」——如果能全量加载,就不需要复杂的检索系统
「Schema 驱动」——修改文档即修改行为,非技术人员也能参与
对于个人知识管理来说,这种方式有一种独特的魅力:你的知识库不再是一个黑盒的向量数据库,而是一组精心组织的、人类可读的 Markdown 文件。你可以用 Obsidian 浏览它的知识图谱,可以直接阅读任何一个页面,可以手动编辑修正 LLM 的输出,也可以通过修改 Schema 来调整系统的行为。
「知识管理的终极形态,或许就是让 AI 帮你维护一个"活"的 Wiki——持久的、复利增长的知识产物。」
❝觉得有用的话,「点赞👍 + 分享👀 + 收藏⭐」一键三连,下次找起来方便,也能让更多人看到。
❞
