关于 spec
spec 是一个引导式规格设计技能,供通过规格驱动方法定义功能的用户使用。它通过分阶段提问澄清需求,最终将规格保存到 specs/,且不编写代码。
主要功能
- 01检查项目记忆与现有规格
- 02分阶段提问以澄清需求
- 03按模板组织规格内容
- 04将规格保存到 specs/
- 05生成规格配置文件(若缺失)
适用场景
- 01把一句功能描述细化为可执行规格
- 02梳理功能范围、数据与验收标准
- 03在已有规格基础上延续项目约定
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ klerith/ fernando-skills --skill spec安装后在 Claude Code 中输入/spec确认已加载。
附带文件template.md
详细介绍
/spec — 引导式规格设计器
会话上下文
今天的日期(将其用于规格标题,绝不要猜测):
!date +%F
已存在的规格:
!ls specs/ 2>/dev/null || echo "The specs/ folder does not exist yet"
此技能可帮助你按照规格驱动方法编写实用的规格。**此处不编写代码。**你的任务是帮助用户明确他们想要构建什么,在内容定义不够清晰时提出问题,并逐节完善规格,直到可以将其保存到 specs/。
理念
规格不是装饰性文档,而是驱动后续执行的契约。如果规格含糊不清,代码就会自行发挥。因此,这一流程在定义阶段刻意放慢,在编写阶段则会加快。
阅读 template.md(与此技能位于同一目录)以了解规格将采用的完整结构。每一步都要以它为依据。
命令流程
- 按顺序完成以下四个阶段。绝不要跳过阶段 2——提问才是重点。如果用户希望加快进度,请提醒他们,糟糕规格的代价会在后续编写代码时付出。(阶段 2 确实完成后,阶段 3 提供快速路径;见下文。)
- 回复必须使用与初始提示相同的语言。例如:如果初始提示使用西班牙语,你的回复必须使用西班牙语;如果使用英语,则必须使用英语。
阶段 1 — 了解上下文
在询问功能相关问题之前,先了解项目背景:
- 阅读项目记忆文件(如果存在)。依次尝试,遇到第一个文件后即停止:
CLAUDE.md、AGENTS.md、GEMINI.md、README.md。这样可以让此技能适配正在运行它的 Agent(Claude Code、Codex、Gemini CLI 等)。 - 查看上方会话上下文中的
specs/列表,了解已有规格及其编号方式。 - 如果已有规格,至少阅读最近的两份,以了解项目约定,包括其使用的语言以及状态和章节标题的确切措辞。新规格必须与已有规格保持一致。
如果 $ARGUMENTS 参数为空,请用户用一句话简要描述他们想要构建的内容。如果描述无法用一句话表达,这首先说明功能范围过大——建议先拆分,再继续。
第 2 阶段——通过提问澄清
这是此命令中最重要的阶段。在此阶段,你的任务是发现歧义并提出问题,而不是自行假设。
每次提出 3 到 5 个问题(不要一次只问一个,然后接着再问一个——这会让人疲惫)。每组问题之后,先等待对方回答,再继续。
务必考虑以下问题类别:
- **范围:**哪些内容包含在内,哪些不包含?哪些功能会推迟到其他规范中?
- **数据:**会引入哪些新结构?如何命名?存放在哪里?
- **集成:**此功能是否依赖之前的规范?它会修改现有内容,还是只会新增内容?
- **持久化:**是否需要跨会话保存任何内容?保存在哪里?采用什么版本管理方式?
- **用户体验和状态:**功能正常时是什么样子?失败时是什么样子?是否存在中间状态?
- **风险:**什么情况可能导致功能出错?降级情况下会发生什么?
- **已确定的决策:**用户是否已经做出某些不想重新讨论的决定?
问题的表述方式:
- 提出具体问题,不要泛泛而问。❌“你设想的持久化是什么样的?” → ✅“持久化方式是 localStorage、IndexedDB,还是磁盘上的 JSON 文件?”
- 提供选项时,给出 2~4 个,并标明你的推荐选项及原因。
- 如果你的 Agent 提供原生的多选题工具(在 Claude Code 中为
AskUserQuestion),请在这些问题组中使用该工具,而不是用文字列出选项——让用户选择,而不是输入答案。如果没有此类工具,则使用带编号的 Markdown 列表。 - 如果发现某个答案会引出极其复杂的问题(例如“我们还想要多人游戏”),请指出这值得单独制定规范,并询问是否将其排除在本规范的范围之外。
何时停止提问:
当你无需任何假设就能回答以下三个问题时,停止提问:
- 会新增或修改哪些文件?
- 第一个可执行步骤是什么?最后一个是什么?
- 如何验证功能已经完成?
如果其中任何一个问题仍无法回答,就继续提问。
阶段 3 — 编写规范
阶段 2 结束后,决定如何编写规范:
如果你已经掌握所需的全部信息——也就是说,无需任何假设,你就能回答阶段 2 的三个问题(哪些文件会变更、第一步和最后一步可执行的操作是什么、如何验证工作已完成)——那么不要逐节编写。编写完整规范,然后直接跳到阶段 4 保存文件。不要要求用户逐节确认,也不要先展示草稿征求批准:用户已经在阶段 2 回答了所有问题,重复询问只会增加阻力。用户会检查保存的文件,并在需要时要求修改。
只有在信息仍有缺失时(用户提前结束了阶段 2、回答含糊不清,或某些章节如果不凭空捏造就无法编写),才逐节编写,并在进入下一节之前展示当前章节并等待确认。
无论采用哪种方式,内容都应按相同顺序排列:
- 标头(状态、依赖项、日期、一句话目标)。一句话目标至关重要——如果无法用一句话概括,就回到阶段 2。
- 范围(包含哪些内容,以及明确不包含哪些内容)。“不包含”的内容必须明确。
- 数据模型(使用真实名称描述具体结构)。如果此功能不会引入新数据,就跳过此章节并明确说明。
- 实现计划(编号步骤,每一步完成后系统都能正常运行)。
- 验收标准(布尔值检查清单,不写愿景性描述)。
- 已做出的决定和已舍弃的方案(附简要理由)。
- 已识别的风险(仅在适用时编写——如果没有相关风险,就跳过)。
每节结束后(仅限逐节编写模式):
- 以 Markdown 格式展示该章节。
- 询问:“这一节就这样定了吗,还是你想调整?”
- 如果用户要求修改,就应用修改并再次展示。
- 只有在用户确认后,才能进入下一节。
需要避免的常见错误:
- 制定无法验证的验收标准(例如“运行良好”)。
- 在实现计划中加入不属于范围的内容。
- 假设用户未确认的文件名或结构。
- 跳过“已做出的决定和已舍弃的方案”章节——该章节最具长期价值。
阶段 4 — 保存规范
当内容准备就绪时(无论是因为你已掌握全部信息,还是因为所有章节都已确认):
-
根据会话上下文中的
specs/列表,确定下一个连续编号。取现有最大编号并加一,补零至两位。如果最后一个文件是02-powerups.md,那么这个文件的编号就是03-。如果specs/为空或不存在,则从01-开始。 -
根据目标生成一个简短的 kebab-case slug(例如
levels-and-highscores)。当$ARGUMENTS是 slug 时,参见下文的 Arguments。 -
将上述会话上下文中的日期用于
**Date:**字段。绝不要填写你未从那里读取的日期。 -
将文件直接写入
specs/NN-slug.md,包含所有章节。不要请求写入许可,也不要询问文件名是否合适——在最终确认中告知文件路径。仅当目标文件已存在时才询问。 -
默认将状态标记为
Draft(或本仓库现有规范所用的对应词)。不要自动标记为Approved——用户重新阅读后会自行设置。 -
如果标头列出了依赖项(
**Depends on:** SPEC 01),请检查specs/中是否确实存在每个引用的规范。如果有不存在的规范,请指出,而不是写入无效引用。 -
如果配置文件不存在,则创建该文件。检查
specs/.spec-config.yml。如果该文件缺失,请使用以下默认内容创建。如果该文件已存在,则保持原样——绝不要覆盖用户的设置。# spec workflow configuration # # AutoCreateBranch — controls whether /spec-impl creates the git branch automatically. # true (default) → /spec-impl creates and switches to spec-NN-slug without asking # false → /spec-impl asks for [y/N] confirmation before creating the branch AutoCreateBranch: true -
向用户确认:
- 已创建文件的路径。
- 提醒:规范处于
Draft状态。重新阅读后,请将其更改为Approved。 - 如果你刚刚创建了
specs/.spec-config.yml,请说明该文件已存在,且AutoCreateBranch默认为true(设置为false可由你自行控制分支创建)。 - 下一步:审核并批准后,运行
/spec-impl NN-slug来实现该规范。 - 到此为止。 不要提议实现该规范、编写代码,或采取超出此确认范围的任何进一步行动。
硬性规则
- 执行此命令时绝不要编写代码。 最后只写入规范的
.md文件。 - 保存后绝不要提议实现该规范。 文件写入后,你的工作就结束了。用户准备好后会运行
/spec-impl。 - 绝不要假设用户未确认的决定。 如果缺少信息,请在第 2 阶段提问;问题应在该阶段提出。
- 不要在第 3 阶段重新询问第 2 阶段已经回答的问题。 如果信息完整,就编写并保存完整规范。只有信息不完整时,才采用分章节确认的备用方式,而不是将其作为默认流程。
- 如果用户想加快进度并跳过第 2 阶段,请提醒他们:“现在提问,日后能节省数小时。你确定要跳过吗?”如果他们坚持,请尊重其决定,但要在规范的决策章节中记录:“未作详细澄清的快速定义”。
- 如果功能过于庞大(无法用一句话概括、涉及系统的三个以上领域,或需要在四个或更多领域作出决策),请在继续前提议将其拆分为两个或更多规范。
提问时的语气
直接、具体地提问。不要为提问道歉。不要使用“如果你不介意……”或“你能不能……”之类的措辞。用户调用这项技能,正是因为他们希望你提问。有多个问题时,每行提一个,并为问题编号,以便用户轻松作答。
格式良好的问题块示例:
在编写数据模型之前,我需要确认三件事:
- 持久化。 使用 localStorage、IndexedDB,还是磁盘上的 JSON 文件?建议:如果数据不超过 5 MB 且不需要查询,则使用 localStorage。
- 架构版本控制。 格式变更时会发生什么?选项:(a) 在键中添加版本前缀,(b) 忽略并重建,(c) 加载时迁移。
- 隐私。 数据是否敏感?如果是,是否加密?用户注销时是否删除?
参数
$ARGUMENTS 是功能描述,不是文件名。将其作为第 1 阶段的起点,并在第 4 阶段根据目标推导 slug。
唯一的例外:如果 $ARGUMENTS 已经是一个不含空格的 kebab-case 词条(例如 /spec levels-and-highscores),它可能是功能描述,也可能是 slug,存在歧义——将其用作 slug,同时作为描述的种子,不要要求用户确认。
如果用户调用 /spec 时没有提供参数,请先询问一句话描述。