AI Agent规范驱动开发:宪法、检查点与交接
系统化展示如何用规范、检查点、显式交接约束AI编程Agent,解决大型特性开发中的上下文衰减问题;是当前最实用的Agent工作流范式。
系统化展示如何用规范、检查点、显式交接约束AI编程Agent,解决大型特性开发中的上下文衰减问题;是当前最实用的Agent工作流范式。
AI 编码 Agent 的能力有一种奇怪的不对称。交给它一个范围明确的任务,它能以比我更快的速度写出更好的代码。但如果交给它一个大型功能——那种需要花上几天、横跨多个层次并修改十几个文件的功能——失败模式就变了。context window 会逐渐塞满,输出质量也会悄然下降,也就是所谓的 context rot。新开的 session 因为缺少历史上下文,会自信满满地虚构一个从未存在过的 API。即使代码本身写得不错,最后你面对的也可能是一份长达 3,000 行、根本无法有效 review 的 diff。
这些问题无法仅靠模型本身解决。它们在很大程度上是流程问题。
我所采用的基础框架并不是我的原创,也不是什么新鲜事物:一份 constitution、若干 spec,以及经过刻意稳定化的 plan。这就是 spec-driven development,多年来一直以各种形式存在。我在日常实践中加入了两种运行机制,让这套方法能够撑过漫长的功能开发周期:明确的 checkpoint 和结构化的 handoff。
我的思维模型是:把 Agent 当成一位才华横溢但健忘的高级工程师。它当下非常敏锐,没有长期记忆,偶尔还会过度自信。你不会把一个需要两周完成的功能丢给这样的人,然后转身离开。你会先交代基本规则,给他一份 spec 和一份 plan,再分阶段 review 他的工作。这就是整个思路。
这些都是标准做法,所以我会简要说明。
Constitution。 一份简短但具有约束力的原则文档,规定项目绝不能违反的规则,例如依赖方向、测试标准、安全规则,以及“先写 spec,再写代码”。它拥有最高优先级;当某项需求与之冲突时,必须明确暴露冲突,而不是悄悄绕过规则完成编码。
Spec。 只描述 WHAT 和 WHY,包括用户价值、功能需求和验收标准。不涉及技术,也不涉及代码。
Plan。 描述 HOW,包括架构、契约,以及一份按顺序排列的细粒度、test-first 任务清单;每项任务都必须说明其如何符合 constitution。最关键的是,plan 一旦获得批准就会被冻结:它是唯一事实来源,Agent 无权在执行过程中悄悄改写它。
这为 Agent 铺设了轨道。但对于长期任务来说,只有轨道还不够。
一份 plan 可能包含 25 项任务。如果一口气执行完全部 25 项,你还是会回到 diff 大到无法 review 的老问题。因此,我会把 plan 切分成多个 checkpoint,也就是一组组适合 review 的任务。Agent 每次只处理一个 checkpoint,完成后就必须停下来。
每次停止时,它都必须完成以下事项:让 gate 全部变绿,包括 lint、类型检查、架构检查和测试;勾选已经完成的任务;写一段简短说明,记录所有偏离 plan 的地方;然后提交 handoff,等待 review。
review 本身分为两个阶段。编码 Agent 不会直接把工作交给我。它会先为另一个独立的 reviewer Agent 写一份简报,说明改了什么,以及为什么这样改。我会先阅读这份简报,因为编码 Agent 选择解释什么,以及刻意遗漏了什么,都能告诉我应该重点查看哪些地方。随后 reviewer Agent 会开始检查 diff,而我会把它的发现与自己的判断进行对照。每个切片只有几百行代码,并且是一个内聚的单元,因此整个过程确实可控。无论如何,批准权都在我手里;不能仅凭某个 Agent 的一句话就继续推进。
由此会自然产生两项效果:
复杂度始终有界。 我 review 的从来不是“整个功能”,而是一个 checkpoint。偏离方向和错误假设会在 checkpoint 2 被发现,而不是拖到 checkpoint 7 才暴露。
验证是真实可信的。 每个 checkpoint 都以 gate 全绿和相应证据作为结束条件,因此“完成”有了明确含义。在亲自运行命令并阅读输出之前,我不会相信它真的完成了。
在步骤之间暂停并不是什么新概念。我真正做成可重复机制的是它的产物:一份由人和 Agent 共同维护的 checkpoint tracker。这样一来,停下来 review 就成了默认流程,而不是事后想起才补上的环节。
大型功能的生命周期往往会超过单个 Agent session。context window 可能被塞满,我可能第二天才回来继续工作,也可能中途更换模型。新 session 对过去三天做出的决定毫无记忆。放任不管的话,它会重新争论已经定下来的选择,或者凭空臆造当前状态。
我是通过一连串乏味的教训才认识到这一点的。新 session 会重新引入我们两天前已经删除的 API,重新讨论早已确定的架构决策,还会悄悄丢掉某项 invariant,仅仅因为背后的推理已经滚出了 context window。在第三次 review 同一个决定之后,我不再坐等这种事情发生。
所以,我不会等到 session 开始退化。我会主动让它退场,并按照我设定的方式,把工作交接给一个全新的 Agent。
每个功能都会配备一份 HANDOFF 文档。这是一份持续更新的页面,只告诉下一个 session 它确实需要知道的内容,不多也不少:
任务导览: 应该按照什么顺序阅读哪些文档,包括 constitution、spec、被冻结的 plan,以及 checkpoint tracker。
绝对不能违反的硬性规则。
当前状态: 所在分支、commit,以及已经完成了哪些 checkpoint。
已经做出的决定,以及这些决定背后的 why,避免它们被重新拿出来讨论。
下一项任务,以及经过有意识判断后暂缓处理的事项。
新的 Agent 会读取 handoff 和被冻结的 plan,于是重新获得可靠的事实基础。不会发生 context rot,也不会凭空编造,因为 ground truth 存放在文档里,而不是塞在一个即将溢出的 context window 中。
在最近一个 AI 系统后端功能中,六个不同的 Agent session 共同完成了七个 checkpoint 的代码。每个 session 都从全新的 context 开始,其中一些甚至使用了不同的模型,但没有任何一个需要我重新解释已经做出的决定。
每份 handoff 写完后,我都会亲自阅读。如果新 session 提出了一个本应由文档提前回答的问题,我就会进一步完善 handoff 模板。
还有一个可以调节的杠杆:并不是每个步骤都值得使用同等强大的模型。规划和 code review 是杠杆效应最高、也最难逆转的环节;一个糟糕的 plan 会污染后续所有工作。相比之下,按照一份被冻结且足够详细的 plan 执行实现,更多是机械性的工作。
在 plan 和 reviewer Agent 上使用推理能力最高的层级,目前是 Fable 5,因为这些环节中的判断会产生复利效应。
实际编码则降低一个层级,使用 Opus 5;对于机械性较强的部分,也可以使用 Sonnet 5,因为 plan 和 checkpoint gate 已经提供了护栏。
每个 checkpoint 都有人类 review 作为安全网,因此用成本更低的模型完成编码也足够安全。这是一种很不错的成本与质量权衡:把预算花在真正需要思考的地方;在轨道已经铺好的环节节省成本。
Request → Constitution → Spec → Frozen Plan
│
└─> ( Checkpoint → Gate → Review ) × N
↑ │
└───── HANDOFF ◀─────┘
可 review 的 diff。 始终以 checkpoint 为单位,绝不交付一个庞然大物。
有事实依据的 Agent。 handoff 加上被冻结的 plan,可以战胜 context rot 和幻觉。
真实的验证。 每次停止时,都必须有全绿的 gate 和验证证据。
成本控制。 在能体现价值的地方使用强大模型;在轨道已经稳固的地方降低一个层级。
连续性。 无论任何一个 session 何时结束,功能开发都能继续。
最出人意料的经验是:随着 Agent 越来越擅长写代码,瓶颈会转移到两个方面——如何让它们始终基于事实工作,以及如何让你自己持续参与其中。constitution、checkpoint 和 handoff 就是我同时解决这两个问题的方式。说实话,它们甚至让我在亲手编写代码时,也成了一名更自律的工程师。
我已经把整套流程制作成模板,包括 constitution、spec/plan 模板、checkpoint tracker 和 handoff 文档,并将其作为 starter kit 放进新项目:hannody/spec-kit。它与编程语言和业务领域无关;你可以 fork 一份,再根据自己的技术栈调整 constitution。
对于后续操作,你可以考虑屏蔽此人和/或举报滥用行为。