Carry の Blog Carry の Blog
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • OpenClaw
  • Hermes Agent
  • Claude Code
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carry の Blog

好记性不如烂键盘
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • OpenClaw
  • Hermes Agent
  • Claude Code
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • OpenClaw

  • Hermes-Agent

    • Hermes Agent 概述
    • Hermes Agent 实战 01|架构总览:用一个 Agent 管一整个机房
    • Hermes Agent 实战 02|多 Profile 与超管模型:一个 Agent 安全地管十几台机器
    • Hermes Agent 实战 03|Gateway 运维:systemd、裸进程,和一个 Telegram token 撞车
    • Hermes Agent 实战 04|模型路由实战:config 全解、thinking 注入与 401/503 源码级根因
    • Hermes Agent 实战 05|技能工程:写、去重、pin,与每周自我审计
    • Hermes Agent 实战 06|让 Agent 自己上班:cron 驱动的无人值守巡检
    • Hermes Agent 实战 07|数据库实战:可直接抄走的 SQL Server 巡检脚本
    • Hermes Agent 实战 08|量化交易助手:持仓盈亏、网格减仓,与「没开单」的真相
    • Hermes Agent 实战 09|接入 OpenWebUI:把每个 Profile 暴露成一个「模型」
    • Hermes Agent 实战 10|升级不翻车,与给上游提 PR:一个被冲掉三次的修复
    • Hermes Agent 实战 11|踩坑合集:当「手动 rm」从来不是真正的修复
    • Hermes Agent 实战 12|工具链外延:用 AI 运维 AI,与这个系列的诞生
    • Hermes Agent 实战 13|旗舰篇:让 Agent 从零部署并灾难恢复一个 7 节点生产集群
    • Hermes Agent 实战 14|跨 Profile 消息路由与自托管服务巡检:两个被忽略的边界
    • Hermes Agent 实战 15|告别临时 RAG:用 Karpathy 的 LLM Wiki 给 Agent 装上可生长的长期记忆
      • 1. 我让 Agent「学一下」,它先翻了个车
      • 2. RAG 每次从零,Wiki 一次编译
      • 3. 实战:给一个 Profile 建知识库
        • 3.1 准备:三层架构与路径
        • 3.2 建好之后,你到底怎么用它
        • 3.3 喂材料(Ingest)
        • 3.4 提问(Query)
        • 3.5 体检(Lint)
      • 4. 上手当天踩的三个坑
        • 坑 1:预装 skill 不一定加载得上
        • 坑 2:长文档会被静默截断
        • 坑 3:raw/ 动了一下,溯源就断了
      • 5. 可复用要点
        • 三条心法
        • 三个硬规则
      • 6. 下一篇
      • 7. Agent 可直接解析的元数据块
  • Claude-Code

  • AI-Agent
  • Hermes-Agent
Carry の Blog
2026-06-29
目录

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 行为
1
2
3

路径用环境变量指定(写进 Profile 的 .env,不写死):

# 给你的 Profile 起一个知识库路径
export WIKI_PATH=~/.hermes/profiles/<your-profile>/wiki
1
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:值得留存的查询结果
1
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
1
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
1
2
3
4
5

raw 源材料自带一小段 frontmatter,关键是 sha256:

---
source_url: https://example.com/slow-sql-tuning
ingested: 2026-06-29
sha256: a3f9c2e1...        # 只对正文算,不含 frontmatter
---
1
2
3
4
5

这个哈希是漂移检测的基础——下次重新摄入同一个 URL,重算 sha256 一比对:一样就跳过,变了就标记并更新。一行哈希,解决「源内容偷偷改了我却不知道」。

# 3.4 提问(Query)

你问「索引碎片和统计信息过期,哪个更拖慢查询?」。它不去翻原始文档——直接读早就编译好的页面:

查 index.md 定位相关页 → read 这些页 → 综合答案
→ 有价值的综合结果归档到 queries/ → append log.md
1
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,标记不一致
1
2
3
4
5
6

# 4. 上手当天踩的三个坑

# 坑 1:预装 skill 不一定加载得上

  • 症状:直接调 research-llm-wiki skill 报错,流程卡住。
  • 原因: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. 可复用要点

# 三条心法

  1. Wiki ≠ Blog,别混 Blog 是对外成品(单向链接、一次发布);Wiki 是对内研究(双向链接、持续迭代)。用 wiki 时别想着「这能直接发吗」,那样会束手束脚。这俩是两种模式。

  2. 每次新会话先做 Orientation Hermes Agent 默认无状态。新会话第一件事:读 SCHEMA.md → 读 index.md → 扫 log.md 最近 20-30 条。跳过这步,Agent 就会给已存在的实体重复建页、漏掉该有的交叉引用。这 5 分钟省的是 2 小时的去重。

  3. 依赖要有回退,长读要防截断 这是上手当天换来的两条——别假设 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,确认每页都登记"
  }
}
1
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_4 Orientation,再做任何写操作

相关阅读:

  • Andrej Karpathy 的 LLM Wiki gist (opens new window) — 原始理念
  • 本系列前作:让 Agent 自己上班:cron 驱动的无人值守巡检
#AI Agent#Hermes#知识库#LLM-Wiki#长期记忆#Obsidian
上次更新: 6/28/2026

← Hermes Agent 实战 14|跨 Profile 消息路由与自托管服务巡检:两个被忽略的边界 Claude Code 概述→

最近更新
01
OpenClaw 实战 11|最佳实践:10 条从真实翻车提炼的 SOP + 推送二次确认硬规则 原创
06-27
02
OpenClaw 实战 07|部署指南:3 形态决策树 + OpenWebUI 接入 + FreshRSS 跨实例 原创
06-27
03
OpenClaw 实战 05|安全边界:SSRF 策略、设备 scope、与会脑补截图的模型 原创
06-27
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式