
最近圈子里Vibe Coding这个词火得不像话朋友圈随便一刷就是我用AI两小时做了个工具大模型写的代码比我手写还利索。确实AI编程将门槛拉到了历史最低点喊一句给我做个设备巡检系统桌面就能长出个网页来。但做了几个项目之后你会发现热闹归热闹AI写出来的代码一旦要改起来那叫一个酸爽——上下文忘了、逻辑串了、改动波及一大片。我自己的两个小项目被生成一时爽重构火葬场折磨了两次之后被迫开始认真研究SDDSpec-Driven Development规范驱动开发。这段时间整个工作流已经彻底重写从环境搭建、全局MD文档设计到需求拆解、AI生成、人工评审走完了一整条AI原生时代的软件工程化路径踩了不少坑也沉淀了一些确实有用的方法论。今天这篇就完整分享出来适合正在用AI写代码、但被代码质量反复折磨的朋友也适合团队里想把AI生成纳入正规研发流程的管理者。1. 先说Vibe Coding为什么大家突然都在用感觉写代码1.1 Vibe Coding的日常长什么样Vibe Coding这个词大体描述的是那种凭感觉、靠氛围、用自然语言对话式的写代码方式。操作起来的画面感非常强打开Trae、Cursor或者GitHub Copilot用大白话描述想要的功能AI哗啦啦生成一坨代码跑一下能用哎就完事了。遇到报错把错误信息粘回去或者直接说帮我修一下AI再给你一版。这一来一回确实有一种在和会写代码的实习生对话的爽感。我最初就是这么干的。一个内部用的巡检数据录入页面从零到能用的1.0版本前后大概三个小时。当时是真兴奋觉得多年的SQL和JavaScript都白学了以后点点鼠标路子就能写系统。但爽完紧接着就是疼。三天后需求方打来电话说录入页要加两个字段我带着AI在代码里定位了半小时改了表单、改了接口、改了校验跑起来又冒出来三个新错误——因为那个页面当时是分三批对话生成的每一批的字段名和数据结构都有点小差异牵一发动全身。1.2 我踩过的那些感觉坑第一坑上下文失忆。Vibe Coding本质上吃的是对话窗口里的上下文。生成完1.0版本窗口里的代码已经几千行了等两周后再来改AI根本不记得这个项目当初是怎么约定的。它只会基于你当前给的几句话重新猜大概率猜出和原来不一致的方案。第二坑代码风格分裂。因为每次对话AI会重新发挥一个项目里经常出现两三种风格的数据请求方式。有用fetch的、有用axios的、还有用XMLHttpRequest的明明是一个前端项目却活成了Web前端发展史的活化石。代码review的时候看着就头大更别提维护。第三坑重构基本靠推倒重来。Vibe Coding生成的东西结构之间的依赖关系往往比较随意这就需要牵一发动全身的最小改动往往做不到。你想加一个字段可能得从数据库表一路改到前端展示层中间还要处理AI生成时埋下的隐性逻辑比如它可能在某个不起眼的脚本里对字段做了二次处理。第四坑测试天然缺失。AI生成的代码大部分只保证了主流程能跑通边界情况、异常输入、并发问题它极少主动处理。我有个自动对账脚本白天跑得好好的月末有大额流水时直接崩了查了半天是数字类型溢出。这种问题在纯Vibe Coding模式下几乎是无解的因为你没有测试也没法快速定位。1.3 别急着否定Vibe Coding的真正价值区间把坑讲得这么细但我不认为Vibe Coding是错的恰恰相反它是当前AI时代最自然的探索方式。它适合的场景也非常清晰原型验证、一次性脚本、个人小工具、临时数据处理。如果你只是想把一个想法快速落地成能看的东西Vibe Coding的效率无可匹敌。但一旦这个项目要交付给别人用、要长期维护、要多人协作Vibe Coding那套脑子里有个模糊感觉就开写的方式就必须让位给更严格的工程化方法。打个比方Vibe Coding就像是兴之所至做一顿家常菜好不好吃全看手感主厨一个人对着锅台自由发挥没问题。但饭店里要做标准化菜品没有SOP没有配方卡后厨早就乱套了。AI原生时代的软件工程需要的正是SOP。2. SDD是什么它解决了什么问题2.1 SDD的核心逻辑规格先行SDD全称Spec-Driven Development规范驱动开发。它的核心思想一句话就能说清楚动手编码之前先把这条代码要实现什么、输入是什么、输出是什么、边界条件有哪些、和周边模块怎么交互这类信息用结构化的文档描述清楚然后AI按着这份规范去生成代码而不是靠猜。和传统瀑布模型里的需求文档不同SDD的规范不是写给客户看的也不是写完就锁进抽屉里的。它是给AI看的施工图同时也是给开发者看的验工标准。一份合格的SDD规范至少要包含这样几个要素业务背景这个功能解决什么问题用户在什么场景下使用功能拆解把需求拆成若干个可独立验收的功能点接口定义明确的入参、出参、错误码、数据类型边界条件空值、超长输入、并发、幂等等情况怎么处理验收标准用什么用例、什么数据来验证代码是对的有了这些前置约束再让AI生成代码生成的代码就不是自由发挥而是照图施工。质量和可预测性都会高很多。2.2 为什么AI原生时代反而更需要规范有人可能会问以前写代码也没见搞这么多文档怎么到了AI时代反而要回到文档驱动这里有个特别容易被忽视的技术原因大模型的上下文窗口是有限的。传统开发模式下信息是分散存储在代码库、数据库、接口文档里的。程序员问一个模块的答案可以在整个代码库里翻找。但AI没有这个能力或者说它的寻找能力受到上下文窗口的严格限制。如果你不主动告诉它项目的整体约定、模块的边界、接口的契约它就只能基于你当前对话里给的那点信息外加自己在海量公开代码里学到的统计规律来发挥。统计规律是什么样的它会把代码写得看起来像那么回事但不一定贴合你的实际需求。规范文档在这里扮演的角色就是上下文压缩。一份设计良好的全局MD文档可以把几个月的项目决策、几百个文件的架构约定、几十次踩坑总结压缩成几千字的结构化文本。AI读这个比让它翻遍整个代码仓库高效得多产出也稳定得多。换句话说在AI时代规范不是官僚主义而是把项目经验喂给AI的最优载体。2.3 SDD与Vibe Coding不是替代是刹车我的核心观点是SDD不是要消灭Vibe Coding而是给Vibe Coding装上刹车和方向盘。最理想的工作状态其实是混合模式用Vibe Coding来探索可行性、快速验证方案用SDD来约束正式交付的代码质量。打个不太恰当的比方Vibe Coding是油门负责冲SDD是刹车和方向盘负责让你不冲出赛道。你可以在一个项目的原型阶段尽情Vibe但一旦确认功能要做进正式系统就必须先把规范立起来再让AI按规范重写或收敛。我目前的工作流是接到需求先写规范规范定了之后让AI按规范生成代码生成完代码我用规范里的验收标准逐项测试发现问题就把问题描述和现场信息回给AI让它修。整个过程既能享受AI带来的效率红利又不会把项目变成一团没法收拾的乱麻。3. 全局MD文档连接Vibe Coding与SDD的那根线3.1 为什么一份md文件能当项目大脑在Vibe Coding实践里全局md文档是很多人的秘密武器。表面上看它就是一份Markdown格式的说明文档但它的本质作用是充当项目的外置大脑。AI模型在生成代码时gpt、claude、gemini这类模型本身没有记忆所有历史信息必须塞进对话上下文。而对话窗口有上限东西一多模型就会忘记前面聊过什么。全局MD文档就是针对这个问题设计的。你不是把它作为一个参考文件丢在仓库里而是每次对话一开始就让AI读取这份文档然后再开始干活。文档里写的项目结构、技术栈、编码规范、接口约定就成了AI在本次对话中始终遵守的宪法。我在实践中的体会是一份好的全局MD效果比你在对话里反复强调你要遵守规范强一百倍。因为对话里的提醒是短时记忆说完可能几十轮之后就被冲淡了但写在文档里的内容是持久记忆AI每一轮生成代码时都会参考。3.2 一份真正有用的全局MD怎么写我见过很多人的全局MD文档写成了项目介绍PPT全是高大上的功能和愿景描述结果AI读了等于白读。真正有用的全局MD应该是一份给AI的入职培训手册它要回答的是以下几个问题这是什么项目核心业务是什么用到的技术栈和版本是什么目录结构怎么组织的新代码应该放在哪代码风格和命名规范是什么有哪些跨模块的约定有哪些已经踩过的坑禁止再犯我自己的模板大概长这样# 项目全局规范 ## 项目定位 一句话描述项目要解决什么问题目标用户是谁。 ## 技术栈 前端React 18 TypeScript Vite 后端Python FastAPI PostgreSQL ORMSQLAlchemy 2.0 脚本Node.js 20 ## 目录结构 - src/frontend前端页面 - src/backend后端接口 - scripts运维脚本 - docs项目文档 新增页面放src/frontend/pages新增接口放src/backend/routers ## 编码规范 - 接口返回格式统一为 { code: 0, data: ..., message: ... } - code为0表示成功非0表示业务错误 - 数据库表名使用snake_case字段名使用snake_case - 前端组件名使用PascalCase文件名使用kebab-case ## 通用约定 - 所有时间字段统一用ISO 8601格式存储 - 金额用Decimal类型禁止用float - 涉及用户相关操作必须记录操作日志 ## 已踩过的坑 1. 不要在业务代码里直接拼接SQL必须走ORM 2. 修改数据库表结构时必须同步更新对应的模型定义 3. 不要在前端直接存储敏感信息统一走后端接口获取权限这份文档不需要很长但每一句话都要是可执行的约束。AI读完之后生成代码时的行为会有肉眼可见的变化——接口格式不会偏离、命名不会跑偏、也不会在业务层搞小动作。这就是全局MD文档连接Vibe Coding和SDD的桥梁作用它让自由散漫的Vibe Coding有了一个不依赖对话记忆的规范锚点。3.3 如何让AI真的把MD当回事光写了文档还不够AI不是人它不会主动去读仓库里的文档。你得在每次对话的开头明确要求它读取。我常用的开场白是开始工作前先阅读项目根目录下的GLOBAL.md理解项目规范后再动手。如果规范里有不清楚的地方先问我不要自己推测。还有一个细节全局MD文档本身也是要版本管理的。项目经历了几轮迭代之后文档里的某些约定可能已经过时了这时候如果不更新文档AI就会照着错误约定生成新代码制造新的不一致。我一般每完成一个里程碑就过一遍全局MD删掉过时的内容补充新踩坑的经验始终保持文档和代码现状同步。4. 实操从零搭一套SDD最小闭环4.1 环境与工具链准备所有的理念最终要落到工具和流程上。我现在的开发环境是这样的供大家参考IDETrae也可以用Cursor二者都是面向AI编程深度优化的编辑器。Trae在国内网络环境下比较省心Cursor对代码库的全局理解更强选哪个看你自己的习惯。AI模型Claude系列用于前端页面生成效果最好GPT系列在逻辑推理类任务上更稳。国内的话可以选择对应的国内模型服务。实际上模型不是最核心的重要的是流程。项目记忆全局MD文档 docs/specs目录前者放项目级约定后者放各个模块的功能规格。版本管理Git GitFlowAI生成的代码也走代码评审和分支管理绝不能直接推到主干。测试Vitest前端 Pytest后端每次AI改完代码至少跑一遍相关测试。这套环境不是一次配齐的是踩了N次坑之后的沉淀。最初我直接在Trae里开了一个新项目就开始聊后来发现项目稍微大一点对话窗口就扛不住了。后来把全局MD做起来又把每个模块的需求拆成独立spec工作的节奏感一下就出来了。4.2 一份可直接抄写的Spec模板SDD的核心产物是spec文档。下面这个模板是我在项目里反复打磨后的版本结构比较通用适合中小型功能模块的开发可以直接抄来用。# 功能规格[功能名称] ## 背景 一两句话说明这个功能是为了解决什么问题 ## 功能拆解 - [ ] 功能点1描述具体行为 - [ ] 功能点2描述具体行为 ## 输入定义 | 字段 | 类型 | 必填 | 说明 | |-----|-----|-----|------| | name | string | 是 | 用户名称长度限制50字 | | count | number | 否 | 数量默认1最大99 | ## 输出定义 | 字段 | 类型 | 说明 | |-----|-----|------| | code | number | 0成功非0失败 | | data | object | 返回数据 | | message | string | 提示信息 | ## 边界条件 - 输入姓名为空时返回错误码1001 - 数量超过99时返回错误码1002 - 重复提交相同请求时应实现幂等处理 ## 验收标准 1. 调用接口传入合法参数返回成功 2. 调用接口传入空姓名返回1001 3. 调用接口传入数量100返回1002 4. 连续提交5次相同请求仅第一条生效 ## 涉及变更 - 新增接口POST /api/xxx/yyy - 前端新增页面src/frontend/pages/xxxx.vue - 数据库新增表xxxx写这个spec有个小技巧验收标准一定要写清楚因为验收标准就是你后面让AI改代码的裁判文书。AI生成的代码对不对拿验收标准逐条跑就行有bug就告诉它违反了几号验收项它改起来针对性会强很多。4.3 一个完整案例从任务描述到代码落地光讲模板太抽象了拿一个实际的小项目走一遍全流程。上个月我们内部要做设备巡检记录系统需求方的原始描述是做一个网页让工人可以填巡检记录顺便能看到历史记录最好能统计一下故障率。原始描述就是典型的Vibe思维——模糊、笼统、充满想象空间。如果直接把这句话甩给AI做出来的东西大概率方向有偏差。所以第一步是把它变成结构化的规格。我花了一个小时与需求方沟通搞清楚几个关键问题巡检记录要填哪些字段历史记录按什么维度过滤统计报表是按天出还是按周出工人需要登录吗还是直接填最终整理出来的spec非常清晰巡检项目设备编号、巡检人、巡检日期、运行状态正常/异常、备注、温度值可选历史记录按设备编号和日期范围筛选列表倒序展示统计报表按周展示所有设备的异常率用柱状图呈现权限不需要登录但有管理员页面可以删除误填的记录然后我把这份spec交给了AI让它按spec生成前端页面和后端接口。因为spec已经把字段、类型、边界条件都写清楚了AI生成的代码几乎没有出现结构性的偏差第一版就有九成能跑。剩下的一成小问题靠验收标准逐条纠错快速收敛。这个例子想说明的是SDD不是要把一个半小时能干完的活拉长到三天相反前期用一小时写清楚规格后面AI写代码一次成型省掉的是反复返工的几十个小时。站在项目全周期看SDD是效率的最大化而不是流程的累赘。5. 迁移到SDD会遇到的坑与我的解法5.1 渐进迁移别搞一刀切从纯Vibe Coding到SDD的迁移最容易犯的错误是步子迈太大。一上来就规定每个功能、每块代码都必须有完整spec团队或个人很快就扛不住因为很多小改动根本不值得走完整的流程。我的建议是分级按照变更的大小来决定规范的严格程度。小改动改一个文案、调一个样式不需要specVibe Coding直接改中改动新增一个接口、一个页面需要写精简版spec只写输入、输出、验收标准大改动新增一个模块、重构核心逻辑需要完整spec包含背景、拆解、边界、验收、变更清单用这个分级策略既不会让SDD变成沉重的负担也能在关键节点把工程化的好处吃满。5.2 AI不遵守规范的排查思路即便写了规范和全局MDAI在生成代码时仍然偶尔会跑偏。这种情况不用慌按照下面的顺序排查大概率能快速解决第一检查是否在对话开头让AI读过规范。很多人写好了文档但对话一开始就说帮我写个函数AI根本不知道你有这个文档。需要在对话开头先执行读文档的动作。第二检查规范文档本身是否清晰。如果规范里有模糊表述比如统一的错误处理AI不知道该统一成什么样就会自由发挥。解决办法是把规范写得更具体比如直接写出错误响应格式为code/data/messagemessage开头用大写字母。第三把规范里的相关条目直接粘进对话。如果AI在生成某个具体功能时违反了规范可以把规范原文贴出来外加一句请严格遵守上述规则重新生成。这比让AI自己去找规范再改有效得多。5.3 文档会过期规范要活起来要说SDD最大的敌人不是AI不够聪明而是文档写了一堆但没人维护最后变成一堆僵尸文档。我见过很多团队规范攒了几十页读起来全是正确的废话根本没人看AI自然也不会看。解决这个问题就三个字小步跑。规范别一次性写很多而是跟着项目走。每次踩坑顺手把教训写进全局MD每次模块迭代顺手更新对应的spec每次用法有变化马上改文档。让文档和代码保持同步这比字斟句酌写一份完美文档重要得多。我自己有个小习惯每次让AI改完代码都会回头检查相关文档是否需要更新如果有变动顺手改掉绝不留到以后。这个以后通常就是不存在的。6. 写在最后的几条心得这套从Vibe Coding到SDD的工作流我实际跑了两三个月最大的感受是对代码可控性的信心回来了。AI编程最大的问题不是生成不了代码而是生成的代码不可控。SDD解决的就是这个不可控问题先定标准再执行既保留了AI的效率又守住了工程的质量底线。最后分享三个小技巧第一全局MD文档不要追求大而全追求约束可执行。每一条都能对应到具体的代码行为否则就是废话。第二spec的验收标准请一定用数据说话。说要很快不如说100个并发请求响应时间不超过200ms说要处理异常不如说请求超时返回504并且日志打印超时的URL。第三AI原生开发真正值钱的不是写代码的手速而是定义问题的能力。谁能把模糊的需求转成清晰的规格谁就能让AI变成十倍产能的放大器。所以我建议你把写spec当成第一技能去练这比追任何一个新模型都重要。我个人估摸着接下来一段时间SDD会慢慢成为AI原生开发的主流姿势。因为大家很快会发现AI生成代码的能力已经过剩真正稀缺的是高质量的需求定义能力。早点把这套流程跑起来等项目规模上来的时候你就知道它有多香了。