你有没有过这样的经历?

学了一堆技术,笔记散落在各处——有道云、飞书文档、VS Code的临时文件、浏览器的书签。想用的时候找不到,找到了又不记得上下文。

Karpathy(OpenAI联合创始人、前特斯拉AI总监)最近提出了一个优雅的解法:LLM Wiki——不用向量数据库,不用传统RAG,让LLM自己维护一个Markdown知识库。

今天这篇文章,带你从零搭建一个可闭环的个人Wiki RAG系统。用Ollama本地模型,完全离线,代码不到300行。

读完你会觉得:我行了,我也能搭。

Karpathy的LLM Wiki是什么?

一句话:让LLM帮你维护一个结构化的Markdown知识库。

传统做法是这样的:

文档 → 分块 → Embedding → 向量数据库 → 检索 → LLM回答

Karpathy的做法是这样的:

raw笔记 → LLM编译 → 结构化Wiki → 直接塞给LLM

核心区别:不需要向量数据库,不需要Embedding,不需要检索管线。 LLM读一个index.md全局索引,然后按需拉取具体的Wiki文章。

优点: 零基础设施,token效率高,人可读。

缺点: 知识量大了(超过100篇),一个context window装不下索引。

我的方案:混合架构

取两者之长:

raw/ → 原始知识素材(你的笔记)
wiki/ → LLM编译后的结构化文章
向量索引 → 支持大规模精准检索

Wiki层保证知识可读、可维护。 RAG检索层保证知识量大了也能精准找到。

整个系统4个命令搞定:

wiki-rag compile # 编译raw → wiki
wiki-rag query "你的问题" # 查询
wiki-rag add "主题" "内容" # 添加新知识
wiki-rag compile --force # 强制重新编译

环境准备

▪ 1. 安装Ollama

macOS

brew install ollama
ollama serve

▪ 2. 拉取模型

ollama pull deepseek-r1:1.5b # LLM(编译+回答)
ollama pull nomic-embed-text # Embedding模型

为什么选这两个?轻量、离线、够用。 1.5B模型在MacBook上秒回,nomic-embed-text是Ollama生态最常用的Embedding模型。

▪ 3. 创建项目

mkdir wiki-rag && cd wiki-rag

创建 pyproject.toml:

[project]
name = "wiki-rag"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = [
"llama-index>=0.12.0",
"numpy",
]

uv sync

三层架构设计

▪ 第一层:raw/(原始素材)

放你的笔记,随便写,Markdown格式:

raw/
├── python-decorators.md
├── docker-network.md
├── git-rebase-merge.md
├── redis-data-structures.md
└── http2-vs-http1.md

▪ 第二层:wiki/(LLM编译后的结构化文章)

LLM把你的乱七八糟笔记编译成结构化的Wiki文章:

COMPILE_PROMPT = """你是一个知识整理专家。请将以下原始笔记编译为一篇结构清晰的Wiki文章。

要求:

  1. 保留所有核心技术要点
  2. 使用清晰的标题层级
  3. 关键术语加粗
  4. 保留核心代码
  5. 末尾添加「一句话总结」
  6. 生成3-5个标签"""

智能跳过: 用MD5哈希检测文件变化,没改动的自动跳过。

▪ 第三层:向量索引(RAG检索)

把Wiki文章分块,生成Embedding,存到本地JSON:

分块 → Embedding → 存储

paragraphs = [p for p in content.split("\n\n") if p.strip()]
for para in paragraphs:
emb = client.embeddings(model="nomic-embed-text", prompt=para)
chunks.append({"text": para, "embedding": emb["embedding"]})

查询时:问题Embedding → 余弦相似度 → 取Top3 → 拼接上下文 → LLM回答。

核心代码

整个系统就一个文件 src/wiki_rag.py,不到300行。

▪ 编译:raw → wiki

def compile_raw_to_wiki(raw_file, force=False):
# 1. 检查是否需要重新编译(MD5哈希)
if not force and file_hash_unchanged(raw_file):
return None # 跳过

# 2. 调用LLM编译
content = raw_file.read_text()
resp = client.chat(model="deepseek-r1:1.5b", messages=[
{"role": "user", "content": COMPILE_PROMPT.format(content=content)}
])

# 3. 写入wiki/
wiki_path = WIKI_DIR / raw_file.name
wiki_path.write_text(resp["message"]["content"])

▪ 查询:向量检索 + LLM回答

def query(question):
# 1. 问题的Embedding
q_emb = client.embeddings(model="nomic-embed-text", prompt=question)

# 2. 余弦相似度检索Top3
scored = [(cosine_sim(q_emb, chunk["embedding"]), chunk)
for chunk in index_data["chunks"]]
top3 = sorted(scored, reverse=True)[:3]

# 3. 拼接上下文 → LLM回答
context = "\n\n".join(chunk["text"] for _, chunk in top3)
resp = client.chat(model="deepseek-r1:1.5b", messages=[
{"role": "user", "content": f"基于以下内容回答:\n{context}\n\n问题:{question}"}
])
return resp["message"]["content"]

就这么简单。 没有向量数据库,没有FAISS,没有复杂的检索管线。

跑起来

编译

uv run python -m src.wiki_rag compile

📝 编译: docker-network.md ... ✅ 完成

📝 编译: redis-data-structures.md ... ✅ 完成

...

📊 编译完成: 5 篇新编译

📑 索引已更新: 5 篇文章

✅ 向量索引构建完成: 68 个chunk

查询

uv run python -m src.wiki_rag query "Python装饰器是什么"

💡 回答: Python装饰器是一种高阶函数...

踩坑记录

▪ 坑1:LlamaIndex的Ollama集成502

LlamaIndex的Ollama客户端在Mac上频繁502。

解决方案: 直接用 ollama Python SDK,绕过LlamaIndex的集成层。

▪ 坑2:Ollama并发限制

Embedding请求并发太高会502。

解决方案: 逐个请求,不批量。

▪ 坑3:模型选择

9B的Qwen模型编译5篇文章就要几分钟,还经常超时。

解决方案: 用1.5B的deepseek-r1,够快够用。

扩展方向

这个MVP能跑起来后,可以往这些方向扩展:

  • 换更强的模型: 等Mac内存够大,换7B/14B模型,编译质量会更好
  • 换向量存储: JSON → FAISS → Chroma,支持万级文档
  • 增量更新: 只重新编译变化的文件(已支持)
  • Web界面: 加个Streamlit前端,从CLI变成Web应用
  • 多源接入: 不仅读Markdown,还能读PDF、网页、Notion

完整代码

GitHub仓库: https://github.com/helloworldtang/wiki-rag

clone下来,装好Ollama,uv sync + compile 就能跑。

13个单元测试全通过,端到端验证成功。

不是demo,是真能用的MVP。

一句话总结

Karpathy说:知识管理正在成为AI工作流的核心成本。用LLM Wiki + RAG,你可以在本地搭建一个真正可用的个人知识库——零API费用,完全离线,数据自己掌控。

试试看,你会发现:真没那么难。