用 Claude Code 和 Obsidian 搭建Karpathy的LLM Wiki
下载文件Andrej Karpathy大神(OpenAI早期核心成员,前特斯拉AI Director)分享了自己如何使用LLM搭建知识库的方法。
传统 RAG的致命缺点是“无状态”和“失忆”:每次你问问题,LLM 都要重新在文档里大海捞针,且不能累积知识。Karpathy 的方案抛弃了RAG这一套,让 LLM 把原始资料“编译(Compile)”成一个结构化的 Wiki。
因为Karpathy并没有给出具体的prompt或者skill,也没有标准实现或固定工具链,而是只提供了一个“idea file”(模式说明),目前具体的实现方法大多都是社区中补全出来的。我来为大家讲解具体的实现步骤,所用到的工具,以及我根据Karpathy的理念编写的skills和约束,以及注意事项。
样例GitHub仓库:jason-effi-lab/karpathy-llm-wiki-vault。
核心理念
Andrej Karpathy 的 LLM Wiki 理念可以精简为**“将知识管理视为软件工程”,其核心逻辑是从“即时检索” (RAG) 转向“持续编译” (Compilation)。
以下是该理念的高效准确描述:
1. 核心转换:从检索到编译
- 传统 RAG: 像临时翻书。每次提问都从原始文档中重新搜寻碎片,知识不积累,无状态。
- LLM Wiki: 像编译代码。在数据摄入时就通过 LLM 进行深度合成与链接,将零散资料转化成结构化的、有状态的持久制品。
2. 三层架构 (The 3-Layer Architecture)
这一模式通过严格的目录结构确保知识的准确性与可维护性:
raw/(不可变源层): 存放原始论文、笔记、网页剪藏。它是事实之源,LLM 只读不写,确保可追溯性。wiki/(已编译制品层): 由 LLM 全权维护的 Markdown 页面。包含概念、实体摘要及其间的双向链接。这是知识库的“执行文件”。Schema(治理层): 即CLAUDE.md或AGENTS.md。它是 LLM 的作业规范,定义了文件命名、元数据格式及更新工作流,使 AI 成为纪律严明的图书管理员。
3. 三大核心操作 (The Loop)
- 摄入 (Ingest): 新资料进入时,LLM 会更新 10-15 个相关 Wiki 页面,修正旧观点,标记新矛盾。
- 查询 (Query): 优先通过
index.md索引导航,实现精准查询。高质量的回答会回填(File back)到 Wiki 中,实现知识复利。 - 审计 (Lint): AI 定期执行“体检”,寻找逻辑冲突、孤儿页面或知识缺口,保持系统健康。
4. 终极比喻
“Obsidian 是 IDE,LLM 是程序员,Wiki 是代码库”。 人类负责决策与提供素材,LLM 负责枯燥的簿记与维护工作(Bookkeeping)。最终形成一个随着阅读量增加而自动进化的私有化 Wikipedia。
| 维度 | 传统 RAG | Karpathy LLM Wiki |
|---|---|---|
| 核心理念 | 即时检索:提问时才去海量碎片中打捞 | 知识编译:摄入时即通过 LLM 转化为结构化知识库 |
| 处理时机 | 查询时:每次提问都从零开始搜索块 | 摄入时:提前处理并合成知识 |
| 知识状态 | 无状态:像临时翻书,回答完知识即消散 | 有状态:知识被“编译”为持久的制品 |
| 知识复利 | 无累积:每次查询成本和认知负担相同 | 持续增长:新知识会更新旧页面,探索结果也可存回 |
| 结构化程度 | 扁平碎片:数据以孤立的文本块形式存储 | 关联图谱:以实体/概念为中心,建立双向链接 |
| 矛盾处理 | 被动/忽略:RAG 可能同时输出多个来源的矛盾信息 | 主动发现:摄入时 LLM 会对比旧知识并标记矛盾 |
| 适用规模 | 海量数据:支持数百万文档,无上下文上限 | 中小规模:目前最适合 ~100-200 篇高质量文章 |
| 基础设施 | 复杂:需向量数据库、Embedding 模型及 pipeline | 极简:只需本地 Markdown 文件,无数据库依赖 |
| 用户界面 | 聊天流:瞬时性的对话记录 | IDE/Markdown:持久化的知识工作空间 |
知识库架构
最终生成的知识库架构如下,这里以Claude Code + claudian插件为例,你也可以使用OpenCode, Gemini CLI等智能体。
基于 Karpathy 的 LLM Wiki 理念构建,结合 Claude Code 体系。
🏛️ 你的知识库文件夹 (LLM-Wiki-Vault)
├── 🖼️ assets/ ← 统一媒体资源层:存放图片、PDF、附件(Obsidian设置附件路径至此)
│
├── 📥 raw/ ← 原始资料收件箱(只读事实层,文件处理后移动至 archive)
│ ├── 📄 01-articles/ ← 网页剪藏、技术文章 (.md)
│ ├── 🎓 02-papers/ ← 论文、深度研报、PDF文档
│ ├── 🎙️ 03-transcripts/ ← 视频/播客转录文本、会议记录
│ ├── 💡 04-meeting_notes/ ← 头脑风暴或会议纪要等
│ └── 🗃️ 09-archive/ ← 已归档区:`/ingest` 执行成功后,源文件自动移动至此
│
├── 🧠 wiki/ ← 知识编译输出层(LLM 拥有完全写权限,人类阅读层)
│ ├── 📑 index.md ← 全局内容字典:记录所有 wiki 页面及其一句话索引
│ ├── 📜 log.md ← 行为流水线:以 Grep-friendly 格式记录 ingest/query 历史
│ ├── 🏗️ concepts/ ← 抽象层:方法论、架构模式、第一性原理
│ ├── 👥 entities/ ← 实体层:人名、公司、工具软件、项目
│ ├── 🔍 sources/ ← 摘要层:针对 raw 文件的一对一核心观点提炼
│ └── 💎 syntheses/ ← 综合层:针对复杂提问生成的深度研究报告
│
├── 🤖 CLAUDE.md ← 全局心智规范:定义语言协议、读写权限与 Wiki Schema
│
└── ⚙️ .claude/ ← Claude Code 官方配置目录
└── 🛠️ skills/ ← Agent Skill中心
├── ⚙️ ingest/ ← 自定义:编译收件箱 raw 文件到 wiki,并执行 09-archive 归档
├── 🔎 query/ ← 自定义:检索 wiki/index 并读取相关页面,生成带双链引用的回答
├── 🩺 lint/ ← 自定义:知识体检,修复死链、补充 index、发现认知冲突
├── 🔌 obsidian-cli/ ← Obsidian官方:调用 Obsidian 原生 API 进行检索、打开页面
└── 🪄 defuddle/ ← Obsidian官方:将网页 URL 自动清理并转化为 Markdown 存入 raw/
CLAUDE.md内容如下:
# 语言设定与核心角色 (Global Rules)
- **语言指令**:无论输入何种语言,你必须始终使用**简体中文**进行思考、回复和知识库的编写。
- **角色定义**:你正在维护一个 **LLM Wiki**(根据 [Karpathy 的规范](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f)),你的任务是将碎片化的信息编译成结构化、高度相互链接的 Obsidian 知识库。
# 核心目录与权限边界 (Immutability & Architecture)
你必须严格遵守以下文件操作权限,这是不可逾越的底线:
- `/raw/` (不可变层 - Immutable):
- **绝对只读**。这里存放我的原始素材、网页剪藏和自媒体文案。
- **禁止修改或删除此目录下的任何文件**。它是事实的唯一真相来源。
- `/assets/` (媒体资产层):
- 存放图片、PDF和媒体。引用时使用 Obsidian 标准语法 `![[文件名称.png]]`。
- `/wiki/` (编译输出层 - You Own This):
- 这是你的专属工作区。你需要在此处创建、更新、提炼知识并解决矛盾。
# Wiki 核心文件契约 (The Wiki Schema)
当你在 `/wiki/` 中工作时(尤其是执行写入操作后),必须维护以下基石:
1. **`wiki/index.md` (总目录)**:
每次向 wiki 新增知识页后,必须同步更新此文件,将其按分类加入目录中。
格式要求: [[页面名称]] — 一句话描述。
- Entities/Concepts: 使用 TitleCase 命名。
- Sources/Syntheses: 使用 kebab-case 命名。
范例:
```markdown
# Wiki Index
## Sources
- [[摘要-source-slug]] — 该资料的核心主旨摘要。
## Entities
- [[EntityName]] — 该实体的身份定义或核心功能。
## Concepts
- [[ConceptName]] — 该概念或框架的核心定义。
## Syntheses
- [[synthesis-slug]] — 该页面回答的复杂问题。
```
2. **`wiki/log.md` (操作日志)**:
只能追加写入(Append-only)。每次操作后记录:`## [YYYY-MM-DD] <动作> | <操作简述>`。
操作类型: ingest, query, lint, sync
范例:
```markdown
## [2026-04-11] ingest | 引入项目 Claude Code 核心概念
- **变更**: 新增 [[ClaudeCode]], [[摘要-claude-code-docs]]; 更新 [[index.md]]
- **冲突**: 无 (或: 冲突 [[RAG架构]], 已标注)
## [2026-04-11] query | 解析 Karpathy LLM-Wiki 理念
- **输出**: 已保存至 [[分析-karpathy-wiki-philosophy]]
## [2026-04-11] lint | 周度健康检查
- **结果**: 修复 2 处死链,发现 1 个孤儿页面 [[UnlinkedPage]]
```
3. **内容分类**:
- `/wiki/concepts/`:存放概念、框架、方法论(如 `Agent_Skill.md`)。
- `/wiki/entities/`:存放人物、公司、工具、产品(如 `Claude_Code.md`)。
- `/wiki/sources/`:存放从 `raw/` 提炼出的原始素材摘要。
4. **强制双向链接**:
每一个 wiki 页面必须包含 `## 关联连接` 区域,使用 Obsidian 双链 `[[页面名称]]` 链接到其他相关概念。绝不能产生孤岛页面。
5. **矛盾处理原则**:
如果新摄入的知识与旧知识冲突,不要静默覆盖。在页面中新建 `## 知识冲突` 区块,将两种说法都保留并做对比。
# 工作流指令说明 (Workflows / Skills)
当被要求执行以下操作时,请遵循核心逻辑(未来可能由专用 Agent Skills 接管):
- `/ingest <路径>`:读取指定的 `raw/` 文件,将其核心价值提炼并整合到 `wiki/` 目录的相关概念/实体中。必须更新 index 和 log。
- `/query <问题>`:通过读取 `wiki/index.md` 寻找相关文件,进行深度阅读后综合回答,并在回答中必须使用 `[[wikilink]]` 标注引用来源。
- `/lint`:全局扫描 `wiki/` 目录,找出孤岛页面(没有双链)、死链(链接不存在的页面)以及存在逻辑冲突的地方,并向我报告。
# 页面 Frontmatter (YAML) 规范
所有生成的 wiki 页面必须包含以下 YAML 头部:
---
title: "页面标题"
type: concept | entity | source | synthesis
tags: [知识标签]
sources:[关联的raw文件相对路径]
last_updated: YYYY-MM-DD
---
第一步:数据摄入 - 原始资料收集
这一步是唯一需要人类手动进行的步骤。Karpathy重度依赖 Obsidian Web Clipper 官方剪藏插件,一键将网页提取为干净的 Markdown 格式。 涉及工具: Obsidian, Obsidian Web Clipper,Defuddle/Defuddle skill。
- 安装Obsidian并创建知识库,在知识库中创建
/raw文件夹,作为数据摄入的入口。(我一般都起名叫/inbox,一个意思) - 在浏览器中安装Obsidian Web Clipper官方剪藏插件,在插件设置中,指定剪藏笔记保存的路径为
你的OB仓库/raw。 - 你也可以使用
defuddle工具和defuddle skill来进行知识的摄入,具体我之前的视频中有讲。他们都是Obsidian CEO @kepano写的。官方Web Clipper插件底层也是Defuddle。 - 必须是 .md 文件吗?不能是 PDF 或电子书吗?:可以,但 Karpathy 强烈推荐将网页剪藏为 .md 格式,因为 Markdown 是LLM的“母语”,解析效率最高,Token 消耗最少,且格式非常干净。
第二步:LLM 自动化编译与构建(Ingest)
LLM 读取原始数据,自动提取概念、生成总结,并在 wiki/ 文件夹下生成带有 YAML frontmatter(元数据)和双向链接的新 Markdown 文件。 涉及工具:Claude Code(或其他智能体工具,比如OpenCode),obsidian-cli skill。
- 你可以直接发送提示词给Claude Code,但是,这样的步骤显然更应该使用skill。
- 以下是我编写的
ingest-skill,核心功能就是把/raw里的资料整理成wiki。在智能体中直接执行/ingest即可触发。
ingest-skill内容如下:
---
name: ingest
description: 将 raw/ 目录下的原始资料编译到 wiki/ 中。处理完成后,将源文件自动移动到 raw/09-archive/ 归档。支持 `/ingest` (扫描 raw/ 下所有未归档文件) 或 `/ingest <path>` (处理指定文件)。当用户提到"摄取"、"导入"、"收入"资料,或要求将文件加入知识库时,也应该触发此技能。绝对忽略 raw/09-archive/ 目录。
user-invocable: true
---
# ingest 技能
## 核心工作流:Inbox & Archive
你正在维护一个 **LLM Wiki**(Obsidian 知识库)。`raw/` 目录是"待处理收件箱",`wiki/` 是"编译输出层"。
**目录结构约定:**
- `raw/01-articles/` — 网页剪藏的 Markdown 文章
- `raw/02-papers/` — 论文和 PDF 文献
- `raw/03-transcripts/` — 视频转录文案
- `raw/09-archive/` — **已处理文件的归档目录,禁止读取**
- `wiki/sources/` — 资料摘要
- `wiki/entities/` — 实体(人物、公司、工具、产品)
- `wiki/concepts/` — 概念(框架、方法论、理论)
## 触发逻辑
1. **用户执行 `/ingest`**:扫描 `raw/` 所有子目录(排除 `09-archive/`),找出待处理文件。
2. **用户执行 `/ingest <path>`**:仅处理指定文件。
3. **隐式触发**:用户说"把这个资料摄入知识库"、"导入这篇文章"时,自动执行 ingest。
## 编译流水线
对每个待处理源文件,严格按以下步骤执行:
### 步骤 1:读取源文件
- **如果是 `.md` 文件**:使用读取工具完整读取内容。
- **如果是 `.pdf` 文件**:使用读取工具尝试提取文本。如果无法提取或内容为空,改为记录文件元信息(文件名、页数)在 sources 页面中。
### 步骤 2:提炼核心并翻译
从源文件中提取:
- **核心主旨**:这段资料讲什么(1-2句话)
- **实体**:人物、公司、工具、产品等具体名词
- **概念**:框架、方法论、理论等抽象名词
如果是非中文内容,则翻译成中文。
### 步骤 3:创建来源摘要
在 `wiki/sources/` 创建 Markdown 文件:
```markdown
---
title: "摘要-文件slug"
type: source
tags: [来源, 原始文件]
sources: [raw/01-articles/xxx.md]
last_updated: YYYY-MM-DD
---
## 核心摘要
[3-5句话的核心总结]
## 关联连接
- [[EntityName]] — 关联实体
- [[ConceptName]] — 关联概念
```
文件名使用 kebab-case:`摘要-{文件slug}.md`
### 步骤 4:知识网络化(实体/概念页面)
对于步骤 2 提取的每个实体和概念:
**目标目录:**
- 实体 → `wiki/entities/`
- 概念 → `wiki/concepts/`
**处理逻辑:**
1. 页面不存在 → 按照 CLAUDE.md 的 Frontmatter 规范创建新页面
2. 页面已存在 → 读取现有内容,**增量合并**新信息
3. **发现冲突** → **立即暂停**,向用户报告冲突内容,询问处理方式后再继续
**页面模板:**
```markdown
---
title: "页面名称"
type: entity | concept
tags: [标签]
sources: [关联的源文件]
last_updated: YYYY-MM-DD
---
## 定义
[对该实体/概念的定义]
## 关键信息
[从源文件中提取的详细信息]
## 关联连接
- [[摘要-source-slug]] — 来源
- [[RelatedEntity]] — 相关实体
```
### 步骤 5:更新全局注册表
**更新 `wiki/index.md`:**
按照 CLAUDE.md 规定的格式,将新增页面添加到对应分类下:
- Sources: `[[摘要-source-slug]] — 该资料的核心主旨`
- Entities: `[[EntityName]] — 该实体的身份定义`
- Concepts: `[[ConceptName]] — 该概念的核心定义`
**更新 `wiki/log.md`:**
追加操作日志(Append-only):
```markdown
## [YYYY-MM-DD] ingest | 操作简述
- **变更**: 新增 [[PageName]]; 更新 [[index.md]]
- **冲突**: 无 (或: 冲突 [[ConflictingPage]], 已暂停等待决策)
```
### 步骤 6:归档源文件
在确认以下全部完成后,将源文件移动到 `raw/09-archive/`目录:
- sources 页面已创建
- 实体/概念页面已创建或更新
- index.md 已更新
- log.md 已更新
**绝对禁止修改源文件内部的文字。**
## 冲突处理流程
当发现新旧知识冲突时:
1. **暂停**:停止当前 ingest 流程
2. **报告**:向用户说明冲突内容(哪个页面、冲突点是什么)
3. **询问**:请用户选择处理方式:
- A) 保留新旧两者,标注为"知识冲突"
- B) 用新知识覆盖旧知识
- C) 放弃本次 ingest
4. **继续**:根据用户选择继续或终止
## 注意事项
- 绝对不读取 `raw/09-archive/` 下的任何文件
- 所有 wiki 页面必须包含 `## 关联连接` 区域,不能产生孤岛页面
- 使用简体中文编写所有内容
- 实体命名使用 TitleCase,概念和来源使用 kebab-case
第三步:深度查询与知识复利
面对特定课题,让 LLM 进行跨文档的综合研究,并将高质量的分析结果存回知识库,实现知识的增量与结网。 涉及工具: Claude Code(或其他智能体工具,比如OpenCode),marp(obsidian插件,或skill),json-canvas(也有skill,我之前讲过)等等。
这一步是RAG吗?可以用NotebookLM吗? 绝对不能,恰恰相反,Karpathy的理念恰恰是为了对抗RAG 和 NotebookLM。 核心思想:Wiki > RAG RAG(包括 NotebookLM)是“无状态”的:系统本身没有记忆,知识没有积累。 你今天问,它搜一遍;明天问,它还要再搜一遍。它是一个“只读(Read-only)”的阅览室。 Karpathy 的 Agentic Wiki 是“有状态”和“编译”的:构建一个持续进化的知识库(LLM Wiki),知识是“被编译”的,而不是“临时检索”的。当你提问时,Agent 是在阅读已经被提炼过的网络结构,并将高质量的问答结果存回知识库中。
案例一:矛盾点挖掘
对比我知识库里 OpenClaw 和 Claude Code 这两个工具的所有测试笔记。
列出它们在处理长文本项目时的底层机制差异。
如果发现这两者的能力有重叠或互斥,请明确指出。将分析结果生成对比表格,存入 wiki/comparisons/。
案例二:盲区发现
审视我过去三个月关于‘Agent开发’的所有知识节点。
作为一名 15 年经验的全栈开发者,帮我指出我在架构选型、优化或部署思路上,还有哪些信息的严重缺失?
列出我下一步应该去摄入的 3 个方向。
提问后,你可以命令 Agent:“把刚才的对比分析转化为 Marp 格式的幻灯片,并存入 wiki/comparisons/ ”。下次打开 Obsidian,你就能直接看到排版好的 PPT。同样你也可以生成canvas, excalidraw等。
query-skill内容如下:
---
name: query
description: 在本地 Wiki 知识库中回答用户提问。当用户使用 /query 命令、或用自然语言询问关于"我的笔记/历史决定/过往笔记/知识库"中的内容时调用。必须先读取 wiki/index.md 定位相关页面,再深度阅读,最后以双链引用格式回答。禁止凭模型记忆回答。如果知识库中没有相关内容,必须声明"本地知识库中未找到,以下为通用知识回答"。
user-invocable: true
---
# query 技能
## 核心目标
将用户的提问转化为对本地 Wiki 的深度检索。提取相关页面信息,综合出带有明确引用来源的双链回答。当回答具有高价值时,主动将其固化为知识库的一部分。
## 触发场景
- 用户输入 `/query <问题>`
- 用户用自然语言询问:`"我的笔记里关于 X 是怎么说的"`、`"过去我对 Y 的决策是什么"`、`"查询 Z 相关的知识"`
- 用户提及 wiki、知识库、笔记、记录等关键词
## 降级策略
如果问题属于纯通用知识(如"太阳系有几颗行星"),且 wiki/index.md 中无相关内容:
>本地知识库中未找到相关内容,以下为通用知识回答:[直接回答]
---
## 检索与综合流水线
### 步骤 1:查阅全局索引
**永远的第一步**:读取 `wiki/index.md`
在 index.md 中定位与问题相关的:
- Entities(实体)
- Concepts(概念)
- Sources(摘要)
- Syntheses(综合)
### 步骤 2:深度阅读目标文件
选取步骤 1 中找到的最相关页面,使用读取工具获取完整内容。
### 步骤 3:综合与回答
综合信息,回答用户问题。
**双链引用规范**:
- 每当引用某个 Wiki 页面的信息,在文本中使用 `[[页面名称]]` 标注
- 整段引用同一页面:段落首尾各引用一次
- 引用特定原文:使用 Markdown 块引用 `> 引用内容`
### 步骤 4:高价值内容固化
如果满足以下条件,主动询问用户是否保存为 synthesis:
- 回答超过 2 个段落
- 内容具有分析对比性或总结性
询问话术:
>这是一个有价值的总结,是否需要我将其保存到 wiki/syntheses/ 目录?
用户同意后,按照 CLAUDE.md 规范创建文件:
```markdown
---
title: "页面标题"
type: synthesis
tags: []
sources: []
last_updated: YYYY-MM-DD
---
# 总结内容
```
并在 `wiki/index.md` 的 Syntheses 分类下注册。
### 步骤 5:记录操作日志
无论是否生成 synthesis 页面,查询结束后必须在 `wiki/log.md` 末尾追加:
```markdown
## [YYYY-MM-DD] query | <操作简述>
- **输出**: <引用页面列表或"即时回答未保存">
```
格式必须完全遵循 CLAUDE.md 中的示例。
---
## 强制约束
- **禁止凭记忆回答**:必须先检索知识库
- **禁止过度引用**:同一页面的信息在段落首尾引用一次即可
- **禁止静默回答**:知识库无相关内容时必须声明
---
## 关联连接
- [[wiki/index.md]] — 全局索引入口
- [[wiki/log.md]] — 操作日志
- [[CLAUDE.md]] — Wiki 架构总规范
第四步:知识库维护(Lint)
定期对知识库进行体检,排查知识库中的逻辑断层、自相矛盾或死链接。这也是为什么我用了lint这个程序员专属词汇。
涉及工具: Claude Code(或其他智能体工具,比如OpenCode),lint-skill(自己编写)。
以下是我编写的lint-skill。
---
name: lint
description: 知识库全局健康度检查。扫描 wiki/ 目录,检测死链(页面引用不存在的双链)、孤儿页面(无任何页面引用它)、未同步索引(文件存在但未在 index.md 注册)和知识冲突。当用户输入 /lint、/scan、/health 或要求“检查知识库状态”、“检查健康”时调用。
user-invocable: true
---
# lint 技能:知识图谱健康巡检
## 核心目标
将软件工程中的“静态代码分析”引入知识管理。定期运行此 skill,找出知识库长期演进中产生的:死链、孤岛、未同步索引、认知冲突。
## 触发条件
- 用户输入 `/lint`
- 用户询问“我的知识库健康状况如何”
- 用户要求“检查知识库状态”或“检查健康”
## 知识库路径
- 使用 Glob 工具动态定位当前工作区下的 wiki/ 目录
## 巡检流水线
### 第 1 步:索引一致性检查
1. 读取 `wiki/index.md` 全部内容
2. 扫描 `wiki/` 下所有 `.md` 文件(排除 index.md 和 log.md)
3. 提取 index.md 中注册的所有双链链接 `[[页面名称]]`
4. 比对:找出已注册但文件不存在的条目 OR 文件存在但未注册的页面
### 第 2 步:双向链接健康检查
1. 扫描所有 `.md` 文件,提取所有 `[[双链]]` 格式的链接
2. 如果链接指向的页面不存在 → 标记为**死链**
3. 统计被引用的页面(排除 self-reference)
4. 找出从未被任何其他页面引用的页面 → **孤儿页面**
### 第 3 步:认知冲突审查
1. 全局搜索所有 `.md` 文件中包含 `## 知识冲突` 的页面
2. 提取每个冲突的简要描述(冲突双方是什么)
3. 统计带未解决冲突的页面(认知技术债)
### 第 4 步:收件箱积压检查(可选跳过)
- 本 skill 仅扫描 wiki/,跳过 raw/ 收件箱检查
## 报告输出规范
扫描完成后,输出结构化报告,严格遵循以下格式:
```markdown
## 🩺 知识库健康体检报告 — YYYY-MM-DD
### ✅ 绿灯项
- [运行良好的项目]
### ⚠️ 黄灯项
- **发现 N 个孤儿页面**:[列表] - 建议添加关联或分类
- **发现 N 个未同步索引**:[列表] - 文件存在但未在 index.md 注册
### ❌ 红灯项
- **发现 N 个死链**:[来源页面] → [[不存在的目标页面]]
- **存在 N 个未解决的知识冲突**:[页面名称]
### 🛠️ 下一步行动
1. 是否需要自动修复未同步索引?
2. 是否需要针对知识冲突进行重新推演?
```
## 硬约束
- **仅读扫描**:生成报告前,禁止修改、删除、重命名任何文件
- **手动确认**:报告后等待用户确认再执行修复
- **静默日志**:修复完成后,在 wiki/log.md 追加 `## [YYYY-MM-DD] lint | 修复了 N 个问题`
```
注意事项与风险
上下文窗口:Karpathy 表示目前的方案在 40万字 级别运行良好。但如果你要把这个工作流扩大,每次重新编译或深度 Query 时,都需要把巨大的知识树推入大模型的上下文窗口,无论是使用 Claude 还是 Gemini API,这会导致极高的 Token 开销(API 成本不可控)。
高昂的 Token 成本:智能体的操作非常消耗token。即便我在skill中加入了技能链,使用了obsidian-cli skill,但每次更新如果都要把关联的十几个文件和系统 Prompt 推给大模型,你的 API 费用依旧会暴增。
AI幻觉:这是这套系统最致命的缺陷。由于整个 Wiki 由 LLM 自动化编译并相互链接,如果大模型在某次处理中产生了幻觉(伪造了某个数据或联系),这个错误会被写成 Markdown 永久固化在知识库中。未来的推理会以此为“事实基石”,导致错误指数级放大。
我的看法
Karpathy只给出了理论,并没有给出具体实现,目前社区中也都是根据其理论来进行技术补全。 但总体说来,Karpathy的核心理念,描绘的是个人知识管理(PKM)必然的终极形态——人类只做高价值的信息筛选与战略提问,AI 接管所有繁琐的节点编织。 反传统RAG,让知识库系统拥有了持久化状态,知识才开始产生复利。
最后,还是要强调一点:注意Token消耗,注意Token消耗,注意Token消耗!
Karpathy原文翻译
英文原文:llm-wiki
# LLM Wiki
一种利用 LLM 构建个人知识库的模式。
这是一个理念文件,旨在供你复制并粘贴到你自己的 LLM 代理(例如 OpenAI Codex、Claude Code、OpenCode / Pi 等)中。它的目标是传达高层级的核心理念,而具体的构建细节将由你的代理与你协作完成。
## 核心理念
大多数人对 LLM 和文档的体验类似于 RAG(检索增强生成):你上传一堆文件,LLM 在查询时检索相关的片段,然后生成答案。这种方式可行,但 LLM 在回答每个问题时都是从零开始重新发现知识,没有知识的积累。如果问一个需要综合五份文档的微妙问题,LLM 每次都必须重新寻找并拼凑相关碎片。没有任何东西被沉淀下来。NotebookLM、ChatGPT 的文件上传以及大多数 RAG 系统都是这样运作的。
这里的理念则不同。LLM 不仅仅是在查询时从原始文档中检索,而是**增量地构建并维护一个持久化的 Wiki** —— 这是一个位于你和原始资料之间的、结构化的、互相关联的 Markdown 文件集合。当你添加新资料时,LLM 不只是为了以后的检索而对其进行索引,而是阅读它,提取关键信息,并将其整合到现有的 Wiki 中 —— 更新实体页面、修订主题摘要、记录新数据与旧主张的矛盾之处,从而强化或挑战不断演进的综合认知。知识被“编译”一次后便*保持更新*,而不是在每次查询时重新推导。
这就是关键区别:**Wiki 是一个持久化的、具有复利效应的工件。** 交叉引用已经建立,矛盾点已被标记,综合综述已经反映了你所读过的一切。随着你添加的每一份资料和提出的每一个问题,Wiki 都会变得更加丰富。
你永远(或极少)亲自编写 Wiki —— LLM 负责编写和维护所有内容。你负责提供资料、探索和提出正确的问题。LLM 负责所有的苦活累活 —— 摘要、交叉引用、归档和簿记,正是这些工作让知识库随着时间的推移变得真正有用。在实践中,我一边打开 LLM 代理,另一边打开 Obsidian。LLM 根据我们的对话进行编辑,我实时浏览结果 —— 点击链接、查看关系图谱、阅读更新后的页面。Obsidian 是 IDE;LLM 是程序员;Wiki 则是代码库。
这可以应用于许多不同的场景。例如:
- **个人**:跟踪你自己的目标、健康、心理、自我提升 —— 归档日记条目、文章、播客笔记,并随着时间的推移建立起关于你自己的结构化画像。
- **研究**:在数周或数月内深入研究某个主题 —— 阅读论文、文章、报告,并增量地构建一个带有演进论点的全面 Wiki。
- **阅读书籍**:边读边归档每一章,构建角色、主题、情节线索及其关联的页面。读完后,你就拥有了一个丰富的配套 Wiki。想想看像 [Tolkien Gateway](https://tolkiengateway.net/wiki/Main_Page) 这样的粉丝 Wiki —— 成千上万个互相关联的页面,涵盖了角色、地点、事件、语言,由志愿者社区耗时多年建成。你可以在阅读时个人化地构建类似的东西,而所有的交叉引用和维护工作都由 LLM 完成。
- **业务/团队**:由 LLM 维护的内部 Wiki,数据源自 Slack 讨论帖、会议记录、项目文档、客户电话。可能由人工参与审核更新。Wiki 能保持最新,是因为 LLM 完成了团队中没人想做的维护工作。
- **竞争分析、尽职调查、旅行规划、课程笔记、爱好深挖** —— 任何涉及知识长期积累且需要组织有序(而非零散)的场景。
## 架构
分为三个层级:
**原始资料 (Raw sources)** —— 你策划的源文档集合。文章、论文、图片、数据文件。这些是不可变的 —— LLM 只从中读取,绝不修改。这是你的“事实来源”。
**Wiki** —— 一个由 LLM 生成的 Markdown 文件目录。包含摘要、实体页面、概念页面、对比分析、概览、综合综述。LLM 完全拥有这一层。它创建页面,在新资料到达时更新页面,维护交叉引用,并保持一切一致性。你负责阅读,LLM 负责编写。
**架构规范 (The schema)** —— 一个说明文档(例如 Claude Code 的 `CLAUDE.md` 或 Codex 的 `AGENTS.md`),告诉 LLM Wiki 是如何结构的、有哪些惯例,以及在摄入资料、回答问题或维护 Wiki 时应遵循的工作流。这是关键的配置文件 —— 正是它让 LLM 成为一名纪律严明的 Wiki 维护者,而不是一个通用的聊天机器人。随着你逐渐摸索出适合自己领域的方案,你和 LLM 会共同演进这份文档。
## 操作
**摄入 (Ingest)**。你将新资料放入原始集合中,并告诉 LLM 进行处理。一个典型的流程:LLM 阅读资料,与你讨论关键要点,在 Wiki 中编写摘要页,更新索引,更新整个 Wiki 中相关的实体和概念页面,并在日志中追加一条记录。一份资料可能会触及 10-15 个 Wiki 页面。就个人而言,我更喜欢逐个摄入资料并保持参与 —— 我阅读摘要、检查更新,并引导 LLM 重点关注哪些内容。但你也可以在较少监督的情况下批量摄入多份资料。由你决定适合自己风格的工作流,并将其记录在架构规范中供未来会话使用。
**查询 (Query)**。你针对 Wiki 提出问题。LLM 搜索相关页面,阅读并综合出带有引用来源的答案。答案可以根据问题采取不同的形式 —— Markdown 页面、对比表格、幻灯片 (Marp)、图表 (matplotlib)、画布 (canvas)。重要的洞察:**好的答案可以作为新页面重新归档到 Wiki 中。** 你要求的对比、分析或发现的关联都是有价值的,不应消失在聊天历史中。这样,你的探索过程就会像摄入的资料一样,在知识库中产生复利。
**巡检 (Lint)**。定期要求 LLM 对 Wiki 进行“健康检查”。检查内容包括:页面之间的矛盾、已被新资料取代的陈旧主张、没有入向链接的孤立页面、提到了但缺乏独立页面的重要概念、缺失的交叉引用、可以通过网络搜索填补的数据空白。LLM 擅长建议新的调查问题和寻找新资料。这能确保 Wiki 在增长过程中保持健康。
## 索引与日志
两个特殊文件帮助 LLM(以及你)在 Wiki 增长时进行导航。它们用途各异:
**index.md** 是以内容为导向的。它是 Wiki 中所有内容的目录 —— 列出每个页面及其链接、一行简短摘要,以及可选的元数据(如日期或来源数量)。按类别组织(实体、概念、来源等)。LLM 在每次摄入时都会更新它。在回答查询时,LLM 首先阅读索引以寻找相关页面,然后深入挖掘。这在中等规模(约 100 份资料,数百个页面)下表现出奇地好,且避免了对基于嵌入 (Embedding) 的 RAG 基础设施的需求。
**log.md** 是按时间顺序排列的。它是一个只增记录,记录了何时发生了什么 —— 摄入、查询、巡检。一个有用的技巧:如果每个条目都以一致的前缀开始(例如 `## [2026-04-02] ingest | 文章标题`),日志就可以用简单的 Unix 工具解析 —— `grep "^## \[" log.md | tail -5` 可以让你看到最后 5 条记录。日志为你提供了 Wiki 演进的时间线,并帮助 LLM 了解最近完成了哪些工作。
## 可选:CLI 工具
在某些时候,你可能想构建一些小工具来帮助 LLM 更高效地操作 Wiki。对 Wiki 页面进行搜索引擎是最显而易见的需求 —— 在小规模下,索引文件就足够了,但随着 Wiki 的增长,你需要真正的搜索。[qmd](https://github.com/tobi/qmd) 是一个不错的选择:它是一个用于 Markdown 文件的本地搜索引擎,具有 BM25/向量混合搜索和 LLM 重排序功能,全部在本地运行。它既有 CLI(以便 LLM 可以调用 shell 命令),也有 MCP 服务器(以便 LLM 可以将其作为原生工具使用)。你也可以自己构建更简单的东西 —— 随着需求产生,LLM 可以帮你“直觉驱动式编程 (vibe-code)”一个简单的搜索脚本。
## 提示与技巧
- **Obsidian Web Clipper** 是一个浏览器扩展,可将网页文章转换为 Markdown。对于快速将资料存入原始集合非常有用。
- **本地下载图片**。在 Obsidian 设置 → 文件与链接中,将“附件默认存放路径”设置为固定目录(例如 `raw/assets/`)。然后在设置 → 快捷键中,搜索“下载”找到“下载当前文件的附件”并绑定快捷键(例如 Ctrl+Shift+D)。剪藏文章后,按下快捷键,所有图片都会下载到本地磁盘。这是可选的,但很有用 —— 它让 LLM 可以直接查看和引用图片,而不是依赖于可能失效的 URL。注意,LLM 无法在一次读取中原生阅读带有内嵌图片的 Markdown —— 解决方法是让 LLM 先读文本,然后根据需要单独查看部分或全部引用的图片以获取额外上下文。虽然有点笨重,但效果不错。
- **Obsidian 的关系图谱 (Graph view)** 是查看 Wiki 形态的最佳方式 —— 哪些是相连的,哪些页面是核心枢纽,哪些是孤立页面。
- **Marp** 是一种基于 Markdown 的幻灯片格式。Obsidian 有相关插件。适合直接从 Wiki 内容生成演示文稿。
- **Dataview** 是一个 Obsidian 插件,可以在页面前置数据 (frontmatter) 上运行查询。如果你的 LLM 为 Wiki 页面添加了 YAML 前置数据(标签、日期、来源计数),Dataview 可以生成动态表格和列表。
- Wiki 本质上只是一个 Markdown 文件的 Git 仓库。你可以免费获得版本历史、分支功能和协作支持。
## 为什么这种模式有效
维护知识库最枯燥的部分不是阅读或思考,而是“簿记”工作:更新交叉引用、保持摘要最新、记录新旧数据的冲突、维持几十个页面的一致性。人类往往会放弃维护 Wiki,因为维护负担的增长速度超过了其价值。LLM 不会感到厌倦,不会忘记更新交叉引用,并且可以一次性修改 15 个文件。Wiki 能够维持下去,是因为维护成本几乎为零。
人类的工作是策划资料、指导分析、提出好问题,并思考这一切意味着什么。LLM 的工作是除此之外的一切。
这个理念在精神上与 Vannevar Bush 的 Memex (1945) 相关 —— 一个私人的、经过策划的知识存储器,文档之间具有联想路径。Bush 的愿景与此更为接近,而不是现在的互联网:私密的、积极策划的,且文档之间的关联与文档本身同样具有价值。他无法解决的部分是谁来负责维护,而 LLM 解决了这个问题。
## 注意事项
本文档刻意保持抽象。它描述的是一种理念,而非特定的实现。具体的目录结构、架构惯例、页面格式、工具链 —— 所有这些都取决于你的领域、你的偏好以及你选择的 LLM。上述提到的所有内容都是可选的和模块化的 —— 挑选有用的,忽略没用的。例如:你的资料可能全是文本,所以完全不需要处理图片。你的 Wiki 可能足够小,只需索引文件即可,不需要搜索引擎。你可能不在乎幻灯片,只想要 Markdown 页面。你可能想要一套完全不同的输出格式。使用本模式的正确方法是将其分享给你的 LLM 代理,共同协作实例化一个符合你需求的版本。本文档唯一的任务是传达这种模式,剩下的交给你的 LLM。