| name | spec-writing |
| description | 需为非平凡功能/重构写设计文档(spec/design doc/RFC)时。 |
Spec Writing
概述
把一个还没动手的方案写成可评审、可追溯、可验收的设计文档。核心:spec 是决策的固化——它记录"为什么这么定、定了什么、没定什么、怎么算实现成功",而不是知识的搬运(堆背景介绍)或愿望的罗列(只说要做什么不说怎么做)。
何时使用
- 要做一个非平凡功能/重构/迁移,想先写设计再动手
- 要把脑里模糊的方案固化成可给同事评审的文档
- 已有设计草稿,想审查写得好不好
不该用:小到一目了然的改动(直接做,写 spec 是负担);纯研究性命题还没结论时(先做 spike 调研,有了结论再写 spec——spec 记录决策,调研产出结论)。
与相邻 skill 的衔接:spec-writing 在"需求澄清 → 写 spec → 拆任务"流水线的中间。spec 定稿后,把方案交给 task-breakdown 拆成可执行任务;需求还太模糊连方案都形不成时,先澄清(见 clarifying-questions,未实现)再写 spec。
核心内容
先判断时机:spec 之前还有没有重大未知
不是所有"写个 spec"的需求都该直接开写。如果方案的核心决策还依赖未澄清的未知,硬写出来的 spec 就是空架子或一堆猜测。先问自己:写 spec 需要的决策,我都有依据了吗?
判断标准——把"影响方案结构的关键决策"列出来,看每条是哪种状态:
- 已明:有依据、能定。直接写进 spec 的决策部分。
- 需要澄清:用户一句话能定(范围、约束、目标)。写 spec 前先问,不要替用户猜。
- 需要调研:一句话定不了,得查/试/比(技术选型、性能可行性)。先做 spike(专门的调研任务,产出结论而非代码),有结论再写 spec——否则 spec 里只能写"待定",决策部分就空了。
如果大量关键决策都是"需要调研"状态,说明现在不是写 spec 的时机——先做调研。澄清和调研占 spec 前置工作的大头,跳过它们直接写,是最常见的失败模式。
判断后的产出顺序(很重要,别把几步混在一起让用户困惑):
- 关键决策大多"已明" → 直接写 spec。
- 有"需要澄清"项 → 先把澄清问题列给用户(阻塞项优先),等回答。这一步的产出就是"澄清问题清单",不要同时甩一份假设性 spec——用户分不清该先回答问题还是改 spec。
- 有"需要调研"项 → 标出该做哪些 spike,说明"结论出来才能填 spec 的哪几节"。产出是"spike 清单 + 这些 spike 解锁的 spec 章节",同样不提前硬写。
- 混合 → 澄清问题 + spike 清单一起给,标注各自解锁什么。把"前置工作"和"spec 本体"分开交付。
澄清问题怎么问(这一步的产出质量直接决定 spec 质量):
- 每条带"为什么问":让用户理解这个未知为什么影响方案,而非凭空盘问。差:"QPS 多少?";好:"读 QPS 大概多少?(决定能否用单机 Redis 还是必须集群)"。
- 给默认假设让用户确认,而非开放式追问:"我假设日读 < 1k QPS、单机够用,不对请纠正"——用户一句话能校正;纯开放式问题用户得从头想,消耗耐心。
- 问影响方案结构的,不问实现细节:问"实时还是离线计算"(改变架构),不问"用 Flink 还是 Spark"(实现细节,spec 阶段还太早)。
- 一次别超过 6-8 条:多了用户接不住。真有更多未知,先问阻塞第一刀的,其余用默认假设推进。把未知按"阻塞/非阻塞"分类(阻塞项先问、非阻塞用假设推进)很关键——
task-breakdown 的"澄清未知"对此有更细的分类法,可参考。
反例:用户说"写个限流 spec",你直接套模板写"背景/方案/步骤"——但"限流维度(接口/用户/IP)、算法(令牌桶/漏桶)、单机/分布式"都没定,写出来的方案部分全是占位符。
spec 写什么:决策,不是知识
spec 的价值密度集中在决策上。每写一段问自己:**这是决策,还是背景知识?**两者的篇幅分配严重失衡是 spec 写差的信号:
- 决策(spec 的核心):选了什么方案、为什么选它、放弃了什么、怎么算成功。这是别人来评审、未来回溯时要看的东西,值得详细写。
- 背景(spec 的脚手架):问题是什么、为什么做、相关技术是什么。点到决策够用为止,不要写成技术科普。读者不需要在限流 spec 里学"什么是令牌桶算法"——他们需要知道"我们为什么在令牌桶和漏桶之间选了令牌桶"。
反例:搜索功能 spec 一半篇幅在介绍 Elasticsearch 基于 Lucene、支持全文检索、生态丰富——这是知识搬运,不是决策。读者看完不知道你们为什么选它、什么场景选它、不选它会怎样。
研究基础怎么写:调研/spike 的结论要进 spec,但只写"对决策有用的结论",不写调研过程。差的做法是堆"我查了 A、B、C,A 是……B 是……"的流水账;好的做法是直接给"对比结论 + 选定理由",如"对比 Redis 滑动窗口与 Sentinel 网关限流:Redis 方案在多实例下计数精确(误差<1%)、Sentinel 依赖单网关成瓶颈,选 Redis"。读者要的是结论支撑决策,不是重新跟你调研一遍。
显式标注未决项,别藏不确定性
spec 里一定有没定死的东西(技术选型还在权衡、依赖外部团队、待 spike 结论)。显式标出来,不要把它们包装成"已定方案"蒙混过关。藏起来的不确定性会在实现期爆炸——下游按"已定"去做,结果方案根本没敲定,返工。
标注方式:
- 待定项:明确写
TBD:xxx,待 yyy 后定。例:分布式事务方案 TBD,待 Saga 与最终一致性的压测对比后定。
- 选项 + 权衡:一时定不了的,列候选方案 + 各自的代价,标"待选"。例:
消息队列:Kafka(吞吐高、运维重)vs RabbitMQ(够用、轻量),倾向 RabbitMQ,待容量评估确认。
显式 TBD 让评审者一眼看到"哪里还没定",也能让 spec 在未决状态下流转(不必等所有事都想清才能写)。
范围:做什么,同样重要的是不做什么
明确"本轮做什么"的同时,显式列出"不做什么"。范围不清是 spec 失败的高频原因——什么都往里塞,最后要么无限膨胀做不完,要么做出来的和初衷不符。
"不做什么"包含两类:
- 本轮排除:相关但本轮不做的(如"做搜索本轮不做向量搜索,留后续")。写出来防止范围蔓延。
- 明确不属于:容易混淆但不是 spec 范围的(如"限流 spec 不管鉴权,那是另一个 spec")。写出来防止边界模糊。
验收标准:spec 要定义"实现怎样算成功"
spec 不止写"做什么",还要写"做完怎么算成功"——可验证的验收标准。否则实现完了没法判断达标与否,"是否完成"变成主观感受。
好的验收标准是可观测、可量化的:
- 差的验收:"搜索功能上线"(上线了但慢、不准、缺功能都算吗?)
- 好的验收:"核心商品搜索 P95 < 200ms、Top-10 召回率 > 90%、支持前缀匹配与高亮;订单/用户搜索本轮不做"
验收标准同时是 spec 范围的反向校验——如果你写不出验收标准,说明"做什么"本身还没定义清楚,回去补范围。
风险与回滚(高风险方案的必备维度)
对高风险方案(迁移、架构重构、数据变更、破坏性改动),spec 必须有"风险与回滚"维度。这类方案最怕的不是"怎么做",而是"做错了怎么办":
- 风险:可能出什么事?(数据不一致、服务中断、性能退化、兼容性破坏)
- 发现机制:怎么尽早发现做错了?(监控、灰度、对比校验、回滚触发条件)
- 回滚方案:错了怎么退回?(特性开关、双写、分阶段切换、可回滚的部署)
低风险的小改动不必硬塞这个维度,过度防御也是 spec 的负担。
审查已有草稿:先分类,再对症
用户拿一份已有草稿让你"看看",先判断它属于哪种问题,处理方式完全不同:
- 信息不足型:草稿只写了背景/愿望,核心决策全空(如"要加搜索功能,用 ES"——为什么用 ES、搜什么、怎么算成功都没写)。这种其实是"现在还不是写 spec 的时机"——退回前置流程:列澄清问题 + 必要的 spike,别在残缺草稿上打补丁。
- 写法缺陷型:草稿信息基本齐,但写法差(堆背景、藏不确定性、没验收、范围蔓延)。这种才是"改草稿"——逐条指出具体问题 + 改法。
审查意见要排优先级,别一次甩十几条。按"致命 → 重要 → 锦上添花"分:致命的是会导致返工或方向错的(藏了不确定性、范围不清、没验收);重要的是影响可读性的(堆背景);锦上添花的是措辞结构。先改致命的——一份 spec 修好最致命的 1-2 条,价值远大于把 10 条小毛病都列出来。一次列太多,用户接不住、反而无从下手。
审查用具体定位而非泛泛批评:指出"第 X 段是背景科普,应压成一句决策依据",而不是"写得不够详细"。
产出形态
最终交给用户的是精简、结构化的内容,不是论证长文:
- 写 spec 时:用骨架的章节结构,决策部分每条带"为什么",背景一两句点到。别把决策推理过程、候选方案的逐个展开(除非是 TBD 权衡需要)全倒进去——读者要结论,不是陪你想一遍。
- 判断时机 / 审查草稿时:产出是"澄清问题清单"或"审查意见(按优先级)",编号列表为主。别在意见里掺大段 skill 原文引用或方法论解释——那是你的工作依据,不是交付物。
- TBD 与选项权衡:用紧凑格式(
TBD:xxx,候选 A(代价)/B(代价),倾向 X,待 Y),别展开成多段。
记住:spec 的读者是评审者和未来的实现者,他们要快速判断"这方案对不对、怎么做",不是欣赏你分析得多彻底。
spec 的结构骨架
按需取用,不必每节都有——以"能讲清决策"为准:
# <标题>
## 元信息 <日期、状态(草稿/评审中/已定)、范围>
## 背景与目标 <问题是什么、为什么做、目标是什么;背景点到够用>
## 研究基础 <决策依据:调研结论、对标、数据;不是科普>
## 范围 <做什么 + 明确不做什么>
## 设计 <核心决策:选了什么、为什么、放弃什么;未决项标 TBD>
## 风险与回滚 <高风险方案必备;低风险可省>
## 验收标准 <怎样算实现成功:可观测、可量化>
## 后续 <下一步动作、依赖、待定项的解决计划>
常见错误
| 问题 | 修法 |
|---|
| 核心决策未知未澄清就硬写 spec | 先判断决策状态,需澄清先问、需调研先做 spike |
| 堆背景知识,决策却一带而过 | 压缩背景到"决策够用",篇幅让给"为什么这么定" |
| 把未决项写成已定方案 | 显式标 TBD + 列选项权衡,别藏不确定性 |
| 范围只有"做什么"没有"不做什么" | 显式列排除项,防范围蔓延 |
| 没有"做完算成功"的标准 | 写可观测、可量化的验收标准 |
| 高风险方案没写风险与回滚 | 迁移/重构/破坏性改动必加风险与回滚维度 |
| 小改动也套完整模板硬撑篇幅 | 按需取节,能讲清决策即可,不为全而全 |
| 信息不足型草稿直接打补丁 | 退回前置流程:列澄清问题 + spike,别在残缺上修 |
| 审查意见一次列十几条不排优先级 | 按"致命/重要/锦上添花"分,先改最致命的 1-2 条 |