Spec Kit Workflows 深度解析:用 specify workflow CLI 编排、扩展与恢复多步 SDD 流程
Workflows 是 Spec Kit(spec-kit)中把多步规格驱动开发(Spec-Driven Development, SDD)过程自动化的引擎:它将命令调用、提示词、Shell 步骤与人工检查点(gate)串联成可重复执行的序列,并原生支持条件分支、循环、fan-out/fan-in,以及从任意中断点精确恢复。读完本文,你将掌握 specify workflow 全部子命令的用法、workflow YAML 的完整定义规范、overlay 覆盖机制的优先级模型,以及表达式插值背后的 Shell 安全边界,并能基于内置 speckit 全流程工作流为自己的项目定制自动化流水线。
1. Workflows 解决什么问题
在手动模式下,一次完整的 SDD 循环需要依次执行 speckit.specify → speckit.plan → speckit.tasks → speckit.implement,并在每个阶段之间人工审阅产物。Workflow 引擎把这些步骤固化成一份 YAML 定义,由引擎按序调度:
- 链式编排:命令、prompt、shell 步骤按
steps列表顺序执行; - 控制流:
if、switch、while、do-while、fan-out/fan-in提供分支、循环与并行展开; - 人工检查点:
gate步骤让流程暂停等待人工审批; - 断点续跑:每次运行(run)的状态被持久化,
specify workflow resume可从暂停或失败的那一步精确恢复。
引擎实现位于 engine.py,模块 docstring 明确了它的五个职责:解析 workflow YAML、校验步骤配置与依赖、按类型分发执行步骤、管理支持恢复的状态持久化、处理分支/循环/fan-out 等控制流。CLI 层实现集中在 _commands.py。
2. 运行工作流:specify workflow run
specify workflow run <source>
<source> 可以是 catalog ID、URL 或本地文件路径 三种来源之一。
| Option | Description |
|---|---|
-i / --input |
Pass input values as key=value (repeatable) |
--json |
Emit the run outcome as a single JSON object |
workflow 声明的输入(inputs)可以通过 --input 显式传入;未传入的输入会在交互终端上逐个提示。官方内置工作流的典型调用:
specify workflow run speckit -i spec="Build a kanban board with drag-and-drop task management" -i scope=full
2.1 --json 输出契约
加上 --json 后,终端不再打印格式化文本,而是输出唯一一个机器可读的 JSON 对象;不带该标志时默认输出保持不变:
specify workflow run my-pipeline.yml --json
{
"run_id": "662bf791",
"workflow_id": "build-and-review",
"status": "paused",
"current_step_id": "review",
"current_step_index": 0
}
输出有三个精确的契约细节(原文档明确定义,写 CI 脚本时应依赖它们):
workflow_id取自 YAML 内部的workflow.id,而不是文件名——判断工作流身份时不要拿路径做假设;- JSON 恒为两空格缩进的 pretty-print,走纯 stdout 且不含 Rich 标记,因此永远可以解析;
- 运行期间所有步骤进度输出(gate 提示、prompt 步骤的 CLI 子进程输出等)全部重定向到 stderr,stdout 只承载这一个 JSON 对象。读取时从 stdout 取对象,stderr 可保持挂在终端上或单独捕获。
从源码可以印证 run_id 的形态:engine.py 中 RunState 在未显式提供 ID 时执行 self.run_id = str(uuid.uuid4())[:8],即取 UUID 的前 8 位十六进制——这就是示例中 662bf791 的由来。
2.2 failed / aborted 时的 error 字段
失败或被中止的运行会在 payload 中多出一个 error 字段,承载终止步骤的错误消息:
{
"run_id": "662bf791",
"workflow_id": "build-and-review",
"status": "failed",
"current_step_id": "boom",
"current_step_index": 0,
"error": "Command exited with code 3"
}
completed 与 paused 状态的运行省略 error 字段。同时该错误消息会持久化进运行状态的 state.json,事后可以用 specify workflow status <run_id> --json 取回同一条消息,无需保留进程内的输出。
2.3 项目上下文要求
注意:绝大多数 workflow 命令要求项目已经通过
specify init初始化。唯一的例外是specify workflow run <local-file.{yml,yaml}>——直接以本地 YAML 文件为来源时可以在项目之外运行,此时运行状态会存放在当前目录下的.specify/workflows/runs/<run_id>/。
3. 状态模型:.specify/workflows/runs/<run_id>/
每次 workflow 运行都会把完整状态落盘到 .specify/workflows/runs/<run_id>/,包含三个文件:
state.json— 当前运行状态与步骤进度(含run_id、workflow_id、status、current_step_index、current_step_id、step_results、error等字段);inputs.json— 解析后的输入值;log.jsonl— 逐步执行日志(append 写)。
这一持久化机制正是 specify workflow resume 能够从暂停点(例如 gate)或失败点继续执行的前提。源码层面还有几个值得了解的设计(见 engine.py 的 RunState 类):
- 原子写:
save()在锁内通过临时文件 +os.replace写入,并发的 fan-out 线程既不会在序列化中途改写step_results,也不会让读者看到半写文件; - run_id 严格校验:
_RUN_ID_PATTERN限制run_id只能由字母数字加连字符/下划线组成且不能以-开头,因为它会被直接拼接进文件路径——这是防止恶意 ID 逃逸出runs/目录的防护; - 双锁隔离:状态保存用
_lock,日志追加用独立的_log_lock,高频日志不会与状态序列化互相争用。
4. 恢复与查询:resume / status / list
4.1 恢复运行
specify workflow resume <run_id>
| Option | Description |
|---|---|
-i / --input |
Updated input values as key=value (repeatable) |
--json |
Emit the resume outcome as a single JSON object |
恢复的语义是"从停下的那一步精确继续",适用于两类场景:响应了一个 gate 之后继续、或修复了导致失败的缺陷后继续。
--input 传入的值会覆盖合并到该运行已存储的输入上,并重新按 workflow 声明的输入类型校验,然后带着更新后的值重跑被阻塞的步骤。这让运行可以使用"暂停之后才出现的信息",或在失败后换用纠正过的值:
specify workflow resume <run_id> --input cmd="exit 0"
4.2 查询状态与运行列表
specify workflow status [<run_id>]
| Option | Description |
|---|---|
--json |
Emit run status (or the runs list) as a JSON object |
带参数显示指定 run 的状态,不带参数则列出全部运行。运行状态共 6 种:created、running、completed、paused、failed、aborted。
4.3 列出已安装工作流
specify workflow list
列出当前项目中已安装的 workflow。被禁用的工作流仍会保留在列表中并标记为 [disabled]。
5. 安装、更新与生命周期管理
5.1 安装:specify workflow add
specify workflow add <source>
| Option | Description |
|---|---|
--dev |
Install from a local YAML file, package directory, or archive |
--from <url> |
Install from a custom URL (<source> names the expected workflow ID) |
安装来源覆盖 catalog、HTTPS URL、本地 YAML 文件、包含 workflow.yml 的目录,以及 .zip / .tar.gz / .tgz 归档;归档中 workflow.yml 可以位于根目录,也可以位于唯一的顶层目录内。目录与归档安装会保留完整的工作流包(含脚本等伴生文件),三种归档格式遵循相同的校验与安装行为。
specify workflow add <local-directory> 会把完整本地 workflow 包安装到 .specify/workflows/<id>/;归档安装保留同样的包内容。
5.2 更新:specify workflow update
specify workflow update [workflow_id]
更新单个已安装的 catalog 工作流;不带 ID 时更新全部。更新会先提示确认,若下载或校验失败则保留已安装的旧副本,避免把项目里的可运行版本换坏。
5.3 启用 / 禁用 / 删除
specify workflow enable <workflow_id>
specify workflow disable <workflow_id>
被禁用的工作流保持已安装、已列出的状态(标记 [disabled]),但拒绝运行,直到重新启用。
specify workflow remove <workflow_id>
从项目中移除一个已安装的 workflow。
5.4 搜索与详情
specify workflow search [query]
| Option | Description |
|---|---|
--tag |
Filter by tag |
--author |
Filter by author |
在所有激活的 catalog 中搜索匹配 query 的 workflow。
specify workflow info <workflow_id>
展示某个 workflow 的详细信息,包括其步骤、输入与要求(requirements)。
6. Catalog 管理:search 和 add 从哪里找
Workflow catalog 决定了 search 与 add 的检索范围,按优先级顺序检查。catalog.py 的解析实现与文档描述的顺序完全一致:
6.1 列出 / 添加 / 移除 catalog
specify workflow catalog list
显示所有激活的 catalog 来源。
specify workflow catalog add <url>
| Option | Description |
|---|---|
--name <name> |
Optional name for the catalog |
把自定义 catalog URL 追加到项目的 .specify/workflow-catalogs.yml。
specify workflow catalog remove <index>
按 catalog 列表中的索引移除一个 catalog。
6.2 解析顺序(first match wins)
- 环境变量 —
SPECKIT_WORKFLOW_CATALOG_URL覆盖所有 catalog; - 项目配置 —
.specify/workflow-catalogs.yml; - 用户配置 —
~/.specify/workflow-catalogs.yml; - 内置默认 — 官方 catalog + 社区 catalog(仓库中随附 workflows/catalog.json 与 workflows/catalog.community.json)。
7. Workflow 定义:内置 Full SDD Cycle 全解
Workflow 用 YAML 定义。下面是文档给出的、随 Spec Kit 内置的 Full SDD Cycle 工作流示例:
schema_version: "1.0"
workflow:
id: "speckit"
name: "Full SDD Cycle"
version: "1.0.0"
author: "GitHub"
description: "Runs specify → plan → tasks → implement with review gates"
requires:
speckit_version: ">=0.7.2"
integrations:
any: ["copilot", "claude", "gemini"]
inputs:
spec:
type: string
required: true
prompt: "Describe what you want to build"
integration:
type: string
default: "copilot"
prompt: "Integration to use (e.g. claude, copilot, gemini)"
scope:
type: string
default: "full"
enum: ["full", "backend-only", "frontend-only"]
steps:
- id: specify
command: speckit.specify
integration: "{{ inputs.integration }}"
input:
args: "{{ inputs.spec }}"
- id: review-spec
type: gate
message: "Review the generated spec before planning."
options: [approve, reject]
on_reject: abort
- id: plan
command: speckit.plan
integration: "{{ inputs.integration }}"
input:
args: "{{ inputs.spec }}"
- id: review-plan
type: gate
message: "Review the plan before generating tasks."
options: [approve, reject]
on_reject: abort
- id: tasks
command: speckit.tasks
integration: "{{ inputs.integration }}"
input:
args: "{{ inputs.spec }}"
- id: implement
command: speckit.implement
integration: "{{ inputs.integration }}"
input:
args: "{{ inputs.spec }}"
该定义的字段要点:
schema_version目前只接受"1.0",engine.py 的validate_workflow会对其他版本报错;workflow.id/name/version/author/description:元信息,id是后续所有命令(run、overlay、resolve)引用的身份标识;requires:咨询性的前置条件(spec-kit 版本、集成)。注意它不是运行时闸门,只被校验识别键,不限制步骤能力(见第 8 节安全说明);inputs:type(string/number/boolean)、required、default、prompt、enum五个可选约束;steps:有序步骤列表,command类型的步骤默认type: command。
仓库中实际维护的版本见 workflows/speckit/workflow.yml,与上面的文档示例有两处可留意的演进:speckit_version 要求为 >=0.8.5(源码注释说明 0.8.5 是首个支持引擎端解析 integration: "auto" 默认值的版本,旧版本会把 "auto" 当作字面集成键而在分发时失败);integration 输入默认值改为 "auto",且 integrations.any 列表扩展为 alquimia、claude、copilot、gemini、opencode——注释同时强调这是一个非封闭的建议性列表,任何提供四个核心命令的集成都可以运行该工作流。
上述步骤序列产生的执行流程为:
specify (command)
→ review-spec (gate) --approve--> plan (command)
--reject--> Abort
plan → review-plan (gate) --approve--> tasks (command)
--reject--> Abort
tasks → implement (command)
运行命令:
specify workflow run speckit -i spec="Build a kanban board with drag-and-drop task management"
8. 步骤类型与安全边界
| Type | Purpose |
|---|---|
command |
Invoke a Spec Kit command (e.g., speckit.plan) |
prompt |
Send an arbitrary prompt to the AI coding agent |
shell |
Execute a shell command and capture output |
init |
Bootstrap a project (like specify init) |
gate |
Pause for human approval before continuing |
if |
Conditional branching (then/else) |
switch |
Multi-branch dispatch on an expression |
while |
Loop while a condition is true |
do-while |
Execute at least once, then loop on condition |
fan-out |
Dispatch a step for each item in a list |
fan-in |
Aggregate results from a fan-out step |
各步骤类型的执行器分别位于 steps/ 目录下(command/、gate/、shell/、init/、prompt/、if_then/、switch/、while_loop/、do_while/、fan_out/、fan_in/),由引擎按类型注册表分发。
安全须知(务必阅读):
shell步骤以你本人的权限运行本地命令,不存在任何能力沙箱——requires只是咨询性的前置条件块(spec-kit 版本、集成),不是运行时闸门,它无法限制步骤能做什么。尤其不存在requires.permissions能力闸门:校验器会刻意拒绝这个键,因为它暗示了一个并不存在的沙箱(engine.py 中_RECOGNIZED_REQUIRES_KEYS只承认speckit_version与integrations两个键,其余键一律报校验错误)。因此:运行任何来自 catalog 或下载来的 workflow 之前先审查其源码,并用gate步骤在敏感或破坏性 shell 命令之前强制显式批准。
9. 表达式语言、Shell 安全与输入类型
9.1 表达式命名空间
步骤通过 {{ expression }} 语法引用输入与前置步骤输出:
| Namespace | Description |
|---|---|
inputs.spec |
Workflow input values |
steps.specify.output.file |
Output from a previous step |
item |
Current item in a fan-out iteration |
context.run_id |
Current workflow run ID |
context.workflow_dir |
Resolved absolute path to the workflow source directory. Empty string for string-loaded workflows. |
可用过滤器:default、join、contains、map、from_json(实现见 expressions.py)。
condition: "{{ steps.test.output.exit_code == 0 }}"
args: "{{ inputs.spec }}"
message: "{{ status | default('pending') }}"
9.2 插值与 Shell 安全(关键)
表达式采用纯字符串替换:{{ ... }} 的值原样拼进周围文本,不做任何引用或转义。这对拼 args、message 很方便,但对 shell 步骤有重要后果:run 字段会交给系统 shell(POSIX 上是 /bin/sh -c),因此任何被插值的内容都会被当作 shell 语法解释,而不只是数据。
如果插值值可能包含 ;、|、&、$( )、反引号或引号,就可能改变或扩展实际执行的命令。风险主要来自两类不受 workflow 作者完全控制的值:
inputs.*— 由运行 workflow 的人提供;- 前置步骤的输出(如
{{ steps.plan.output.stdout }})— 若来自prompt步骤,那是 AI 智能体生成的文本,而智能体又被其读取的文件、工单、网页内容影响。当智能体输出流入shell步骤时,应视为不可信。
表达式语言中没有 shell 转义过滤器,shell 步骤没有沙箱,因此下列实践都不能保证"中和"恶意值。唯一可靠的手段是约束插值值能是什么,并把无法约束的值彻底排除在 run 字段之外。逐一审查每个插值了不可控值的 run 字段,至少做到:
-
在源头用
enum/白名单约束值。 当inputs.*流入run字段时,把它限制在固定的安全值集合内,使调用方根本无法注入任意 shell 文本——这是引擎能提供的最强控制,优先于任何下游缓解:inputs: target: type: string enum: [staging, production] # caller cannot inject arbitrary text -
把无法约束的值排除在
run之外。 无法白名单化的值(尤其是智能体/prompt输出)不要插值进run;用if/switch对它做固定条件分支,或在command/prompt步骤中处理它,而不是用它拼 shell 命令。 -
引号不是安全边界。 给替换加引号(
'{{ inputs.x }}')可以让 shell 把可信值当作单个参数、避免空格分词,但值本身若含有配对的引号字符仍能"逃逸"并注入 shell 语法。对受约束值加引号以保证正确性;永远不要指望引号让不受约束的替换变安全。 -
gate 不检查下一步,且
message原样打印。gate只渲染自己的message/show_file——它不显示、不解析、不清理其后的命令,批准也不能中和可注入的插值。不要把不可信的原始数据插值进message:它按原样输出、不做控制字符剥离,智能体或调用方输出可能注入终端/ANSI 转义来篡改或隐藏审批提示。message只放可信的、受约束的文本;需要展示不可信材料时改用show_file——其路径与内容在展示前会做控制/ANSI 剥离。
shell 步骤按设计就是任意命令原语;上述做法只能降低暴露面、保证执行哪个命令仍由作者掌控,无法消除插值不可控值的风险。
9.3 Shell 步骤环境变量
Shell 步骤自动获得以下环境变量(设置逻辑见 steps/shell):
| Variable | Description |
|---|---|
SPECKIT_WORKFLOW_DIR |
Resolved absolute path to the workflow source directory (same value as {{ context.workflow_dir }}). Not set when the workflow has no source path. |
9.4 输入类型与强制转换
| Type | Coercion |
|---|---|
string |
Pass-through |
number |
"42" → 42, "3.14" → 3.14 |
boolean |
"true" / "1" / "yes" → True |
10. 状态与恢复:Gate 裁决输入(verdict_input)
verdict_input 把一个 gate 的裁决绑定到一个具名 workflow 输入。该输入必须在 workflow 的 inputs 块中声明;未声明的引用会被 specify workflow validate 报告。
verdict_input 在 fan-out 模板内不受支持——fan-out 的各条目共享 workflow 输入,而运行状态只能表示一个处于暂停中的 gate。需要审批整个批次时把 gate 放在 fan-out 之前,需要审阅聚合结果时放在 fan-in 之后。
输入值语义:
| Value | Behavior |
|---|---|
| 非空字符串,匹配某个 option(大小写不敏感) | Gate 自动裁决;output.choice 被设为所配置 option 的原始拼写 |
| 非空字符串,无匹配 | Gate 立即失败 |
| 非字符串 | Gate 立即失败 |
| 缺失或空串 | TTY 下 Gate 提示输入;否则暂停 |
默认值语义:非空的 default 会在首次运行时即被当作裁决消费——匹配 option 则 gate 自动裁决,不匹配则立即失败。
示例定义:
inputs:
spec_verdict:
type: string
default: ""
steps:
- id: review-spec
type: gate
message: "Approve the specification?"
options: [approve, reject]
on_reject: retry
verdict_input: spec_verdict
恢复时提供裁决:
specify workflow resume <run_id> --input spec_verdict=approve
对于 on_reject: retry,绑定的 reject 裁决会在 gate 暂停之前被消费:对应的存储输入被重置为 "",此后的再次恢复会重新提示或暂停,直到提供另一个裁决。approve、abort、skip 三种结果则不改变输入。
正因这个重置机制,配合 on_reject: retry 使用的 verdict 输入必须接受 ""。如果它声明了 enum,必须包含空字符串——否则重置值会违反输入自身的 enum,导致运行再也无法用任何输入恢复。specify workflow add 会将其报为校验错误:
inputs:
spec_verdict:
type: string
enum: ["", approve, reject]
default: ""
11. Workflow Overlays:不改装、可叠加的本地定制
Overlay 让项目在不编辑已安装 workflow.yml 的前提下扩展或覆盖一个已安装 workflow,从而在 specify bundle update 或 specify workflow add 升级后本地定制依然安全。
当 specify workflow run <workflow-id> 加载 workflow 时,引擎会把基础 workflow 与该 workflow id 的所有已启用 overlay 组合(compose),组合结果与其他 workflow 定义一样接受校验。组合逻辑实现在 overlays/ 包中(composer.py、merge.py、schema.py)。
11.1 优先级模型:lower-wins
Overlay 是声明一组针对基础 workflow 步骤列表的编辑操作的 YAML 文件。优先级规则是 lower-wins:优先级数值高的先应用、数值低的后应用(最后应用者胜出)。从 merge.py 的注释可以看到实现语义:edits 按合并顺序排列(最低优先级在前、最高优先级在后),每个 anchor 的胜出编辑是 edits[-1]——即数值最低(最高优先级)的 overlay 最后落笔,决定 anchor 的最终命运;低优先级的 remove 无法阻止高优先级的覆盖。同等优先级的 overlay 按 ID 字母序应用,最后一个 ID 在冲突中胜出。
项目 overlay 文件位于:
| Location | Purpose |
|---|---|
.specify/workflows/overlays/<id>/*.yml |
Project-local customizations |
11.2 Overlay 文件格式
推荐格式以操作名为键、以锚点步骤 id 为值:
id: "my-overlay"
extends: "speckit"
priority: 10
enabled: true
edits:
- insert_after: implement
step:
id: run-lint
type: shell
run: "ruff check src/"
- replace: review-spec
step:
id: review-spec
type: gate
message: "Review the generated spec (overlay override)."
options: [approve, reject]
on_reject: abort
显式格式同样受支持:
edits:
- operation: insert_after
anchor: implement
step:
id: run-lint
type: shell
run: "ruff check src/"
字段说明:
| Field | Required | Description |
|---|---|---|
id |
yes | Overlay 标识符,用于 specify workflow overlay * 命令。只允许小写字母、数字、连字符;不能有句点、下划线、路径分隔符,也不能用 overlays。 |
extends |
yes | 该 overlay 所作用的 workflow id。与 id 相同的安全格式;overlays、runs、steps 为保留字。 |
priority |
no | 整数;默认 10。数值越低优先级越高、冲突中胜出。缺失或非法值回退到 10。 |
enabled |
no | 布尔;默认 true。禁用的 overlay 被忽略。 |
edits |
yes | 非空的编辑操作列表。 |
编辑操作:
| Operation | step required |
Effect |
|---|---|---|
insert_after |
yes | 在锚点步骤后立即插入 step。 |
insert_before |
yes | 在锚点步骤前立即插入 step。 |
replace |
yes | 用 step 替换锚点步骤。 |
remove |
no | 从列表中移除锚点步骤。 |
anchor 是基础 workflow 中某个步骤的 id。Anchor 会在 then、else、steps、cases.* 与 default 块内递归解析,因此可以定位嵌套的基础步骤;但 fan-out 模板(fan-out 步骤内部的 step)不能作为 anchor。步骤 id 不能包含 :——该字符保留给引擎生成的嵌套 id 使用。
11.3 Overlay CLI 命令
添加项目 overlay:
specify workflow overlay add <path-to-overlay.yml> --priority <n>
校验 overlay 文件并复制到 .specify/workflows/overlays/<extends>/<id>.yml。--priority 默认 10,并覆盖文件中的 priority 字段。
列出 overlay:
specify workflow overlay list <workflow-id>
按 resolver 优先级顺序显示该 workflow 的全部 overlay;禁用的 overlay 会在列表中明确标出,并在 workflow 解析时被忽略。
修改优先级:
specify workflow overlay set-priority <workflow-id> <overlay-id> <n>
启用 / 禁用:
specify workflow overlay disable <workflow-id> <overlay-id>
specify workflow overlay enable <workflow-id> <overlay-id>
移除:
specify workflow overlay remove <workflow-id> <overlay-id>
删除该 overlay 的项目文件。
查看组合结果:
specify workflow resolve <workflow-id>
打印层栈(base + overlays)以及组合后每个步骤的来源归属。排查"某个步骤到底被哪个 overlay 贡献或覆盖"时非常有用。
11.4 实战示例
示例一:在实现之后自动跑 Lint。 针对内置 speckit workflow,创建 project-overlay.yml:
id: "add-lint"
extends: "speckit"
priority: 10
edits:
- insert_after: implement
step:
id: run-lint
type: shell
run: "ruff check src/"
安装并运行:
specify workflow overlay add project-overlay.yml --priority 10
specify workflow run speckit -i spec="Build a kanban board"
组合后的 workflow 将跑完整个 SDD 周期,并在 implement 步骤之后自动执行 ruff check src/。
示例二:替换一个人工 gate。
id: "skip-plan-review"
extends: "speckit"
priority: 5
edits:
- replace: review-plan
step:
id: review-plan
type: command
command: speckit.plan
input:
args: "{{ inputs.spec }}"
数值越低优先级越高。若需要与上面的 add-lint overlay 冲突中胜出,就把它设为 priority: 5。该示例把 review-plan 的 gate 替换为一个非交互的 command 步骤。
11.5 与 Bundles、升级的交互
specify workflow add <local-directory> 把完整本地 workflow 包安装进 .specify/workflows/<id>/;归档安装保留相同的包内容。当已安装的 workflow 被刷新或重装时,.specify/workflows/overlays/<id>/ 中的项目 overlay 得以保留,因为它们位于已安装 workflow 目录之外。
11.6 Overlays 的限制
- Overlay 只作用于步骤列表:不能改 workflow 元数据(name、description、inputs、
requires)或表达式逻辑; - Fan-out 模板不能作为 anchor;
- 指向基础 workflow 中不存在的步骤 id 的 overlay,会在 workflow 被解析时触发校验错误;
- Overlay 不能定位由其他 overlay 添加的步骤;
- Overlay 不能新增输入,也不能修改基础 workflow 的输入 schema。
12. FAQ
工作流遇到 gate 步骤时会发生什么?
运行暂停并等待人工输入。审阅之后执行 specify workflow resume <run_id> 继续。
同一个 workflow 可以运行多次吗?
可以。每次运行获得唯一 ID 和独立的状态目录。用 specify workflow status 查看全部运行。
谁在维护 workflows? 大多数 workflow 由其各自作者独立创建与维护。Spec Kit 维护者不审阅、不审计、不背书、不支持 workflow 代码。请自行审查 workflow 源码后再安装,使用风险自负。
13. 相关文档
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00