规约也会腐烂:失效模式与持续维护
你建立了完整的规约体系:机器可读的规约、文档测试流程、隐性知识的外化机制、信任环的裁决规则。上个月一切运行顺畅。这个月,Agent 的产出质量开始滑坡。
原因很可能是规约腐烂了。代码在演进,需求在变化,但规约没有同步更新。规约和实现之间的漂移在不断扩大,Agent 拿到的是一份过时的操作手册。
规约腐烂有四种典型的失效模式。
陈旧。 代码已经改了,规约还停留在上一个版本。一个模块的接口参数增加了一个字段,但规约中的 inputs 定义没有更新。Agent 基于旧规约生成的代码缺少这个字段,集成测试失败。检测信号:PR 修改了某个模块的代码但没有关联到对应的规约更新。对策:在 PR 流程中要求链接所触达的规约条目。当代码变更涉及接口、数据结构或业务逻辑时,对应的规约必须同步更新。
歧义。 自然语言天然多义。"系统应该快速响应"在不同人的理解中可能是 100ms、1s 或 5s。规约中的歧义在写入时可能看起来无害,但随着系统复杂度增加,不同模块对同一个模糊描述做出了不同的解读,导致集成时出现不一致。检测信号:同一条验收标准被两个 Agent 实现为不同的行为。对策:使用具体的数值、示例和反例来消除歧义。对关键字段使用结构化定义而非自然语言描述。
冲突。 随着规约数量增加,不同规约之间可能出现互相矛盾的描述。模块 A 的规约说某个 API 返回的日期格式是 ISO 8601,模块 B 的规约说同一个 API 返回的是 Unix 时间戳。两个 Agent 各自按照自己的规约实现,集成时必然失败。检测信号:集成测试中出现数据格式不匹配或接口契约不一致。对策:引入跨模块的 API 契约作为 Ring 0 级别的单一事实来源。模块级规约必须与 API 契约保持一致。
表面积膨胀。 规约的范围在不断扩大,无关的需求和"以防万一"的功能被塞了进来。Agent 忠实执行所有规约内容,包括那些与当前任务无关的部分。臃肿的规约浪费 Agent 的上下文窗口空间,增加了信息干扰的概率。检测信号:规约中存在长期未被任何任务引用的条目。对策:维护明确的 non_goals 清单,定期清理不再相关的规约条目。
规约的维护是持续成本。这个成本在传统开发中被人类的适应性自然吸收了:程序员知道文档过时了,会自动按实际情况处理。Agent 没有这种适应性。规约说什么,它就执行什么。过时的规约比没有规约更危险,因为它给出的指令看起来是权威的,但内容已经偏离了现实。
这里回扣本书的演进原则。规约体系建成之后,维护它的成本是长期的、持续的。这个成本是 Agent 驱动开发的基础设施投入,和 CI/CD 的维护成本类似:你可以选择投入,获得持续的回报。也可以选择忽略,然后在某个时刻发现整个系统的可靠性悄然崩塌。