本教程系统讲解 LLM Wiki(基于大语言模型的个人知识库)这一新兴知识管理范式,深入分析它与 RAG、知识图谱的关系,并带你用 FastAPI + 智谱 GLM 构建完整的 llm-wiki 知识管理服务:导入文档、由 LLM 编译为带双向链接的 Wiki 页面、可视化图谱,并基于 Wiki 向 LLM 提问。

前置教程

如想快速开始学习本教程,你可能需要先完成以下前置教程:

资源下载

1. LLM Wiki 概念详解

1.1 什么是 LLM Wiki

LLM Wiki 是由 Andrej Karpathy 提出的一套个人知识库管理方法。它的核心思想可以概括为一句话:

Obsidian 是 IDE,LLM 是程序员,Wiki 是代码库。

传统知识管理依赖人手动整理笔记、维护目录结构;LLM Wiki 则让 AI 承担"知识编译"工作——将新摄入的资料提炼成结构化、带双向链接的维基页面,实现知识的累积与复利。

1.2 核心理念:LLM 是编译器,聊天是入口,Wiki 是产品

LLM Wiki 最关键的范式转变在于:把"综合"从查询阶段前移到摄取阶段

graph LR A[原始资料
raw] --> B[LLM 编译器] B --> C[结构化 Wiki 页面
含双向链接] C --> D[用户查询] D --> E[基于沉淀知识作答] classDef input fill:#d6eaf8,stroke:#1a6b8a,stroke-width:2px classDef model fill:#ffecd6,stroke:#ca6f1e,stroke-width:2px classDef wiki fill:#d5f5e3,stroke:#1e8449,stroke-width:2px classDef query fill:#ebdef0,stroke:#6c3483,stroke-width:2px class A input class B model class C wiki class D,E query

新资料一进来,模型立刻将其编译成可导航的知识页面;等用户查询时,查的是被反复消化过的知识资产,而非原始文档堆。

1.3 三层架构

LLM Wiki 将知识系统划分为三层:

层级 作用 说明
Raw Sources(原始材料层) 事实仓库 存放 PDF、网页剪藏、播客转录稿等外部素材,不可变、只读不改,保证可追溯性
Wiki(维基派生层) 系统核心 由 AI 生成的结构化 Markdown 页面,按实体、概念分门别类,充满密集的双向链接(Obsidian [[双向链接]] 语法)
Schema(模式规则层) 系统"大脑" 用自然语言约定的目录结构、标签规范、链接规则,通常为 AGENTS.mdCLAUDE.md
graph LR A[Schema 模式规则层
AGENTS.md] --> B[Wiki 派生知识层
结构化页面+双向链接] C[Raw 原始材料层
不可变素材] --> B classDef schema fill:#fdebd0,stroke:#b9770e,stroke-width:2px classDef wiki fill:#d5f5e3,stroke:#1e8449,stroke-width:2px classDef raw fill:#fadbd8,stroke:#922b21,stroke-width:2px class A schema class B wiki class C raw

没有 Schema,LLM 只是写作者;有了 Schema,LLM 才是知识库维护者。

1.4 两个必不可少的辅助文件

  • 索引表(index.md:Wiki 的"花名册",每次创建新页面都追加"页面链接 + 一句话摘要"。查询时 LLM 只需扫一眼索引即可定位相关页面,避免 Token 消耗过大。
  • 日志库(log.md:按时间顺序追加的操作时间线(如"摄取了文件 A,创建了概念 B"),便于审查 AI 行为和找回"短期记忆"。

2. LLM Wiki 与 RAG 的关系

2.1 广义 RAG 与狭义 RAG

  • 狭义 RAG(Retrieval-Augmented Generation):特指"检索增强生成"这一技术架构,即查询时从向量数据库中检索相关片段,连同问题一起交给大模型生成回答。
  • 广义 RAG:泛指"基于外部知识辅助大模型回答"这一类方案。从广义上讲,LLM Wiki 也属于"用外部知识增强 LLM"的范畴,因此可以将 LLM Wiki 视为广义 RAG 的一种。

2.2 LLM Wiki 与传统 RAG 的对比

维度 LLM Wiki 传统 RAG
核心定位 人类可读的知识编译层,持续维护 查询时检索合成,即时响应
工作方式 摄取阶段提前编译,持续更新 查询阶段检索 chunk,实时合成
知识积累 知识可积累、可溯源、可读性强 结论不积累,每次重新推导
优势 可维护、可溯源、适合长期研究 灵活高效,适合实时查询
劣势 需要维护,不适合实时高频场景 检索片段割裂,跨文档综合能力弱

2.3 为什么 LLM Wiki 不是 RAG 的替代品

LLM Wiki 与传统 RAG 是叠加关系而非互斥替代:

  • 一次性问答、实时监控、大规模低价值粗筛 → 用传统 RAG,灵活高效
  • 长期主题研究、个人第二大脑、知识沉淀 → 用 LLM Wiki,知识可积累

正确路线是按查询类型路由,而非按语料体量升级。本教程的示例项目先实现 LLM Wiki 的核心流程,读者可在此基础上叠加向量检索,形成混合方案。

3. LLM Wiki 与知识图谱的关系

3.1 知识图谱概述

知识图谱以节点(实体、概念)和(关系)表达知识之间的关联,如"张三家住北京"中,"张三"与"北京"是节点,"家住"是关系。知识图谱擅长表达和推理复杂的关系网络。

3.2 LLM Wiki 的链接网络

LLM Wiki 用 Obsidian 双向链接([[链接名]] 在页面之间建立关联。当多个 Wiki 页面互相链接时,就构成了一张天然的链接网络——这与知识图谱在结构上高度相似:

  • Wiki 页面 → 知识图谱的节点
  • 页面间的 [[双向链接]] → 知识图谱的边
graph LR A[页面A 大语言模型] --> B[页面B RAG] B --> C[页面C Embedding] B --> A C --> B classDef wiki fill:#d5f5e3,stroke:#1e8449,stroke-width:2px class A,B,C wiki

3.3 对比与联系

维度 LLM Wiki 链接网络 知识图谱
构建方式 LLM 摄取时自动生成 实体关系抽取,人/机器维护
链接语义 双向链接,无明确关系类型 边带关系标签(如"属于""位于")
表达粒度 页面级关联 实体级细粒度关系
可视化 Obsidian 图谱视图 PyVis 等专用图谱工具

联系:LLM Wiki 的链接网络是"轻量级"知识图谱,无需复杂的关系抽取即可获得可导航的知识结构;对于需要细粒度关系推理的场景,可再叠加知识图谱技术。

4. 综合示例:llm-wiki 知识管理服务

4.1 项目目标与架构

示例项目 llm-wiki 将 LLM Wiki 的核心流程封装为完整服务,实现以下目标:

  • 文档管理:导入、列出、删除原始 Markdown 文档
  • Wiki 处理:由 LLM 将文档编译为带双向链接的 Wiki 页面,并维护 index.mdlog.md
  • 图谱可视化:根据 Wiki 页面间的 [[双向链接]] 构建并展示图谱
  • LLM 问答:基于 Wiki 内容向 LLM 提问

整体架构如下:

graph LR U[前端页面
static/index.html] -->|文档管理/摄取/提问| A[FastAPI 后端
main.py] A --> S[wiki_core.py
文档管理/摄取/图谱/查询] S --> F[raw 原始文档] S --> W[wiki 生成页面+index+log] S --> L[智谱 GLM] classDef frontend fill:#d6eaf8,stroke:#1a6b8a,stroke-width:2px classDef backend fill:#d5f5e3,stroke:#1e8449,stroke-width:2px classDef core fill:#ebdef0,stroke:#6c3483,stroke-width:2px classDef store fill:#fdebd0,stroke:#b9770e,stroke-width:2px classDef llm fill:#ffecd6,stroke:#ca6f1e,stroke-width:2px class U frontend class A backend class S core class F,W store class L llm

4.2 项目结构

llm-wiki/
├── config.py                  # 服务配置(GLM Key、目录、端口)
├── main.py                    # FastAPI 后端,各功能接口
├── wiki_core.py               # 核心逻辑(文档管理、摄取、图谱、查询)
├── requirements.txt           # 依赖管理
├── README.md                  # 项目说明
├── raw/                       # 原始文档目录(含 2 篇预置文档)
├── wiki/                      # 生成的 Wiki 页面目录(摄取后生成)
└── static/
    └── index.html             # 前端页面

4.3 环境准备与配置

创建独立 conda 环境 llm-wiki,依赖统一使用 uv 安装:

conda create -n llm-wiki python=3.10 -y
conda activate llm-wiki
pip install uv

cd llm-wiki
uv pip install -r requirements.txt --index-url https://pypi.tuna.tsinghua.edu.cn/simple

编辑 config.py 确认 GLM 配置(示例已内置可测试的 API Key,读者可替换为自己的):

# config.py(核心片段,完整代码请查看 llm-wiki/config.py)
ZHIPU_API_KEY = "ZHIPU_API_KEY"
ZHIPU_API_BASE = "https://open.bigmodel.cn/api/paas/v4"
LLM_MODEL_NAME = "glm-4.7-flash"

RAW_DIR = "raw"              # 原始文档目录
WIKI_DIR = "wiki"            # 生成的 Wiki 页面目录
INDEX_FILE = "index.md"      # Wiki 索引文件
LOG_FILE = "log.md"          # 操作日志文件

4.4 文档管理

wiki_core.py 提供 raw 目录的文档管理:列出、导入、删除。main.py 中对应接口如下:

# main.py(核心片段,完整代码请查看 llm-wiki/main.py)
@app.get("/api/files")
async def list_files():
    """列出 raw 目录下的文档"""
    return {"files": wiki_core.list_raw_files()}

@app.post("/api/files/import")
async def import_file(file: UploadFile = File(...)):
    """导入文档到 raw 目录"""
    filename = file.filename or "未命名.md"
    content = (await file.read()).decode("utf-8")
    wiki_core.import_raw_file(filename, content)
    return {"message": f"文档 {filename} 导入成功"}

4.5 Wiki 摄取:LLM 编译知识

摄取是 LLM Wiki 的核心。ingest_document() 将一篇原始文档交给 GLM,要求其提炼为结构化 Wiki 页面(含 [[双向链接]]),并更新索引与日志:

# wiki_core.py(核心片段,完整代码请查看 llm-wiki/wiki_core.py)
def ingest_document(filename: str) -> str:
    """摄取单个文档:由 LLM 提炼为 Wiki 页面,更新索引与日志"""
    path = os.path.join(RAW_DIR, filename)
    with open(path, encoding="utf-8") as f:
        content = f.read()

    prompt = f"""你是个人知识库的维护者。请阅读下面的文档,将其提炼为一篇结构化的 Wiki 笔记。

要求:
1. 以 `# 标题` 开头,正文用简洁的 Markdown 结构
2. 提炼文档中的核心概念、实体、人物,每个概念用独立小节描述
3. 使用 Obsidian 双向链接语法 [[链接名]] 关联相关知识
4. 全文控制在 600 字以内,只保留关键事实

待处理文档内容:
{content}"""

    wiki_content = _call_glm([{"role": "user", "content": prompt}])

    # 保存 Wiki 页面,更新 index.md 与 log.md
    base = os.path.splitext(filename)[0]
    wiki_filename = f"{base}.md"
    os.makedirs(WIKI_DIR, exist_ok=True)
    with open(os.path.join(WIKI_DIR, wiki_filename), "w", encoding="utf-8") as f:
        f.write(wiki_content)
    _upsert_index(wiki_filename, _first_title(wiki_content))
    _append_log(f"摄取文档 {filename},生成 Wiki 页面 {wiki_filename}")
    return wiki_filename

_call_glm() 封装了对智谱 GLM 的调用,并针对免费模型的限流(429)做了自动重试与退避等待。

4.6 图谱构建

build_graph() 扫描所有 Wiki 页面,解析其中的 [[双向链接]],生成图谱数据(节点 + 边),供前端用 vis-network 渲染:

# wiki_core.py(核心片段,完整代码请查看 llm-wiki/wiki_core.py)
def build_graph():
    """根据 Wiki 页面的 [[双向链接]] 构建图谱(节点 + 边)"""
    nodes = []
    edges = []
    seen_nodes = set()

    for page in list_wiki_pages():
        name = os.path.splitext(page)[0]
        if name not in seen_nodes:
            seen_nodes.add(name)
            nodes.append({"id": name, "label": name, "category": "wiki"})

    for page in list_wiki_pages():
        name = os.path.splitext(page)[0]
        path = os.path.join(WIKI_DIR, page)
        with open(path, encoding="utf-8") as f:
            text = f.read()
        for target in _extract_links(text):
            if target not in seen_nodes:
                seen_nodes.add(target)
                nodes.append({"id": target, "label": target, "category": "concept"})
            edges.append({"from": name, "to": target, "label": ""})

    return {"nodes": nodes, "edges": edges}

4.7 LLM 问答

query_wiki() 收集全部 Wiki 页面内容作为上下文,交由 GLM 基于沉淀的知识回答,避免模型凭空编造:

# wiki_core.py(核心片段,完整代码请查看 llm-wiki/wiki_core.py)
def query_wiki(question):
    """基于 Wiki 内容向 LLM 提问,返回答案"""
    # 收集全部 Wiki 页面内容作为上下文
    context_parts = []
    for page in list_wiki_pages():
        path = os.path.join(WIKI_DIR, page)
        with open(path, encoding="utf-8") as f:
            context_parts.append(f"## 页面:{page}\n{f.read()}")
    wiki_context = "\n\n".join(context_parts)

    system_prompt = (
        "你是一个基于个人知识库的问答助手。请依据提供的 Wiki 笔记内容回答用户问题,"
        "尽量引用笔记中的表述,不要编造笔记中不存在的信息。"
    )
    return _call_glm([
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": f"{wiki_context}\n\n## 用户问题\n{question}"},
    ], temperature=0.3)

4.8 前端页面

前端为单页 HTML 应用,位于 static/index.html。你可以前往 llm-wiki/static/index.html 查看完整的示例代码。页面包含三个页签:

  1. 文件管理:列出 raw 目录文档,支持导入与删除,提供"开始摄取"按钮
  2. Wiki 图谱:使用 vis-network 可视化 Wiki 页面间的双向链接关系
  3. LLM 问答:输入问题,基于 Wiki 知识库回答

4.9 运行与测试

第一步:创建环境并安装依赖(见 4.3 节)

第二步:启动服务

python main.py

启动后访问 http://localhost:8000,即可看到知识管理界面。

第三步:使用流程

  1. 文件管理:确认 raw 目录已有 2 篇预置文档(也可导入/删除)
  2. 开始摄取:点击"开始摄取",LLM 将文档编译为 Wiki 页面(2 篇约需 1~2 分钟)
  3. Wiki 图谱:切换到图谱页签,查看页面间的双向链接网络
  4. LLM 问答:输入问题(如"什么是 RAG?"),查看基于 Wiki 的回答

也可用 curl 直接验证接口:

curl.exe -X POST http://localhost:8000/api/chat -H "Content-Type: application/json" -d "{\"question\": \"什么是 RAG\"}"

运行与测试示意图

4.10 配合 Obsidian 使用

LLM Wiki 的双向链接与 Obsidian 天然契合。可下载安装 Obsidian

  1. 打开 Obsidian,选择"打开本地仓库",指向 llm-wiki/wiki/ 目录
  2. 在 Obsidian 中即可查看所有 Wiki 页面与 [[双向链接]]
  3. 切换到"图谱视图",以可视化方式浏览页面间的链接网络

配合 Obsidian 使用示意图

提示:Obsidian 的图谱视图与示例项目前端的 vis-network 图谱互为印证,均可直观展示 LLM 编译出的知识网络。

5. 总结

5.1 核心内容回顾

  • LLM Wiki 概念:Obsidian 是 IDE,LLM 是程序员,Wiki 是代码库
  • 三层架构:Raw 原始材料层(不可变)、Wiki 派生知识层(双向链接)、Schema 模式规则层
  • 与 RAG 的关系:LLM Wiki 是"摄取阶段编译",传统 RAG 是"查询阶段检索",二者叠加互补
  • 与知识图谱的关系:Wiki 双向链接网络是轻量级知识图谱,无需复杂关系抽取
  • 示例项目:FastAPI + GLM 实现文档管理、Wiki 摄取、图谱构建、LLM 问答全流程

5.2 常见问题与解答

问:摄取时报 GLM 限流(429)怎么办?

答:免费模型有速率限制,代码已内置自动重试与退避等待。可稍后重试,或更换自己的 API Key、降低并发。

问:wiki/ 目录为什么一开始是空的?

答:Wiki 页面由 LLM 在"摄取"步骤中生成。执行摄取后,wiki/ 下会生成对应页面以及 index.mdlog.md

问:问答时模型说"笔记中没有这个信息"?

答:这是预期行为。示例的问答只依据 Wiki 内容作答,不编造。若需更开放的回答,可调整 query_wiki() 的提示词。

问:预置文档在哪里?

答:示例项目 llm-wiki/raw/ 已内置相同文档,可直接使用;也可通过前端"导入"功能添加自己的文档。

问:图谱中出现了文档中没写过的节点?

答:这些是 LLM 在生成 Wiki 页面时,根据正文语义自动补充的 [[双向链接]] 指向的概念节点,属于正常现象。