先写 Spec 会拖慢 AI 编程吗?真正该比的不是出码速度,而是交付总耗时
本文最后更新于 2026-07-29,文章内容可能已经过时。
先写 Spec 会拖慢 AI 编程吗?真正该比的不是出码速度,而是交付总耗时
5 分钟,AI Agent 已经生成了一个看起来相当完整的订单管理页面:搜索框、状态筛选、编辑按钮、导出功能,一个不少。
另一边,Agent 还没写一行代码,反而连续追问:
- 搜索是在当前页面过滤,还是请求后端接口?
- 修改订单状态是否需要二次确认?
- 导出当前筛选结果,还是导出全部订单?
- 状态修改失败后,页面是否需要回滚?
只看前 5 分钟,直接编码似乎赢麻了。
但一进入验收,问题开始集中出现:搜索只能匹配当前页,导出绕过了筛选条件,订单状态可以随意回退,接口失败后页面仍显示“修改成功”。
于是,前面省下来的 10 分钟,被后面的解释、删除和重写一点点吃掉。
AI 编程最容易制造的错觉,是把“代码已经生成”误认为“任务已经完成”。
那么,先写 Spec 究竟是在增加流程,还是在提前消灭返工?
要回答这个问题,不能比较谁先吐出代码,而应该比较:从收到需求到交付可验收版本,两条流程分别用了多久。
需要提前说明:本文给出的是一套可复现的 A/B 实验方案。由于没有附带真实运行日志、固定 Commit、Token 账单及截图素材,文中不会虚构测试数字;结果表保留为实测记录位,方便你在自己的项目中直接复现。
同一句需求,Agent 可能理解成三个产品
本次案例使用一段未经产品化润色的口头需求:
帮我做一个订单管理页面,支持搜索、筛选、修改状态和导出。页面风格跟项目里现有后台保持一致,做完以后帮我跑一下测试。
这句话听起来已经很明确,实际上至少藏着十几个产品决策。
以“搜索”为例,它可能是:
- 只过滤当前页面已经加载的数据;
- 调用后端搜索接口;
- 同时搜索订单号、用户名和手机号;
- 输入后立即搜索;
- 点击按钮后搜索;
- 支持模糊匹配,也可能只支持精确匹配。
“修改状态”同样不简单。哪些状态可以互相切换?已取消订单能否恢复?操作前是否确认?接口失败后如何提示?列表要不要回滚?
“导出”则可能是导出当前页、全部订单,或者当前筛选条件下的全部结果。
直接编码时,Agent 不会让这些问题凭空消失。它只会根据代码上下文、常见模式和模型偏好,替你做出一组看似合理的决定。
这也是 AI 编程返工最常见的来源:问题不一定出在代码能力,而在于 Agent 悄悄承担了产品经理的工作。
搭建一场尽量公平的 A/B 实验
要比较“直接编码”和“Spec 优先”,首先要控制变量。
两组实验应尽量保持以下条件一致:
- 使用同一模型和同一 Agent 工具;
- 从相同 Git Commit 创建两个独立分支;
- 使用相同开发环境、依赖版本和上下文窗口;
- 提供完全相同的原始需求;
- 开放相同的文件读取、终端和测试权限;
- 采用同一套验收清单;
- 不在中途给其中一组额外补充业务背景。
实验记录中至少应保留:
| 项目 | 记录内容 | | 测试日期 | 按实际执行日期填写 | | 模型与版本 | 按 Agent 中实际显示的信息填写 | | Agent 工具 | 工具名称及版本 | | 初始 Commit | 固定 Commit Hash | | 项目环境 | 操作系统、运行时、包管理器 | | 上下文材料 | Agent 可读取的目录、文档与接口定义 | | 计时方式 | 从发送初始 Prompt 开始连续计时 | | 验收方式 | 人工检查、自动化测试及构建结果 |特别要避免一种“假对比”:A 组只得到一句口头需求,B 组却额外拿到了接口文档、字段定义和业务规则。这样测出来的不是 Spec 有没有用,而是谁获得的信息更多。
A 组:收到需求后直接编码
请阅读当前项目,并根据以下需求直接完成开发。
在修改后运行测试,说明改动文件、实现结果和仍存在的问题。
需求:
帮我做一个订单管理页面,支持搜索、筛选、修改状态和导出。
页面风格跟项目里现有后台保持一致,做完以后帮我跑一下测试。
这条路线的优势很直接:启动快,适合快速验证界面、临时代码和低风险任务。
它的风险同样明显:原始需求没有说明的部分,Agent 必须选择自行假设、暂停追问,或者根据项目现状补全。
B 组:先生成轻量 Spec
暂时不要写代码。请先将下面的口头需求整理成轻量 Spec,包含:
1. 目标与使用场景
2. 功能范围
3. 数据与交互规则
4. 异常和边界情况
5. 明确不做的内容
6. 可逐项检查的验收标准
如果存在关键歧义,请先提出不超过 5 个澄清问题,不要自行假设。
需求:
帮我做一个订单管理页面,支持搜索、筛选、修改状态和导出。
页面风格跟项目里现有后台保持一致,做完以后帮我跑一下测试。
人工确认 Spec 后,再发送执行指令:
请严格按照已确认的 Spec 实现,不要擅自扩展范围。
完成后逐条对照验收标准自检,并列出:
- 已完成项
- 未完成项
- 与 Spec 不一致的地方
- 实际运行和测试结果
这里的关键不是让 Agent 写一份长篇需求文档,而是强迫双方在编码前确认:“完成”到底是什么意思。
别只看最终页面,要逐轮记录它在哪里走偏
如果实验只展示两张最终页面截图,几乎得不出有价值的结论。
真正需要记录的是两条时间线:
A 组:读项目 → 编码 → 首次运行 → 人工验收 → 纠偏 → 返工 → 再测试
B 组:澄清问题 → 生成 Spec → 人工确认 → 编码 → 首次运行 → 验收
截图也应该服务于证据链,而不是只做装饰。建议保留:
- 原始需求输入;
- Spec 生成前后的内容差异;
- 两组首次实现页面;
- Agent 出现典型误解时的对话;
- 两组关键代码 Diff;
- 构建报错、测试失败和边界遗漏;
- 最终成品并排对比;
- 标注编码、测试、纠偏和返工的时间轴。
截图前务必遮盖 API Key、仓库地址、用户数据和本地路径。
分歧一:“搜索”到底在哪里发生?
直接编码组最容易采用项目中成本最低的实现,例如对当前列表执行前端过滤。
代码可能完全正确,交互也能正常运行,但如果订单数据采用服务端分页,用户搜索不到其他页面的数据。这不是传统意义上的 Bug,而是需求理解错误。
Spec 需要提前确认:
- 搜索字段是什么;
- 搜索由前端还是后端执行;
- 是否保留分页;
- 清空关键词后如何恢复列表;
- 请求失败时显示什么状态。
分歧二:状态修改不是一个下拉框那么简单
Agent 很容易把“修改状态”理解为:展示一个下拉框,选择后调用更新接口。
真正验收时,问题才会暴露:
- 是否允许从“已完成”回退到“处理中”;
- 高风险操作是否需要二次确认;
- 请求期间是否禁用重复点击;
- 接口失败后,UI 是否恢复旧状态;
- 成功后刷新当前页还是整个列表。
如果这些规则没有提前说明,Agent 写得越快,错误假设进入代码的速度也越快。
分歧三:“导出”最容易做成看似可用
页面上出现“导出”按钮,并不代表功能符合需求。
至少要确认:
- 导出当前页还是全部数据;
- 是否继承当前搜索和筛选条件;
- 导出由前端生成,还是调用异步任务接口;
- 字段顺序和表头名称是什么;
- 无数据、超时和下载失败如何提示。
这些分歧最终都会变成代码 Diff:先删除错误的本地过滤,再接入后端接口;先推翻当前页 CSV,再重写筛选条件传递;先补上乐观更新,再处理失败回滚。
返工并不是 Agent 又写了一遍代码,而是团队终于补上了编码前没有完成的产品决策。
多花的 10 分钟,究竟有没有赚回来?
实验不能只统计“首次可运行时间”。一段代码能运行,不代表它能验收。
建议使用下面这张表完整记录:
| 指标 | 直接编码组 | Spec 优先组 | |---|---:|---:| | 开始编码前耗时 | 待实测 | 待实测 | | 首次可运行耗时 | 待实测 | 待实测 | | 首次验收通过项数 | 待实测 | 待实测 | | 人工纠偏次数 | 待实测 | 待实测 | | 代码返工轮数 | 待实测 | 待实测 | | 修改文件数 | 待实测 | 待实测 | | Token/API 成本 | 待实测 | 待实测 | | 最终交付总耗时 | 待实测 | 待实测 |返工还应继续分类:
1. 需求理解错误:功能做出来了,但含义不对;
2. 实现缺陷:需求理解正确,代码存在 Bug;
3. 遗漏边界条件:正常路径可用,异常状态缺失;
4. 无效过度开发:做了本次任务不需要的抽象或功能。
Spec 最可能减少的是第一类问题,其次是边界遗漏。它不会自动解决所有实现缺陷,也不能代替测试。
还可以计算两个辅助指标。
前置时间回收率
前置时间回收率 = Spec 减少的返工时间 ÷ Spec 前置耗时
如果 Spec 前置花费 10 分钟,只减少了很少的返工,它可能不值得;如果减少的返工明显超过前置投入,说明这 10 分钟获得了回报。
有效代码保留率
有效代码保留率 = 首次生成代码中最终保留的部分 ÷ 首次生成代码总量
这个指标不必追求伪精确。可以结合 Git Diff,重点判断首次实现是局部调整,还是核心逻辑被整体推翻。
当然,单次实验不能证明普遍规律。更可靠的做法,是分别测试三个等级的任务:
- 简单:单组件文案或样式修改;
- 中等:订单列表、表单或后台页面;
- 复杂:多接口联动、权限控制和状态流转。
Spec 不是万能药,它也可能制造新的浪费
“先写 Spec”并不天然正确。
如果任务只是调整按钮颜色、增加一个固定字段,写十几页文档显然是在用会议流程解决便利贴问题。
Spec 优先更适合以下任务:
- 修改涉及多个文件;
- 前后端接口需要联动;
- 存在状态流转和权限规则;
- 异常情况会影响数据一致性;
- 有明确验收人或交付标准;
- 做错之后推翻成本较高。
直接编码更适合:
- 一次性原型;
- 可随时删除的实验代码;
- 需求一句话就能准确验收;
- 改动范围小且没有业务歧义;
- 用户需要先看到东西,才能进一步表达需求。
还有一种常见失败:Agent 把“轻量 Spec”写成一份过度设计文档,自行补充数据库、缓存、消息队列和权限系统。看起来专业,实际只是把代码阶段的幻想搬到了文档阶段。
因此,Spec 必须约束两件事:
- 有歧义先提问,不要自行假设;
- 只描述当前任务,不擅自扩展范围。
普通用户可直接复制的五段式轻量 Spec
你不需要成为产品经理,也不需要学习复杂的需求管理方法。大多数 AI 编程任务,用下面五段就够了。
一、要解决什么问题
说明使用者、使用场景和当前痛点。
二、用户会执行哪些操作
按照实际操作顺序,列出搜索、筛选、编辑、提交等动作。
三、输入、输出和数据字段
列出输入内容、接口参数、页面字段和输出结果。
四、哪些情况不做或暂不支持
明确排除项,防止 Agent 擅自扩大范围。
五、怎样才算验收通过
把“完成”改写为可以逐项检查的结果。
订单管理页面可以这样写验收标准:
- 输入订单号后,通过后端接口查询匹配订单;
- 状态筛选与关键词搜索可以同时生效;
- 导出结果继承当前筛选条件;
- 修改状态前显示确认提示;
- 接口失败后恢复原状态并展示错误信息;
- 页面通过项目现有构建与测试命令;
- 不新增权限系统,不修改现有订单数据结构。
记住一个决策口诀:
需求一句话就能验收,直接写;需要解释“完成是什么意思”,先写 Spec。
更稳妥的进阶做法,是让 Agent 先提出最多 5 个关键问题,再生成 Spec。这样既能控制沟通成本,也能避免它凭空扩写一份充满假设的“专业文档”。
如果你也想复现这组实验,可以把文中的“直接编码 Prompt”和“轻量 Spec 模板”分别交给同一模型测试。前往 api.884819.xyz,选择你常用的模型,用同一段需求跑两次。
8848AI 平台使用用户名和密码即可注册,不需要邮箱验证;平台内置 AI 对话功能,注册后可以直接使用,国产模型如 Deepseek、千问等完全免费。平台没有月租和订阅,采用按量付费方式。
新用户注册即送体验token。测试时,请不要盯着谁先生成代码。真正值得记录的是:谁更早通过最终验收,谁的首次代码保留得更多,以及你的时间究竟花在了编码、澄清,还是返工上。
AI 编程的瓶颈,正在从“模型能不能生成代码”,转向“人能不能准确描述完成标准”。
但这次实验还留下了一个更关键的问题:Spec 应该由人来写,还是让 Agent 先反问你 5 个问题,再自动生成?
下一篇,我们将对比三种需求澄清方式——一句话直接开工、AI 自动补全需求、AI 主动追问——看看哪一种最省时间,也最不容易把项目带偏。
本文由8848AI原创,转载请注明出处。关注8848AI,带你从零开始学AI。#AI编程 #SpecCoding #AIAgent #Prompt技巧 #人工智能 #开发效率 #8848AI