24- 别把大需求直接丢给 AI:这是我 Spec Kit (SDD)专栏最后想说的事

1 阅读13分钟

别把大需求直接丢给 AI:这是我 Spec Kit(SDD) 专栏最后想说的事

写到这里,我这个 Spec Kit 专栏基本也快收尾了。

specifyclarifyplantasksimplement,到项目宪法、Claude Code 配置边界,再到这篇大需求拆解,我能掏的基本都掏出来了。

所以这篇不再讲某一个命令怎么用,而是讲一个更靠前的问题:

一个真实项目里的大需求,到底应该怎么交给 Spec Kit?

刚开始用 Spec Kit 时,很容易有一个想法:

能不能把一个完整大需求直接丢给 Claude,让它一次性生成 spec、plan、tasks,然后直接实现?

比如我这个项目是一个博客 Monorepo,包含:

apps/web              # React H5 前端
services/auth-service # 认证服务
services/backend      # 博客主业务服务
services/log-service  # 日志审计服务
packages/shared-*     # 共享包

如果我直接说:

帮我实现完整博客系统,包括登录、注册、忘记密码、文章列表、文章详情、评论、点赞、收藏、个人中心、日志审计。

这不是一个适合直接进入 Spec Kit 的需求。

它太大了。

它不是一个 feature,而是一组领域模块。

所以我现在更推荐的流程是:

人工领域拆分
  ↓
模块编排
  ↓
大模块二次拆分
  ↓
选择一个清晰模块进入 Spec Kit
  ↓
/speckit-specify
/speckit-plan
/speckit-tasks
/speckit-implement

一句话概括:

人工负责把大需求拆成可控模块,Spec Kit 负责把单个清晰模块落地。


一、为什么必须先拆解?

大需求拆解不是为了形式好看,也不是为了多写几份文档。

它主要解决三个问题。

1. 解决 AI 上下文执行失控的问题

AI 很擅长处理边界清晰的小任务。

但如果一个需求太大,里面同时包含认证、内容、互动、日志、前端体验等多个模块,AI 在执行过程中很容易出现上下文失控:

前面约定的边界后面忘了
当前阶段不做的能力被提前实现了
不同模块的职责混在一起
实现过程中不断追加新文件和新逻辑
最后 tasks 很长,但每一步都不够聚焦

比如忘记密码这个功能,如果不提前拆清楚,AI 可能会把这些内容一次性都做进去:

基础密码重置
验证码真实发送
验证码存储
验证码校验
防刷策略
安全审计
前端体验优化

看起来很完整,但这已经不是一个阶段了。

所以拆解的第一个目的就是:

把 AI 每次需要处理的上下文压小,让它只围绕当前模块执行。

2. 解决 Spec Kit 大需求阶段过多的问题

Spec Kit 的流程是:

/speckit-specify
/speckit-plan
/speckit-tasks
/speckit-implement

如果需求太大,Spec Kit 会被迫生成一个非常大的规格和计划。

结果通常是:

spec.md 很大
plan.md 很大
tasks.md 很长
用户故事很多
Phase 很多
依赖关系复杂
实现时很难判断当前到底做到哪里

这时候不是 Spec Kit 不好用,而是输入给它的需求颗粒度太大了。

更合理的方式是:

一个模块进入一次 Spec Kit
一个阶段生成一套 spec / plan / tasks
一个 feature 分支只处理一个清晰目标

这样 Spec Kit 的每次输出都更容易审查,也更容易执行。

3. 解决多阶段开发需要合并主干的问题

大需求通常不是一个分支从头做到尾。

更现实的流程应该是:

模块 A 开发完成
  ↓
验收通过
  ↓
合并回主干 main/master
  ↓
再基于最新主干开始模块 B

这样做有几个好处:

每个阶段都能独立验收
每次合并范围更小
冲突更少
后续模块基于最新代码继续开发
如果某个阶段跑偏,回滚成本更低

如果一个大需求长期停留在一个巨大 feature 分支里,后面会很痛苦:

分支越来越大
改动范围越来越广
和主干差异越来越多
合并冲突越来越难处理
review 很难聚焦

所以拆解的第三个目的就是:

让每个模块都能独立开发、独立验收、独立合并主干。


二、第一步:人工领域拆分

大需求不能一开始就进入 Spec Kit。

第一步应该是人工做领域拆分。

所谓领域拆分,就是先回答:

这个大需求里面到底包含哪些相对独立的业务模块?

以我的博客项目为例,一个完整博客系统可以先拆成这些领域:

认证领域
内容领域
互动领域
用户领域
日志审计领域
前端体验领域

每个领域应该尽量满足一个原则:

领域之间没有强耦合,最多是弱依赖。

比如:

认证领域:登录、注册、忘记密码、Token 刷新、退出登录
内容领域:文章列表、文章详情、文章发布、文章管理
互动领域:点赞、评论、收藏
用户领域:用户资料、个人中心、登录态展示
日志审计领域:登录日志、操作日志、审计记录
前端体验领域:路由、页面缓存、错误提示、移动端交互

这些领域之间不是完全没有关系。

比如互动需要登录态,日志可能记录认证和内容操作。

但它们不应该混在一个 Spec Kit feature 里一次性做完。


三、为什么要先做领域拆分?

因为 AI 很擅长补细节,但不一定知道你的项目边界。

比如认证领域,在我的项目里有明确边界:

auth-service 是认证事实源
backend 是前端到 auth-service 的中间层
前端只调用 backend,不直接调用 auth-service
Token 使用 HttpOnly Cookie
密码哈希使用 Argon2id

如果不先人工拆领域,AI 可能会补出一些看起来合理、但不符合项目边界的方案:

前端直接调用 auth-service
backend 直接修改认证数据
把验证码发送、校验、风控一次性都做了
把日志审计和主流程强行混在一起

这就是大需求直接进入 AI 的风险。

AI 会补全。

但补全的结果不一定是你当前阶段想要的。

所以领域拆分的意义是:

先让人确定边界,再让 AI 在边界内展开。


四、第二步:模块编排,先做哪里再做哪里

领域拆出来以后,下一步不是马上进入 Spec Kit。

还要做模块编排。

模块编排解决的是:

哪些模块先做?
哪些模块后做?
哪些模块依赖前置能力?
哪些模块可以暂时不做?

以这个博客项目为例,我会这样编排:

1. 认证基础能力
2. 内容浏览能力
3. 互动能力
4. 日志审计能力
5. 前端体验优化

为什么这样排?

因为互动能力依赖认证和内容。

比如点赞、评论、收藏都需要:

用户已登录
文章已存在
后端能校验登录态

所以不应该先做互动。

日志审计也类似。

如果主业务流程还没稳定,过早做日志审计,日志字段和事件类型很容易反复改。

所以更合理的是:

先主流程
再增强能力
最后补审计和体验

五、第三步:模块太大时继续拆分

领域拆分之后,有些模块仍然很大。

比如“认证基础能力”看起来是一个模块,但里面其实还可以继续拆:

登录
注册
退出登录
Token 刷新
忘记密码基础重置
验证码真实发送和校验
账号安全审计

这时候不能把整个“认证基础能力”直接丢给 Spec Kit。

还要继续拆。

比如拆成:

模块 1:登录注册基础链路
模块 2:忘记密码基础重置链路
模块 3:验证码真实发送和校验
模块 4:账号安全审计和风控

每个小模块都应该满足:

目标清楚
边界清楚
依赖清楚
验收清楚

只有满足这些条件,才适合进入 Spec Kit。


六、用当前 forgot-password 举例

当前项目里的 forgot-password feature,其实就是从“认证领域”里拆出来的一个小模块。

它不是完整账号恢复系统。

它只做一个阶段:

忘记密码基础重置链路

它的边界是:

前端只调用 backend
backend 调用 auth-service
auth-service 负责真实密码更新
当前阶段验证码不校验
不新增验证码数据库表
不新增 Redis 验证码状态
不记录明文密码、完整验证码、完整 Token

如果继续往后拆,完整账号恢复能力还可以有后续模块:

模块 1:忘记密码基础重置链路
模块 2:验证码真实发送和校验
模块 3:验证码防刷和频率限制
模块 4:密码重置安全审计
模块 5:前端体验和错误提示优化

所以当前 feature 只做模块 1,是合理的。

这就是“模块太大继续拆分”的意义。


七、用 XMind 或大纲描述模块和依赖

人工拆解时,可以用 XMind,也可以用 Markdown 大纲。

重点不是工具,而是结构。

我更推荐每个任务固定几个字段:

task_id
目标描述
功能需求
完成标准
约束条件
依赖任务

比如忘记密码基础重置链路,可以先人工拆成这样:

task_id: T001
目标描述: 明确忘记密码基础重置链路边界
功能需求:
  - 前端只调用 backend
  - backend 调用 auth-service
  - auth-service 负责真实密码更新
  - 当前阶段验证码不校验
完成标准:
  - 当前阶段目标清晰
  - Non-Goals 清晰
  - 可以进入 Spec Kit specify
约束条件:
  - 不新增验证码数据库表
  - 不新增 Redis 验证码状态
  - 不记录明文密码、完整验证码、完整 Token
依赖任务: 无

继续拆下一层:

task_id: T002
目标描述: 定义 auth-service 忘记密码 DTO 和响应结构
功能需求:
  - 定义手机号字段
  - 定义新密码字段
  - 定义确认密码字段
  - 定义通用响应结构
完成标准:
  - auth-service DTO 字段明确
  - backend DTO 可按此对齐
约束条件:
  - 当前阶段验证码字段可以接收,但不参与真实校验
依赖任务: T001

再拆 backend 代理层:

task_id: T003
目标描述: 定义 backend 代理层 DTO 和前端接口契约
功能需求:
  - backend DTO 对齐 auth-service DTO
  - backend 暴露给前端统一接口
  - 前端只感知 backend 接口
完成标准:
  - web → backend 契约明确
  - backend → auth-service 契约明确
约束条件:
  - backend 不直接修改认证凭据
  - backend 只作为前端到 auth-service 的中间层
依赖任务: T002

这样任务依赖就非常清楚:

T001 明确边界
  ↓
T002 auth-service DTO
  ↓
T003 backend 契约

注意,这里我不会单独标“并行”或“串行”。

因为真正决定顺序的是:

后一个任务是否依赖前一个任务的结果。


八、人工拆解后,再进入 Spec Kit

人工拆解完成后,再把结构化任务交给 Spec Kit。

不是这样:

/speckit-specify 帮我实现忘记密码功能

而是这样:

/speckit-specify

请根据以下人工拆解任务,生成当前阶段的 feature specification。
本阶段只实现忘记密码基础重置链路,不实现真实验证码发送和校验。

[粘贴 T001、T002、T003 ...]

这样 Spec Kit 拿到的不是一个模糊的大需求,而是一组已经人工拆好的模块任务。

接着再执行:

/speckit-plan
/speckit-tasks
/speckit-implement

这样生成出来的:

spec.md
plan.md
tasks.md
quickstart.md

都会围绕当前模块展开,而不是围绕整个大需求无限扩张。


九、一个模块一个 feature 分支

大需求拆成模块以后,我不建议一个 feature 分支做完所有模块。

更稳的是:

一个模块 = 一个 feature
一个 feature = 一次 Spec Kit 流程
一个 feature = 一个 feature 分支

比如认证领域可以拆成多个 feature:

feature/auth-login-register
feature/forgot-password-reset
feature/forgot-password-code-verification
feature/auth-security-audit

每个 feature 都有自己的:

spec.md
plan.md
tasks.md
quickstart.md

这样做的好处是:

目标更清楚
上下文更小
plan 更容易审查
tasks 更容易执行
验收更独立
出问题更容易回滚

如果所有模块都塞进一个 feature 分支,最后很容易变成:

一个超大的 spec.md
一个超大的 plan.md
一个很长的 tasks.md
一堆互相影响的代码修改

这不是 Spec Kit 最舒服的使用方式。


十、完整流程总结

最终我推荐的完整流程是:

1. 人工理解大需求
2. 人工做领域拆分
   - 每个领域尽量独立
   - 领域之间没有强耦合,最多弱依赖
3. 做模块编排
   - 先做哪里
   - 后做哪里
   - 哪些模块依赖前置模块
4. 如果模块仍然太大,继续拆分
   - 拆到目标清楚
   - 拆到边界清楚
   - 拆到可以独立验收
5. 用 XMind 或 Markdown 大纲写结构化任务
   - task_id
   - 目标描述
   - 功能需求
   - 完成标准
   - 约束条件
   - 依赖任务
6. 选择一个模块作为当前 feature
7. 创建 feature 分支
8. 执行 /speckit-specify
9. 执行 /speckit-plan
10. 执行 /speckit-tasks
11. 人工审查 spec / plan / tasks 是否跑偏
12. 执行 /speckit-implement
13. 验收当前 feature
14. 再进入下一个模块

也可以压缩成一句话:

人工先拆领域和模块,Spec Kit 再落地单个模块。

最后总结

Spec Kit 很适合做一件事:

把一个边界清晰的 feature 变成可执行计划。

但它不应该替代人工完成大需求的顶层拆解。

在我的博客 Monorepo 项目里,我会先人工做:

领域拆分
模块编排
大模块二次拆分

然后再把其中一个清晰模块交给 Spec Kit:

/speckit-specify
/speckit-plan
/speckit-tasks
/speckit-implement

一句话总结:

大需求不要直接交给 Spec Kit;先人工拆成领域和模块,再让 Spec Kit 落地单个模块。

写完这篇,我这个 Spec Kit 专栏基本就算收尾了。

不是因为 Spec Kit 没得讲了,而是从入门流程、单个命令、项目宪法、Claude Code 配置边界,到最后这篇大需求拆解,已经基本覆盖了我在真实项目里踩过的主要问题。

如果只记住一句话,我希望是:

不要指望 AI 替你完成顶层拆解。人先把边界拆清楚,Spec Kit 再把单个模块落地。