Hermes Agent 实战 15|告别临时 RAG:用 Karpathy 的 LLM Wiki 给 Agent 装上可生长的长期记忆原创
# 告别临时 RAG:用 Karpathy 的 LLM Wiki 给 Agent 装上可生长的长期记忆
系列第 15 篇。前面讲的
MEMORY.md记忆系统解决的是「Agent 记得住上次说过什么」,但它救不了一类更深的痛:散落在几十个会话里的知识,永远不会自己长成一张网。这篇讲 Andrej Karpathy 的 LLM Wiki 模式——怎么照它的约定,给一个长期运行的 Profile 搭一套会自我维护的结构化知识库,以及我上手当天踩的三个真实的坑。
# 1. 我让 Agent「学一下」,它先翻了个车
那天我把 Hermes 官方文档里 llm-wiki skill 的 URL 丢给主 Agent,说「带我学习一下这个」。我以为它会直接调起预装的 research-llm-wiki skill——结果第一步就失败了:skill 加载报错,Agent 回退到了通用网页抓取。
抓取又撞上第二个坑:文档太长,read 出来的内容被截断了,前半段讲完架构,后面的工作流全没了。Agent 自己想了个办法——执行一段 JS 直接拿完整 DOM 文本,才把整篇 SKILL.md 完整读进来。
折腾完这两下,它才真正讲明白了 LLM Wiki 是什么。下面就照它的约定走一遍——用一个管数据库的 ops Profile 当例子,看怎么搭出一套真能用的知识库。
# 2. RAG 每次从零,Wiki 一次编译
设想一个管数据库的 ops Profile,手里一堆 DBA 日常:慢 SQL 战例、故障 runbook、各种「上次那个坑怎么填的」。这些东西如果只丢进向量库走 RAG,问题是——
- 每次查询都从零检索:知识没有沉淀,LLM 每次都要重新读一遍源材料、重新理解
- 没有交叉引用:「这个故障」和「那个配置」之间的关联,每次都要现推
- 矛盾不会暴露:三月的结论和六月的结论打架,没人会主动告诉你
Karpathy 的 LLM Wiki 反过来——把知识「编译」一次,之后只增量维护。
这里的「编译」不是随便用的词,它精确对应编译型语言 vs 解释型语言的差别:
- RAG = 解释执行:每次提问,临时去原始文档里捞一段、临时塞给 LLM 现读现懂,答完就扔。下次同样的问题,同样的重活再干一遍。
- Wiki = 编译执行:在摄入那一刻就把重活一次干完——读懂原文、提炼要点、跟已有知识建立交叉引用、撞上重复就合并、撞上矛盾就标记,最后写成一页结构化的成品。之后你提问,Agent 直接读这页成品,不再碰原始材料。
说白了,「编译」就是把散乱的原始材料(raw/)一次性加工成互联、去重、标注好矛盾的知识页面(entities/、concepts/)——这道加工只做一次,结果固化在 Markdown 里。代价是摄入时贵一点,收益是之后每次查询都便宜、而且越用越准(交叉引用已经在那了,矛盾已经被标过了)。
而且它的实现成本低到离谱:整个 wiki 就是一堆 Markdown 文件,没有数据库,没有专用工具,用 Obsidian、VS Code 甚至 cat 都能打开。
# 3. 实战:给一个 Profile 建知识库
下面把上面那套架构落到一个 Profile,按「准备 → 执行 → 验证」走。
# 3.1 准备:三层架构与路径
LLM Wiki 的核心是三层,职责严格分离:
Layer 1 (raw/) → 原始来源(URL/PDF/笔记),只读,永不修改,用于溯源
Layer 2 (wiki/) → Agent 加工的 entities/ concepts/ comparisons/,可迭代
Layer 3 (SCHEMA) → 领域定义、标签体系、更新策略,约束 Agent 行为
2
3
路径用环境变量指定(写进 Profile 的 .env,不写死):
# 给你的 Profile 起一个知识库路径
export WIKI_PATH=~/.hermes/profiles/<your-profile>/wiki
2
初始化后的目录长这样:
wiki/
├── SCHEMA.md # 规范:领域、标签 taxonomy、页面阈值
├── index.md # 内容目录:每页一行摘要
├── log.md # 操作日志,append-only,按年滚动
├── raw/ # Layer 1(immutable)
│ ├── articles/
│ ├── papers/
│ └── transcripts/
├── entities/ # Layer 2:实体页(人/组织/产品/模型)
├── concepts/ # Layer 2:概念页
├── comparisons/ # Layer 2:对比分析
└── queries/ # Layer 2:值得留存的查询结果
2
3
4
5
6
7
8
9
10
11
12
# 3.2 建好之后,你到底怎么用它
这是上一版漏掉的关键。知识库搭好后,你和它的日常交互就三个动作,外加一条铁律:
| 你想干嘛 | 你对 Agent 说的话 | 它在背后做的事 |
|---|---|---|
| 喂材料 | 「把这篇加进知识库」+ 一个 URL/文件 | Ingest:抓取 → 编译成页面 → 更新索引 |
| 提问 | 「索引碎片和统计信息过期,哪个更拖慢查询?」 | Query:读已编译的页面 → 综合回答 → 标出处 |
| 体检 | 「lint 一下知识库」 | Lint:扫断链 / 孤儿页 / 矛盾 / 过期 |
铁律——每个新会话先 Orient:动手前先让 Agent 读一遍 SCHEMA.md + index.md + log.md。它默认无状态,不先看一眼「现在已经有什么」,就会给已存在的实体重复建页、漏掉本该连的交叉引用。(这条坑在 §4 详述。)
注意:你全程说自然语言,不需要记命令。下面把三个动作各拆开看一遍 Agent 实际怎么执行。
# 3.3 喂材料(Ingest)
你丢给它一篇慢 SQL 优化的文档,说「加进知识库」。Agent 在背后走这套固定流程:
① 抓取 → 存到 raw/articles/slow-sql-tuning.md(带 sha256)
② 检查 index.md + search_files,看相关页面是否已存在
③ 写/更新 Layer 2 页面(达到阈值才建新页)
④ 建立双向 [[wikilinks]],每页至少 2 个出站链接
⑤ 更新 index.md(页数+1)、append log.md
2
3
4
5
预期日志(log.md 里追加一行):
## [2026-06-29] ingest | 慢 SQL 优化指南
- raw/articles/slow-sql-tuning.md (sha256: a3f9...)
- 新建:concepts/slow-query-optimization.md
- 更新:entities/sqlserver.md(+2 出站链接)
- index 总页数:14 → 15
2
3
4
5
raw 源材料自带一小段 frontmatter,关键是 sha256:
---
source_url: https://example.com/slow-sql-tuning
ingested: 2026-06-29
sha256: a3f9c2e1... # 只对正文算,不含 frontmatter
---
2
3
4
5
这个哈希是漂移检测的基础——下次重新摄入同一个 URL,重算 sha256 一比对:一样就跳过,变了就标记并更新。一行哈希,解决「源内容偷偷改了我却不知道」。
# 3.4 提问(Query)
你问「索引碎片和统计信息过期,哪个更拖慢查询?」。它不去翻原始文档——直接读早就编译好的页面:
查 index.md 定位相关页 → read 这些页 → 综合答案
→ 有价值的综合结果归档到 queries/ → append log.md
2
跟 RAG 最大的不同在回答的可追溯性:它会带着出处回你——「据 [[slow-query-optimization]] 和 [[statistics-staleness]] 两页,统计信息过期影响更大,因为……」。你能顺着 [[wikilink]] 一路点回当初摄入的 raw/ 源文件,每条结论都查得到根。
而且这个回答本身如果有价值,会被归档回 queries/ 成为一页新知识——下次再问类似问题,它连综合都省了,直接读这页。这就是「越用越准」。
# 3.5 体检(Lint)
知识库会随着摄入慢慢「长歪」:断链、孤儿页、自相矛盾。你定期说一句「lint 一下」,Agent 跑这套健康检查(这是长期运行的命脉):
① 孤儿页:没有任何入站 [[wikilink]] 的页面
② 断链:[[链接]] 指向不存在的页
③ 索引完整性:文件系统 vs index.md 对账
④ Frontmatter 校验:必填字段、标签是否在 taxonomy 内
⑤ 矛盾检测:标记 contested: true / contradictions: 的页
⑥ 源漂移:重算 raw/ 的 sha256,标记不一致
2
3
4
5
6
# 4. 上手当天踩的三个坑
# 坑 1:预装 skill 不一定加载得上
- 症状:直接调
research-llm-wikiskill 报错,流程卡住。 - 原因:skill 的可用性依赖运行时环境,预期它「一定在」是脆弱假设。
- 解药:留一条回退路径。skill 挂了就退回通用能力(web_extract / read_file)手动走一遍,别让单个 skill 成为唯一入口。本质上 LLM Wiki 的价值在那套约定(三层架构 + 工作流),不在某个 skill 封装。
# 坑 2:长文档会被静默截断
- 症状:读官方 SKILL.md,前半段架构读到了,后半段工作流凭空消失。
- 原因:单次读取有长度上限,超长内容被截断,而且不报错——你以为读全了,其实没有。
- 解药:长文档要么分段读(
offset翻页),要么像当时那样执行 JS 抓完整 DOM 文本。关键是意识到截断会静默发生,读完顺手确认尾部内容在不在。
# 坑 3:raw/ 动了一下,溯源就断了
- 症状:手贱改了
raw/下一个源文件,之后 Lint 的 sha256 检测全乱。 - 原因:raw/ 是不可变层,任何修改都会让漂移检测失效、溯源断裂。
- 解药:所有修正都发生在 Layer 2。源材料错了也不动它——在 wiki 页里注明「原文有误,实际为 X」,用 frontmatter 标
contested。raw/ 永远是「当时抓到的原样」。
# 5. 可复用要点
# 三条心法
Wiki ≠ Blog,别混 Blog 是对外成品(单向链接、一次发布);Wiki 是对内研究(双向链接、持续迭代)。用 wiki 时别想着「这能直接发吗」,那样会束手束脚。这俩是两种模式。
每次新会话先做 Orientation Hermes Agent 默认无状态。新会话第一件事:读
SCHEMA.md→ 读index.md→ 扫log.md最近 20-30 条。跳过这步,Agent 就会给已存在的实体重复建页、漏掉该有的交叉引用。这 5 分钟省的是 2 小时的去重。依赖要有回退,长读要防截断 这是上手当天换来的两条——别假设 skill 一定在,别假设长文一定读全。两个假设各崩一次。
# 三个硬规则
- 页面阈值:实体/概念在 2+ 源出现或在某一源中扮演核心角色,才建新页;一次性提及不建页。
- 链接规范:每页至少 2 个出站
[[wikilink]];孤立页等于不存在。 - 大小控制:单页 >200 行就拆;一个 wiki 页应该 30 秒能读完。
# 6. 下一篇
LLM Wiki 是 Karpathy 的「纯 Markdown + 人工 curation」流派。OpenClaw 的 memory-wiki 插件走了另一条路——把同样的理念做成带结构化 claims、机器可读摘要、矛盾仪表板的工程化版本。下一篇拆解它的三种工作模式(isolated / bridge / unsafe-local),以及那个让很多人误判为故障的「9 个空报告」。
下一篇:OpenClaw 知识库三态论:那 9 个「空报告」不是 bug
# 7. Agent 可直接解析的元数据块
{
"_meta": {
"doc_version": "2026-06-29",
"article_id": "hermes-15-llm-wiki",
"profile_context": "any",
"estimated_setup_time": "20min"
},
"quick_start": {
"step_1": "export WIKI_PATH=~/.hermes/profiles/<name>/wiki",
"step_2": "初始化三层结构:SCHEMA.md + index.md + log.md + raw/ + entities/ + concepts/",
"step_3": "ingest 源材料:存 raw/(带 sha256)→ 写 Layer 2 页面 → 建双向链接 → 更新 index/log",
"step_4": "每次新会话先 Orientation:读 SCHEMA.md + index.md + log.md 最近 30 条"
},
"safety_rules": [
"新会话动手前必须 Orientation(读 SCHEMA + index + log),否则会重复建页",
"raw/ 是不可变层,所有修正发生在 Layer 2,绝不修改源文件",
"新标签必须先写入 SCHEMA.md 的 taxonomy 再使用",
"依赖 skill 要留回退路径;读长文档防静默截断(分段读或抓完整 DOM)"
],
"verification": {
"check_orphans": "扫所有 Layer 2 页面,找零入站 [[wikilink]] 的孤儿页",
"check_broken_links": "找指向不存在页面的 [[链接]]",
"check_drift": "对 raw/ 每个带 sha256 的文件重算哈希,标记不一致",
"check_index": "对账文件系统 vs index.md,确认每页都登记"
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
AI Agent 使用指南:
- 当用户说「帮我给这个 Profile 建知识库」→ 执行
quick_start.step_1到step_2 - 当用户给一个新来源(URL/文件)→ 执行
step_3,完成后verification.check_index核对 - 当用户说「我的 wiki 好像乱了」→ 依次跑
check_orphans/check_broken_links/check_drift - 接管一个已有 wiki 时 → 先无条件执行
step_4Orientation,再做任何写操作
相关阅读: