我花了一下午让 Claude Code 遵循"规格驱动开发",结果出乎意料

本文由 Claude Code 基于我与她的真实开发对话总结撰写,所有数据和引用均来自公开研究。

先说结论

Vibe coding 不是坏习惯,它就是 AI 编程的默认形态,而且会越来越普及。

看看趋势:GitHub 说 2026 年 41% 的代码是 AI 生成的;RedMonk 预测这个比例还会涨。未来产品经理、设计师都能用自然语言写代码,专业程序员会变少,但编程的总量会爆炸。

所以 SDD(Spec-Driven Development)的定位不是"取代 vibe coding",而是让 vibe coding 更可控。就像开车:自动挡让驾驶变简单,但学会看路、懂交规才能开得好。

  • 简单任务——内部工具、原型、个人项目——纯 vibe coding 够用
  • 复杂任务——生产系统、团队协作、长期维护——SDD 能帮你少踩坑

为什么要搞这个

最近在玩 Claude Code 写代码,体验大概是:简单需求一把梭,效果不错。但稍微复杂一点,就开始出问题——AI 写的代码方向偏了、边界情况没处理、聊了 20 轮之后忘了最初在说什么。改一个地方崩三个地方。

这事儿有数据支撑:

  • 84% 的开发者在用 AI 编码工具,但只有 29% 信任它们
  • GitClear 分析了 2.11 亿行代码,AI 生成的代码重复率是手写的 4 倍
  • 96% 的开发者认为 AI 代码不完全正确,但只有 48% 每次都检查

Simon Willison 说得好:“如果 LLM 写了代码,你 review 了、测试了、能给别人解释清楚了——那不叫 vibe coding,那叫软件工程。”

所以我开始琢磨:怎么让 AI 写代码的过程更可控?

Vibe coding 的问题

“Vibe Coding” 是 Karpathy 在 2025 年初造的词,指的是用自然语言跟 AI 对话写代码。这确实是现在的主流,而且会越来越普及。

但在某些场景下会遇到瓶颈:

  • 68% 的人认为 AI 代码"快但不靠谱"——速度快了,长期质量是问题
  • 63% 的人报告调试 AI 代码的时间比手写还多
  • 11% 的人直接放弃项目——代码太乱、bug 太多,修不下去

Red Hat 的描述很精准:“vibe coded 项目通常在三个月左右撞墙。” 代码库膨胀到没人能完全理解,AI 的上下文窗口只能看到碎片。

METR 做过实验:让有经验的开源开发者分别用 AI 和不用 AI 完成复杂任务。结果?用 AI 的反而慢了 19%。 但 80% 的人还是更偏好用 AI,因为"感觉更轻松"。这就是"感觉快"和"实际快"的区别。

所以问题不是 AI 能不能写代码,而是怎么让它写出的代码可控、可审查、可维护。

Vibe coding 的价值

在讨论局限之前,得承认:vibe coding 就是 AI 编程的默认形态。

快速原型。 想验证一个想法?5 分钟出 demo,这在以前不可能。2026 年 41% 的代码是 AI 生成的——绝大部分都是探索性代码。

降低门槛。 非技术背景的人现在能"编程"了。Stack Overflow 上有个编辑用 vibe coding 从零搭了个项目,代码是"一团糟",但她学会了基本概念,项目也确实能用。

效率倍增。 Hashnode 的分析说,10 年以上经验的开发者用 AI 工具效率能提升 81%。资深开发者知道好代码长什么样,能一眼看出 AI 哪里写错了。

所以问题不是"该不该用",而是"什么时候需要加一层控制"。 市区通勤不需要导航,跨省自驾就需要了。

核心矛盾

AI 编程的本质是个翻译过程:把人的意图翻译成代码。 翻译质量取决于意图的精确度(你可控)和 AI 的理解能力(你不完全可控)。

这就引出了一个矛盾:

意图越精确,前期成本越高;意图越模糊,后期修错成本越高。

意图精确度:  低 ◄─────────────────────► 高
前期成本:    低                              高
后期风险:    高                              低
认知负担:    低(你说几句话就行)             高(要写 spec)
反馈速度:    快(秒级看到结果)               慢(要走完流程)

Vibe coding 选了左边,SDD 选了右边。大多数讨论都在争论"该选哪边",但真正的问题是:能不能根据场景动态选择?

Martin Fowler 的批评有价值——他不反对 SDD,他反对"所有场景都走完整流程"的一刀切。SDD 的 spec 有轻重之分,一个 5 行的 spec 和一个 50 行的 spec,成本和精确度完全不同。

SDD:给 vibe coding 加控制

SDD(Spec-Driven Development)不是取代 vibe coding,而是在需要的时候加刹车和方向盘

核心思想:先写清楚"要做什么",再让 AI 去做。 这不是新概念——瀑布时代写需求文档,敏捷时代写 User Story。但 SDD 在 AI 时代有了新的意义:AI 猜意图的能力有限,明确的 spec 能显著提升产出质量。

MSR'26 把 SDD 分成了三个层次:

  1. Spec-First——先写 spec,指导 AI 生成代码。最轻量,适合单个功能。
  2. Spec-Anchored——spec 保留作为后续维护的基准。中等投入,适合长期维护的功能。
  3. Spec-As-Source——spec 是唯一主文件,代码完全由 AI 生成。最重,适合 spec 稳定的场景。

这三个层次是在光谱上选了三个"停靠点"。Spec-First 最靠近 vibe coding——花几分钟写个简要 spec,就能显著提升质量。Spec-As-Source 最远——持续维护 spec,换来"代码可以随时丢弃重建"的能力。

Martin Fowler 体验了 Kiro、Spec-kit、Tessl 三个工具后,指出了真实问题:

  • “虚假控制感”——即使有了完整的 spec,AI 还是经常不按规矩来
  • markdown 爆炸——大量冗余的 markdown 文件,“我宁愿 review 代码也不想 review 这些 markdown”
  • 过度设计——修个小 bug 也要走完整流程,杀鸡用牛刀

他的结论是:SDD 工具需要更好支持迭代式开发,小的、原子化的工作包,而不是上来就搞一堆前置设计。

社区实践

调研了一圈,发现已经有一批人在实践 SDD。

Ivo Kund 的硬核实验: 把项目的 src 目录全删了,只靠 spec 重新生成。用 Claude Code 跑了大约 1 小时,花了 1% 的周配额。最后 Claude 自动把原始版本和重建版本并排打开,截图对比。那些微小的差异正好暴露了 spec 里没写清楚的地方——spec 的质量直接决定重建的质量。

XB Software 的发现: spec 的大小必须匹配任务的大小。试图一次性生成整个应用,模型会崩溃。把项目拆成小的、边界清晰的功能点,每个单独出 spec,质量就稳定了。

Gauge + Playwright: Ivo 用 ThoughtWorks 的 Gauge(Markdown 写 spec 的 BDD 框架)配合 Playwright 做 e2e 测试。75 个 e2e 测试 23 秒跑完,可以作为 pre-commit hook。spec 不仅仅是文档,是真正可执行的验证。

三个取舍

SDD 不是完美无缺,而是结构性的取舍——你得到一些东西,就必须放弃另一些。

取舍一:精度 vs 灵活性

spec 写多细?这是核心张力。

写太细,需求还没写代码就锁死了。需求变了(而需求几乎一定会变),要同时改 spec 和代码,维护两份"真相"。

写太粗,AI 又回到了"猜"的模式,SDD 的价值大打折扣。

所以真正的难点不是"要不要写 spec",而是spec 应该写到什么粒度。变化快的功能,spec 保持轻量;变化慢的核心逻辑,spec 可以写详细些。一刀切行不通。

取舍二:前置投资 vs 回报不确定性

SDD 要求写代码之前投入时间写 spec、做 plan、拆 task。这个投资能不能收回来,取决于你对需求的理解有多准确。

如果对需求理解清楚,SDD 回报很高——代码质量提升,后期调试和返工成本降低。

如果理解不清楚(而这种不确定性在软件开发中很常见),可能花了 30 分钟写 spec,写到一半发现需求本身就定义错了。这时候 spec 不是在帮你,而是在浪费时间。

SDD 假设你能事先把需求想清楚。但很多时候,你不写代码就根本不知道需求是什么。 这不是 SDD 的 bug,是软件工程的本质困难。

取舍三:审查对象转移

SDD 把审查重点从代码转移到 spec。听起来合理——审 50 行 spec 比审 500 行代码容易。但 Fowler 的体验说明不一定成立。

Spec-kit 生成了大量 markdown 文件,又长又重复。Fowler 说"我宁愿 review 代码也不想 review 这些 markdown"。因为 spec 文件本身也需要理解和判断——可能包含模糊描述、遗漏的边界条件、自相矛盾的需求。

更麻烦的是,还要审 AI 对 spec 的遵循程度——spec 说了要做 A,代码做没做?这相当于多了一层审查工作。

所以 SDD 的真实 overhead 不只是"写 spec 的时间",还包括"审 spec 的时间"和"验证一致性的时间"。

我的方案

综合了上面的实践和教训,我给 Claude Code 写了一个 SDD skill,流程六个阶段:

1. Spec      → 定义"做什么"
2. Plan      → 定义"怎么做"
3. Tasks     → 拆分成原子任务
4. Implement → TDD:RED → GREEN → REFACTOR
5. Verify    → 收集验证证据
6. Review    → 两阶段审查

Phase 1: Spec — Markdown 包含 Problem、Requirements、Acceptance Criteria、Edge Cases、Out of Scope。借鉴 Spec-kit,但合并成一个文档,减少冗余。

Phase 2: Plan — 技术方案、架构决策、需求到任务的映射、测试策略。借鉴 Amazon Kiro。

Phase 3: Tasks — 原子任务,每个有关联需求、复杂度估算(S/M/L)、TDD 步骤。借鉴 Spec-kit。

Phase 4: Implement — 严格 TDD,必须走完 RED → GREEN → REFACTOR。借鉴 Ivo Kund 的 /implement 命令。

Phase 5: Verify — 跑测试、lint、类型检查,逐条对照验收标准。没有新鲜验证证据,就不能声称完成。

Phase 6: Review — Stage 1 查规格合规,Stage 2 查代码质量。Stage 1 不通过就不进 Stage 2。借鉴 Faros AI 的 spec review gates。

Skill 放在 ~/.claude/skills/sdd/,Claude Code 启动时自动加载。

实测

纸上谈兵没用。我建了个 TypeScript + Vitest 计算器项目,已有 add 和 subtract,任务加一个 multiply 函数。

  • Phase 1: 生成了 feat-multiply.md,5 个功能需求、6 个验收标准、5 个边界情况
  • Phase 2-3: 3 个 Task,每个有 TDD 步骤、验证命令、依赖关系
  • Phase 4: 严格执行 RED → GREEN → REFACTOR,9 个测试全部通过
  • Phase 5: 测试、lint、类型检查全部通过,每个 AC 和 EC 都映射到具体测试
  • Phase 6: Stage 1 PASS,Stage 2 PASS

整个流程跑了大约 7 分钟。一个简单的 a * b 函数,产出了 4 份文档 + 9 个测试 + 完整验证证据。

说几句实话

测试结果看起来漂亮,但有几个地方让我犹豫。

第一,测试场景太简单。乘法函数需求明确、边界可枚举、没有需求变更——这恰好是 SDD 最适合的场景。如果换成"实现带权限管理的文件上传模块"这种需求不清晰的任务,SDD 的前置阶段会不会变成漫长拉锯?我怀疑会。

第二,Phase 2(Plan)和 Phase 3(Tasks)有大量重复。Plan 里写了实现步骤,Tasks 里又拆了一遍。如果是自己用,我可能会合并这两个阶段,小功能没必要拆这么细。

第三,7 分钟里,Claude Code 在写文档上花了大部分时间,真正写代码和测试可能只有一两分钟。如果只是想快速实现功能,这个 ratio 会让你觉得"太啰嗦了"。

结论:vibe coding 是默认,SDD 是增强

默认用 vibe coding,需要时加 SDD。

用两个维度判断:

  • 需求明确度 — 你对要做什么有多确定?
  • 变更复杂度 — 改动涉及多少文件、多少模块?
graph LR A[需求明确] --> B{变更复杂度} B -->|高| C[轻量 SDD] B -->|低| D[纯 vibe coding] E[需求不明确] --> F{变更复杂度} F -->|高| G[先 vibe 再 spec] F -->|低| H[纯 vibe coding] C --> C1[写简要 spec] G --> G1[探索后补 spec]
  • 简单场景: 纯 vibe coding。改动小,试错成本低。这是日常开发的常态。
  • 中等场景: 轻量 SDD。花 2-5 分钟写个简要 spec,给 vibe coding 加层保险。
  • 复杂场景: 先 vibe 再 spec。需求不清晰,先用 vibe coding 探索验证,确认方向后再补 spec。

核心原则: SDD 不是 vibe coding 的替代品,是它的增强工具。你不会为了去超市买瓶水而开导航,但跨省自驾时导航是必须的。

最后,随着 AI 越来越强,vibe coding 能覆盖的场景会越来越多。但"意图精确度"这个矛盾一直都在——系统越复杂,越需要清晰的规格来驾驭。

写在最后

SDD 不是什么革命性的新方法论。它更像是给 vibe coding 加的一套"安全装备"。

Vibe coding 是未来。 AI 越来越强,自然语言编程会越来越普及,专业程序员会变少,但编程的总量会爆炸。这个趋势挡不住。

SDD 只是让你少踩几个坑。 简单活儿 vibe coding 完全够用;复杂活儿花几分钟写个 spec,能省不少返工时间。关键是看情况,别死脑筋。

Fowler 说的"虚假控制感"确实存在——spec 写得再好,AI 也不一定会照做。但复杂场景下,一份不完美的 spec 也比没有强,至少给了你一个对照的基准,而不是在 AI 生成的代码迷宫里瞎猜。

如果你也在用 Claude Code,可以试试把 SDD 作为"复杂场景下的增强模式":

git clone git@gitee.com:sheweifan/skills.git ~/.claude/skills

下次遇到复杂功能时,Claude Code 会自动走 SDD 流程;简单功能时,纯 vibe coding 也完全没问题。


项目地址:gitee.com/sheweifan/skills