本文最后更新于 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