跳转至

02 · Agent Notes:写给 AI 看的决策文档

dsh 的 spec 不叫 spec,叫 Agent Note,全部放在 .agents/notes/ 下。他们自己的定位是:"agent 写的 RFC"——记录一个决策的 why 和 放弃了什么,即代码和文档承载不了的部分。

截至 2026-08-15 的规模:proposed 25 篇 / implemented 507 篇 / rejected 11 篇 / archived 142 篇(按日期命名的英文 note 计数),每篇配英文、中文、i18n sidecar 三件套。三周后(09-04)是 27 / 657 / 9 / 175,增量的用法变化见第 09 章。

它长什么样

路径本身编码了状态和类别:

.agents/notes/{lifecycle}/{class}/yyyy-mm-dd-topic.md
             proposed/    feature/
             implemented/ bug-fix/
             rejected/    simplification/
             archived/    architecture/
                          process/
                          testing/

类别是闭集,由脚本校验;故意没有 refactor(他们认为它和 simplification 重叠,判别标准"可观察行为是否变化"已经覆盖了)。

每篇的骨架也是固定的。proposed 阶段:问题 → 提案 → 考虑过的替代方案 → 验收标准 → 风险。转正为 implemented 后必须改写成现在时:问题 → 决策 → 替代方案 → 后果。

它是怎么被实践的(一个真实例子)

以"防止模型重复调用同一工具"这个小插件为例,它的完整轨迹发生在 2026-07-08 一天内:

  1. 先写一篇提案进 proposed/:模型卡死时会反复跑同一条失败的 grep,白烧 token,问题真实且检测便宜
  2. 实现 + 测试 + 把提案挪到 implemented/,三件事在同一个 PR 里——挪的时候把所有"我打算做 X"改写成"现在的行为是 X"
  3. 修一条 review 意见,当晚合并

关键规则:每个非平凡改动必须在同一个 PR 里新增或更新一篇 note。粒度很细——一个几百行的小插件就配一篇。这不是"先写大文档再瀑布开发",而是每个 PR 自带一页决策记录。

要注意的是,上面这条"先进 proposed 再转正"的路径是特例而非常态:已经做出的决策直接从 implemented 开始,统计见第 09 章。

三条最值得学的设计

1. "考虑过的替代方案"是必填项

他们的原文理由(转述):一个决策如果不写清楚它打败了谁,以后一定会被反复重新争论——而防止重新争论正是 Agent Notes 存在的意义。

被否决的提案同样保留(保留到它不再能防住一个合理的错误为止,README 的原话是 "Keep a rejected note only while it prevents a plausible mistake; otherwise delete",到期就整篇删除,而不是改写)。rejected/ 里有一篇《2026-07 NIH 审计否决的依赖替换清单》:一次全仓库审计问了每段手写代码"有没有现成的包能替代",23 个看起来很合理的替换方案逐个被证据否决(比如某个包无法表达必需的字节上限、某个替换只能删 15 行却引入 1MB 依赖),全部留档。文档里明确写着:未来再提同类方案,必须击败这里记录的理由,不能只重新引用政策。

2. implemented note 与代码同步维护,过时则归档冻结

代码后来改了路径、重命名了包,必须在同一个改动里更新 note 中的事实(只更新事实,不改决策本身)。彻底过时的 note 走归档:三件套整体移入 archived/,之后永久冻结——不许编辑、不许翻译、不许当作现行规则引用,有脚本校验冻结清单。

3. 没有中心化的 INDEX.md——这个决定本身也是一篇 note

他们曾有自动生成的总目录,后来专门写了一篇 note 论证删掉它:路径已经编码了全部元信息,总目录是信息重复;几十个并行分支每加一篇 note 都要改同一个文件,是可预测的合并冲突热点;而 agent 找东西靠目录树和全仓库搜索,不靠翻目录页。文件系统本身就是索引。

反 slop:连"文档腐坏的样子"都有清单

他们维护一份 slop 清单,专门列 AI 写文档的坏毛病,当审计项跑:

  • 叙述历史("以前是 X,现在改成 Y")——文档只写现状,历史归 git 和 note
  • 状态标注("已实现!""future: ...")——状态会烂掉,代码本身就是状态
  • 推理过程复述——只留结论和契约,删掉推导路径
  • 强调通胀——到处加粗等于没有重点
  • implemented note 里出现 "should"、迁移计划、验收清单——这叫 spec-speak,格式门禁直接拒绝

为什么这套东西对 AI 开发特别重要

人类团队的决策记忆存在人脑里,口口相传尚可维持。agent 没有跨会话记忆,每次都是新会话冷启动——它对"为什么这里没有 X""为什么当时不选 Y"的唯一信源就是仓库里的文字。Agent Notes 本质上是给无记忆的协作者外挂了一份决策历史,而"替代方案必填"和"rejected 留档"防的正是无记忆协作者最容易犯的错:兴冲冲重新发明一个早被否决的方案。


← 上一章 · 返回目录 · 下一章:机器门禁 →