从 Vibe Coding 到 SDD:AI 协作开发的工程化演进
轻松程度没有变,但这次我们做出了工程应该有的样子。
起点:一次”跑通了但不对”的经历
几周前,我按照 Microsoft Learn 的实验手册(LAB_AK_13)用 VSCode + GitHub Copilot + GitHub Spec Kit 做了一次 RSS Feed Reader 的开发练习。手册设计得很完整:先生成 constitution.md 定义项目章程,再生成 spec.md 描述需求,然后是 plan.md 技术方案,最后是 tasks.md 任务列表,Copilot 按图索骥完成实现。
整个过程大约花了一个小时,应用跑起来了。
但我注意到一个问题:如果直接把手册扔给 AI,让它”读完手册然后写代码”,它确实能写出来——但写出来的东西不符合 SDD 的流程要求。它会跳过规范文档阶段,直接进入实现,结果是代码能跑,但没有 constitution、没有 spec、没有 tasks,整个文档体系是缺失的。
这让我开始思考一个问题:AI 缺的不是代码能力,缺的是被约束的能力。
问题的本质:没有合同,就没有工程
Vibe Coding 的核心体验是”想到什么说什么,AI 帮你实现”。这种方式在探索阶段很爽,但在工程交付场景里有一个致命缺陷:没有可验证的规范,就没有办法判断”做对了”还是”做完了”。
AI 生成的代码能跑,但:
- 它是否覆盖了所有需求?不知道,没有 spec 对照。
- 它是否遵循了技术约束?不知道,没有 constitution 约束。
- 它是否完成了所有任务?不知道,没有 tasks 追踪。
SDD(Spec-Driven Development,规范驱动开发)解决的正是这个问题。它的核心不是”让开发变得更复杂”,而是在动手之前把”什么算做对”说清楚。
四层文档体系:
- constitution.md:项目边界和技术约束(什么不能做)
- spec.md:需求规范,用 Given-When-Then 格式写验收标准
- plan.md:技术方案,架构决策和项目结构
- tasks.md:可执行任务列表,每个任务对应具体文件和验收点
这四个文档,就是人和 AI 之间的合同。
这次实验:双 AI 协作,人退出执行链
基于上次的经验,这次我换了一种方式。
我把角色拆成两个:
- HuaQloud(Claude Sonnet):架构师,负责读懂需求、生成规范文档、设计验证方案
- OpenCode(Qwen3.5):编码者,负责按 tasks.md 实现代码
我作为项目发起者,做了三件事:
- 把实验手册和参考项目交给 HuaQloud,说明”直接读手册会跑偏,需要你先生成规范文档”
- 确认 HuaQloud 生成的四层文档符合预期后,授权开始实现
- 在最终验收时审查结果
整个开发过程,我没有写一行代码,也没有手动触发任何 Copilot 命令。
结果:约 25 分钟,从零到可运行的 MVP。14 个源码文件,构建 0 错误 0 警告,6 项 API 测试全部通过。
Man-in-the-Loop:人不可缺席的三个环节
有人会问:既然 AI 能全自动,人还有什么用?
这个问题问反了。正是因为人在关键环节介入,AI 才能高效且正确地执行。
1. 需求理解:客户真正想要什么?
实验手册里有一句话很关键:“如果直接让 AI 读手册,它能把应用做出来,但不符合 SDD 的流程要求。”
这个判断,是我作为发起者做出的。AI 没有能力自己意识到”我跑偏了”——它只会按照最直接的路径完成任务。把需求翻译成正确的任务描述,是人的工作。
在真实项目里,这对应的是:和客户对话,理解他们说”我要一个 RSS 阅读器”背后真正的场景和约束——是给个人用还是团队用?需要持久化吗?MVP 范围是什么?这些问题 AI 无法替你去问客户。
2. 验收标准:什么叫”做对了”?
这次实验里,我设计了 6 项验证用例:
- 空列表初始状态
- 添加有效 URL
- 重复 URL 的幂等性处理
- 空 URL 的 400 拒绝
- 多条记录的完整性
这些测试用例不是凭空来的,它们来自 spec.md 里的 Given-When-Then 验收标准,而那些标准是我在理解需求之后定义的。
验收标准定义了”做对”的边界。没有这个边界,AI 交付的是它认为对的东西,不一定是你需要的东西。
3. 质量把关:过程中的判断和纠偏
报告初稿出来后,我发现 3.2 节过于简略,要求细化到每个 Task 的完成情况。这个判断,AI 自己不会做——它完成了任务,认为已经足够好了。
“足够好”的标准是人定义的,不是 AI 定义的。 这就是 Man-in-the-Loop 的核心价值:不是替 AI 干活,而是在关键节点做判断。
工程应该有的样子
回到最开始的问题:SDD 有没有让开发变得更复杂、更沉重?
没有。
生成四层规范文档花了不到 5 分钟。OpenCode 执行三个 Phase 的实现花了约 20 分钟。整个过程我的参与感和 Vibe Coding 差不多——说清楚要什么,等结果,确认,推送。
但质量完全不同。 Vibe Coding 的结果是”能跑的代码”,SDD 协作的结果是”有规范、有验证、有文档、可追溯的工程交付物”。
这两者的差距,不是 AI 能力的差距,是工作方式的差距。
AI 时代的工程师,核心竞争力不再是”能写代码”,而是:
- 能定义需求:把模糊的想法转化为可验证的规范
- 能设计约束:告诉 AI 什么不能做,比告诉它什么能做更重要
- 能判断质量:在 AI 认为”完成了”的时候,知道哪里还不够好
Vibe Coding 降低了入门门槛,SDD 提升了交付上限。两者不是对立的,而是同一条路上的两个阶段。
轻松程度没有变,但这次我们做出了工程应该有的样子。
延伸阅读:项目仓库导航
本文所有内容均有完整的项目记录可供参考,代码和文档均已开源:
仓库地址:https://github.com/cloudzun/RSSFeedReader/tree/002-ai-sdd-collaboration
仓库结构如下:
RSSFeedReader/
├── StakeholderDocuments/ # 原始需求文档(项目目标、功能描述)
├── specs/001-mvp-rss-reader/
│ ├── constitution.md # 项目章程:技术约束与边界定义
│ ├── spec.md # 需求规范:3 个 User Story + 验收标准
│ ├── plan.md # 技术方案:架构决策与项目结构
│ ├── tasks.md # 任务列表:19 个可执行任务,按 Phase 分组
│ ├── lab-report.md # 完整实验报告:逐任务完成记录 + 验证结果
│ └── tech-article.md # 本文
├── backend/RSSFeedReader.Api/ # ASP.NET Core Web API(端口 5151)
└── frontend/RSSFeedReader.UI/ # Blazor WebAssembly(端口 5213)
如果你对 SDD 流程感兴趣,建议按顺序阅读 constitution.md → spec.md → plan.md → tasks.md,可以完整还原从需求到实现的推导过程。lab-report.md 则记录了每个任务的实际交付情况和 6 项 API 验证结果,适合作为自己项目的参考模板。