现在可以把最终需求简报交给 Spec Kit,继续生成 SPEC 文档了。
8.1 把最终需求简报交给 Spec Kit
进入已经初始化 Spec Kit 的胶囊系统项目,然后调用 $speckit-specify(或者用自然语言给 Codex 交代使用需求简报生成 SPEC 文档)。这次不要重新概括需求,也不要改用项目目录里较早保存的旧版本。13.7 中代码块里的完整需求简报是基础输入,后续经过用户确认的人工审核兜底和规则缺口反馈则作为补充输入。
可以向 Codex 输入下面这条指令:
使用
$speckit-specify,以 13.7 中的《胶囊系统主流程需求简报》全文作为基础功能描述,并纳入后续已经确认的人工审核兜底与规则缺口反馈补充,生成胶囊系统第一版 SPEC。同时读取当前项目宪章,并检查生成结果是否符合宪章中的全部核心原则。
这里有一个容易忽略的地方。Spec Kit 不只是把需求简报整理成固定格式,它还会读取项目中的宪章。需求简报负责记录本次功能的目标、范围和取舍,宪章负责约束所有功能都不能违反的长期原则。对于胶囊系统来说,已经形成衍生证据并被采纳的新增内容必须继续进入关系判断和知识页演化;已保存的原始证据 URL 和衍生证据,不能在未经用户确认时被永久删除;重要不确定情况也必须暂停并交给用户决定,不能在缺少依据时继续猜测。
执行完成后,Spec Kit 会创建本次功能目录,并把当前功能写入:
specs/001-capsule-main-flow/spec.md
同时生成的 checklists/requirements.md 用来检查 SPEC 是否完整、可验收,是否混入了不应该在需求阶段决定的实现细节。项目中的 .specify/feature.json 则记录当前功能目录,让后续的 $speckit-plan 和 $speckit-tasks 知道应该读取哪一份 SPEC。
8.2 SPEC 的文件头
打开生成的 SPEC,最前面是这样一组信息:
# Feature Specification: 胶囊系统第一版主流程
**Feature Branch**: N/A(当前项目未初始化 Git 仓库)
**Feature Directory**: `specs/001-capsule-main-flow`
**Created**: 2026-08-15
**Status**: Draft
**Input**: 第 13 章 13.7 节《胶囊系统主流程需求简报》,以及后续确认的人工审核兜底与规则缺口反馈补充
这些字段不负责描述系统行为,它们负责确认“现在读的是哪一份 SPEC,它从哪里来,处在什么阶段”。
| 英文字段 | 中文含义 | 在这份 SPEC 中的作用 |
|---|---|---|
Feature Specification |
功能规格 | 标明当前 SPEC 的功能名称,这里对应胶囊系统第一版主流程 |
Feature Branch |
功能分支 | 记录该功能对应的 Git 分支;当前项目还没有初始化 Git,所以写为 N/A,也就是“不适用” |
Feature Directory |
功能目录 | 记录本次功能在 Spec Kit 项目中的位置,后续命令通过它找到同一组资料 |
Created |
创建日期 | 说明这份 SPEC 在何时生成,便于以后追踪版本变化 |
Status |
当前状态 | Draft 表示草稿,它已经可以接受检查,但还不等于用户正式批准 |
Input |
输入依据 | 指明 SPEC 根据哪一份需求生成,防止后续误用旧需求简报 |
这里的 Feature Branch 和 Feature Directory 很容易混淆。前者服务 Git 版本管理,后者服务 Spec Kit 的资料定位。即使项目暂时没有 Git 分支,Spec Kit 仍然可以通过 Feature Directory 找到 spec.md、质量检查表,以及后面生成的规划和任务文件。
8.3 SPEC 的整体逻辑
这份 SPEC 不是把需求简报换成英文标题以后重新排列一遍。它按照一条逐步收紧的逻辑,把产品判断变成开发可以执行、测试可以核对的约定:
需求简报 + 项目宪章
↓
Scope Boundaries
确定当前功能负责什么、不负责什么
↓
User Stories
按用户目标组织有价值的完整路径
↓
Acceptance Scenarios + Edge Cases
写出典型场景和容易产生歧义的输入
↓
Functional Requirements
补齐系统必须执行或禁止的行为
↓
Key Entities + Assumptions
统一核心对象,并记录当前采用的前提
↓
Success Criteria
从整个功能层面判断最终结果是否合格
↓
Plan / Tasks / Tests
选择实现方案,拆分任务并完成验证
这条顺序也解释了需求简报和 SPEC 的关系。需求简报里可以写“第一版只做个人知识库”“所有附件只做一次性处理”,因为作者此时正在作产品取舍。到了 SPEC,这些判断必须分别进入范围边界、用户场景、功能需求和成功标准。只有这样,后续开发时才不会把一句产品判断理解成可做可不做的背景说明。
用户故事是价值主线
如果一定要从这份 SPEC 中找出一条主线,那么这条主线确实是用户故事,但不能进一步理解成“整份 SPEC 只由用户故事驱动”。用户故事负责按照用户目标组织开发内容和优先级,让我们先看到用户最终要完成什么,而不是先看到几十条彼此分散的功能需求。
胶囊系统的第一条用户故事是:
作为个人用户,我提交一份资料后,希望系统判断它与现有知识的关系,并把其中被采纳的新内容融合进主题页或概念页,而不是只保存一份孤立摘要。
这条故事从“资料提交”一直走到“知识页演化”,单独实现以后,用户已经能够获得一段完整价值。因此它被标为 P1。PDF、图片和音频虽然处理方式不同,但用户并不是为了“使用 PDF 功能”而使用胶囊系统,所以没有把每一种文件格式都拆成一条用户故事。它们被放进第二条故事的验收场景和功能需求中。
用户故事内部还有一组固定字段:
| 英文字段 | 中文含义 | 它解决的问题 |
|---|---|---|
User Story |
用户故事 | 哪类用户希望完成什么目标,并获得什么价值 |
Priority |
优先级 | 先实现哪一段用户价值;P1 高于 P2 |
Why this priority |
优先级理由 | 解释这条故事为什么排在当前位置,避免优先级只是随手填写 |
Independent Test |
独立测试 | 只实现这一条故事时,怎样单独证明它已经产生可用价值 |
Acceptance Scenarios |
验收场景 | 在具体条件和操作下,系统必须给出什么结果 |
Given |
已知条件 | 场景开始时已经成立的前提和状态 |
When |
发生动作 | 用户或系统执行了什么动作 |
Then |
期望结果 | 动作发生以后,可以观察和核对的系统结果 |
例如,第二条用户故事中有这样一条验收场景:
Given 用户提交包含正文和图片的 PDF,When 系统处理 PDF,Then 系统提取或识别正文文字、忽略其中的图片,并且不保存 PDF 文件。
这里没有说明使用哪个 PDF 库,也没有规定 OCR 服务。SPEC 先固定用户能够观察到的结果:正文文字被提取,内嵌图片不参与处理,PDF 原文件不被保存。至于怎样做到,要到 Plan 阶段结合项目环境决定。
功能需求形成横向约束
用户故事适合表达从开始到结果的一条完整路径,但有些规则会同时影响多条路径。功能需求承担的就是这部分工作。它不再追随某一次具体经历,而是完整规定系统在所有相关场景中必须怎样处理。
在 Functional Requirements 中,每条需求都有 FR 编号。FR 是 Functional Requirement 的缩写,也就是功能需求。句子里的 MUST 表示必须执行,MUST NOT 表示明确禁止,MAY 表示允许但不强制。这些词特意使用大写,是为了标出约束强度,不是普通的英文强调。
例如,FR-006 规定:
系统
MUST只持久保存文本内容和来源 URL,MUST NOT持久保存任何非文本附件。
这条规则会同时约束 PDF、独立图片、音频、视频、网页图片和审核队列。假如只把它写在 PDF 的验收场景里,AI 可能在做人工审核功能时又保存一份图片附件,因为“方便用户复核”在很多系统里本来就是常见设计。FR-006 把这个口子彻底封住了。
所以,可以把用户故事理解成纵向的价值路径,把功能需求理解成横向的行为约束。前者决定按什么目标组织开发,后者保证不同用户故事不会采用互相矛盾的规则。
其余栏目补齐容易遗漏的部分
用户故事和功能需求已经承担了大部分内容,但仍然不够。其余栏目分别补上范围、异常、名词和整体验收:
| 英文栏目 | 中文含义 | 在文档中的职责 |
|---|---|---|
Scope Boundaries |
范围边界 | 确定第一版处理什么、不处理什么 |
In Scope |
范围内 | 列出当前功能负责的对象和职责 |
Out of Scope |
范围外 | 明确排除当前版本不负责的功能,防止开发时自行扩张 |
User Scenarios & Testing |
用户场景与测试 | 按用户目标组织主要路径,并为每条故事准备独立验证方法 |
Edge Cases |
边界情况 | 记录已经进入功能范围、但容易失败或产生歧义的输入 |
Requirements |
需求 | 汇总整个功能必须遵守的约定 |
Functional Requirements |
功能需求 | 规定系统必须执行、禁止或允许的行为 |
Key Entities |
关键实体 | 统一系统反复处理的核心对象及其关系,但暂不决定数据库字段 |
Success Criteria |
成功标准 | 判断整个功能完成以后是否达到预期,而不只检查单个场景 |
Measurable Outcomes |
可测量结果 | 为成功标准给出比例、数量、时间或零容忍结果 |
Assumptions |
假设 | 记录需求没有明确说明、当前暂时采用的合理前提 |
标题后面的 *(mandatory)* 表示这是 Spec Kit 模板要求必须填写的栏目。它和 Priority: P1 不是同一个概念:mandatory 约束文档结构,P1 表示用户故事的实现优先级。
成功标准前面的 SC 是 Success Criterion 的缩写。验收场景检查的是某条用户故事在特定条件下能否成立,SC 检查的是整个功能组合起来以后有没有达到预期。例如,PDF 验收场景只处理一次 PDF 提交,SC-005 则要求完成整组媒体资料验收以后,系统持久保存的非文本附件总数仍然为 0。
Key Entities 也不是提前设计数据库。以这份 SPEC 为例,它定义了原始证据、衍生证据、资料索引和审核项。后续 AI 在规划数据结构、页面和处理流程时,会反复使用这些名词。如果这里不先固定含义,“原始证据”就可能在某个任务里指 URL,在另一个任务里又变成 PDF 文件,最后各模块对同一个词产生两种理解。
Assumptions 则负责公开那些没有必要继续追问、但开发时必须采用的前提。例如,第一版只有一个个人用户,资料提交者和不可逆操作确认者是同一个人。这项假设让 AI 不必自行增加组织、角色和权限系统。假设不是永远正确的事实;以后产品范围改变时,它也要跟着修改。
8.4 同一条需求怎样贯穿整份 SPEC
很多内容会在 SPEC 中出现不止一次,看起来好像重复,其实每次回答的问题不同。拿“PDF 原文件不保存”这一条来看,它在文档里经过了五层转换:
| 所在位置 | 具体表达 | 承担的职责 |
|---|---|---|
In Scope |
第一版接收 PDF | 确认 PDF 属于当前功能处理的对象 |
Out of Scope |
不保存、归档或管理 PDF 原件,也不处理 PDF 中的图片 | 排除系统不承担的职责 |
Acceptance Scenario |
提交包含正文和图片的 PDF 后,提取正文、忽略图片、不保存文件 | 给出一条可以实际执行的验收场景 |
FR-006 与 FR-008 |
所有非文本附件都不得持久保存;PDF 只能提取文字 | 把单个场景上升为稳定的系统规则 |
SC-005 |
完成媒体资料验收后,持久保存的非文本附件数量为 0 | 从整个功能层面核对规则有没有真正实现 |
如果删除其中任何一层,都会留下不同的问题。没有范围边界,AI 不知道 PDF 是否属于第一版;没有验收场景,测试人员不知道怎样操作;没有功能需求,其他媒体可能采用另一套规则;没有成功标准,系统即使偷偷留下附件,也缺少一次面向整体结果的核对。
再看网页图片无法可靠转换的情况。它首先出现在第二条用户故事中,规定系统要把证据标记为不完整;随后又进入第三条用户故事,由审核队列让用户决定怎样继续。FR-016 固定图片处理结果,FR-031 到 FR-037 固定人工处理方式,最后由 SC-006 和 SC-007 分别验收网页图片和审核队列。这个例子说明,用户故事不是互相隔离的页面清单,一次真实处理可以从一条故事进入另一条故事。
8.5 AI 怎样根据 SPEC 继续开发
AI 写代码很快,但当需求留有空白时,它也会根据常见做法自行补全。对于普通资料管理系统,“上传以后保存原文件”“冲突时用新内容覆盖旧内容”都可能是合理默认。可在胶囊系统里,这两个默认恰好违反已经确定的产品规则。
SPEC 的作用,就是把这类不能由 AI 自行决定的地方固定下来。Out of Scope 阻止 AI 把综合页和多级权限一起做进第一版;功能需求让每项实现都能回到明确编号;验收场景给测试设计提供已知条件、操作和期望结果;成功标准则检查多个模块组合起来以后,用户最终看到的结果是否正确。
后续执行 $speckit-plan 时,AI 会根据用户故事识别需要交付的完整功能路径,再根据功能需求和关键实体设计实现方案。这里的 Plan 是实现计划,负责回答采用什么结构和技术来满足 SPEC。执行 $speckit-tasks 时,AI 再生成 Tasks,也就是可以逐项完成的任务列表。
任务通常会按照用户故事分组,让每个 P1、P2 故事都能独立实现和验证。但实际开发顺序还要考虑依赖关系。项目初始化、公共数据结构和所有故事共同依赖的基础处理,可能要先于某条用户故事完成。因此,用户故事驱动的是可交付的功能切片,依赖关系决定任务真正的先后顺序。
到了实现和测试阶段,Given / When / Then 提供场景级检查,SC 编号提供整个功能的验收目标。不过,验收场景本身还不是自动化测试代码。AI 仍然需要在 Plan 和 Tasks 阶段决定哪些结果用单元测试验证,哪些需要集成测试或人工验收。Tests 指的就是这些实际执行的测试。
因此,这份 SPEC 不是由某一个栏目单独驱动的。更准确的理解是:宪章和范围控制方向,用户故事驱动价值路径,功能需求约束系统行为,验收场景与成功标准驱动验证。AI 得到的也不再是一段只能靠上下文揣摩的想法,而是一组可以互相核对的开发约定。
8.6 检查生成结果
这一步最需要检查的不是篇幅,而是需求简报里的判断有没有真正转换成约束和验收场景。例如,“系统不保存任何非文本附件”不能只留在范围说明里,还要出现在功能需求和成功标准中;网页图片的忽略、转换和证据不完整,也要分别有可以验证的结果。
同样,审核队列不能只停在一个模糊的功能名称上。SPEC 需要明确三类审核对象:处理中断、知识冲突和不可逆操作,并说明用户能看到什么、可以作出哪些决定,以及系统怎样继续或终止原来的处理流程。这样生成的 SPEC 才能成为后续规划的依据。
完整 SPEC 比前面的独立图片示例长得多,继续放在正文里会打断阅读,所以本节只解释它的结构和逻辑。阅读配套资料时,可以选择任意一条 FR,反向检查它来自哪条用户故事或范围约束,再向下确认是否有验收场景和成功标准。这比单独计算文档中有多少条需求更能发现问题。
完整 SPEC 文档:
- 胶囊系统第一版 SPEC外部文档