
1. Vibe Coding 的两面性它解决了什么又制造了什么最近这半年Vibe Coding 这个词几乎被说烂了。我自己的项目群里隔三差五就有人甩出一句“我用 AI 两小时写了个工具站上线了”配一堆略显兴奋的截图。这词儿其实没有特别严格的学术定义但从实践角度说白了就是你用自然语言描述需求让 AI 一句句把代码吐出来你负责“感受”这个 vibe氛围/方向对不对剩下的交给模型。很多人把它翻译成“氛围编程”“感觉编程”我觉得更贴切的叫法是“靠手感驱动开发”。但你要是真的在自己项目里连续用了三四周 Vibe Coding会发现一个扎心的事实写的时候是真爽改的时候是真想哭。先说它解决了的真问题。过去写一个原型从拉工程、配依赖、写接口定义再到调样式怎么也得折腾一两天。现在只要你把需求讲清楚AI IDE我用的是 Cursor 和 Trae 这几个能在十几分钟里把骨架搭出来页面能跑、接口能通效率确实提了一个量级。这一点我完全不否认Vibe Coding 在创意探索、单页 Demo、一次性脚本、个人小工具这些场景里几乎是降维打击。你不需要出门左转去查框架文档你把想法“说”给机器机器帮你翻译成代码这种体验在五年前是做梦。可问题也来得很快。凡是稍微“长大了”一点的工程凡是需要长期维护、多人协作、稳定迭代的项目Vibe Coding 模式会迅速撞上三堵墙。第一堵墙是“代码垃圾债”。AI 不懂你的业务上下文它只会沿着对话历史里的惯性往下“圆”。你今天让它“加个筛选”它就把列表页的筛选逻辑塞进组件里明天你说“复用一下筛选逻辑”它又复制一份改了改。三五个功能迭代下来组件里塞满了鬼函数、魔法数字、用不到的 import 和几十个 props。Code Review 时你根本不敢细看因为一细看就非要重写不可。第二堵墙是“没人敢重构”。代码是 AI 写的但你得人肉兜底。问题在于人类对自己没写过的代码天然缺乏掌控感。你不知道这段逻辑当时是照着哪个“假想需求”写的不知道改了会不会引发雪崩。我有个朋友做独立开发半年攒了 3 万行 AI 生成的代码最后想加一个支付功能花了两周都没搞清楚原来的订单状态机是怎么流转的只能推翻重来。第三堵墙是“联调永远对不上”。AI 写接口、写前端、写数据库模型它总是默认一切都顺理成章。它不会主动看你的字段命名规范不会遵守你的错误码约定更不会去读公司那套内部基建的接入文档。于是前后端接口对不上、数据库迁移脚本顺序错了、鉴权逻辑漏了页面这类事故在 Vibe Coding 项目里几乎是日常。你在 vibe 里有多爽联调时就有多痛。所以行业里开始往“AI 原生时代的软件工程化”这个方向探索是必然的。不是说 AI 写代码不行而是我们对待 AI 写代码的“姿态”不行我们太快把手从方向盘上挪开了。Vibe Coding 把“写代码”这件体力活儿交给了 AI但把“想清楚需求”这件智力活儿也顺手扔给了 AI这才是大问题。于是有了我们今天的主角SDDSpec-Driven Development规范驱动开发。2. SDD 的核心设计思路把“感觉”固化成交互契约SDD 也不是什么新造的概念在传统软件开发里规格说明书、接口契约、TDD 里的测试先行本质上都是“先立规矩再干活”。但到了 AI 时代SDD 被赋予了新的含义和新的紧迫性因为你现在面对的“执行者”不是一个会主动问需求的人而是一个极度聪明但极度缺乏常识假设的模型。2.1 SDD 到底是什么一个关系型协作模式我用最通俗的方式解释一下我的理解。传统开发里人跟人协作靠的是语言、文档、默契和无数次会议。你给后端说“给我一个用户列表”后端会追问“分页吗含不含已删除返回哪些字段”——因为人脑会自动补全这些细节。但 AI 不会。你跟 AI 说“给我一个用户列表”它只会基于概率生成一个“看起来最像”的实现。大概率是返回全部用户、没有分页、字段命名随机。SDD 的做法就是把“应该给后端提的需求”提前写好写成一个机器可读、人可审、逻辑可校验的“规格文档”。我们把这种文档叫 Spec它可以是一份 Markdown也可以是一组结构化的 YAML/JSON。核心思路只有一个人和 AI 不直接对话写代码人和 AI 一起对着 Spec 对话。这个流程跑起来之后协作关系就发生了根本变化人的职责拆解需求、明确边界、定义输入输出、定验收标准AI 的职责照着 Spec 做翻译官把结构化规格翻译成高质量、可维护的代码人再次介入的时机Code Review 和验证环节而不是逐行盯着 AI 生成代码。换句话说人从“逐行监督流水线”的工人变成了“设计图纸并验收成品”的工程师。这是整个工作流最核心的转变。2.2 为什么 SDD 能解决 Vibe Coding 的痛三个关键转变我把 Vibe Coding 和 SDD 的差异总结成一张对比表方便你直观感受维度Vibe CodingSDD规范驱动开发起点一句话需求一份结构化 Spec需求来源模型猜测上下文里捡人主动拆解后写入文档确定性低同需求多次生成结果不同高Spec 不变则行为可预期重构风险极高AI 不理解全局可控改动 Spec 后按契约重写团队协作各写各的联调痛苦以 Spec 为对齐基准接口先行适用阶段原型探索、试验性开发正式迭代、多端联调、长期维护第一从“模型没有记忆”升级为“项目有了长期记忆”。Vibe Coding 的上下文窗口再大也是对话级的今天聊的内容三天后就忘了三周后换个人来聊AI 完全不认识这个项目。SDD 的 Spec 是持久化在仓库里的一份权威文档它相当于给 AI 装了一个“超长记忆外挂”无论什么时候、谁来做打开仓库就能看到完整的逻辑约定。第二从“代码复审”前置为“规格复审”。以前 AI 生成完代码你一行行查 bug——这一步实际上在检查的都是“模型理解对了吗”“边界处理了吗”。SDD 把这个环节大大提前你重点检查 Spec 写得对不对而不是对着代码去猜意图。Spec 对了AI 生成的代码至少不会跑偏。这个转变在团队场景里价值极大Review 的颗粒度从“逐行为”降到了“逐契约”效率完全不是一个量级。第三从“开发占主导”回归到“需求占主导”。Vibe Coding 最大的隐患是AI 的“温柔顺从”会放大需求的不确定性。你脑子里其实只有一个模糊的想法但 AI 天生会给你补全得“看起来特别完整”于是你被它牵着走最后做出来一个根本不是自己最初想要的东西。SDD 强制你在写代码之前先“想清楚”这种强制性本身就是一种质量保障。2.3 一个容易误解的点SDD 不等于写文档我得特别澄清一下SDD 不是让你回到写一堆没人看的 Word 的时代。很多同学一听“规范驱动”第一反应是“又要写几十页设计文档了”马上头大。不是这样的。SDD 的“规范”是精简的、可执行的、面向机器和人都能理解的契约式文本。它不必面面俱到只需要规定清楚这几个核心要素意图这一段子系统到底要做什么、不做什么输入/输出对外暴露的接口、数据结构、错误码约束代码风格、目录结构、不允许引入什么验收标准什么样的表现才算“完成”边界哪些事不要做、哪些功能明确不属于本模块。写这份文档的时间跟你过去在群里反复解释需求、跟人扯皮联调的时间比起来其实是省钱的。而且它一旦写好可以在多个 AI 会话、多个开发人员之间反复复用边际成本会越来越低。我自己在实践里最大的体感是有了 Spec 之后AI 更像一个靠谱的同事而不是一个“盲猜的翻译器”。你给它一份结构清晰的契约它产出的代码质量稳定到让人吃惊——函数命名统一、错误处理完整、边界情况覆盖齐全好像它早就知道该怎么做。3. 落地实操我从 Vibe Coding 平滑迁移到 SDD 的四步法理论讲了半天很多朋友会问那我到底该怎么做总不能明天一上线就让团队所有项目推倒重写吧当然不用。我的建议是在现有项目里先选一个新的、边界清晰的小模块做试点把 SDD 流程完整跑通再逐步铺开。下面这套方法我在不同项目里试过有坑有收获今天把它整理成一份可以直接照着做的四步法。3.1 第一步先做“规范前置”给 AI 立一份全局规矩文档无论你用 Cursor 还是 Trae第一步不是急着写功能而是先建立项目的“宪法”。我在热词里看到大家提到的“vibe coding 全局 md 文档”本质上就是这个东西——但很多人的写法太简单只放了一句“你是资深前端工程师请输出优雅的代码”这远远不够。我的全局规范文档一般放在仓库根目录命名为AGENTS.mdCursor、Trae、GitHub Copilot 等主流工具都认里面固定包含以下几块内容# AGENTS.md - 项目级 AI 协作规范 ## 项目身份 - 项目名、定位、所属业务域 - 核心领域词汇表防止 AI 把“用户ID”写成“userId”或者“uid” ## 技术栈与目录约定 - 前端框架 / 后端框架 / 数据库 / 部署方式 - 目录结构页面放哪、组件放哪、api 封装放哪、工具函数放哪 ## 编码规范 - 命名文件 PascalCase、变量 camelCase、常量 UPPER_SNAKE - CSS 方案、状态管理方案、请求库封装约定 - 禁止Class 组件、any 滥用、重复代码要求抽取公共函数 ## 工作流约定 - 先读 AGENTS.md 再读对应模块的 SPEC.md 再开始写代码 - 所有新功能必须先在 docs/specs/ 下新增 Spec 文档 - 涉及接口调用时先查 api 文档或原有请求封装这份文档就是 AI 的“入职培训手册”。实测下来有了它之后再生成的代码风格统一度能提升一个档次至少不会出现一个项目里五种文件命名风格的惨状。注意这份文档一定要放在仓库根目录且文件名固定因为很多 AI 工具会默认读取它而不是靠你每次对话时临时“喂”给它。3.2 第二步把需求拆解成结构化 Spec做成可复用的“开发卡片”这一步是整个流程的重头戏也是“人该干的活儿”。拿到一个需求先别急着跟 AI 说“帮我写个登录页”而是先花十分钟把需求拆成一个结构化的开发卡片。我把 Spec 模板固定成了下面这个样子每次直接用# SPEC-XXX登录页与登录态持久化 ## 背景与目的 - 用户需要访问受保护的仪表盘页面 - 登录后需保持会话 7 天记住我勾选时 ## 功能范围 ### 包含 - 邮箱密码登录 - 第三方 GitHub OAuth 登录 - 错误提示密码错误/账号不存在/网络异常 ### 不包含 - 注册流程已有独立页面 - 找回密码暂未排期 ## 接口约定 - POST /api/v1/auth/login - 请求参数{ email, password, remember } - 响应参数{ token, user: { id, name, avatar } } - 错误码40101 密码错误 / 40102 账号不存在 / 50000 服务异常 ## 数据结构 - User: { id: string, name: string, avatar: string, email: string } - Token 存储localStorageremembertrue 时/ sessionStorage默认 ## 页面与交互 - 页面路径/login - 布局居中卡片、背景图、logo - 提交后按钮 loading 1.5s 以上防重复提交 - 校验通过拉取 /api/v1/user/me 回填用户信息跳转 /dashboard ## 验收标准 1. 正确账号密码可正常登录并跳转 2. 错误密码提示“密码错误”不泄露账号是否存在的细节 3. 刷新页面后登录态不丢失若勾选记住我 4. 重复点击提交按钮不会产生并发请求你别嫌这个模板长写这份文档的时间最多 15 分钟但它直接决定了 AI 后面两小时产出的代码值不值得留。有了这份 SpecAI 不会再“自由发挥”去设计接口、选择存储方案、决定跳转逻辑——它只需要做一个听话的实现者。有一个小细节值得单独说Spec 里一定要写清楚“不包含什么”。这是我从踩坑里学来的。AI 特别擅长超卖——你说做个登录页它顺手帮你把忘记密码、短信验证、防机器人验证码全加上了。表面上看起来“很贴心”但每多一个功能你就多一份需要维护的代码。把边界画清楚是 SDD 的精髓之一。3.3 第三步用“模块化会话”来写代码而不是一个会话聊到天荒地老很多人的 Vibe Coding 习惯是一个聊天窗口从早上聊到晚上从“写登录页”聊到“改页脚颜色”。这种连续会话会让上下文越来越长AI 越到后面越“糊涂”而且前面的错误决策会不断影响后面的生成结果。SDD 模式下我建议把所有开发工作拆成“模块化会话”。具体操作是每次会话只做一件事。如果做登录页就只做登录页做完验收完归档关掉会话窗口每次会话的开始把AGENTS.md和对应的SPEC-XXX.md先拖给 AI告诉它“先读这两份文档然后按照 Spec 实现”等 AI 写出第一版不要急着继续提需求先自己人肉过一遍验收标准把不符合的点一次性列给它改改完后做一次小的 Code Review确认没问题了把这个会话归档记录“SPEC-XXX 已实现”。这个习惯的背后逻辑是AI 的上下文窗口就像工作台你在上面放越多的“历史杂物”留给当前任务的“工作空间”就越少。每次会话清空重来配合常驻的 Spec 文档AI 反而每次都处于状态最佳的起点。用 Trae 这类国内 AI IDE 做这套流程体验很好的一点是它在比较新的版本里支持了项目级上下文自动召回读全局文档再响应这跟 SDD 的指导思想天然契合。我在实际使用 Trae 跑上面的流程时发现只要第一步的 AGENTS.md 写得好后面在代码区直接选中代码块问问题它的回答精准度高很多。3.4 第四步把验收变成“客观标准”让 AI 自己给自己打分传统 Code Review 靠人肉费时费力而且在 AI 生成代码量大的时候根本看不过来。SDD 模式下我们可以把验收标准变成 AI 可执行的自检清单让 AI 在交付代码之前先自己过一遍。这一步的操作细节是在每份 Spec 的“验收标准”部分不只写自然语言还要加上可执行的检查命令或规则描述。比如运行npm run lint需 0 error运行npm run test需通过所有新增用例代码中不得出现any类型TypeScript 项目接口请求必须走统一封装的request方法不得直接调用fetch关键函数必须有简单的注释说明意图。然后在跟 AI 的会话结束时我固定给它一句话“在交付代码前请对照 SPEC-XXX 的验收标准逐条自查列出你完成了哪些、有哪些是故意没做的。”这一步看着简单实测效果出奇地好。AI 自查后的问题往往比人肉 Review 发现得还多因为它在生成代码时其实一直有“自我怀疑”只是你没给它表达的机会。关于验收还有一个非常实用的做法写完代码后让 AI 自己补充测试用例。你把 Spec 里的边界条件、错误码、异常分支列给它让它生成对应的单元测试。这些测试就是“配套的验收证据”后续改代码时一跑就知道有没有把原来的逻辑改坏掉。4. SDD 的工具链与团队协作模式全员同步而不是各顾各的聊完了单人实践再说说团队场景。SDD 真正威力最大的地方是它天然适配“多人协作 AI 辅助”的现代开发结构。以前团队里的问题是“人跟人之间对齐困难”现在多了一个“人跟 AI 之间对齐也困难”SDD 刚好把这两个问题一起兜住了。4.1 用 Git 管理 Spec规范也要做版本控制、走评审我强烈建议把 Spec 文档纳入 Git 仓库管理和代码一起提交、一起 Review。这比“单独拉一个共享文档表格”要好用得多理由有三第一Spec 和代码天然有对应关系。你看一个 commit 时能看到“这次怎么改的”以及背后的“为什么要这么改”回溯历史轻松太多。第二Spec 走 MR 评审能让团队里每个人在动手写代码之前就“对齐认知”。评审通过后再进入开发就不会出现“你理解的是一个登录页我做出来的是一个账号中心”这种重大偏差。第三Spec 是活的它跟着版本走。你发布 v1.2 时用的 Spec 是什么样代码就是照着那个版本生成的后续排查问题也有据可查。我自己现在的习惯是先提一个 Spec 的 MR等团队 Review 通过再提代码的 MR。虽然步骤多了一步但实际推进速度反而更快因为代码 MR 的摩擦小了很多Reviewer 几乎都是直接 Approve。4.2 团队协作中的分工产品定意图技术定契约AI 定实现SDD 对团队的另一个正向影响是它逼着大家把“职责”想清楚。我总结的分工是产品/业务方定义意图这个功能解决什么问题用户是谁优先级如何技术负责人定义契约接口是什么、数据结构是什么、边界在哪AI 负责实现按照契约翻译成高质量代码团队负责验收逐条对照验收标准检查。这个分工最大的好处是减少了“甩锅”和“拉扯”。以前业务方说“我要个按钮”开发做出来业务方说“我不是这个意思”——信息在对话里失真了。有了 Spec业务方提前确认了功能范围开发提前确认了接口和边界AAI 再在其中扮演“翻译官”整个链条的失真率被大幅压低。不过这条实践对“文档基因薄”的团队有一定阻力。我的建议是从一个小需求开始试点不要上来就全团队推广。找一个大家公认“沟通成本高、容易扯皮”的小模块用 SDD 跑一个迭代把结果和体感摆出来比发十封制度邮件都管用。4.3 哪些场景不适合 SDD哪些场景千万别用凡事都有适用边界。SDD 也不是万能的我遇到这几类场景就不太建议用纯探索期的创意脚本你只是想在本地快速验证一个想法可不可行、数据有没有意思这时候写 Spec 纯属浪费。先用 Vibe Coding 快速跑跑通了再补 Spec一次性数据分析脚本跑完就扔也不会维护没必要花时间写契约需求极度模糊且业务方自己也说不清时这时候强行写 Spec只会把错误的假设固化成文档后面返工成本更高。不如先做一个粗糙原型用原型倒逼业务方把需求想清楚。我自己的判断标准是“这个代码三个月后还会有人看吗”答案是会那就值得用 SDD 流程答案是不会那就怎么快怎么来。Vibe Coding 和 SDD 不是二选一的对立关系而是一条光谱上的两端。我的实践模式是探索期用 Vibe Coding 快速试错一旦方向确认立刻转入 SDD 流程把它工程化。用了这个组合拳之后我个人的产出质量和可维护性都有了明显改善。5. 常见问题与排查技巧实录从“踩坑”里总结的避坑经验最后这部分我把过去踩过的坑、群里朋友问得最多的问题统一整理成一份速查清单。这些问题你不遇到很幸运遇到了可以直接拿来排查。5.1 AI 不遵守 Spec 怎么办换一种“喂”法而不是一味地骂我用 AI 写代码一年多的经验是模型不是不遵守 Spec而是它没意识到“这份文档优先级最高”。很多时候你把一份很长的 Spec 丢给它它读到最后前面写的啥已经“记不清了”于是开始自由发挥。我的解决办法把 Spec 精简到一屏能看完的体量。我见过不少团队友写的 Spec 长达 3000 行这本身就是问题。Spec 不是详细设计文档它只写“契约”不写“过程”。如果某个模块确实复杂就拆成多个小 Spec在每次请求前明确提示优先级。在对话里加一句固定前缀“请严格遵循 AGENTS.md 和 SPEC-20240601.md 中的约定这是优先级最高要求。如果存在矛盾以 Spec 为准。”这句话虽然有点“咒语感”但实测有效让 AI 先复述再动手。在实现前先让它用三句话概括“你打算怎么做”你确认它真的读懂 Spec 了再让它写代码。这一步像极了给实习生安排任务后让他复述一遍能省掉后面 80% 的返工。5.2 Spec 和代码不同步了怎么办把“同步”做成每次开发的固定动作SDD 最常见的腐化现象就是Spec 写于某年某月后来代码改了三轮Spec 已经变成了“一张废纸”。这几乎无法避免但可以靠流程控制住。我规定自己两条规则需求变更时先改 Spec再改代码。哪怕是只改一个字段名也要同步更新 Spec不要让 Spec 滞后于代码。因为 AI 读取优先序是 Spec - 代码上下文Spec 一旦滞后AI 生成的新代码大概率会拿旧契约做事每次 MR 里必须包含 Spec 的 diff。如果这个 MR 动了业务逻辑但 Spec 没有变化说明你漏更新了如果 MR 里只剩 Spec 改动而代码没改说明你在“为了改文档而改文档”需要停下来想想。这两条规则守住了Spec 和代码能长期维持在“互相印证”的健康状态。5.3 团队里有人不配合写 Spec 怎么办从“要求”变成“收益”这个问题挺现实的。有人觉得 Spec 是“没用的文书工作”觉得与其花 15 分钟写文档不如直接让 AI 干完。我的经验是别急着说服所有人先让写 Spec 的人尝到甜头。具体做法是在团队例会里做一次“前后对比”同一个需求A 同事用 Vibe Coding 做了一版B 同事先用 Spec 再做一版。让大家对比两版代码在 Code Review 里找 bug 的耗时、重构时的心理压力、以及后续迭代的速度。用数据说话比用道理说话管用。其实很多抵触情绪源于“不知道怎么写、怕写错、觉得浪费时间”。我就拿自己团队的套路手把手带了一次把第 3 步那个 Spec 模板直接甩给他们让他们照着填空。把“写 Spec”的门槛降到“像填报销单一样简单”接受度一下子就上来了。根据我个人的体会从 Vibe Coding 到 SDD本质上不是工具的变化而是“心态和习惯”的一次升级。它要求我们重新承认一件事AI 再强它也只是执行者需求的定义权、契约的制定权、质量的验收权这些工程师的核心价值永远要攥在自己手里。把这个观念转过来你调教出来的 AI 会越来越精准你手里的项目也会越跑越稳。