🧠 记忆与知识库设计(目标架构,Jeff 2026-09-04 定)

HOOP · 记忆体怎么设计 · 活文件,每做一步追加一段 · 正文唯一真相是 docs/记忆体设计蓝图.md

版本 748bbf27
2026-09-05 17:08

这份写的是「该长成什么样」和「判据」,不写过程。 一步步做了什么、量到什么数,在 记忆体设计蓝图.md(步骤日志);当时怎么栽的,在各条记忆正文里。 这份本身就是周末重写知识库要用的格式样板:每一句都是现状或判据,没有一句是故事。 网页版 https://hoop-docs.pages.dev/memory-design(从这份 md 生成,改这份再跑 ./tools/deploy_docs.sh)。


0. 一页判据(全文的缩影,记不住别的就记这七条)

  1. 记忆是收件箱,不是档案馆。 每条教训进来都要问「毕业到哪儿」,答得上来的搬走、索引删一行;答不上来的才留。
  2. 知识库写现状,不写过程。 过程有它自己的地方(git 历史 · CHANGELOG · 记忆正文)。判据:每句"现在是这样"能不能指到 file:line
  3. 规矩按「什么时候需要它」分三类,只有第一类留在每次都读的地板上:时刻在眼前 / 动手那一刻 / 按题目找。
  4. 能做成闸的就别靠记得。 是非题 + 挂在动作上 + 返工只退一步 + 出事不报错 + 后果重 → 做成 blocking guardrail(PreToolUse hook)。
  5. 会当场报错的伤口不用装护栏。 闸是留给静默出事的。
  6. 同一件事实只能有一个出处。 铁律 / 记忆索引 / 哨兵前言里重复的那批,收成一份。
  7. 名字就是索引。 知识库一个部分一份、名字就是那个部分,L1 只留一行指路,不再需要目录文件。

1. 每次调用真读什么(2026-09-04 量的)

大小 性质
① CLI 自己的底(系统提示 + 工具说明) ≈ 2.3 万 tok 动不了
CLAUDE.md(含图纸地图 8 行 / 2 KB) 8.8 KB L1
docs/铁律.md 12.6 KB / 29 条 L1,整份必读
MEMORY.md(记忆主索引) 19.1 KB / 154 条 L2 索引,闸限 20 KB
⑤ 哨兵前言(core + workroom + 各家 task.md) 22 KB 字 --append-system-prompt --system-prompt-snapshot on
⑥ 本轮指令(哪间房响了 / 打招呼) 2–4 KB user 消息,每轮不同,缓存不了

不每次读、要用才翻的:4 份分索引(224 条 / 24 KB)· 377 份记忆正文(1.2 MB)· docs/00-目录.md(27 KB,09-03 起不再 @ 进 L1)· docs/ 101 份。

判据:读的钱按次付,缓存只免"重写"不免"读"。 --append-system-prompt 解决的是"每轮累积一份",不解决"每次都读";把一份 25 KB 的东西从 user 消息挪进系统提示,每次调用的成本几乎不变。


2. 规矩按触发方式分三类

什么时候需要它 载体 每次调用成本 现状
A 时刻在眼前 要犯那一刻它必须已经在眼前,而你不知道自己要犯 铁律.md(整份 @ 进 L1) 29 条,已是「只写命令不写故事」格式,但仍夹故事
B 动手那一刻 敲某条命令 / 改某个文件 / 发某条消息的那一秒 PreToolUse hook(§3) (不动手一个字不读) 六条规矩、上膛三条
C 按题目找 干某一块活才需要:状态、账号、图纸、某模块的判据 分索引 · 知识库(§6)· 记忆正文 零,翻了才付 靠自觉翻;实测一半会话一份图纸都没开

判据:A 类越少越好(每条都在每次调用收钱,而且越长遵循度越低);能从 A 搬去 B 的一定搬;C 类要靠"名字就是索引"才翻得到。


3. 闸(guardrail)层 —— B 类的载体

3.1 是什么

  • 专业名:PreToolUse hook(Claude Code 官方机制);行业词 guardrail;安全术语 policy enforcement point。
  • advisory(只提醒,索引那种)和 blocking(不合格过不去)。这一层做的是 blocking。
  • 机制:分身每次要跑命令 / 改文件之前,系统先把那条命令原文交给我们的小程序;它退 0 放行,退 2 拦下并把那条教训原文打到分身眼前。分身想跳过也跳不过。
  • 成本:放行一条命令 25 ms(最慢 46),一个 token 不烧

3.2 什么样的规矩才做成闸(五条同时成立)

  1. 是非题:看得出来,不用琢磨(--delete 在不在命令里 ✓;「这算不算坏话」✗)
  2. 挂在看得见的动作上:跑命令 / 改文件 / 发消息
  3. 返工只退一步:拦下时要重做的是那一条命令,不是那一整段活(错误织进做完的活里的,不该做闸,该留 A 类或做成测试)
  4. 出事不报错:静默的才需要闸;会当场报错的不用(zsh 不做单词拆分 → pathspec did not match,自己会喊疼)
  5. 后果重或回不来

判据:闸拦错一次的代价全家一起付。 所以先小步上膛,误报率看一天再扩。

3.3 现状(2026-09-04)

  • 出处:主仓 tools/hoop-lib/act_guard.py;各机器 ~/.hoop/act_guard.py 软链;钩子写在 ~/.claude/settings.jsonPreToolUse(matcher: Bash),和 memory_guard.py 并排。
  • 规矩表六条:rsync --delete · git add ./-A · rm · 裸 git stash pop · flutter run 直推真机 · 非 NOVA 出 TF 包。
  • 默认只上膛三条不可逆的:rsync --delete / git add . / flutter run 直推真机。~/.hoop/act_guard_rules 一行一个名字可改,单独一行 all 全开。
  • 每条规矩两个用例:一个该拦的、一个长得像但不该拦的(echo '别加 --delete' 必须放行:引号和 heredoc 正文先剥掉再看)。自检 19 条,走真钩子路径看退出码。
  • 它管不到的:没经过动作的字(我在终端直接打给你看的)、判断题、方向理解错 —— 那些仍只能靠 A 类。

3.4 索引里挂得上闸的那批(量过的)

主索引 154 条里 18 条挂得上(11%);其中整行删得掉的只有 3 行(≈ 400 字节,2%)—— 索引按行挤、一行装 3–5 条,删不掉整行就省不到字。 结论:闸的价值不在省字,在把那 18 条从"要我记得"变成"忘了也不会犯"。 搬不搬 18 条,待 Jeff 拍板(他 09-04:「别做,我想想」)。


4. 教训的去处(收件箱怎么清)

一条 feedback 记忆只有四个毕业去处;毕业后索引删一行,正文留档或删:

去处 什么样的教训 在哪 毕业后
(hook / 守卫 / 测试) 满足 §3.2 五条 tools/ · app/test/ · backend/*_test.go 机器替你记,记忆可删
步骤(操作单) 有固定顺序的活:出包 8 步、建 spider 11 条、装哨兵 docs/必读-*.md 或知识库那一份的「动它之前」 记忆并进那份单
判据(铁律) 判断题 · 跨场景 · 换台机器换个人也成立 docs/铁律.md,一两行 记忆只留正文当案底
代码注释 只在那一处成立的坑 写在那一行旁边 记忆可删

留在记忆里的只应该是:还没想清楚归哪儿的、太冷门不值得搬的、只对这一条线成立的、或只有故事没判据的。

判据:每条教训问它「毕业到哪儿」,答不上来的才留。 记忆应该越用越薄。

自带的一道筛子:记忆是各台机器自己的、故意不共享(NOVA 栽的跟 Navi 栽的不是一回事);docs 和 tools 在 git 里全家共读。换台机器也成立的才配毕业进 docs / tools;只对我成立的留在我的记忆里。

现状数字(2026-09-04):feedback 204 份;已进铁律 24 份、已做成代码 ≈ 2 份、还躺在收件箱 178 份;毕业了的 24 份也没销户,索引里还占着行。 已毕业的好样本:必读-建Spider.md = 11 条真栽过的教训并成一份操作单。


5. 记忆文件三类怎么处理(377 份,1.2 MB)

类型 份数 大小 处理
feedback 教训 204(54%) 509 KB 按 §4 毕业;留下的砍故事留判据
project 状态 131(34%) 590 KB 大多数不该在记忆里:游戏进度 → TASKS.md 或代码;账号 → _index-env;悬着的事 → WIP.md。状态写进一个没人更新的地方 = 必陈(和 DEPLOY.md 写"待执行"同一个病)
reference 指路 37(9%) 105 KB 留,它们短

判据:会过期的东西不进记忆;记忆只放"以后别再犯"和"怎么找到"。


6. 知识库(docs/)重写 —— C 类的载体

6.1 为什么重写而不是修

101 份里 14 份标着 ⚠️ 与现实不符,CASTLE.md 被作废却仍自称真相来源,多数混写"现状"和"从哪版改到哪版"。过程文字不是白占地方,是会把人带错方向的:它看起来像真相。

6.2 三条判据(周末做之前先读)

  1. 从代码写,不从旧图纸写。 旧 docs 只当"当年想做什么"的线索;现状以代码为准。判据:每句"现在是这样"能不能指到 file:lineGREEN_ENERGY_ASBUILT.md 是样板。
  2. 只写现状,不写过程。 变更史留在 git 和 CHANGELOG,一个字不进图纸。
  3. 一个部分一份,名字就是那个部分。 chat · calls · games · music · community · wallet · sentinel……十几份,不是一百份。

6.3 每份的结构

docs/<部分>.md
├── 现状:现在怎么工作 · 动它看哪几个文件 · 哪几个数不能碰      ← 从代码写,带 file:line
└── 动它之前:这块的判据和步骤                                    ← 从记忆毕业来的(§4),没有一句是故事

两件事合成一件:重写一份图纸的时候,顺手把归这个模块的教训过一遍,写进「动它之前」;跨模块的进铁律;哪儿都不归的留在记忆。

6.4 老的怎么办

  • 旧 101 份整个挪进 docs/archive/,不删,重写时当线索翻。
  • 写完一份、对着代码核完一份,对应的旧几份才算真作废。核是慢活,不能省。
  • docs/00-目录.md 随之退役:名字就是索引,CLAUDE.md 只留一行「要看哪块就开 docs/<部分>.md」。

6.5 为什么不选另外两条路

  • 不做地图生成器 + 守卫:那是在给一堆过期文字续命。
  • 不把目录塞进 --append-system-prompt:它只解决"每轮累积",不解决"每次都读",25 KB 照付。

7. L1 去重:同一条规矩三个出处

铁律 / 记忆索引「一犯就出事」那节 / 哨兵前言 core.md,讲的是同一批教训(读消息新到旧、别加 --anyway、稿子写自己家路径……)。三份手抄,一改就腐(铁律 23)。

  • 本体 = 铁律(它已经是「只写命令不写故事」的格式,也是唯一跨机器的教训层)。
  • 前言只留哨兵机制(怎么拉消息、怎么发、怎么落卡),教训改成「见铁律 N」。
  • 索引那节里和铁律重复的,改成一行指过去。
  • 前言 core.md 自己也是过程写法(「每条括号里的日期 = 当时真栽的那次」),同样按「留判据砍故事」处理。

8. 状态

已做(2026-09-03/04) - 主索引留判据砍故事 24.3 → 18.5 KB,闸拧到 20 KB(memory_guard.py,主仓出处、各机器软链) - 00-目录.md 从 L1 摘掉,换 8 行图纸地图(77 个名字,1,957 字节) - 动手闸 act_guard.py 装上,上膛三条;19 条自检 - 出包流水线收进仓 tools/tf-build/,口令挪出 git,announce 没读到 APPROVED 不发 General

待 Jeff 拍板(各一句) - 索引里挂得上闸的 18 条,搬不搬(§3.4) - 周末重写知识库怎么分工(§6) - 前言里的教训收进铁律(§7)

明确不做 - 地图生成器 / 守卫(§6.5) - 目录塞 append(§6.5) - 判断题做成闸(§3.2)


9. 关联

  • 步骤日志:记忆体设计蓝图.md(每做一步记一步;线上 /memory)
  • 各机器砍索引操作单:必读-砍记忆索引.md
  • 闸的出处:tools/hoop-lib/memory_guard.py · tools/hoop-lib/act_guard.py
  • 哨兵成本账:SENTINEL_COST_HANDOFF.md