【风险规避】避坑指南:SPEC 为什么会失败?及应对策略

18 阅读5分钟

核心导读: 任何完美的工程理论,在遭遇“赶进度”和“人性惰性”时,都可能沦为一纸空文。在许多推行 SDD 的团队中,Spec 文档不仅没能成为拯救架构的解药,反而变成了拖慢节奏的“紧箍咒”。 本文将毫无保留地揭开 SDD 落地中最常见的三个失败场景(背景缺失、评审缺位、规约脱节),并为你提供一套基于“审阅-挑战-修正”循环的防御策略,确保规范永远是代码的“唯一真理”。

引言:破窗效应与“薛定谔的规范”

在推行 SDD 的前两个月,一切往往都是美好的。团队充满激情地编写 Markdown,看着 AI 像听话的士兵一样产出干净的代码。

但是,当遇到“双十一”前夕的紧急 Bug 修复,或者老板要求“明天必须上线这个小活动”时,噩梦开始了。 一个资深研发在深夜 11 点打开了 IDE。他觉得写 Spec 太慢了,于是直接对 Cursor 说:“不管架构了,直接在 Controller 里把这个判断加上,跑通就行。” 他心里默念:“我就走这一次捷径,明天我一定会把 Spec 补上。”

但他永远不会补了。 这在软件工程中被称为**“破窗理论(Broken Windows Theory)”**。一旦代码库中出现了没有 Spec 约束的“野生代码”,这块玻璃就被打破了。 随后,**规约脱节(Specification Disconnect)**发生:Spec 上写着系统是单向数据流,但底层的真实代码已经变成了网状调用。此时的 Spec 变成了“薛定谔的规范”——在你看代码之前,你永远不知道 Spec 里写的东西到底算不算数。

为什么 Spec 会失败?我们总结了三大致命陷阱。


第一章:三大典型失败场景剖析

1.1 背景缺失:把 AI 当成“没有过去的打字机”

表现: 开发者在写 Feature_Spec.md 时,极其简略,只有一句:“实现用户注册接口,包含手机号和验证码。” 后果: AI 由于没有全局上下文,直接捏造了一套全新的鉴权逻辑,完全无视了项目中已经存在的 OAuth2 基础组件。 本质: 这是人类怠政。没有前置的“全局宪法(Global Rules)”和“领域边界(Domain Context)”,局部的 Spec 就是没有根基的空中楼阁。

1.2 评审缺位:把 AI 当架构师而非“辅助”

表现: 让人类去写长篇 Spec 很难,于是大家让 AI 自己去推导并生成 Spec。生成后,人类看都不看(或者草草看一眼),直接点击“Approve”,然后让 AI 开始编码。 后果: AI 把幻觉写进了规范里。比如它在 Spec 中规定“为了性能,我们把所有订单数据常驻内存”。人类没审查就放行,最终导致线上服务器 OOM(内存溢出)崩溃。 本质: 忘记了复杂性二分法中“人类把控方向”的铁律。当人类放弃了 Review,SDD 就退化成了最劣质的 Vibe Coding。

1.3 流程形式化:规约脱节的万恶之源

表现: 开发和测试依然围绕着代码来沟通。发现 Bug,直接去修代码。最后为了应付流程,让 AI 根据改好的代码反向生成一个 Spec 存入文档库。 后果: Spec 彻底失去了“驱动(Driven)”的意义,变成了单纯的“文档(Documentation)”。这种本末倒置的做法,会让团队觉得写 Spec 是纯粹的负担。


第二章:应对之道——建立“审阅-挑战-修正”循环

为了防止 SDD 沦为形式主义,我们必须在组织文化和工具链上建立刚性防御机制。

graph TD
    subgraph SDD_Failure_Loop["❌ 失败的破窗循环 (规约脱节)"]
        A1["紧急需求/Bug"] -->|"跳过 Spec 编写"| B1["人类直接修改代码"]
        B1 -->|"代码变脏"| C1["Spec 彻底失效"]
        C1 -->|"下次 AI 依赖错误上下文"| D1["引发更大规模 Bug"]
        D1 --> A1
    end

    subgraph SDD_Success_Loop["✅ 健康的 SDD 闭环 (审阅-挑战-修正)"]
        A2["紧急需求/Bug"] -->|"强制阻断"| B2["更新/编写 Delta Spec"]
        B2 -->|"人类审查 (Review)"| C2{"AI 提出技术计划"}
        C2 -->|"人类挑战质疑 (Challenge)"| D2["修正架构边界 (Correct)"]
        D2 -->|"意图锁定"| E2["AI 执行编码"]
        E2 -->|"自动化验证"| F2["代码即文档, 永远一致"]
    end
    
    style B1 fill:#ffcdd2,stroke:#c62828,stroke-width:2px
    style B2 fill:#c8e6c9,stroke:#2e7d32,stroke-width:2px
    style D2 fill:#fff9c4,stroke:#fbc02d,stroke-width:2px

图 1:失败破窗循环与健康 SDD 闭环的对比

2.1 制度级防御:绝对的“单一真实来源”

团队必须确立一个生死契约:无论是多紧急的 P0 级 Bug,修复的第一步永远是修改 Spec。 你可以只在 Spec 里加一句话:“修复了当 id 为空时的并发争抢问题”,然后再让 AI 去生成代码。哪怕这多花 2 分钟,也保住了系统的概念完整性。 (实操建议:引入第五篇中提到的 Spec Kit,在 CI 层面阻断任何未经 Spec 变更的代码提交。)

2.2 认知防御:保持“挑刺”的心态(Challenge)

不要对 AI 生成的规范照单全收。高级工程师应该像面试候选人一样去**“挑战(Challenge)”** AI 的 Spec:

  • “这个接口的 QPS 峰值可能达到 10 万,你设计的这个 DB 结构扛得住吗?”
  • “如果在步骤 2 断网了,你的补偿机制在哪里?” 当你在前期将 AI 逼到死角,AI 在后续生成代码时就会写得极其严密。

结语:纪律是自由的基石

很多人认为规范(Spec)是对开发自由的扼杀。其实恰恰相反。 正是因为有了坚不可摧的架构纪律,我们才获得了不用在屎山代码中通宵 Debug 的自由。 SDD 不是一个自动驾驶系统,它是一套人机协作的操作系统。如果你选择放开方向盘呼呼大睡,车毁人亡只是时间问题。

规避了这些坑,SDD 就能帮助团队在当下活得很好。但这远不是软件工程的终点。 当所有代码都可以由大模型基于规范自动生成时,我们的行业将走向何方?请翻开本系列的终章——《【未来演进】从 CodeAgent 到全链路 AgentOps:软件 3.0 的终局》