Skip to content

Spec 与需求理解 ​

标签
AI/agent/AI Coding
字数
4079 字
阅读时间
16 分钟

AI Coding 工作流 讲的是 Spec-Driven Development 在整个流程里的位置;这一篇讲规格本身——需求怎么拆、规格写成什么结构、歧义怎么处理。

判据只有一条:你是真的理解了输入和输出之间的业务语义,还是只是让 AI 按样例拟合。

需求拆解要回答的五个问题 ​

拿到需求先拆,拆的是五件事:

输入是什么
输出是什么
中间需要做哪些处理
输入文件之间有什么关联
最终输出需要符合什么契约

这五个问题的答案构成规格的骨架。任何一个没答清楚,后面生成的决策树就是照样例硬凑的——三个样例能过,第四个就崩。

需求拆解回答五件事,这五条构成规格的骨架。

   ① 输入是什么
   ② 输出是什么
   ③ 中间需要做哪些处理
   ④ 输入文件之间有什么关联
   ⑤ 最终输出需要符合什么契约
        │
        ▼
   规格骨架
        │
        └─ 任何一条没答清楚,后面生成的决策树就是「照样例硬凑」的:
           三个样例能过,第四个就崩

判据只有一条:你是真的理解了输入与输出之间的业务语义,
还是只是让 AI 按样例拟合。

Spec Kit:业界的标准流程 ​

那篇提到的 GitHub Spec Kit(2026-05-07 时 v0.8.7,93000+ stars)把这件事工具化了。它的流程值得完整过一遍,因为每一步都有明确的产物和约束来源:

阶段命令产物约束来自
0 · 宪章/speckit.constitutionCONSTITUTION.md——
1 · 规格/speckit.specifyspec.md宪章
1.5 · 澄清/speckit.clarify(可选)原地更新 spec.md——
2 · 计划/speckit.planplan.md(可能附带 research.md / data-model.md / contracts/)宪章 + 规格
2.5 · 检查/speckit.checklist(可选)质量检查清单——
3 · 任务/speckit.taskstasks.md——
3.5 · 交叉核对/speckit.analyze(可选,只读)一致性报告——
4 · 实现/speckit.implement代码 + 测试 + 文档前面全部产物
5 · 收敛/speckit.converge追加未实现项到 tasks.md——

约束传递金字塔 ​

   ┌─────────────────────────────────────────────────────────┐
   │ CONSTITUTION.md   顶层不可违背原则                        │
   │   技术栈 / 质量门 / 合规 / 禁止事项                        │
   │   后续每个阶段都被提供给 AI,确保生成内容遵守这些准则        │
   └──────────────────────────┬──────────────────────────────┘
                              │
                              ▼
   ┌─────────────────────────────────────────────────────────┐
   │ spec.md           要做什么(WHAT)                        │
   │   刻意的技术无关:不写框架、不写数据库、不写 API 结构        │
   └──────────────────────────┬──────────────────────────────┘
                              │
                              ▼
   ┌─────────────────────────────────────────────────────────┐
   │ plan.md           怎么做(HOW)                           │
   │   技术栈 / 组件 / 数据模型 / API 契约 / 部署结构 / 依赖     │
   │   同时受两头约束:过宪章的合规门 + 覆盖 spec 的需求          │
   └──────────────────────────┬──────────────────────────────┘
                              │
                              ▼
   ┌─────────────────────────────────────────────────────────┐
   │ tasks.md          原子可执行任务                          │
   │   有序、细粒度、每个任务带自己的验收标准与依赖说明           │
   │   [P] 标记可并行的任务 —— 多 agent 并行执行的信号           │
   └──────────────────────────┬──────────────────────────────┘
                              │
                              ▼
                        代码 + 测试 + 文档

下层受上层约束:plan.md 若违反宪章,必须修改,或者携带一份成文的正当理由 ——
这是「机械检查」而不是「靠感觉」的具体含义。

「宪章常驻、其余按复杂度加载」是调和「强制五步 vs 小需求」矛盾的关键:
小需求可以只走 specify → tasks → implement。

下层受上层约束。 plan.md 如果违反宪章,必须修改,或者携带一份成文的正当理由——这是「机械检查」而不是「靠感觉」的具体含义。

每一步的产物长什么样 ​

CONSTITUTION.md —— 项目的最高法则。它在后续每个阶段都被提供给 AI,确保生成内容遵守这些准则。**「宪章常驻、其余按复杂度加载」**是调和「强制五步 vs 小需求」矛盾的关键:小需求可以只走 specify → tasks → implement。

spec.md —— 刻意的技术无关:不写框架、不写数据库、不写 API 结构。它描述:

  • feature 与要解决的用户问题
  • 编号的功能需求(如 FR-001)
  • 非功能需求
  • 场景
  • 成功标准

「技术无关」不是洁癖,是分层的必要条件——spec.md 要能对着「用户想要什么」被评审,如果里面混了技术选型,评审就变成技术辩论了。

plan.md —— 技术架构:技术栈、组件、数据模型、API 契约、部署结构、依赖。它要同时受两头约束:过宪章的合规门 + 覆盖 spec 的需求。

tasks.md —— 有序、细粒度、开发者可执行。每个任务带自己的验收标准与依赖说明,[P] 标记可并行的任务(这是多 agent 并行执行的信号)。典型顺序:

setup → tests-first(核心实现前先写测试)→ 核心实现 → 集成 → 收尾

两个 specify 的行为值得单独知道 ​

一、它创建 Git feature 分支。 分支名形如 001-feature-name,spec 写到 specs/<分支>/。后果是:

spec 是一个 PR 单元——分支合并时 spec 跟着一起进。切 feature = 切分支,后续命令从当前分支自动识别在做哪个 feature。

二、歧义被标出,不被猜。 规格不清楚的地方,agent 插入 [NEEDS CLARIFICATION] 标记 + 最多三个结构化问题,而不是自己编一个答案填上。/speckit.clarify 就是解决这个标记的可选回路——你的回答原地更新 spec.md:标记被替换、假设追加到文档里、版本号递增。

这一条是最值钱的设计:它把「AI 猜错了你没发现」变成了「AI 明确列出它不确定的地方等你回答」。对应到 那篇里说的「几百个未言明的决定」——这里给出了让其中一部分显式浮出水面的机制。

歧义被标出、不被猜 —— 这是 Spec Kit 最值钱的设计。

   写 spec 时遇到不清楚的地方
        │
        ▼
   agent 不编一个答案填上,而是插入 [NEEDS CLARIFICATION] 标记
   + 最多三个结构化问题
        │
        ▼
   /speckit.clarify(可选的解决回路)
        │  你的回答原地更新 spec.md:
        │  标记被替换、假设追加到文档里、版本号递增
        ▼
   得到不含待澄清标记的 spec.md ──▶ 继续 plan / tasks

   它把「AI 猜错了你没发现」变成「AI 明确列出它不确定的地方等你回答」。
   └─ 对应到上游那篇说的「几百个未言明的决定」——
      这里给出了让其中一部分显式浮出水面的机制

另一件值得单独知道的事:/speckit.specify 会创建 Git feature 分支
   分支名形如 001-feature-name,spec 写到 specs/<分支>/ 下
   └─ spec 是一个 PR 单元 —— 分支合并时 spec 跟着一起进
      切 feature 就是切分支,后续命令从当前分支自动识别在做哪个 feature

已知的取舍(不要只讲好处)
   产物过多        spec / plan / tasks / research / contracts 一整套,
                   小改动上就是仪式感过重
   写测试但不跑测试  它生成测试,但不会自动执行
   文件比代码多     早期会话里产出的文件数量超过代码
   适用范围        为真实项目的迭代增强设计,不是从零起步的玩具 ——
                   所以「精简路径」是有意存在的
   └─ 实践结论:实验用精简路径,重要的 feature 用完整路径

已知的取舍(不要只讲好处) ​

2026 年 5 月的实测评审对摩擦讲得很直白:

问题说明
产物过多spec、plan、tasks、research、contracts 一整套,小改动上就是仪式感过重
写测试但不跑测试它生成测试,但不会自动执行
文件比代码多早期会话里产出的文件数量超过代码
适用范围它是为真实项目的迭代增强设计的,不是从零起步的玩具——所以「精简路径」有意存在

实践结论:实验用精简路径,重要的 feature 用完整路径。

生态里的其他哲学 ​

Spec Kit 属于「强规格」一派——spec 是单一事实来源。生态里还有别的取向,选型时要看它们解决的是不是同一个问题:

方案取向适合
Spec Kit强规格,spec 是单一事实来源;有宪章、有 clarify 阶段重要 feature 的完整流程
OpenSpec刻意更轻:没有宪章、没有 clarify 阶段、四个命令、delta specs在已有代码库上快速迭代
BMad Method用一支虚拟敏捷团队(从分析师到 QA 的专家 agent)替代产物链需要多角色视角
Superpowers跳过正式规格,专注执行纪律:TDD、评审门、子 agent规格已清楚,缺的是执行约束
Task Master只做一阶段:把 PRD 转成结构化任务已有 PRD,缺任务拆解

这张表回答了一个常见困惑:为什么有人推 Spec Kit 有人推 Superpowers——它们解决的不是同一个环节。Spec Kit 管「做什么」,Superpowers 管「怎么做才不出事」。

生态里的五条取向各管一个环节 —— 选型时要看它们解决的是不是同一个问题。

   ┌────────────────────────────────────────────────────────┐
   │ Spec Kit       强规格,spec 是单一事实来源                │
   │                有宪章、有 clarify 阶段                    │
   │                适合:重要 feature 的完整流程               │
   └────────────────────────────────────────────────────────┘
   ┌────────────────────────────────────────────────────────┐
   │ OpenSpec       刻意更轻:没有宪章、没有 clarify、          │
   │                四个命令、delta specs                     │
   │                适合:在已有代码库上快速迭代                 │
   └────────────────────────────────────────────────────────┘
   ┌────────────────────────────────────────────────────────┐
   │ BMad Method    用一支虚拟敏捷团队(从分析师到 QA)           │
   │                替代产物链                                 │
   │                适合:需要多角色视角                        │
   └────────────────────────────────────────────────────────┘
   ┌────────────────────────────────────────────────────────┐
   │ Superpowers    跳过正式规格,专注执行纪律:                 │
   │                TDD、评审门、子 agent                      │
   │                适合:规格已清楚,缺的是执行约束              │
   └────────────────────────────────────────────────────────┘
   ┌────────────────────────────────────────────────────────┐
   │ Task Master    只做一阶段:把 PRD 转成结构化任务            │
   │                适合:已有 PRD,缺任务拆解                   │
   └────────────────────────────────────────────────────────┘

这张表回答一个常见困惑:为什么有人推 Spec Kit 有人推 Superpowers ——
它们解决的不是同一个环节。Spec Kit 管「做什么」,Superpowers 管「怎么做才不出事」。

规格的产物链(一个具体例子) ​

以「Case CSV + Snapshot JSON → 规则判断 → 结构化 JSON 输出」这类任务为例,从原始需求到可执行的规格要经过几层:

原始需求
  ↓  需求分析
Spec
  ↓  解析
CSV / Case 表格 · Snapshot JSON · Output Schema
  ↓  建立语义
输入字段语义 · 输出字段语义 · 决策树 · 规则匹配逻辑

最后的输出契约通常要覆盖几类 Action,每一类对应一种后续处理:

Action后续处理
可以继续执行走自动化主流程
需要重新查询 / 验证回退一步,重新取数
缺少字段要求补齐字段
无法判断向用户询问

Output Schema 是这一层的核心交付物。字段语义、决策树、规则匹配逻辑都从它推导出来;它一旦变,下面全要跟着变。

需求文档互相冲突时的处理 ​

多份需求文档对同一件事的描述经常不一致。典型情形是 Output Schema 的结构不同:

扁平结构:                    嵌套结构:
state                        state
action                       action
field1                       data {
field2                         field1
...                            field2
                             }

处理动作是三步,顺序不能反:

  1. 让 AI 跨文档 Review 两个版本,把差异摆出来
  2. 按输出契约统一 Schema——以哪个为准要由契约决定,不能取折中
  3. 决策树同步改成统一版本,否则规则还在按旧结构匹配

这一步考的不是技术,是会不会主动发现冲突。让 AI 从两份文档里随便选一份实现,是这条链路上最隐蔽的失败模式:代码能跑,测试能过,但契约是错的。

Spec Kit 里对应的是 [NEEDS CLARIFICATION] 机制——把「需求本身有歧义」变成 agent 必须提出来的问题,而不是它可以自己决定的事。

多份需求文档描述不一致时的处理,三步顺序不能反。

   典型情形:Output Schema 的结构不同
      扁平结构:state / action / field1 / field2 …
      嵌套结构:state / action / data { field1 / field2 … }
        │
        ▼
   ① 让 AI 跨文档 Review 两个版本,把差异摆出来
        │
        ▼
   ② 按输出契约统一 Schema —— 以哪个为准要由契约决定,不能取折中
        │
        ▼
   ③ 决策树同步改成统一版本,否则规则还在按旧结构匹配

   这一步考的不是技术,是会不会主动发现冲突。
   让 AI 从两份文档里随便选一份实现,是这条链路上最隐蔽的失败模式:
   代码能跑、测试能过,但契约是错的。

   Spec Kit 里对应的是 [NEEDS CLARIFICATION] 机制 ——
   把「需求本身有歧义」变成 agent 必须提出来的问题,而不是它可以自己决定的事。

Brainstorming 阶段做的事,就是把「直接开始 Coding」换成:
   发现需求模糊点 ──▶ 向用户提问 ──▶ 明确边界 ──▶ 再生成 Spec
   └─ 产出不是代码,是把「需求里没说清的地方」变成一份清单。
      跳过去,Spec 会把你的猜测固化成规格,后面每一步都在放大这个猜测。

Brainstorming 阶段的价值 ​

规格的质量不取决于生成得快不快,取决于生成之前模糊点有没有被逼出来。Brainstorming 阶段做的事就是把「直接开始 Coding」换成:

发现需求模糊点 → 向用户提问 → 明确边界 → 再生成 Spec

这一步的产出不是代码,是把「需求里没说清的地方」变成一份清单。跳过去,Spec 会把你的猜测固化成规格,后面每一步都在放大这个猜测。

Spec 粒度与 Token 成本 ​

完整流程的代价是文档过细:本来几句话能说清的问题会生成很多章节,Token 和时间成本都被推高。这是 那篇里记的那条固有代价,在 Spec 这一层最明显。

当前的做法是按内容相关性把长文档拆成多个小文档,好处是便于阅读、Review、维护,也便于 AI 取上下文——不用把整份 Spec 塞进每一次调用。

更进一步的优化方向是按任务复杂度动态控制 Spec 深度:小改动只出变更点和验收标准,大改动才铺完整的字段语义与决策树。Spec Kit 的「宪章常驻、其余按复杂度加载」就是这条路的一个实现。

相关 ​

参考 ​

贡献者 ​

文件历史 ​