停止让 AI 直接写代码,开始建立你的 Spec 工作流
June 4th, 2026
Vibe Coding 最折磨的不是写不出来,是改好一个地方又把别的地方改坏了。我折腾了好几个项目之后发现,问题根本不在 AI 身上。
AI 不是不够聪明,是我们没有把决策和边界讲清楚。缺乏明确的规则,AI 记不住你上一次改的东西,它每次都在猜你要什么。试过直接写 Plan 就开干,试过 Superpower 工作流,都有同样的问题。
后来我开始用一种以 Spec 为核心的工作流,搭配 mattpocock/skills 里的多个 skill,把决策记录下来让 AI 的行为变得可控。跑了几个功能下来,减少了 80% 的返工。
我的工作流实践
Spec 设计 -> 实现 -> 质量测试 -> 部署

工作流水线整体很简单,就这四个阶段
- Spec 阶段:写 Spec 把需求决策和边界讲清楚并沉淀,AI 开发功能时必须遵循这个 Spec 文档
- 实现阶段:基于它写 Plan 拆成可执行的任务编排,让 subagent 并行工作
- 质量测试:让 AI 跑端到端的测试,然后进行 Code Review
- 部署:完成 Feature ,进行 CI/CD,中间产物归档
这个流程的核心不是线性执行,而是每一个阶段都自带验证加修正的小闭环:
- AI 生成 Spec 文档,自己循环 review + 修正,然后人工 review 更新
- 实现阶段, subAgent 不仅要开发,还要根据 spec 文档循环自我 review 代码 + 修正
- 测试阶段,完成 e2e 测试和 CR 后,如果有问题就进行循环从实现阶段开始修复再测试
开发者的工作重心放在 Spec 的详细确认和 Plan 的任务编排确认上。
让我用一个真实案例来演示这个差别:
之前我让 AI 写个登录重定向,它第一次忘了处理 token 过期,第二次加上了过期处理却把原本的路由搞坏了,来回折腾五六次。
现在我会在 Spec 里写明:WHEN token 过期 THE SYSTEM SHALL 清除会话并跳转 /login。AI 看到这条契约,一次就能把逻辑全处理对。说白了,你把边界画清楚,它出活才稳。
我们一步一步来拆分各个阶段做什么事情,可以使用什么 skill。
Spec 阶段:把决策和边界真正沉淀下来
这将是开发者在整个工作流中最耗时的一个步骤。
分三部分:
- spec 来源是什么
- 如何生成 spec
- spec 有什么规范
spec 来源是什么
通常就是需求文档、需求评审纪要、设计文档等。
尤其是需求评审的会议纪要,会议上往往会敲定一些关键决策,但很少有人留档。把这些记录喂给 AI 生成 Spec,你会发现很多原本要反复确认的事情直接就清楚了。
如何生成 spec
以前我很喜欢用 superpower 的 /brainstorming skill 生成 spec 文档,用多了发现,它可能询问 3-5 个问题就结束了,很多关键决策还是模糊的,很容易导致返工。
最近开始使用 mattpocock 的几个 skill,比如 /grill-with-docs 或 /grill-me,会根据需求对你持续拷问,建立关键决策(ADR),直到达成一致。
最后根据聊天过程达成的 ADR,生成一份 spec 文档。
我通常习惯在 docs/specs/ 目录下创建 spec 文档,命名为 YYYY-MM-DD-主题.md
spec 的规范
我们需要固定一份 spec 规范,避免 AI 每次随意生成,确保结构永远一致。
我参考了 Spec Kit / Kiro 等业界 SDD 工具的现代实践,形成了一份规范模板,完整内容放在文末附录,你可以直接复制到 specs/index.md 里,然后在 CLAUDE.md / AGENTS.md 中引用。
这份规范里有几个核心格式需要理解:EARS 格式的功能需求、ADR 关键决策记录、GIVEN-WHEN-THEN 验收标准,以及写 Spec 的核心原则和何时该写 Spec 的判断表。下面重点展开讲。
我认为最关键的几个概念需要花点时间理解清楚:
索引和 spec 回填 索引是列出历史的 spec 文档,帮助 Agent 理解历史的决策信息。 而 spec 回填是为了确保,关键功能被修改时 spec 同步更新,不更新的 spec 会非常容易误导 Agent 。这个非常重要。
采用 EARS(Easy Approach to Requirements Syntax, 需求语法简易方法) 格式的功能需求
把功能需求写成 WHEN / WHILE / IF...ELSE 的原子语句,让 AI 实现时有明确触发条件和预期行为。
比如一条登录重定向的需求可以这样写:
WHEN 用户提交带有有效凭据的登录表单
THE SYSTEM SHALL 创建会话并重定向到仪表板
每条都是可测试的约束。
ADR(Architecture Decision Record)关键决策记录
ADR 是 spec 中最长寿的部分,实现细节会变,而决策的为什么是任意 AI 看到这个 spec 文档的指南针。
### ADR-N: <一句话决策>
**Decision**: 具体做了什么。
**Why**: 为什么这么做,对比了哪些替代方案,权衡是什么。
GIVEN-WHEN-THEN 格式的 Acceptance Criteria (验收标准) 把验收标准写得可观察、可验证,这样后面不管是人还是独立 Agent 做 review,都有明确的标准,而不是一句模糊的"能用就行"。
GIVEN <前置条件>
WHEN <动作>
THEN <可观察结果>
每条 AC 必须能被手测或自动化验证。
写 Spec 的核心原则 部分也很重要,详见文末附录。核心就一句话:WHY 比 WHAT 重要,架构图和字段定义会过时,"为什么这么做"几年后还有人需要。
Spec 写完后必须有人类自己认真 review 并 Approve,这个必须是硬性要求。是整个工作流里最重要的把关节点。确认无误后再进入 Plan 和实现阶段。
开发阶段:基于 Spec 生成 Plan 并实现
生成 plan
Spec 批准后,这步基于 Spec 生成 Plan,也是整个工作流中比较关键的一步。
具体做法是:把已经人类深度 Review 并 Approve 的 Spec 和相关文档 ,使用 to-issues skill,
to-issues 会:
- 读取你的 Spec(结合 CONTEXT.md、ADRs 等领域知识)
- 拆解成垂直切片
- 每个切片都是完整的端到端可验证单元
- 自动标记 AFK(agent 可全自动)或 HITL(需要人类 checkpoint)
这些 issues (也可以说是 tasks)就构成了你的 Plan,每个 issue 都有清晰的 "What to build"(端到端的行为描述)、验收标准、Blocked by 等。
实现
subagent 可以直接拿一个 task 去实现,上下文很小。
每个 subagent 都可以使用 /tdd skill 进行每个 Task 的实现,并且每一个闭环都需要自己去完成。
先写测试或者明确验证点,再实现。验证通过再重构。每个小 task 完成后自己先跑验证加测试。失败就迭代。最多有限次重试。
这样做的好处是,有明确的小闭环在约束,而不是黑盒。避免写完一大堆才发现方向错了。
测试与质量保障
开发完成之后,还需要确保整体任务测试能够通过,以及代码质量
先跑 E2E 测试,可以用 /playwright-cli skill 进行端到端测试完整流程。
然后做 Code Review,可以使用 Claude Code 自带的 /review skill,它会开启三个 subagent 进行 review 。
如果出现测试问题、review 问题,总结成一份文档,然后再回到实现阶段,修复这些问题,以此循环,直到问题解决。
在使用这套工作流之前的初始化
项目初始化的时候,推荐跑一次 /setup-matt-pocock-skills。
它会创建 issue 跟踪器、分类标签词汇、领域文档布局。
我推荐你重点关注它建立的 CONTEXT.md,里面会存储你当前项目的领域知识并持久化,此后持续更新。
这份 CONTEXT.md 会在上面的工作流中起到重大作用。
总结
回头看这套流程,真正起作用的就一件事:把决策沉淀成 Spec,让 AI 每次干活都有据可依,而不是凭空猜你要什么。
我自己跑下来最大的感受是:以前觉得 AI Coding 慢是因为 AI 不够聪明,后来发现是我自己没把需求想清楚就扔给它了。Spec 写得越细,后面越省事,这个投入产出比非常明显。
当然这套东西也有代价,写 Spec 本身就需要时间,小改动如果也走全流程反而拖慢节奏。所以附录里也列了"何时写 Spec"的判断表,不是所有改动都需要走这个流程。
下次有需求的时候,不妨挑一个不是特别大的功能,完整走一遍,认真写一份 Spec 试试。
如果你觉得这篇文章对你有帮助,欢迎点赞、分享,你的支持是我持续创作的最大动力!
附录:Spec 规范模板
以下是完整的 Spec 规范模板,可以直接复制到你的 specs/index.md 里,然后在 CLAUDE.md / AGENTS.md 中引用。
# 功能规格索引
每个规格文件是功能的实现合同:背景(WHY)、设计方案、关键决策、对外契约、验收标准。
> 当前代码是最新事实。spec 记录当前实现的合同和决策;当 spec 与代码冲突时,以代码为准并回填 spec。
命名规范:`YYYY-MM-DD-主题.md`(日期为创建日期,主题用 kebab-case)
## 索引
| 更新日期 | 规格 | 说明 |
| -- --- | ---- | --- |
## SDD 标准 Spec 格式
新增 spec 必须遵循以下结构
### 文件头
\`\`\`markdown
# <主题简称>(<kebab-case-id>)
> Status: Draft / Approved / Implemented / Deprecated
> Owner: <负责人>
> Created: YYYY-MM-DD
> Related: 链接到相关 spec
\`\`\`
### 章节模板
| # | 章节 | 必填 | 说明 |
| --- | ---------------------------------- | -------------- | --------------------------------------------------------------- |
| 1 | **Context** | ✅ | WHY—当前痛点、动机、为什么要做这件事 |
| 2 | **Goals & Non-Goals** | ✅ | 明确目标范围;**Non-Goals 必写**,防止 scope creep |
| 3 | **User Stories** | ✅ | `As a <角色>, I want to <动作>, so that <价值>` |
| 4 | **Functional Requirements (EARS)** | ✅ | `WHEN <trigger> THE SYSTEM SHALL <action>` |
| 5 | **Data Model** | 涉及 DB 时 | ER 图 + 字段定义 + 索引 + 约束理由 |
| 6 | **State Machine** | 有状态时 | 状态流图 + 派生状态计算公式 |
| 7 | **Key Algorithms** | 有非平凡算法时 | 关键算法的伪码 + 事务边界 |
| 8 | **API Contracts** | 有对外接口时 | Router / store / hook / export 等本地契约表 |
| 9 | **Key Design Decisions (ADR)** | ✅ | 关键决策 + Why + 替代方案。**为什么这么设计**比"做了什么"更重要 |
| 10 | **Acceptance Criteria** | ✅ | `GIVEN ... WHEN ... THEN ...` 可测试标准 |
| 11 | **Out of Scope** | ✅ | 再次明确不做什么(防止后人误解) |
| 12 | **References** | ✅ | 实施 plan 链接、相关 spec、关键文件锚点 |
### EARS 格式(功能需求)
> EARS = Easy Approach to Requirements Syntax
\`\`\`
WHEN <触发条件> THE SYSTEM SHALL <预期行为>
WHILE <持续条件> THE SYSTEM SHALL <持续行为>
IF <条件> THE SYSTEM SHALL <行为> ELSE <fallback>
\`\`\`
每条需求是一个原子的、可测试的、对系统行为的明确约束。避免模糊措辞如"应该"、"可能"。
### ADR 格式(关键决策)
每个 ADR(Architecture Decision Record)按以下结构:
\`\`\`markdown
### ADR-N: <一句话决策>
**Decision**: 具体做了什么。
**Why**: 为什么这么做,对比了哪些替代方案,权衡是什么。
\`\`\`
ADR 是 spec 中最长寿的部分,实现细节会变,决策的"为什么"是后人接手时的指南针。
### Acceptance Criteria 格式
\`\`\`
GIVEN <前置条件>
WHEN <动作>
THEN <可观察结果>
\`\`\`
每条 AC 必须能被手测或自动化验证。
---
## 写 Spec 的核心原则
1. **WHY 比 WHAT 重要**:架构图和字段定义会过时,"为什么这么做"几年后还有人需要
2. **Non-Goals 必写**:明确"不做什么"和"做什么"同等重要
3. **Lean 而非详尽**:spec 必须人能一次通读完。超过 500 行考虑拆分
4. **代码优先的活文档**:实现中如有偏离 spec,以代码为准回填 spec
5. **EARS / GIVEN-WHEN-THEN 格式化**:可测试、无歧义、机器可读
6. **明确 Out of Scope**:不做什么必须列出,防止 scope creep 和后人误解
## 何时写 Spec
| 改动规模 | 需要 spec? | 需要 plan? |
| ---------------------------------------- | ----------- | ----------- |
| 改 ≤3 个文件,无新 schema/API | ❌ | ❌ |
| 新 feature 或跨模块改动 | 可选 | ✅ |
| 新增 schema 表 / 新增 agent / 新对外接口 | ✅ | ✅ |
| 架构级重构 | ✅ | ✅ |
**维护规则**:改动实现后回填相关 spec;新增页面模块时补一份同结构 spec。