跳至正文
小莱沃 247 篇手记
← 返回专题

AI 原生团队 · 05 / 工作流

规格与代码对齐

不同 AI 工具如何共同消费同一份规格文档,以及如何防止文档和代码随时间漂移

SERIES 32 / 43 AI 原生团队 查看完整内容地图

不同 AI 工具如何共同消费同一份规格文档,以及如何防止文档和代码随时间漂移。


问题

规格文档和代码是两个独立演进的系统。工程师用 Cursor 写代码时,AI 看到的是代码;产品经理在 Notion 更新需求时,工程师不一定知道。随着时间推移,两者出现漂移——代码里有规格没提到的行为,规格里有代码没实现的约束。

这个问题用 AI 工具来写代码后会放大。AI 生成代码时,它只能根据它拿到的上下文来生成。如果规格不在它的上下文里,它就只能猜。

根本原因:AI 写代码时没有读规格,不是因为规格不存在,而是因为没有人传给它。


三个对齐机制

机制一:显式传递规格,在每次实现之前

最可靠、工具无关的方式。实现任何功能前,先让 AI 读对应的规格文档。

先读 docs/requirements/active/REQ-042.md,
了解验收标准和约束后,再实现支付模块的退款流程。

这一步不应该省略,也不应该依赖 AI”可能已经知道”。规格是输入,不是可选背景。

使用需求工具时/req:dev 命令会在开发前自动读取对应的 REQ 文档,把显式传递这一步内嵌到工作流里,不需要每次手动操作。

机制二:测试编码验收标准

把 REQ 的验收标准直接写成测试用例。测试是代码,任何 AI 工具在读取代码库时都会看到它。

# REQ-042 验收标准:退款金额不得超过原订单金额
def test_refund_cannot_exceed_original_amount():
    ...

# REQ-042 验收标准:退款请求在 48 小时内必须处理
def test_refund_request_expires_after_48_hours():
    ...

这样做的效果:即使 AI 没有读 REQ 文档,测试文件已经把规格的关键约束转换成了可见的代码。任何工具读到这些测试,都能理解这些行为是有意的,而不是意外的。

原则:一条验收标准 = 一个测试用例。不能写成测试的验收标准,要么是写得不够具体,要么是需要拆分。

机制三:工具特定的上下文配置

每个 AI 工具都有”告诉它默认读什么”的配置文件。这类配置应该明确指向规格文档的位置,而不只是写代码规范。

工具配置文件配置建议
Claude CodeCLAUDE.md说明 docs/requirements/ 结构,写明开发前必须读 REQ 文档
Cursor.cursor/rules/*.mdc@docs/requirements/ 引用规格目录
Windsurf.windsurfrules同上,指向规格目录
GitHub Copilot.github/copilot-instructions.md写明关键约束和规格位置
任何工具对话开始时手动粘贴粘贴 REQ 文档相关章节,而不是整个文档

这些配置的作用是降低每次传递规格的摩擦,不是消除传递规格这一步。


漂移的来源

了解规格和代码为什么漂移,有助于在对的地方建立检查点。

规格漂移:代码实现后,新情况出现了,工程师直接改代码,没有同步更新 REQ 文档。几个迭代后,REQ 描述的是已经不存在的行为。

代码漂移:REQ 更新了,但开发分支上的代码还是旧版本,或者新的 AI 生成的代码没有读新版 REQ。

两种漂移的共同根因:修改一处,没有同步检查另一处。


防漂移的检查点

在两个关键时刻建立明确的检查:

代码改变时:修改影响到某个已有 REQ 描述的行为时,打开对应 REQ 文档确认验收标准是否还成立。不成立则更新 REQ,同步更新测试。

REQ 改变时:更新 REQ 后,检查对应的测试是否需要同步修改。如果有 AI 工具正在相关功能上工作,重新传入新版 REQ。

这两个检查点不依赖工具,也不需要自动化——它们是判断,不是机械步骤。


不同工具的协作边界

当一个项目里同时使用多个 AI 工具时(Claude Code 做架构分析,Cursor 做日常开发,CI 里用 AI 做代码审查),对齐的核心问题是:谁是规格的权威来源?

答案必须是单一的:docs/requirements/ 里的 Markdown 文件。

每个工具都从这里读取,不维护自己的”理解版本”。工具特定的配置文件(.cursorrulesCLAUDE.md)只是告诉工具”去哪里找规格”,不是规格本身的副本。

docs/requirements/REQ-042.md   ← 唯一权威来源
       ↓
CLAUDE.md    → Claude Code 读取时的入口说明
.cursorrules → Cursor 读取时的引用配置
测试文件     → 验收标准的可执行形式

如果两个工具对同一个功能有不同的”理解”,根因是其中一个没有读最新版的 REQ,不是工具之间需要同步。


最低实践

  1. 每次开发新功能前:先读 REQ,再写代码
  2. 每个 REQ 的验收标准:至少对应一个测试用例
  3. 修改已有行为时:检查对应 REQ 是否需要同步更新
  4. 工具配置文件:写明规格目录位置,而不只是代码规范

发表评论