Skip to content

Spec Coding:AI 编程的正确打开方式

很多人用 AI 写代码,习惯一句话甩过去:"帮我做个登录页面。"然后等 AI 生成,不满意再改,改了又不对,最后越改越乱。

问题不在 AI,而在你没给它足够清晰的约束。

这篇文章讲一种更成熟的 AI 编程方式:先写 Spec,再让 AI 按 Spec 实现。

什么是 Spec

Spec 是 Specification(规格/规范)的缩写。在 AI 编程里,它是一份结构化的自然语言契约,用来告诉 AI:

  • 这次到底要做什么
  • 做成什么样才算对
  • 哪些边界不能碰
  • 最后怎么验证结果

Spec 不是灵感,不是随口一句需求,而是一份可执行的规范文档。

你可以把它理解为:

  • 对产品需求的定义
  • 对实现方式的约束
  • 对结果质量的验收标准
  • 对测试方式的明确说明

代码不再是凭感觉生成的东西,而是 Spec 的衍生结果

Vibe Coding vs Spec Coding

Vibe Coding:凭感觉开发

用户:帮我做个登录页面
AI:(生成代码)
用户:不对,再改
AI:(改了但又引入新问题)
用户:越改越乱...

特点:

  • 上手快,适合小 demo
  • 不稳定,每次产出不一样
  • 难协作,难维护
  • 容易越做越乱

Spec Coding:先写规范再实现

用户:(写好 Spec:需求、边界、验收标准)
AI:(按 Spec 生成代码)
用户:(按 Spec 验证,通过)

特点:

  • 稳定,有约束就可控
  • 可复用,Spec 可以沉淀成模板
  • 可协作,团队共享同一份规范
  • 可验证,有明确的完成标准

类比:Vibe Coding 像即兴弹琴,Spec Coding 像先写好总谱,再让乐手按谱演奏。

一份好的 Spec 长什么样

很多人听到"规范文档"就觉得复杂。其实一份有用的 Spec 不一定很长,但一定要清晰。通常包含 6 个部分:

1. 需求目标:明确"要做什么"

不是只说"做个页面",而是说明:

  • 解决什么问题
  • 给谁用
  • 触发场景是什么
  • 最终希望达成什么结果
markdown
## 需求目标
为内部员工提供一个请假申请入口,支持:
- 按钮点击发起请假
- 选择请假类型(事假/病假/年假)
- 填写起止日期和事由
- 提交后进入审批流程

2. 行为要求:明确"系统应该怎么做"

用结构化的方式描述:

  • 在什么条件下
  • 系统应该执行什么动作
  • 出现异常时怎么处理
  • 不允许发生什么情况
markdown
## 行为要求
- 用户点击"提交"按钮后,前端校验必填项
- 校验通过后调用 POST /api/leave/apply 接口
- 接口返回 200 时显示"提交成功"提示
- 接口返回 400 时显示具体错误信息
- 网络异常时显示"网络错误,请重试"
- 提交过程中按钮置灰,防止重复提交

3. 验收标准:明确"做到什么程度才算完成"

这是最关键的部分,必须明确告诉 AI:

markdown
## 验收标准
- [ ] 选择请假类型后,日期选择器自动限制最长天数
- [ ] 起始日期不能晚于结束日期
- [ ] 事由为空时,提交按钮禁用
- [ ] 提交成功后,列表页自动刷新
- [ ] 连续点击提交按钮不会重复调用接口
- [ ] 所有表单字段有中文 placeholder
- [ ] 移动端适配,输入框不会被键盘遮挡

4. 技术约束:明确"怎么做才不跑偏"

防止 AI "会做,但做法不符合你的体系":

markdown
## 技术约束
- 使用 Vue 3 Composition API + setup 语法糖
- 表单使用 uView 的 u-form 组件
- API 请求统一走 src/utils/request.js
- 日期处理使用 day.js
- 不引入新的 UI 框架
- 不使用 Options API

5. 数据模型 / API / 边界条件

让 AI 少踩坑的关键区域:

markdown
## 数据模型
请假申请表单字段:
- type: string, 枚举 ["sick", "personal", "annual"], 必填
- startDate: string, ISO 格式, 必填
- endDate: string, ISO 格式, 必填, 必须 >= startDate
- reason: string, 最长 500 字, 必填

## 边界条件
- 年假剩余天数不足时,提示"年假余额不足"
- 起止日期跨月时,按自然月分别计算
- 同一天不能提交多条请假申请

6. 测试策略:明确"怎么验证它真的符合 Spec"

markdown
## 测试策略
- 提交空表单,验证必填校验
- 提交合法数据,验证接口调用和成功提示
- 选择病假类型,验证日期限制
- 快速连续点击提交,验证防重复提交
- 断网状态下提交,验证错误提示

Spec 工作流

一套成熟的 Spec 驱动开发流程:

┌─────────────┐
│ 1. 定义 Spec │  ← 先把目标、需求、边界、验收标准写清楚
└──────┬──────┘

┌─────────────┐
│ 2. 制定 Plan │  ← 让 AI 基于 Spec 输出技术方案和任务拆分
└──────┬──────┘

┌─────────────┐
│ 3. 按 Spec   │  ← AI 按规范生成代码
│    实现      │
└──────┬──────┘

┌─────────────┐
│ 4. 按 Spec   │  ← 对照验收标准逐项检查
│    验证      │
└─────────────┘

第一步:定义 Spec

先写清楚你要什么。如果脑子里只有一个粗糙想法,也可以先让 AI 帮你把想法扩写成更完整的规范草案。

第二步:制定 Plan

有了 Spec 之后,让 AI 基于 Spec 输出:

  • 技术方案
  • 模块拆解
  • 实施顺序
  • 风险点
  • 任务清单

第三步:按 Spec 实现

AI 开始写代码。但这时它不是在"猜你的意思",而是在"执行一个已经约定好的规范"。

第四步:按 Spec 验证

对照验收标准逐项检查:

  • 功能是否齐全
  • 边界是否覆盖
  • 测试是否通过
  • 是否与技术约束一致

实际对比

不写 Spec

Prompt: "帮我做个用户列表页,支持分页和搜索"

结果:
- AI 用了 Options API(不符合项目规范)
- 搜索框没有防抖
- 分页组件样式和项目其他页面不一致
- 没有 loading 状态
- 没有空数据提示
- 没有错误处理

写了 Spec

Prompt: "帮我做个用户列表页,要求:
- 使用 Composition API + setup 语法糖
- 搜索框使用 u-search 组件,300ms 防抖
- 分页使用 u-pagination 组件,样式和现有页面一致
- 加载中显示 u-loading
- 空数据显示 '暂无数据' 提示
- 接口异常显示错误提示并提供重试按钮
- 列表项包含:头像、姓名、手机号、部门、状态"

结果:
- 代码完全符合项目规范
- 交互体验完整
- 边界情况都处理了
- 可以直接提 PR

什么时候写 Spec

场景是否需要 Spec
写一个小 demo不需要,Vibe Coding 就够了
原型验证想法不需要,快速试错
正式项目开发需要,稳定性很重要
团队协作需要,统一标准
复杂功能需要,防止遗漏边界
重复性任务需要,沉淀成模板复用

实用建议

1. 别再只给一句模糊需求

至少补上:

  • 目标用户是谁
  • 主要流程是什么
  • 成功标准是什么
  • 哪些情况必须处理
  • 哪些实现方式不能用

哪怕只多写 10 行,质量都会明显提升。

2. 把"验收标准"单独写出来

这是最值钱的动作。很多人写需求会写很多背景,但不写"什么叫完成"。一旦把验收标准写出来,AI 的方向会立刻稳定。

3. 把反复强调的约束沉淀成模板

如果你总要反复提醒 AI:

  • 用某个技术栈
  • 遵守某种目录结构
  • 统一异常处理
  • 不要引入新依赖

那说明这些内容应该固化成一份长期复用的 Spec 模板。

4. 复杂任务先让 AI 帮你补全 Spec

脑子里没想清楚时,最好的做法不是逼 AI 直接写代码,而是先让 AI 帮你一起把 Spec 补完整:

  • 需求有没有漏洞
  • 边界条件漏了没有
  • 验收标准是否可测试
  • 技术方案是否冲突

当 Spec 清楚了,后面实现会顺很多。

小结

  • AI 写代码已经够强了,真正稀缺的是"约束能力"
  • Spec 是给 AI 写的施工图 + 验收合同
  • 核心六要素:需求目标、行为要求、验收标准、技术约束、边界条件、测试策略
  • 工作流:定义 Spec → 制定 Plan → 按 Spec 实现 → 按 Spec 验证
  • 未来最重要的编程能力,不只是 coding,而是 specification

参考来源

Last updated:

💬 评论区

Built with VitePress · 小周