☰
从Vibe-coding到规格驱动:Spec-kit如何让AI开发不失控
2026/10/11 10:24:32 网站建设 项目流程

Vibe-coding 这个词最近火得厉害,说白了就是"你用自然语言描述需求,让 AI 去写代码"。听起来很美好,但真正在自己的项目里跑一圈之后你会发现,让 AI 写一段能跑的代码不难,难的是让 AI 在你持续加需求、改逻辑的过程中,不把项目越搞越乱。我前一阵用纯 vibe 的方式做了一个小工具,第一天体验极好,第三天开始崩溃:让它改一个状态管理逻辑,它给我重写了整个前端;让它加一个新页面,它把之前实现过的身份验证给我删了。来回折腾两周之后我彻底认清一件事——问题不在 AI 聪明不聪明,而在于我给的"需求"是一堆口语化的、没有边界的、无法验收的废话。后来我换成了 Spec-kit 这套工具,把"凭感觉编码"改造成"规格驱动的 AI 开发",整个从 0 到 1 的体验才算真正顺了。这篇东西就是围绕这个完整过程写的。

1. Vibe-coding 的本质:为什么"凭感觉写代码"会火,又会翻车

1.1 从"自然语言对机器说话"的本质聊起

Vibe-coding 表面上是在聊"AI 写代码",但往深了看,它其实是人机协作模式换挡:以前是你用编程语言给机器下达精确指令,现在是你用自然语言向 AI 传递意图。这个转变的核心价值不是"省掉了敲键盘的时间",而是把需求表达的成本拉低了几个量级。以前你做一个需求,要设计数据结构、拆接口、写函数、测边界条件,中间任何一环断了就卡住;现在你只要说"帮我做个页面,左边是任务列表,右边是编辑区域",AI 就能生成一版能跑的东西。

这种模式能火,是因为 LLM 的代码生成能力确实跨过了一个门槛——从"能看懂提示词"到"能按照描述搭建出完整模块"。当一个工具能把你脑子里的画面变成可执行的程序,你会不由自主地越用越多、越用越激进。我自己最开始就是这么上瘾的:一个下午生成三个原型,每个都能跑,效率拉满。但你很快就会碰到一个尴尬的边界:AI 理解的是"你当下说的这句话",它不理解"这个项目为什么长成这样"。于是你每说一句话,它都像是在一个陌生的代码库里做一次全新判断,而不是在一个有共识的项目里做一次增量修改。这个边界,就是 vibe-coding 翻车的起点。

1.2 纯 Vibe-coding 容易失控的四个关键点

我把这两周踩过的坑总结成四类,基本覆盖了纯 vibe-coding 的失控方式。

第一是需求漂移。你最开始说"做一个任务管理工具",AI 生成了一版 A;过两天你说"再加个日历视图",AI 基于自己的理解生成了一版 B,但 B 里可能已经悄悄把原来的列表交互改掉了。因为 AI 没有记忆,你每次对话它都在重新揣测你的完整意图,而你的需求其实是在演化中的。结果就是项目像一盘散沙,每一次新需求都在改地基。

第二是代码膨胀。AI 特别喜欢"多做一点"。你让它实现一个按钮,它顺手给你加了 loading 状态、防重复提交、事件埋点。单个看都没毛病,但合起来就是海量未经 review 的代码堆积在项目里。我那个小工具最后膨胀到 7000 多行,有一半功能我根本不知道它存在,更别提维护了。

第三是回归破坏。这是最疼的。AI 给你加新功能的时候,它未必知道旧功能依赖了哪些内部约定。它可能用一个新方法重写了数据流,然后你的旧的登录逻辑就静默失效了。而且这种破坏往往不是立刻爆出来的,是你某天点到一个页面才发现,它已经坏了两天。

第四是没法验收。你让 AI 写了一个功能,你怎么知道它写完了?纯 vibe-coding 模式里你只能"肉眼看看好像可以",但边界条件、错误处理、数据一致性这些硬指标,你没有清单去核对。一旦项目稍微复杂,这种"貌似可用"的幻觉比 bug 本身更危险。

这四个失控点指向同一个结论:Vibe-coding 缺的不是 AI 的能力,而是约束 AI 的结构。你要给 AI 一个"契约",而不是一句"感觉"。

1.3 Spec-kit 的解法:把 vibe 变成 spec

Spec-kit 的思路很直接:在你说自然语言和 AI 生成代码之间,加一层"规格文件"(spec)。它让你先把产品需求、功能点、验收标准、技术选型用一种半结构化的方式写进一个文件里,然后 AI 所有的生成动作都围绕这个文件展开。这样一来,AI 不再凭感觉猜测你的意图,而是按契约施工。你可以把它理解成:以前你带装修队干活,你在现场口述"这里给我整得高级一点",结果翻车了;现在你先出一套设计图纸,图纸上每一面墙的颜色、每一个插座的位置都白纸黑字,装修师傅按图施工,你按图验收。Vibe 还是那个 vibe,但有了纸面依据。

这个"图纸"就是 spec。它可以简单到一个 Markdown 文件里列几个功能点,也可以复杂到包含数据模型、接口定义、验收标准。关键是它把意图从你脑子里、对话框里,转移到了一个可版本管理、可 diff、可多人 review 的文件里。这就是 Spec-kit 对整个工作流最大的贡献——它让"凭感觉写代码"重新变成一门工程。

2. Spec-kit 的整体设计与核心工作流拆解

2.1 Spec 文件:项目的"设计图纸"长什么样

用 Spec-kit 跑项目,第一个动作不是写代码,也不是打开 AI 对话框,而是写一份 spec 文件。这个文件是全项目的源头。你可以用 Markdown、YAML 或者两者混搭,核心是它需要包含五个层次的信息。

第一是项目背景和技术栈,告诉 AI 这个项目跑在什么环境下。第二是功能清单,每一个功能都要有独立编号和标题,方便后续增量定位。第三是验收标准,对应到具体行为,例如"输入为空时,添加按钮不可点击",而不是"输入框要校验"。第四是数据模型,定义核心实体和字段。第五是边界与约束,明确指出哪些事情不允许 AI 擅自做。

我实际用的 spec 长下面这样,大家感受一下这种半结构化的自然语言表达方式:

# Todo App Spec v1 ## 项目背景 这是一个纯前端的待办事项应用,不需要后端。 ## 技术栈 - React + TypeScript - 样式:CSS Modules - 数据持久化:localStorage ## 功能清单 ### F1: 新增待办 - 顶部输入框 + 添加按钮 - 输入框为空时,按钮禁用 - 支持回车直接提交 - 提交后输入框清空,列表新增一条 - 新条目持久化到 localStorage ### F2: 标记完成 - 每条待办左侧有复选框 - 勾选后文字加删除线,底色变浅 - 状态持久化 ### F3: 删除待办 - 每条待办右侧有删除按钮 - 点击删除前需要有确认动作 - 删除后列表重排,不留空洞 ## 数据模型 - Todo { id: string, text: string, done: boolean } ## 边界 - 不要引入外部 UI 组件库 - 不要新增除上述功能以外的任何功能

你可能会觉得这个文件没什么稀奇的,不就是需求文档吗。但它的作用恰恰在于:一个结构清晰、带验收标准的 spec 文件,是 LLM 能真正稳定输出代码的前提。别小看那些"输入框为空时按钮禁用"的细节,你不在 spec 里写了,AI 就是不会替你想到。

2.2 四阶段工作流:Spec → Plan → Code → Test

Spec-kit 把开发过程固定成四个阶段:写 spec、生成计划、生成代码、跑验收。这四步不是走过场,每一步都在解决一个具体问题。

写 spec 解决的是"AI 不知道你要什么"的问题。生成计划解决的是"AI 步子踩太大"的问题——它先把 spec 拆成可执行的小任务,并且标明哪些文件会被新增、哪些会被修改。你确认了这份计划之后才进入生成代码阶段,相当于你在给 AI 盖章:"按这个思路干。"生成代码阶段才是 AI 真正落笔写代码,因为前面有计划和 spec 约束着,它发挥的空间被压缩在合理范围内。

最后是验收阶段。Spec-kit 会把 spec 里的验收标准变成一组检查项,有些工具还能自动生成测试用例去跑。这一步的价值在于:代码生成完不算完事,验收通过才算。我实际体感是,有了验收约束之后,AI 生成的代码质量明显上了一个档次。因为它"知道"自己写完会被检查,生成的时候就会更谨慎地处理边界情况,而不是糊一片。

2.3 为什么增量生成比全量重写可靠

我见过太多 vibe-coding 的失败案例,死法都是同一个:用户给 AI 说了一堆需求,AI 直接甩给你一个全新的项目,然后用户原来的代码就没了。Spec-kit 的差异化设计之一,就是默认支持在已有代码库上做增量生成。你改 spec 里的某一个功能点,它只对相关文件做局部修改,而不是把整个项目推倒重来。

这个机制特别关键,因为它解决了 vibe-coding 里最伤人的"回归破坏"问题。增量生成的前提是 spec 本身有稳定的功能编号和验收标准,AI 知道这次改的是 F2,就不应该动 F1 的实现。即使它不小心想改 F1 的文件,也有 diff 审查和验收测试两道闸在兜底。实际操作中,我会建议你把它当成默认工作方式:每次只改一小块 spec,只生成一小段代码,只验证一小批功能。小步快跑,而不是一次性给 AI 一个超大型 spec,然后期待它一口气给你变出一个完美项目——那是我用过最高效的翻车方式。

3. 从 0 到 1 实操:用 Spec-kit 跑通一个待办事项应用

3.1 初始化项目与配置模型

前面的设计讲清楚了,就该上手了。先说环境准备。Spec-kit 是一个命令行工具,前提是你机器上有 Node.js 环境。我用的是 npm 安装,命令如下:

npm install -g spec-kit spec-kit --version

不同版本的 CLI 命令命名可能略有差异,但大体逃不出 init、plan、build、run、test 这几个动作。你本地装好之后,可以先跑一下spec-kit --help看当前版本支持哪些命令,以你实际版本为准。

然后初始化项目:

spec-kit init todo-app cd todo-app

init 会生成一个标准目录结构,大概包含spec/目录(用来放 spec 文件)、output/目录(AI 生成的代码)、配置文件和一个 README。目录结构不用死记,核心只有一个:一切从 spec 文件开始,其余都是它的产物。

接下来要配置你希望 AI 使用的模型。Spec-kit 不会自己带一个和大脑连接的模型,它需要对接 LLM API。在项目根目录里有一个配置文件,大概长这样:

{ "model": "claude-sonnet-4-5", "apiKeyEnvVar": "SPEC_KIT_API_KEY", "temperature": 0.2 }

这里的apiKeyEnvVar表示从环境变量读取 API Key,这是个好习惯,不要把密钥写进配置文件再提交到 Git。你在命令行里先用环境变量注入 Key:

export SPEC_KIT_API_KEY="你的密钥"

然后运行spec-kit doctor或者spec-kit models --list来检测模型通道是否连通。连通了,这一步就算过了。模型选型上我多说一句:写 spec 和生成代码我倾向于同一个模型前后保持一致,不要经常换,因为不同模型对 spec 的理解方式有差异,换来换去会让增量生成质量波动。

3.2 写第一份 Spec 文件

配置完成,开始写 spec。在spec/目录下新建todo.spec.md,把我在前面展示那五段内容粘贴进去。这里有几个实操建议。

第一,功能编号务必保持稳定。F1、F2、F3 这些编号是整个增量系统的锚点,你后面加功能按 F4、F5 排下去,不要中间穿插改名。第二,验收标准宁可啰嗦也不要抽象。多写"点击后发生什么""空状态长什么样"这种可观察的行为,少写"体验要好""性能要优"这种没法验收的形容词。第三,边界条件单独列一个章节,明确禁止 AI 做哪些事。你会发现这条反而最有用,因为 AI 默认倾向是"能多做一个功能就多做",你得拉缰绳。

写完 spec 之后,别急着生成代码。先让 Spec-kit 帮你审一遍 spec 的完整性,运行:

spec-kit check spec/todo.spec.md

它会提示你缺了哪些必要信息,比如没写技术栈它会警告,验收标准太模糊它会建议补充。这个 check 动作虽然小,但能帮你把很多"AI 会理解错"的坑提前填掉。

3.3 生成计划、代码,并跑通最小闭环

Spec 就绪,进入正式开发流程。第一步生成计划:

spec-kit plan spec/todo.spec.md

运行之后,它会输出一份开发计划,列出为完成这份 spec,AI 计划创建哪些文件、修改哪些文件、每个文件大致承载什么逻辑。这个过程非常值得你盯一眼。你不需要看懂每行计划,但你一定要检查两点:第一,计划里有没有列出多余的模块,比如你只想要一个纯前端应用,它却计划搭一个 Express 后端;第二,计划里有没有遗漏 spec 中的关键功能。

我在实际使用时,发现这步是纠正 AI 理解偏差成本最低的时机。改计划只是文字层面的东西,等它生成完代码再改回来,那就变成了代码重构。

计划确认没问题之后,生成代码:

spec-kit build spec/todo.spec.md

执行完,output/目录下就会多出完整的项目文件。直接跑起来看看:

spec-kit run

此刻你应该能看到一个可交互的待办应用,输入、新增、勾选、删除这些功能都能用。别高兴太早,第一版能跑只是起点。接下来是验收:

spec-kit test spec/todo.spec.md

这个命令会把 spec 中的验收标准逐一和当前代码的实际行为核对,能通过单元测试的就自动跑,跑不了的给人工核验清单。我自己的习惯是:先跑 test,再看浏览器效果,最后手工过一遍边界场景。三条全绿,这个最小闭环才算真的闭合。

3.4 追加需求:体验一次真正的增量开发

最小闭环走通之后,你一定会加需求。这里我用"给待办加一个编辑功能"来演示完整的增量开发流程,这个场景最能体现 Spec-kit 的价值,也能帮你对比出和纯 vibe-coding 差异在哪里。

先在 spec 文件里追加一个新的功能块:

### F4: 编辑待办 - 双击待办文字进入编辑态 - 编辑态下文本变成输入框,自动聚焦 - 按回车或失焦保存修改 - 按 Esc 取消修改并恢复原文字

注意新增内容是插入到原有 spec 里,而不是另起一个新的对话诉求。这是 spec 驱动和 vibe 驱动的关键差异:对话是一次性的,spec 是持续演化的契约。旧功能的描述一个字都不用动,AI 通过对比 spec 的版本差异就知道这次增量只涉及 F4。

然后重新走一遍流程:

spec-kit plan spec/todo.spec.md --diff spec-kit build spec/todo.spec.md --incremental spec-kit test spec/todo.spec.md

此时--diff和--incremental会告诉工具"只要处理新增变更部分,不要动旧代码"。生成完之后,你去检查一下 F1、F2、F3 的行为是否还正常。如果我前面说的机制工作正常,这三个功能不受任何影响。这一步的实际体验和纯 vibe-coding 有天壤之别——在纯 vibe 模式下,F4 的加入很可能导致 F1 的复选框事件失效,因为 AI 可能顺手重构了事件绑定逻辑;而在 spec 增量模式下,F4 被隔离在自己的执行单元里,破坏面被限制住了。这也是我后来把 Spec-kit 作为个人项目默认工作流的最核心原因。

4. 实战中高频踩坑与排查技巧

4.1 Spec 写得太抽象,AI 发挥空间太大

第一个高频问题:spec 写得太像产品宣传语。比如验收标准写成"用户可以轻松地管理待办事项",那 AI 就真的会按它的理解给你自由发挥。它可能给你加一个拖拽排序,也可能加一个标签分类,全看它当天心情。结果是 spec 越抽象,生成结果越不可控,你想复现都难。

解决办法是在写 spec 时,强制自己用"行为 + 条件"的句式。把"用户可以轻松管理"改成"用户在输入框中输入文字后点击添加按钮,列表末尾出现一条新待办,且输入框内容被清空"。描述越靠近代码行为,AI 的自由度越被压缩。如果你发现自己写的验收标准没法直接翻译成一个 if 条件,那就说明它还不够具体。

4.2 改需求的正规姿势:改 Spec,而不是临时追加话术

我见过很多用户在用工具的时候,一边用 spec 驱动,一边又忍不住在 build 的时候附带一段对话:"对了,顺便把按钮改成圆角的。"这是很自然的冲动,但恰恰是破坏增量机制的元凶。一旦你通过对话带入了 spec 之外的需求,AI 就会进入"多轮对话模式",它会开始猜测你的隐藏意图,然后制造出 spec 里没有的代码,下一次增量生成时这些代码因为不在 spec 里,很容易被误判为垃圾代码而被清理。

正确做法是:任何新需求先落到 spec 里,哪怕只是一个临时想法,你先花一分钟把它写成一条带编号的功能记录,再跑增量 build。过程虽然慢了十几秒,但它能保证 spec 是"真相的唯一来源"。这是我踩过坑之后才真正养成的好习惯:永远先改 spec 文件,再执行生成命令。

4.3 生成代码的审查要点与测试兜底

Spec-kit 优化了流程,但它没有消除代码审查环节。你要有一个清醒认识:AI 生成的代码依然是需要 review 的代码,只不过它们的模块边界更清晰了。我总结了一套自己的审查清单。

先看安全边界:所有外部输入有没有做基础校验。再看数据持久化逻辑:刷新页面之后状态是否还在。然后看文件结构:新生成的代码是否遵守了项目原有的目录约定。最后看死代码:有没有生成但从未被调用的函数或组件。这套清单不需要懂所有细节,但是要用它建立基本防线。

测试这块,我会给 spec 中的每一个验收标准打一个标记,凡是能自动化的都尽量让它跑在 CI 里。实际工作中,我是把 spec-kit test 的输出和项目的自动化测试脚本挂在一起,每次增量 build 后强制跑一遍。如果你维护过一个因为 AI 随手重构而悄悄坏掉两周的旧功能,你会理解我为什么对回归这么敏感。

4.4 常见问题与对应策略速查

在实际跑项目时,有一些高频问题几乎每个用户都会遇到。我整理成表格方便你排查。

症状大概率原因处理办法
生成代码总是推倒重写,旧代码反复被替换增量参数没加,或者 spec 中旧功能描述被误删检查 build 命令是否带 --incremental,在 spec 中保留完整旧功能描述
AI 生成的交互看着对,跑起来不对验收标准只写了正常路径,没有边界条件补充"输入为空、重复提交、快速连点"等边界行为
模型擅自增加 spec 之外的额外功能spec 边界属性缺失在 spec 单独写"边界"章节,明确禁止新增额外功能
新功能写完后旧功能失效旧功能依赖了未写在 spec 内的隐性约定把关键业务约定写进 spec 的背景章节,并检查增量 diff
再次 build 时 AI 找不到自己之前生成的代码目录结构混乱或文件命名不稳定在 spec 中固定目录结构和关键文件名,让 AI 有锚点
同一个需求生成两次结果完全不同模型参数不稳定,或使用了较强的采样将 temperature 调低到 0.2 左右,并固定模型版本
模型报错说 spec 内容无法解析格式混用,Markdown 列表嵌套混乱保证每个功能块的结构一致,按模板逐条填写

这张表里大部分问题的根子都是同一个:spec 信息不够完整,给 AI 留了猜测空间。你填的细节越多,这些随机性成本就越低。

最后再分享一点个人体会。我一开始接触 Spec-kit 的心态是"又多一个 AI 写代码的工具",但用了一段时间才发现,最大的收获不是生成代码的速度,而是我终于可以回头审查自己三个星期前写的项目了。因为每一块功能都对应着 spec 里的一个编号,项目为什么长成这样、某个功能当初是怎么约定的,一目了然。这种感觉,才是 Vibe-coding 真正该追求的状态——保留自然语言描述需求的爽感,同时拿回工程化管理项目的掌控力。如果你也在为 AI 生成代码越改越乱发愁,建议你找个小项目试这一套流程,从写一份规格文件开始,你会感受到节奏变化带来的安稳感。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询