选择适合你的工作流:方法论组合实践
本章要点
来到这一节,你已经认识了第五章介绍的全部三种方法论。让我们快速回顾一下它们各自的核心关切:
Vibe Coding 问的是:我如何以最自然的方式,和 AI 一起把想法快速变成代码?
TDD(测试驱动开发) 问的是:AI 生成的代码,怎么证明它真的做到了我要求的事?
SDD(规范驱动开发) 问的是:在动手之前,我们要构建的究竟是什么?
三个问题,三个不同的焦点。你现在手里有三把工具,接下来的挑战是:面对一个真实的任务,你该用哪把?
这正是本节要回答的问题。读完这一节,你会获得:
- 一个清晰的决策框架,帮你根据任务规模和风险等级快速选择方法论
- 理解 TDD 和 SDD 如何协同工作——它们不是竞争关系,而是互补关系
- 认识三种实际工作中最常见的方法论组合模式
- 建立一种"弹性切换"的工作节奏,让你在不同场景间自如转换
三条光谱上的三个刻度
要理解如何选择,先要看清楚这三种方法论在本质上代表着什么。
我想用一个比喻来描述它们之间的关系:想象你要建一个房子。
Vibe Coding 是这样盖的:你走进一片空地,脑子里有个大概的画面——"三室一厅,有个院子"——然后你带着一个手艺非常好的工人,每天早上说"今天我们先把这面墙立起来",下午说"窗户放这里感觉不错,换个位置试试"。你凭感觉推进,工人随机应变,最快两周能住进去。
TDD 是这样检验的:你在盖房子的每一步,都预先定下验收标准——这面墙必须能承重多少,这扇门必须能开关多少次不坏,这块地板必须防滑到什么程度。建完一块,就对照标准验收一块。工人的活再快再漂亮,没过验收就不算完成。
SDD 是这样规划的:在动第一块砖之前,你先请建筑师画完所有图纸——几室几厅、承重结构在哪、水管电线怎么走、外立面风格是什么。所有人看过图纸,达成共识,确认"我们要盖的就是这个",然后才开工。
三种方式,严谨程度递增,前期投入也递增。没有哪种"绝对更好",只有哪种"更适合当前的情况"。
如果你回头看第五章,会发现 Karpathy 提出 Vibe Coding 时,他自己就在强调"扔掉就不心疼的周末项目";Superpowers 的 TDD 框架在严肃工程项目(如 chardet 7.0.0)上展现了惊人的威力;而 Spec Kit、OpenSpec、Kiro 这些 SDD 工具,无一例外都在瞄准那些需要长期维护、多人协作的真实系统。
这不是巧合,而是每种方法论的设计初衷使然。
你的任务,需要多少"安全网"
当你面对一个具体任务时,选择工作流的关键问题不是"这个方法论好不好",而是**"这个任务出了问题,代价是多大"**。
换句话说:你需要多厚的安全网?
这个代价,可以从三个维度来衡量:
生命周期:这段代码会存活多久?是今晚用完就扔的脚本,还是会在生产环境跑好几年的核心逻辑?生命越长,积累的问题就越难清理,安全网要越厚。
影响范围:这段代码会被多少人、多少系统依赖?是你一个人用的小工具,还是每天有几万用户依赖的服务?影响越广,一个隐藏的 bug 能造成的损失就越大。
可见度:这段代码将来出了问题,你能找到吗?如果代码结构清晰、有测试、有规格,一旦出错,你有工具可以定位。如果代码是纯 vibe 生成的、你从未仔细读过,出了问题你可能连从哪开始查都不知道。
把这三个维度放在一起,你大致可以得到一个直觉上的判断:
一个周末写的个人工具,生命周期短、影响范围小、你自己用、出了问题最多就是"这个工具今天不好用了"——安全网需求很低,Vibe Coding 完全够用。
一个中型功能模块,要加到你长期维护的项目里,会被你的代码库依赖、将来要被你或同事修改——安全网需求中等,至少需要 TDD 来保证每个关键行为都有测试覆盖。
一个新产品的核心架构,从零开始、多人参与、预计运行很多年、出错有真实业务损失——安全网需求高,需要 SDD 把规格写清楚,再配合 TDD 把实现验证好。
TDD 与 SDD:一对互补的搭档
在真正进入组合实践之前,有一个关系值得单独说清楚:TDD 和 SDD 不是竞争关系,而是互补关系。
这两种方法论解决的是相邻但不同的问题。
SDD 问的是**"要构建什么"**——它关心功能的边界、架构的约束、接受标准的定义。一份 SDD 规格文档像是建筑图纸:它描述了这栋楼要有几层、每层做什么用途、哪些墙是承重墙。
TDD 问的是**"实现正确了吗"**——它关心每一段代码的行为是否符合预期,边界情况是否被处理。一份 TDD 测试套件像是建筑验收标准:它描述了什么情况下这栋楼算是"合格"。
工程师 Josh Duncan 在他关于多智能体开发的文章里,用一句话把这个关系说得很清楚:"SDD 关注的是为 AI 代理定义要构建什么,TDD 关注的是验证人类构建的是否正确。你完全可以——而且应该——把它们结合起来使用。"
把这个逻辑延伸开来,两者的关系实际上是这样的:你的 SDD 规格文档为 AI 代理定义了"目标";AI 代理用 TDD 的方式实现代码,测试验证每一步的正确性。规格是战略层,测试是战术层,它们在不同的抽象高度上协同工作,互不冲突。
在实际项目里,你很快会发现这种组合的美妙之处:写规格的过程,往往自然地帮你想清楚了测试应该覆盖哪些场景。当你在 SDD 阶段写下"用户尝试登录时,如果密码错误超过五次,账户应被临时锁定",你其实同时定义了一个需要 TDD 验证的具体行为。规格和测试,是同一种严谨思维的两个层面的表达。
三种实际工作中的组合模式
理解了三种方法论的关系,我们来看它们在实际工作中最常见的三种组合模式。
模式一:轻量起手——Vibe Coding(可选配 TDD)
适用场景:快速原型、一次性脚本、学习探索、早期想法验证
工作节奏:
你有一个想法,或者需要快速验证某个技术方案是否可行。这时候你不需要写任何规格,直接在 Claude Code 里开始描述需求,让 AI 出第一版。结果大致对了就迭代,跑不起来就修,感觉差不多了就收工。整个过程可能只需要一两个小时,甚至更短。
如果这个原型后来证明值得深化——比如你的 demo 让老板很感兴趣,决定把它做成正式产品——你有两个选择:用 SDD 补写规格(从 vibe 升级到规范),或者直接在已有代码的基础上补测试,然后开始严肃的迭代。
如果这个原型就是个一次性的东西,用完就扔,那就不需要做任何升级。
有些开发者在 Vibe Coding 阶段也会做轻量的 TDD:先写两三个最关键的测试用例,让这些测试成为 AI 的导航锚点,避免代码在迭代过程中悄悄漂移。这是个有效的中间状态——不需要完整的 TDD 循环,但也不是完全没有约束的纯 vibe。如果你对代码正确性有一点要求,但又不想做完整的规格,这个"半严谨"的模式很适合你。
典型对话:
"先让 AI 写一个能跑的版本,我测试几个关键路径,够用就行。如果这个功能重要,我等下再补测试。"
模式二:稳健迭代——TDD 主导
适用场景:中型功能模块、需要长期维护的代码、已有项目上的功能扩展
工作节奏:
你在一个已有的项目里要加一个新功能。这个功能不算特别复杂,但它会被依赖,将来要被修改,出了问题你需要能快速定位。
这种情况下,TDD 是一个非常合适的起点。你不需要写完整的 SDD 规格,但你在开始写任何实现代码之前,先把这个功能的"验收标准"用测试描述出来:正常路径怎么走、边界情况怎么处理、出错时应该返回什么。
这些测试本身,就是一种轻量的"规格"——它们比自然语言更精确,因为测试是可执行的。
然后你把测试交给 AI,告诉它:"请写出能让这些测试通过的实现代码。"AI 有了明确的导航仪,生成的代码质量会比纯 vibe 要高,出现方向性错误的概率也大大降低。
典型对话:
"你是这个功能的实现,你的工作是让这些测试通过。不要实现测试里没有要求的东西。"
这种模式的成本不高——写测试本身不需要太多时间,而换来的收益是:每次修改代码,你可以快速知道有没有破坏原有行为。这个"修改的安全感",在长期维护的代码里价值极高。
模式三:全套工程——SDD + TDD 协同
适用场景:全新项目、需要多人协作的系统、架构层面的决策需要审查的情况
工作节奏:
你要从零开始构建一个有明确功能边界的系统,或者你要对一个存量系统做一次重要的架构改动。这种情况下,直接开始写代码的风险太高——不同时间、不同上下文生成的代码很容易出现不一致,而且当系统规模增大之后,没有规格的代码库会变得越来越难以理解和维护。
这里,SDD 和 TDD 的分工就非常自然地浮现出来了:SDD 负责"战略层",TDD 负责"战术层"。
第一步,用 SDD 的方式把规格写清楚:要构建什么功能、技术约束是什么、每个模块的接口边界在哪里、接受标准是什么。这份规格不需要一次写完美,写完初稿之后你和 AI 反复推敲,发现不一致、填补漏洞,直到你满意为止。
第二步,有了规格,AI 生成实现计划,把工作拆成一个个可执行的任务模块。
第三步,在每一个任务模块的实现阶段,切换到 TDD 模式:先写测试,再让 AI 实现,跑测试验证。规格给了测试"要验证什么"的方向,测试给了实现"要满足什么"的约束,代码是最终的产物。
三层叠加,每一层都对下一层的质量负责:规格约束了测试的覆盖范围,测试约束了代码的行为,整个系统的可信度因此大大提高。
这种完整的组合听起来很重,但对于一个预计运行一两年以上的真实产品来说,这个前期投入几乎是必要的——因为代价不是"现在花多少时间",而是"将来遇到问题时,有没有工具和依据来应对"。
从 Vibe 到规范:项目演进中的方法论切换
真实项目很少从一开始就能判断清楚它会演变成什么。很多时候,一个"周末玩具"在某天突然变成了"有实际用户的产品";一个"快速验证的原型"在某天被老板说"就做成这个,下个月上线"。
这种演进,是 Vibe Coding 最常见的升级路径,也是方法论切换最自然发生的时刻。
开发者、作家 Hari Krishnan 在描述这个过程时,提出了一个很实用的概念:"形式化触发器"(formalization trigger)——当一个项目满足某些条件时,你应该主动停下来,从 vibe 模式切换到更严谨的工作流。
他建议的触发器包括:
代码开始承担真实用户的业务责任时;你需要邀请其他人参与开发时;你意识到"这段代码我三个月后再看肯定看不懂"时;你发现自己在修一个 AI 生成的 bug 时,不知道从哪开始查时。
当这些信号出现,就是切换信号。不需要等到代码已经乱到无法收拾——越早建立规格和测试,维护成本就越低。
从实操角度,切换的路径通常是这样的:用 OpenSpec 这样的轻量工具,对现有代码库"补写"一份规格——不是从零建规格,而是用 Delta 标记(新增、修改、删除)的方式,描述"接下来我们打算做什么变更"。然后在这次变更里,引入 TDD 循环。下一次变更,再写提案、再走 TDD。慢慢地,规格覆盖率上来了,测试覆盖率上来了,代码库从一个"全靠感觉"的 vibe 产物,变成了一个有据可查的工程系统。
这个过程不需要一次性完成,也不需要停工重写——可以随着业务迭代,一点一点地补。
一张决策地图
把上面讲的内容整合成一个实用的决策框架,可以这样来看:
任务规模小、生命周期短、无需维护
↓
Vibe Coding(按需加轻量 TDD)
任务规模中等、需要长期维护、只需功能正确性保障
↓
TDD 主导(红-绿-重构循环)
全新系统 / 重要架构改动 / 多人协作 / 长期产品
↓
SDD + TDD 协同(规格 → 测试 → 实现)
还有一个维度值得加进来:你有多了解这个领域?
如果你对要做的事情非常熟悉——技术选型、架构模式、常见坑你都清楚——那么 Vibe Coding 或者轻量 TDD 可能就够了,因为你脑子里有隐性的"规格",只是没有写出来而已。
如果你在一个对自己来说相对陌生的领域——新的技术栈、新的业务逻辑、新的团队规范——那么 SDD 的价值会成倍放大,因为写规格的过程会逼迫你把那些"我以为我懂"的假设暴露出来,让 AI 帮你填补认知的空白。
给初学者的一点建议
如果你刚刚开始学习 AI 编程,这些方法论听起来可能既令人兴奋又令人困惑——每一种都有道理,但要在真实的任务里判断该用哪种,感觉还是很模糊。
这是正常的。方法论的选择能力,是一种需要积累的直觉,不是读完一节就能获得的知识。
我的建议是:先从 TDD 开始培养这种直觉。
原因有两个:第一,TDD 的核心动作——在写代码之前先想清楚"什么叫做对"——这个习惯在 Vibe Coding 和 SDD 里同样有价值。它不是 TDD 独有的,而是所有严谨工程实践的底层思维。第二,TDD 的成本比 SDD 低,但它能给你一种立竿见影的反馈——跑测试、看结果、修代码,这个循环非常具体,容易建立成功体验。
等你养成了"做事情之前先想清楚验收标准"的习惯,再去学 SDD,你会发现规格不过是"测试思维"在更高层次的延伸——只是从可执行的代码,变成了可读的文档。
而 Vibe Coding,你其实从一开始就在用了。你需要建立的,不是"如何 vibe"的能力,而是"什么时候该停止 vibe、切换到更严谨模式"的判断力。
小结
这一章,我们走完了 AI 编程方法论的完整旅程:从 Karpathy 在 2025 年初提出的 Vibe Coding 新范式,到用测试为 AI 导航的 TDD,再到让规格成为唯一真相的 SDD,最后来到这一节——把三者放在一起,学会按情境选择和组合。
方法论不是用来崇拜的,是用来解决问题的。没有一种方法论放之四海而皆准,但有一个原则可以:根据任务的生命周期、影响范围和风险等级,决定你需要多少结构,然后选择刚好够用的方法论。
Vibe Coding 带来了速度,让想法能快速落地。TDD 带来了约束,让代码的正确性有据可查。SDD 带来了共识,让多人和多轮对话的 AI 开发不会失去方向。它们之间不是竞争关系,而是在不同的抽象层次上协同:规格定义了目标,测试验证了结果,代码是连接两者的实现。
未来,你会经历很多次的方法论切换——在一个项目的早期 vibe 出原型,在它成熟后引入 TDD 保证质量,在它变大后用 SDD 守住架构。这种"弹性切换"的节奏感,是 AI 时代工程师最值得培养的工作能力之一。
从下一章开始,我们将带着这套方法论的视角,进入具体的前端开发实战。你会看到,这些抽象的工作流原则,是如何在一个个真实的功能开发过程中,帮你把 AI 的能力发挥到最大——同时让代码保持可控、可信、可维护。
练习
思考题 1:给自己的项目分级
回顾你最近接触过的三个项目或编程任务,无论大小,把它们按"生命周期 × 影响范围 × 可见度"三个维度评级(低/中/高),然后根据本节的决策框架,判断它们各自应该用哪种方法论。
你当时实际使用的是哪种方法论?如果和框架的建议不同,是因为当时资源有限,还是因为框架的建议本身不适用于你的情况?
思考题 2:SDD 和 TDD 的分工
有这样一个场景:你要给一个电商平台增加"用户积分系统"功能——用户购买商品可以获得积分,积分可以兑换优惠券,积分有有效期。
如果你决定用 SDD + TDD 的组合来开发这个功能,请尝试回答:
- SDD 阶段应该澄清哪些问题?(提示:积分如何计算?有效期如何定义?兑换规则是什么?)
- TDD 阶段最先应该写哪些测试用例?(提示:正常路径、边界情况、异常处理)
- 这两个阶段的产出,在内容上有哪些重叠?哪些互补?
实践题 3:方法论升级实验
找一个你最近用 Vibe Coding 写的小功能(几十到几百行代码都可以)。
现在,尝试"升级"它:
- 用 TDD 的方式,补写三个最核心的测试用例(不需要覆盖所有场景,只选最重要的三个)
- 运行这些测试,看看它们是通过了,还是发现了之前没有注意到的问题
- 如果测试失败了,你能找到是 AI 当时做了什么"意外决定"吗?
记录下你补写测试的过程和结果,体会"事后补测试"和"事先写测试"的区别。
讨论题 4:方法论的代价值得付吗
TDD 需要写测试的时间,SDD 需要写规格的时间。有一种常见的说法是:"我们项目时间很紧,来不及做这些额外的工作。"
你认为这个理由成立吗?如果在紧张的时间压力下必须简化,你会优先保留哪一种方法论?为什么?
思考题 5:你的工作流是什么
现在,用一句话描述你理想的 AI 编程工作流:在什么情况下你会用什么方法,以及它们如何配合?
写下来,贴在你的工作桌上——它会随着你的经验积累而不断更新。三个月后回头来看,你一定会发现它发生了变化。