AI 写代码的速度已经快到让团队“害怕”:一个需求丢进去,几分钟就能生成几百行代码。但真正的痛点往往在后面——代码生成得越快,返工和推倒重来的次数也越多。
这不是模型能力的问题,而是流程的问题。很多团队把 AI 编码当作“更快的打字员”,但 AI 真正需要的不是一段更明确的指令,而是一整套“规格说明(Spec)、计划(Plan)、任务(Tasks)”的可追溯工作流。换句话说,AI 编程的成功率,取决于需求被拆解到多细,以及每一轮需求变化有没有被完整记录。
这篇文章就围绕 Spec Kit 这套思路展开,我会把它拆成需求评估、Specify、Plan、Tasks 四个核心环节,并结合模板、示例和变更记录技巧,说明白一个关键问题:怎样让 AI 写得越快,代码越可靠,而不是越快越乱。
1. 返工的根本原因:代码缺的不是提示词,而是规格
只要让 AI 写过业务代码,基本都会经历同样的循环:第一次生成看起来很合理,一跑就发现边界条件没处理;补了一轮提示词,它改了 A 却弄坏了 B;再继续对话,模型逐渐“忘记”了前面的约束,最后只能重新开一个会话再来一遍。
很多文章把这个归因于“上下文窗口不够”“模型推理能力不行”,但实际上,真正的问题出现在需求侧:
- 需求描述停留在“做个按钮”“接一个接口”这种口头层级;
- 没有明确的验收标准,模型只能猜测“写完”是什么意思;
- 技术方案没有经过影响分析,改动范围失控;
- AI 生成的代码没有和需求条目、任务条目建立映射;
- 需求一变,直接开口头需求,没有任何记录,模型和历史上下文全部失效。
这个现象在传统开发里也存在,但传统开发中“人”会主动补全模糊地带。问题是,AI 不会补全,它只会按照字面意思执行。你给它模糊输入,它就回你模糊输出。返工的次数,基本上和需求规格的模糊程度成正比。
Spec Kit 要解决的就是这件事:在提示词和代码之间,插入一层“规格工程”的动作。它不是一个简单的模板,而是一个从评估到拆解再到变更追踪的闭环。
2. Spec Kit 的核心概念与整体流程
Spec Kit 不是一个官方标准名词,而是一类 AI 编码工作流的统称。它的核心理念是:AI 编码不能直接“从需求跳到代码”,中间必须经过三个可审查、可记录、可回滚的中间产物。
这三个中间产物正好对应标题里的三个英文词:
| 阶段 | 关键动作 | 输出产物 | 核心问题 |
|---|---|---|---|
| 需求评估(Discovery) | 判断需求是否适合交给 AI、边界是否清晰 | 需求文档 / 可行性结论 | 能不能做、值不值得做 |
| Specify | 把需求写成机器可理解的规格说明 | Spec 文档 | 到底要做什么、做到什么程度算完成 |
| Plan | 基于规格做技术方案和影响分析 | Plan 文档 | 怎么做、改哪里、风险在哪 |
| Tasks | 把计划拆成可执行、可验证的任务 | 任务清单 | 每一步做什么、做完如何验证 |
这个流程的本质,是把传统开发中的“需求分析、技术设计、任务拆分”显式化,而不是让 AI 在聊天框里边猜边写。
这里有一个容易误解的地方:很多人以为 Coding Plan 或 Token Plan 就是写一个“编码计划”,然后直接让 AI 开始干活。从 Spec Kit 的角度看,Plan 只是中间一环。如果前面没有规格说明,Plan 本身也是空中楼阁;如果后面没有 Tasks 和变更记录,Plan 执行到一半就失真了。
整套流程的理想状态是:每一个需求,都能追溯到一份 Spec;每一份 Spec,都对应一份 Plan;每一份 Plan,都拆成一组可验证的 Tasks;每一次需求变化,都同步更新这三份文档并留下记录。代码只是这个流程的最终产物,而不是唯一产物。
3. 需求评估:不是所有需求都适合让 AI 写
Spec Kit 的第一步不是写 Spec,而是先做需求评估。很多团队跳过这一步,导致 AI 在根本不该动手的需求上浪费大量 token。
需求评估要回答三个问题:
第一个问题:需求是否足够清晰?
如果需求本身还没有定论,比如 UI 交互还在探索、数据口径还没对齐、权限模型还不明确,这时候让 AI 生成代码,生成的越多,后续推倒重来的成本越高。正确做法是先做人肉讨论,把不确定性压缩到可控范围,再进入 AI 编码流程。
第二个问题:需求是否适合 AI 实现?
AI 擅长的是模式明确、上下文可收敛、验证方式清晰的任务,比如 CRUD 接口、表单页面、配置类代码、单元测试、数据迁移脚本。AI 不擅长的是强业务判断、跨系统协调、涉及合规和复杂权限的变更。适合 AI 的需求,应该具备可测试性和可局部验证性。
第三个问题:变更成本是否可控?
即使是一个小需求,如果它会改动核心表结构、影响线上支付流程或者修改公共权限模块,就要在评估阶段标注高风险。这类需求不是不能交给 AI,而是必须有更严格的 Plan 和人工审查环节,不能直接一句“帮我改一下”就让它动手。
需求评估阶段的输出,不一定是长篇文档,可以是一个简单的评估卡片:
# 需求评估卡片 ## 需求编号 REQ-202506-001 ## 需求标题 订单列表支持按支付状态筛选 ## 需求描述(一句话) 在订单管理页面新增支付状态筛选下拉框,支持待支付、已支付、已退款三种状态。 ## 业务价值 减少客服查询订单时间,预计每日节省 30 分钟人工操作。 ## 是否清晰 [是/否] 是 说明:筛选交互已确认,状态枚举已有明确字典。 ## 是否适合 AI 实现 [是/否] 是 理由:属于标准 CRUD 页面功能,前端筛选逻辑 + 后端查询条件,均可单元测试验证。 ## 风险评估 [低/中/高] 低 影响范围:仅订单列表查询接口和列表页,不涉及支付状态流转逻辑。 ## 结论 可以进入 Specify 阶段。这个卡片不需要很长,但一定要把“不确定的点”写清楚。如果评估阶段发现需求描述里还有大量“待确认”“看情况”“后面再说”,说明还没有到让 AI 写代码的时机。
4. Specify:把“人话需求”翻译成“可验收规格”
需求评估通过之后,进入 Specify 阶段。这个阶段的目标只有一句话:让 AI 和人类对“做完”这个词达成一致。
传统开发里,需求确认靠开会、口头对齐、原型图。Spec Kit 的做法是把所有对齐结果固化成一份规格文档。这份文档不需要像软件工程教材那样严格,但必须包含几个关键要素。
4.1 用户故事与验收标准
用户故事描述使用场景,验收标准描述可验证的行为。两者的关系是:验收标准必须能从用户故事推导出来,并且每条验收标准都可以明确判断通过或不通过。
# Spec 文档模板 ## 需求编号 REQ-202506-001 ## 用户故事 作为订单管理员,我希望在订单列表页按支付状态筛选订单, 以便快速定位待处理订单。 ## 功能描述 订单列表页新增支付状态筛选器,支持三种状态: 待支付、已支付、已退款。 ## 验收标准(AC) - AC1: 页面加载时默认显示全部订单。 - AC2: 选择“待支付”后,列表只展示支付状态为待支付的订单。 - AC3: 筛选条件变更时,列表自动重新请求数据,页码重置为第一页。 - AC4: 当筛选结果为空时,页面显示空状态提示,不展示空白表格。 - AC5: 后端查询接口支持 status 参数,取值限定为 pending / paid / refunded。 - AC6: 非法 status 参数返回 400 错误,不影响其他参数查询。 ## 边界条件 - 页码超出最大范围时,返回空列表。 - 筛选状态和搜索关键词叠加使用时,接口逻辑使用 AND 关系。 ## 依赖 - 订单状态枚举已有字典表。 - 列表接口已存在,需要新增查询参数。 ## 不做的事(Out of Scope) - 不做支付状态的批量筛选。 - 不做筛选状态的本地记忆。Spec 的价值不在于文档本身,而在于它把验收标准前置了。AI 在写代码之前就已经知道“做完”的定义,人类在 AI 动手之前就能审查这些标准是否完整。现实中经常出现的情况是,Spec 写完,团队发现 AC 本身就有歧义,这时候改文档的成本远低于改代码的成本。
4.2 为什么 Specify 比写提示词重要
很多人觉得,Spec 不就是一份更长的提示词吗?为什么不直接在 Prompt 里写清楚?
关键在于复用性和可审查性。聊天框里的提示词是一次性的,上下文一滚动就丢失了;Spec 文档是可以反复引用、版本化、与代码绑定审查的。AI 编码工具可以根据 Spec 生成代码,人工 review 时也可以对照 Spec 检查每一段代码的合理性。
所以建议的做法是:把 Spec 放在代码仓库里,和源码一起管理。这样每一轮代码变更都能直接看到对应的规格说明。
5. Plan:从规格到技术方案的桥梁
Spec 回答“做什么”,Plan 回答“怎么做”。在传统开发里,这一步是概要设计和详细设计;在 AI 编码工作流里,这一步是给 AI“划范围、定方向、标风险”。
一份合格的 Plan 至少要包含以下内容:
# Plan 文档模板 ## 需求编号 REQ-202506-001 ## 技术方案概述 后端在订单查询接口 OrderQueryService 中新增 status 筛选条件, 前端在订单列表页新增筛选下拉框组件。 ## 涉及模块 - backend: order-service, OrderQueryService - frontend: order-page, filters/StatusFilter.tsx ## 影响分析 - 订单查询接口新增可选参数 status,不影响已有参数。 - 不影响订单创建、支付、退款流程。 - 数据库无需变更,状态字段已存在。 ## 改动清单 1. 修改 OrderQueryService 查询构造逻辑。 2. 修改订单列表页筛选区域,新增状态下拉框。 3. 新增 Controller 层参数校验。 4. 补充查询接口单元测试。 ## 风险点 - 现有调用方如果依赖无 status 参数时的返回结果,新增参数不改变默认行为,风险低。 - 前端筛选组件需与现有搜索组件交互,注意事件冒泡导致双重重启问题。 ## 验证方式 - 后端:运行新增单元测试。 - 前端:本地启动,手动验证 AC1-AC6。这个 Plan 的价值在于,它提前暴露了可能出错的地方。比如“前端筛选组件需与现有搜索组件交互,注意事件冒泡导致双重重启问题”——如果 AI 在写代码前没有这个概念,生成出来的代码大概率会出现重复请求的 bug。有了 Plan,AI 在执行任务时会主动规避这类问题,人类 review 时也有了重点。
从实际操作看,Plan 阶段最容易被忽略的是“不做的事”。AI 模型在生成代码时有很强的过度实现倾向,你让它加一个筛选按钮,它可能会顺手把排序功能也重写了。Plan 里明确“本次不改排序逻辑”,可以大幅减少无效代码变更。
6. Tasks:把计划拆成可执行、可验证的最小单元
Plan 是设计文档,Tasks 是执行清单。Spec Kit 的最后一环,是把 Plan 里的改动清单进一步拆成 AI 可以直接执行、人类可以逐项验收的任务。
6.1 任务拆解的原则
任务拆解最核心的原则是:每个任务必须有一个明确的“完成定义(Definition of Done)”。
一个任务如果还需要解释“大概做完就行”,说明粒度还不够细。合理的任务粒度,应该是:任务描述里包含具体文件、具体函数、具体的验证命令和验收方式。
# Tasks 清单示例 ## Task 1:后端查询参数支持 - 文件:order-service/src/main/java/.../OrderQueryService.java - 动作:在 query 方法中新增 status 参数,校验取值。 - 完成定义: - 单测覆盖 pending / paid / refunded 三种取值。 - 非法返回值返回 400。 - 编译通过,测试通过。 - 验证命令:mvn test -Dtest=OrderQueryServiceTest ## Task 2:Controller 参数校验 - 文件:order-service/src/main/java/.../OrderController.java - 动作:新增 @RequestParam 参数 status,并配置枚举校验。 - 完成定义: - 接口文档更新。 - 参数校验测试通过。 - 验证命令:mvn test -Dtest=OrderControllerTest ## Task 3:前端筛选下拉框 - 文件:order-page/src/components/filters/StatusFilter.tsx - 动作:新增下拉框组件,绑定状态值。 - 完成定义: - 组件接收 value 和 onChange 属性。 - 选项包含全部订单/待支付/已支付/已退款。 - 验证命令:npm run test -- StatusFilter ## Task 4:列表页状态联动 - 文件:order-page/src/pages/OrderListPage.tsx - 动作:状态变更时触发列表重新请求,页码重置。 - 完成定义: - 状态变化后列表刷新。 - 分页页码重置为第一页。 - 与现有搜索条件保持 AND 关系,无双重请求。 - 验证命令:本地启动,手动验证 AC1-AC6任务拆好后,可以一次性交给 AI,也可以逐个执行。我的建议是:如果任务之间有强依赖,比如 Task 2 依赖 Task 1,就按顺序执行,不要并行;如果任务完全独立,可以并行,但每个任务的验收仍然单独进行。
6.2 Tasks 与编码计划的关系
现在很多 AI 编码工具都支持“Coding Plan”“Agent Plan”之类的模式,本质上是让 AI 先生成一个执行计划再动手。Spec Kit 里的 Tasks 和这类模式的区别在于:AI 工具生成的 Plan 往往是从代码库探测得到的,偏向“文件级改动”;而 Spec Kit 的 Tasks 是从业务需求和验收标准推导出来的,偏向“行为级拆分”。
更稳妥的做法是:把 Spec Kit 的任务清单作为主控,AI 工具自带的 Plan 作为执行过程中的参考。不要让 AI 自己直接决定做什么,而是把任务一个个喂给它,每一步都对照完成定义验证。这样即使 AI 执行出偏差,也能在单个任务级别快速发现,而不会一路错到上线。
7. 让每一次需求变化都有记录
Spec Kit 最容易被人忽略、但长期价值最高的部分,是变更记录。
AI 编码中最让人头疼的场景就是:需求在编码过程中被口头修改了,AI 继续按照新需求改代码,但原 Spec、Plan、Tasks 全部停留在旧状态。等到下一次需求迭代,团队回头看上一版本代码,已经无法回答“这段逻辑当时为什么这么写”。
解决方法是把需求变更当成一次正式的“修订流程”:
- 需求方提出变化,先更新需求评估卡片;
- 如果变化影响验收标准,更新 Spec 文档,标注变更版本;
- 如果变化涉及技术方案,更新 Plan 文档;
- 重新拆分或调整 Tasks 清单;
- 代码仓库提交时,关联对应的 Spec 版本。
实际操作中的核心机制,是在 Git 提交信息里带上需求规格的编号和变更描述。比如:
git add . git commit -m "feat(order): REQ-202506-001 支持按支付状态筛选订单 - Spec 版本: v1.2 - 变更说明: 新增退款状态筛选,调整 AC5 参数取值 - Tasks: T3 前端筛选下拉框完成 - 关联: REQ-202506-001 / SPEC-202506-001"这种提交习惯坚持下来,最大的收益是“每次需求变化的痕迹都是可检索的”。以后再有人问“为什么这里有退款状态”,直接查 git log 就能看到 Spec 版本和当时的变更说明,不需要再去问已经离职的同事,也不需要重新猜。
更进一步,可以在代码仓库里建立固定的规格目录结构:
docs/ specs/ REQ-202506-001-spec.md REQ-202506-001-plan.md REQ-202506-001-tasks.md所有和需求相关的文档和代码提交保持同一个编号前缀,整个迭代周期里,无论是人还是 AI,都能快速定位到对应材料。
8. 实际项目中的常见问题与排查建议
Spec Kit 不是万能银弹,落到不同团队会遇到不同问题。从工程实践来看,最常见的几个问题集中在以下表格中。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 写 Spec 耗时太长,团队不想做 | 把 Spec 写成了需求文档,追求格式完整 | 检查 Spec 是否包含大量与验收无关的背景描述 | 精简模板,只保留用户故事、验收标准、边界条件三项核心 |
| AI 生成的代码和 Spec 不一致 | Tasks 描述粒度太粗,AI 有自由发挥空间 | 对照 Spec 检查各任务的完成定义是否明确 | 细化任务描述,明确文件路径、函数名和验证命令 |
| 需求频繁变化,文档跟不上 | 变更流程没有制度化 | 检查每次需求变化是否同步更新 Spec 和 Tasks | 把“更新 Spec”作为需求变更的一环强制执行 |
| 多人协作时 Spec 被相互覆盖 | Spec 文档没有版本管理 | 检查文档是否放在 Git 仓库统一管理 | Spec 入库,每次变更走 PR 评审 |
| Token 消耗高,但产出质量低 | 跳过评估,直接把模糊需求交给 AI 试错 | 统计返工次数和 Token 消耗的对应关系 | 强制先评估,不清晰的需求不进入编码流程 |
| AI 在编码过程中“发挥太多” | Plan 里没有明确 Out of Scope | 检查 Plan 的改动清单是否包含超出需求的内容 | 在 Plan 和 Spec 中明确不做事项 |
这些问题的共同点,都在于流程被绕过,而不是工具本身不行。Spec Kit 的有效性高度依赖团队是否愿意把“写文档”从负担变成质量前置投资。
9. 最佳实践与工程建议
结合前面几个章节,整理出在实际项目中更容易落地的几条建议。
9.1 从轻量模板开始,不要一步到位
不要一开始就搞完整的规格体系,那会让团队产生强烈的抵触情绪。建议先用一个精简的 Spec 模板跑完一个需求,确认流程有效后再逐步丰富。一个只包含“用户故事 + 验收标准 + 不做的事”的 Spec,已经能挡住大多数返工。
9.2 把 Spec Kit 当成团队约定,而不是个人习惯
如果只有一个人写 Spec、其他成员仍然直接丢需求给 AI,流程很快会失效。比较有效的做法是在团队内部统一模板,并把“没有 Spec 不进入编码”作为约定。这不一定是硬性规定,但至少要形成一种共识:AI 编码也是编码,同样需要设计文档。
9.3 让 AI 参与维护 Spec
Spec 文档不一定全部由人肉编写。在需求评估之后,可以先让 AI 根据讨论记录生成一版 Spec 草稿,再由人来校对和补充验收标准。这样做的目的是降低文档维护成本,但人必须负责最终的准确性和完整性。
9.4 每次评审先看 Spec,再看代码
代码评审时,建议把评审顺序固定为:先看这次提交对应哪个 Spec 版本,再看 Tasks 完成定义,最后看代码实现。如果代码实现与 Spec 不一致,需要先讨论是代码错了还是 Spec 过时了。这个顺序能避免无休止的“风格讨论”和“实现方式争论”。
9.5 定期归档可以让你看到变化趋势
每过一两个迭代,回头看一眼已经关闭的需求:哪些需求第一次就做对了,哪些返工了,返工的是因为 Spec 模糊、Plan 遗漏还是 Tasks 太粗。这种复盘不需要额外投入太多时间,但它能帮你找到团队在 AI 编码流程中真正的薄弱环节。
10. 总结与后续实践方向
这篇文章的核心观点是:AI 编码时代,返工的根源往往不在模型能力,而在于需求从“人话”到“代码”之间缺少可追溯的规格层。Spec Kit 从需求评估开始,经过 Specify、Plan、Tasks,最后落到变更记录,本质上是在 AI 和最终代码之间建立一座中间桥梁,让每一行代码都能回答“为什么做”“做到什么程度”“对应哪条需求”。
如果你正在尝试让 AI 写更多生产代码,我的建议是不要继续在聊天框里碰运气了。先选一个简单的需求,按评估卡片、Spec、Plan、Tasks 四个环节完整跑一遍。哪怕是手工整理一份简短模板,也能明显感受到验收标准前置带来的不同。等你发现返工率降低、review 变得更聚焦时,自然会理解这套流程的价值。
下一步可以重点研究两件事:一是如何把 Spec Kit 和 CI/CD 流程结合,让 Tasks 的完成定义直接变成自动化检查项;二是如何让 AI 更高效地维护 Spec 文档的版本变化,减少人工维护成本。这两件事都做好了,AI 编码就不再是一次性的代笔,而是真正可以长期维护的工程能力。