Skip to content

代谢协议规范 v2

本页地位

这是 kb-metabolism 代谢协议的权威规范,供兼容实现引用。工具可以被重写,协议和信号日志跟人走。 当前协议版本:2(与 .kb/config.jsonversion 字段对齐)。v1 → v2 变更见版本与演进承诺——数据格式不变,仅法医判定语义升级,无需迁移。

设计不变量

任何声称兼容本协议的实现必须满足:

  1. 文件 + git 是真相,一切索引均为派生物,可随时丢弃重建
  2. 访问日志是唯一不可再生的数据——追加式 JSONL,存于 vault 内,重建索引不得影响它
  3. 检索必须走门;没有日志就没有衰减判定
  4. AI 提案、人判决、git 兜底可反悔——不存在自动删除
  5. 零 LLM 时系统必须完整——智能只是省力插件
  6. vault 自包含:拷走目录 = 带走整个系统;秘密(secrets.json)永不进 git

分层模型

L0 核心(人读)   ≤ l0Cap(默认 100)条硬上限。每条 = 一句可复述判断 + 何时会再用。
L1 资料(AI 读)  能被检索到即可。零信号超过衰减窗口 → 处决候选。
inbox(暂存)     inboxDays(默认 30 天)到期。到期前升级或进名单。
_graveyard/       墓地。git mv 移入,可反悔;随时可真删(人工)。

frontmatter 字段

被管理笔记的 YAML frontmatter 使用 kb_ 前缀命名空间:

字段类型必填含义
kb_idstring(8 字符 base64url)系统分配稳定身份:出生(capture)或索引自愈时分配,终生不变;信号按它认领,移动/改名不丢续命记录。撞号(文件被复制)时索引给后到者重发
kb_tier"L0" | "L1" | "inbox"分诊后必有层级;缺失 = 未分诊
kb_use_whenstringL0/L1 必填一句话:什么时候会再用到(入口税
kb_triagedYYYY-MM-DD分诊后必有分诊日期
kb_expiresYYYY-MM-DD仅 inbox过期日,默认分诊日 + inboxDays
kb_digestedboolean可选已被消化为 L0,营养转移完毕

入口税铁律:写不出 kb_use_when 的内容,只能进 inbox 层。 兼容实现不得绕过。

信号日志(access.log.jsonl)

位置:<vault>/.kb/access.log.jsonl。追加式 JSONL,每行一条:

json
{"ts":"2026-07-09T10:23:29.390Z","tool":"kb_read","path":"sqlite-fts5.md","id":"aB3xK9pQ"}
{"ts":"2026-07-09T10:24:01.102Z","tool":"kb_search","query":"全文检索"}
字段类型说明
tsISO 8601信号时间(UTC)
toolstring信号来源(见下表;命名空间开放,未知工具必须被容忍)
pathstring?记录时刻的路径——给人读日志用(读取/引用类信号必有)
idstring?笔记稳定身份(frontmatter kb_id)——认领以它为准
querystring?检索词(检索类信号必有)

信号认领规则

法医等消费方把信号归给笔记时:id 按 id 认领;无 id 的历史行按"记录时路径 = 当前路径"兜底。 含义:笔记移动后,带 id 的信号无损跟随;仅有 path 的历史行会失联。 一次性根治:kb migrate-signals 给可解析的历史行补 id(自动备份原日志)——这是对 "日志只允许追加"红线的唯一官方豁免,目录大整理前务必先跑。

信号金字塔(法医认定的效力等级)

tool语义免死窗口
kb_cite被引用进真实产出citeDays(默认 180 天)
kb_read经门读取全文decayDays(默认 90 天)
kb_injecthooks 注入摘要且真相关(写入方必须做实词级相关性判定,如 idf 加权覆盖度)injectDays(默认 30 天)——摘要即答案也是使用,效力最低
kb_search / kb_add检索、捕捉不续命(记账用)
kb_ui管理界面浏览/检索不续命——观察 ≠ 使用

兼容实现新增信号类型时:默认不续命。让一种信号续命是协议级决定,必须升版本。

解析容错:读取方必须容忍撕裂行(进程中断产生的半行 JSON),跳过即可。

法医判定规则

法医只产出提案(处决名单),执行必须经人批准。一篇笔记成为候选,当且仅当:

  • inbox 层kb_expires 已过;或
  • 非 L0 层同时满足全部五条:
    1. 最后一次 kb_read 距今超过 decayDays(或从未被读)
    2. 最后一次 kb_cite 距今超过 citeDays(或从未被引用)
    3. 最后一次 kb_inject 距今超过 injectDays(或从未被注入)
    4. 活反链数 = 0(全 vault 扫描,含不受管理的目录;exclude 的除外)。链接只在两种情况下算担保:来源自身活着(内容年龄 ≤ decayDays,或有窗口内 read/cite/inject 信号),或来源在创作目录(outputDirs,铁证不降级)。只算一层,不做图迭代——死簇互链同批上榜,被使用的索引页仍保护其子节点
    5. 最后内容变更距今超过 decayDays——年龄取 git 历史中最后一次真实修改:纯重命名与批量提交(单提交文件数 > bulkCommitThreshold,默认 30)不算触碰;触碰全被过滤的文件回退出生时间;非 git 仓库回退 mtime

L0 永不上榜——挤掉 L0 是消化仪式里的显式人工动作,不是法医的职权。

处决与反悔

  • 名单格式:Markdown checkbox 列表(- [ ] \path` — 理由),人勾选 [x]` 即批准
  • 执行 = git mv_graveyard/(非 git 仓库降级为 rename),并建议自动提交
  • 还魂 = git mv 回库内任意位置
  • 墓地内容的真删除永远是人工操作,任何实现不得提供自动清空

配置文件(.kb/config.json)

jsonc
{
  "version": 1,                 // 协议版本
  "managed": ["**/*.md"],       // 受管理范围(glob)
  "exclude": ["_graveyard/**"],
  "captureDir": ".",
  "l0Cap": 100,
  "inboxDays": 30,
  "decayDays": 90,
  "citeDays": 180,
  "outputDirs": [],             // 创作目录:其中的引用是铁证级吸收信号
  "judgment": { "provider": "human", "triageModel": "…", "digestModel": "…" },
  "embedding": { /* 可选,见语义检索 */ }
}

完整字段语义见配置参考

版本与演进承诺

  • version 字段缺省视为 1
  • 破坏性变更(字段语义改变、信号效力改变、法医规则改变)必须升 version,并随版本发布迁移说明
  • 新增可选字段、新增不续命的信号类型属于兼容变更,不升版本
  • 先例:kb_id 与信号 id 字段(0.4.0 引入)即兼容新增——旧行仍被兜底认领,协议版本保持 1
  • v1 → v2(信号效力与法医规则改变,故升版本):kb_inject 从不续命升为第三档存活证据(injectDays,默认 30 天,写入方必须做实词级相关性判定);反链从无条件豁免降级为活源担保;年龄口径从"最后提交"改为"最后内容变更"(重命名与批量提交不算触碰)。迁移:无——日志与 frontmatter 格式不变,旧 config 缺省字段按默认值生效;v1 时代记录的 kb_inject 历史行在 v2 下自动获得效力(30 天窗口早已过期的行无实际影响)

MIT License