GitHub Spec Kit 实战(二):写一份不偏的 /speckit.specify

GitHub Spec Kit 实战(二):写一份不偏的 /speckit.specify

上一篇文章(《GitHub Spec Kit:让规格成为可执行的代码》)我们跑通了完整流程。但跑通不等于写好——/speckit.specify 这一步最容易翻车。

我前前后后写了 20 多份 spec,翻车翻到麻木。最常见的偏,不是写得不够详细,而是从第一句就写错了

  • 第一句就在讲 React、SQLite、PostgreSQL
  • 需求里塞了一堆"也许用户还需要 XX 功能"
  • 验收标准全是"系统响应时间 < 200ms"这种程序员视角
  • 没写 [NEEDS CLARIFICATION],AI 替你猜,猜错了一行行回滚

这篇文章把 /speckit.specify 的所有坑拆开讲清楚。看完你应该能写出一份 AI 不需要反复返工的 spec。

一句话原则:写什么,不写什么

/speckit.specify 命令的源码在仓库 templates/commands/specify.md,里面有句反复出现的话:

Focus on WHAT users need and WHY.
Avoid HOW to implement (no tech stack, APIs, code structure).
Written for business stakeholders, not developers.

翻译成中文:写用户要什么为什么别写怎么实现

这不是说说而已。AI 拿到你的 spec 后会逐字读,里面出现"React"它就用 React,出现"PostgreSQL"它就上 PostgreSQL。你只想做个相册管理,AI 顺手给你整一套云存储抽象——那是你的 spec 喂的,不是 AI 主动加的

一份合格的 spec 长这样

Spec Kit 的 spec-template.md 强制四节:

章节必填写什么
User Scenarios & Testing3-5 个按优先级排序的用户故事,每个能独立交付
RequirementsFR-001/002/…,每条可测试
Success CriteriaSC-001/002/…,业务视角、可验证、技术无关
Assumptions你替用户做的合理默认
Key Entities涉及数据时业务实体的定义和关系

注意一个细节:不适用的章节直接删掉,不要留"N/A"。模板的注释里专门写了。

User Scenarios:按 P1/P2/P3 排的故事

这是 spec 里最值钱的一节。Spec Kit 的 spec-template.md 对 User Story 有三条硬要求:

Each user story/journey must be INDEPENDENTLY TESTABLE - meaning if you implement just ONE of them, you should still have a viable MVP

意思是:P1 单独做完,就是一个能跑的产品。P2、P3 是迭代加分项。这样设计的好处是——AI 拿到 spec,先做 P1,能跑通;做 P2,再增量;做 P3,再叠加。不会一上来铺大而全的架构

我用上一篇文章的相册例子重写一遍(按 Spec Kit 模板的口径):

### User Story 1 - 按日期自动建相册 (Priority: P1)

我上传一张照片,系统自动按拍摄日期归到对应相册里。

**Why this priority**: 这是 MVP 的核心——没有这一步,整个产品价值为零。
**Independent Test**: 上传 5 张不同日期的照片,验证 5 个相册自动出现。

**Acceptance Scenarios**:
1. **Given** 我没建过相册,**When** 我上传一张拍摄于 2024-03-15 的照片,
   **Then** 系统自动建一个"2024 年 3 月"相册并把这张照片放进去。
2. **Given** 已有"2024 年 3 月"相册,**When** 我上传同一月的另一张照片,
   **Then** 这张照片被加进已有相册,不新建。

Why this priorityIndependent Test 是模板里强制要求的两段,别省。前者让 AI 知道排序逻辑,后者让 AI 知道做完这条该验收什么。

Requirements:每条都能塞进测试用例

spec-template.md 给的格式是 FR-001 / FR-002 / … 编号列表,每条写 System MUST ...Users MUST be able to ...。注意几个细节:

### Functional Requirements

- **FR-001**: 系统 MUST 保留照片原始 EXIF 信息中的拍摄日期,作为自动分组的依据。
- **FR-002**: 系统 MUST 按"年-月"粒度自动创建相册,不支持自定义分组粒度(v1)。
- **FR-003**: 系统 MUST 在相册内按拍摄时间倒序显示照片。
- **FR-004**: 用户 MUST 能在主页面拖拽照片到不同相册重新分组。
- **FR-005**: 相册 MUST 不支持嵌套——相册里没有子相册。
- **FR-006**: 系统 MUST [NEEDS CLARIFICATION: 单用户还是多用户?多用户的话相册隔离规则?]

几条死规则:

  1. 每条独立可测——FR-001 不能写成"系统处理照片正确"。要写"系统保留 EXIF 拍摄日期",验收时一查就知道。

  2. 明确说"不做"FR-002 里"不支持自定义分组粒度(v1)“、FR-005 里"不支持嵌套”——把你主动砍掉的范围写出来。AI 不会替你加"也许你想要 XX 功能",但也不会替你砍。你不写它就猜。

  3. [NEEDS CLARIFICATION] 标记不能超过 3 个specify.md 源码里明文规定:

    LIMIT: Maximum 3 [NEEDS CLARIFICATION] markers total
    Prioritize clarifications by impact: scope > security/privacy > user experience > technical details

    而且优先级顺序也写死了:scope > security/privacy > UX > technical 细节。技术选型怎么选、数据库用什么表——这些不是澄清项,是后面 /speckit.plan 的事。

Success Criteria:业务视角的"做完了"

这是 AI 翻车最严重的一节。spec-template.md 里给出了好例子和坏例子的对比:

好的:

  • “Users can complete checkout in under 3 minutes”
  • “System supports 10,000 concurrent users”
  • “95% of searches return results in under 1 second”
  • “Task completion rate improves by 40%”

坏的(直接抄模板的):

  • “API response time is under 200ms” —— 太技术,应该写"用户提交后立刻看到结果"
  • “Database can handle 1000 TPS” —— 实现细节,应该写用户侧指标
  • “React components render efficiently” —— 框架相关
  • “Redis cache hit rate above 80%” —— 技术栈相关

判断标准很简单:一个完全不懂技术的 PM,能拿这条 SC 去验吗? 能→好;不能→改。

Spec Kit 模板给出的四条死规则:

  1. Measurable:带具体数字(时间、百分比、计数、速率)
  2. Technology-agnostic:不提框架、语言、数据库、工具
  3. User-focused:从用户/业务视角描述,不是系统内部
  4. Verifiable:可测试、可验证,不依赖实现细节

相册例子的 SC:

### Measurable Outcomes

- **SC-001**: 用户上传 100 张不同日期的照片,从上传到全部归入对应相册,时间不超过 30 秒。
- **SC-002**: 用户在 5000 张照片的库中,找到任意一张照片的时间不超过 5 秒。
- **SC-003**: 95% 的首次用户,在 2 分钟内完成首次上传+查看自动归类结果的全流程。
- **SC-004**: 用户拖拽照片重分组的操作,平均 1.5 秒内系统反馈完成。

每条都能拿到用户面前直接验。

Assumptions:你替用户做的默认

这节容易被忽略,但它救命。模板要求把所有"spec 里没说但你做了合理默认"的决定写下来:

## Assumptions

- 目标用户为个人消费者(不是企业团队),不需要多用户权限隔离
- v1 仅支持 JPG/PNG 格式,HEIC/RAW 在 v2 考虑
- 移动端响应式支持(自适应布局),但不做原生 App
- 数据存储在用户本地优先,云同步在 v2 考虑
- 现有项目用 SQLite 做本地存储(这个算"现状",不是 spec 决定)

注意最后一条:Assumptions 写默认行为,不写实现选型。“用 SQLite"这条其实不该写——它属于 plan 阶段。你可以在 Assumptions 里写"假定本地有持久化存储能力”,至于用 SQLite 还是文件系统,那是 plan 的事。

Key Entities:涉及数据才填

spec-template.md 注释里写明 “include if feature involves data”。相册例子需要:

### Key Entities

- **Photo**: 一张照片,含原始 EXIF 信息中的拍摄日期、文件大小、格式;属于一个且仅一个 Album。
- **Album**: 一个相册,标识为"年-月"格式的标题(如"2024 年 3 月");包含 0 个或多个 Photo;相册之间无层级。
- **User**: 一个用户,拥有 0 个或多个 Album。

只有"是什么"和"什么关系",没有"用什么字段、什么类型、什么索引"。后者是 plan。

写完后:3 轮自检

specify 命令会自动生成一份 checklists/requirements.md 做质量检查。但你写完就该自己过一遍——下面是 Spec Kit 内置检查项的人工版:

Content Quality

  • 全文搜 React/Vue/Spring/MySQL/Redis/Django/PostgreSQL/Redis/Kafka/任何技术栈名字——命中就改
  • 全文搜 should / 最好 / 考虑——这些是软词,spec 要的是 MUST
  • 每段是否聚焦用户价值?不是就在往实现细节滑

Requirement Completeness

  • [NEEDS CLARIFICATION] 不超过 3 个
  • 每条 FR 都能直接写成一个测试用例
  • 每条 SC 都符合"PM 能拿去做验收"标准
  • 边界条件在 Edge Cases 里写出来(断网、文件超大、日期缺失等)

Feature Readiness

  • P1 单独做完能跑通吗?
  • 没写的"不做"明确说出来了吗?
  • Assumptions 写完整了吗?

一个反例:从合格到翻车只要一句话

给你看个真实场景——用户最初的需求写的是:

我想做一个照片管理应用,前端用 React Native,后端用 Python FastAPI,数据存 PostgreSQL,支持 AI 自动打标签……

这一段从第一句就坏了。技术栈占了 80%,AI 会按这些字面信息去搭项目,结果不是你想要的。

改写后:

做一个照片管理应用。用户上传照片后,系统按拍摄日期自动归入对应相册;用户可在主页面拖拽照片重新分组。MVP 阶段(v1)只支持单用户本地使用。

然后按 Spec Kit 模板写四节。/speckit.specify 一跑出来的 spec.md,没有任何一个技术选型词。等 /speckit.plan 阶段,AI 会根据 spec + 你的 codebase 上下文自己选型——这才是 Spec Kit 想让你做的事。

写完就准备进 plan 阶段

specify 命令会在 checklists/requirements.md 里给出三项结论之一:

  • All items pass → 直接进 /speckit.plan
  • 有 [NEEDS CLARIFICATION] → 命令会自动生成澄清问题给你(最多 3 个,每个带 A/B/C 建议答案),你答完它再更新 spec
  • 其他项失败 → 命令会自检 3 轮修复,第 3 轮还修不好就标红让你人工处理

把澄清问题答好,spec 就稳了。下一篇会讲 /speckit.constitution 怎么写——那是 spec 之前的"项目宪法",决定了所有 spec 都要遵守的硬约束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码绘春秋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值