这篇笔记的目标是把 OpenSpec 的核心模型、默认工作流和命令体系串起来,说明它为什么能把“和编码助手对齐需求”从聊天记录提升为可追踪、可审查、可归档的规范产物。
重点放在 Delta Spec、四类工件、默认 quick path、扩展工作流,以及单仓到跨仓协作的使用边界;具体源码实现、各编辑器插件的安装细节和 stores 的底层文件格式不在这里展开。
参考资料:
官方文档:OpenSpec Documentation Home 、 Commands Reference 、 CLI Reference 、 Multi-Language
扩展阅读:Stores User Guide 、 OpenSpec 中文文档
[TOC]
一、概述
OpenSpec 是由 Fission AI 开源的 AI-Native 规范驱动开发系统(Spec-Driven Development, SDD)。它不是替代编码助手,而是在编码助手前面增加一层规范与计划机制,让“要做什么、为什么这样做、做到什么算完成”先固化为结构化产物,再进入实现阶段。
可以概括为一句话:把需求对齐、方案收敛和实现任务,从一次性聊天上下文,转成仓库内可以长期演化的规范资产。
设计哲学:
- 流动而非僵化:任意产物都可以回改,不要求机械地卡死在某个阶段
- 迭代而非瀑布:允许边讨论边收敛,也允许在实现前后反复修正
- 简单而非复杂:核心载体仍然是 Markdown + Git,而不是额外的专用平台
- 存量项目优先:通过 Delta Spec 处理增量变化,天然适合 brownfield 项目
- 从个人项目扩展到协作场景:单仓可用,跨仓与共享规范场景也能逐步接入
基本信息:
- 许可证:MIT
- 运行环境:Node.js 20.19.0+
- 支持多种主流 AI 编码工具与终端工作流
- 主要语言:TypeScript
二、为什么选择 OpenSpec?
AI 编码助手功能很强,但如果需求只存在于临时对话中,实现结果往往容易偏离原意。OpenSpec 的价值不在于“让助手多记一点上下文”,而在于把上下文沉淀为 change、spec、design、tasks 这些可以持续审查和复用的工程资产。
| 痛点 | OpenSpec 解决方案 |
|---|---|
| AI 每次对话重新猜测意图 | Specs 作为 source of truth,AI 读取后可直接获得长期上下文 |
| 需求分散在聊天记录中 | 每个变更有独立目录,产物结构清晰、便于回溯 |
| AI 做了范围外的事 | proposal.md 中明确 in scope / out of scope |
| 多人协作时需求互相覆盖 | Delta Spec 让多个 change 可以并行推进,最终再合并 |
与同类产品对比
| 对比维度 | OpenSpec | Spec Kit (GitHub) | Kiro (AWS) |
|---|---|---|---|
| 理念 | 轻量、流动、偏 Markdown 资产化 | 规范完整、阶段感更强 | IDE 内一体化体验更强 |
| 阶段控制 | 默认较灵活,可随时回改产物 | 更强调阶段推进 | 工具内流程更集中 |
| 存量项目支持 | 原生支持 Delta Spec,适合增量接入 | 更偏完整流程治理 | 更依赖其自身 IDE 工作方式 |
| 工具锁定 | 工具锁定相对较低 | 更靠近 GitHub 生态 | 更靠近 Kiro 自身生态 |
| 格式 | Markdown + Git | Markdown + Python | 内置格式 |
三、安装与初始化
安装
1
2
3
4
5
6
7
8
# 全局安装
npm install -g @fission-ai/openspec@latest
# 进入项目目录
cd your-project
# 初始化
openspec init
当前版本要求 Node.js 20.19.0 及以上。openspec init 完成后,如果后续升级了 CLI、切换了 profile,或者希望刷新不同工具中的指令文件,还需要在项目内执行一次 openspec update。
初始化选项
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 交互式初始化
openspec init
# 指定目录
openspec init ./my-project
# 非交互式:配置 Claude 和 Cursor
openspec init --tools claude,cursor
# 为所有支持的工具配置
openspec init --tools all
# 指定 profile
openspec init --profile core
初始化后的目录结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
openspec/
├── specs/ # 规范源文件(source of truth,描述系统当前行为)
│ └── <domain>/
│ └── spec.md
├── changes/ # 变更提案(一个文件夹对应一个变更)
│ ├── archive/ # 已完成变更的归档目录
│ └── <change-name>/
│ ├── proposal.md
│ ├── design.md
│ ├── tasks.md
│ └── specs/ # Delta specs(描述变化的内容)
│ └── <domain>/
│ └── spec.md
└── config.yaml # 项目配置(可选)
两个核心目录:
specs/:Source of Truth,按领域组织(如specs/auth/、specs/payments/),描述系统当前行为changes/:提案目录,每个变更独立文件夹,完成后其 specs 合并到主specs/目录
四、核心工作流
默认 quick path(core profile)
当前默认 profile 的高频路径可以概括为下面这条链路:
graph LR
A[Explore] --> B[Propose]
B --> C[Update]
C --> D[Apply]
D --> E[Archive]
D -.可选.-> F[Sync]
F --> E
这个流程里有两个容易混淆的点:
explore位于立项之前,用来澄清问题、比较方案、收敛范围;如果目标已经足够清晰,可以直接从propose开始sync用于把某个 change 的 Delta Spec 提前合并回主specs/,适合长周期变更或需要先同步规范再继续实现的情况;很多场景直接archive即可
扩展工作流(expanded workflow)
1
/opsx:new -> /opsx:ff 或 /opsx:continue -> /opsx:apply -> /opsx:verify -> /opsx:archive
扩展工作流适合对工件生成顺序、审查节奏和 schema 控制要求更高的团队。启用方式不是只改配置文件,而是先执行 openspec config profile 选择 workflows,再执行 openspec update 刷新项目指令。
一次完整变更的典型过程
Propose:生成 planning artifacts
1
2
3
4
5
6
7
8
/opsx:propose add-dark-mode
Created openspec/changes/add-dark-mode/
✓ proposal.md — why we're doing this, what's changing
✓ specs/ — requirements and scenarios
✓ design.md — technical approach
✓ tasks.md — implementation checklist
Ready for implementation. Run /opsx:apply.
propose 的作用不是直接写代码,而是一次性生成 proposal、specs、design、tasks 四类工件,让 change 先具备可审查的计划面。
Update:在实现前后修订工件
1
/opsx:update add-dark-mode
当范围、方案或任务拆分发生变化时,update 用来保持 proposal、specs、design、tasks 之间的一致性。它的重点不是追加零散注释,而是让已有工件重新对齐。
Apply:按照 tasks 执行实现
1
2
3
4
5
6
7
8
/opsx:apply
Implementing tasks...
✓ 1.1 Add theme context provider
✓ 1.2 Create toggle component
✓ 2.1 Add CSS variables
✓ 2.2 Wire up localStorage
All tasks complete!
apply 按 tasks.md 的任务粒度推进实现。对于长会话、多文件改动和中断恢复场景,这种“先任务化再执行”的方式,通常比直接在聊天中描述需求更稳定。
Sync / Archive:同步规范并归档 change
1
2
3
4
/opsx:archive
Archived to openspec/changes/archive/2026-03-10-add-dark-mode/
Specs updated. Ready for the next feature.
归档阶段通常做两件事:
- 将 Delta Specs 合并到
openspec/specs/(更新 source of truth) - 将变更文件夹移动到
openspec/changes/archive/<日期>-<change-name>/
五、四大产物(Artifacts)
每个变更文件夹包含四个产物,层层递进:
1
2
3
4
proposal -> specs -> design -> tasks -> implement
▲ ▲ ▲ │
└───────────┴─────────┴───────────────────┘
随时可回溯更新
| 产物 | 回答的问题 | 内容 |
|---|---|---|
proposal.md |
为什么做?范围是什么? | 意图、范围(in/out of scope)、方法概述 |
specs/ |
系统行为变了什么? | Delta Spec,描述新增/修改/删除的需求 |
design.md |
技术上怎么做? | 技术方案、架构决策 |
tasks.md |
具体做什么? | 实现清单,checkbox 形式 |
示例:proposal.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Proposal: Add Dark Mode
## Intent
Users have requested a dark mode option to reduce eye strain
during nighttime usage.
## Scope
- Add theme toggle in settings
- Support system preference detection
- Persist preference in localStorage
## Approach
Use CSS custom properties for theming with a React context
for state management.
示例:tasks.md
1
2
3
4
5
6
7
8
9
10
11
# Tasks
## 1. Theme Infrastructure
- [ ] 1.1 Create ThemeContext with light/dark state
- [ ] 1.2 Add CSS custom properties for colors
- [ ] 1.3 Implement localStorage persistence
## 2. UI Components
- [ ] 2.1 Create ThemeToggle component
- [ ] 2.2 Add toggle to settings page
- [ ] 2.3 Update Header to include quick toggle
这四类工件为什么要拆开
| 工件 | 关注点 | 不应该混入的内容 |
|---|---|---|
proposal.md |
动机、范围、边界 | 过细的实现细节 |
specs/ |
外部可观察行为 | 类名、表结构、私有实现 |
design.md |
技术路径、架构决策 | 逐条施工式任务 |
tasks.md |
执行顺序、落地清单 | 重复描述需求背景 |
工件拆分的价值不只是“多几个文件”,而是把讨论对象从一个混合大文档拆成四个不同层级的决策面:为什么做、行为怎么变、技术上怎么落地、实现时先做什么。
六、Delta Spec(核心概念)
什么是 Delta Spec?
Delta Spec 是 OpenSpec 最重要的概念。简单来说:
Delta Spec = 行为变更的 diff
它不是重写整份规范,而是只描述“相对于当前系统,哪些行为发生了变化”。
类比理解:
- Git 的
diff描述的是代码文件的变化 - Delta Spec 描述的是系统行为/需求的变化
为什么不直接改主 spec?因为在实际开发中,可能同时有多个功能并行开发。如果都直接修改主 spec 文件,就会产生冲突。Delta Spec 让每个变更独立描述自己的改动,互不干扰,最终归档时才合并。
Delta Spec 在产物中的体现
执行 /opsx:propose add-2fa 之后,change 目录通常会生成如下结构:
1
2
3
4
5
6
7
openspec/changes/add-2fa/
├── proposal.md # 为什么做(动机、范围)
├── specs/ # Delta Spec 就在这里
│ └── auth/
│ └── spec.md # 这就是 Delta Spec 文件
├── design.md # 怎么做(技术方案)
└── tasks.md # 做什么(任务清单)
注意 specs/ 文件夹,它不是完整的系统规范,而是只包含本次变更涉及的行为差异。
同时,项目中还有主规范:
1
openspec/specs/auth/spec.md # 主 spec(当前系统的完整行为描述)
关系图:
graph LR
A[主Spec] -->|当前行为| B[系统]
C[Delta Spec] -->|行为差异| B
C -->|sync 或 archive| A
Delta Spec 的格式
使用三个 section 标记变更类型:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Delta for Auth
## ADDED Requirements
### Requirement: Two-Factor Authentication
The system MUST support TOTP-based two-factor authentication.
#### Scenario: 2FA login
- GIVEN a user with 2FA enabled
- WHEN the user submits valid credentials
- THEN an OTP challenge is presented
## MODIFIED Requirements
### Requirement: Session Expiration
The system MUST expire sessions after 15 minutes of inactivity.
(Previously: 30 minutes)
## REMOVED Requirements
### Requirement: Remember Me
(Deprecated in favor of 2FA.)
三种变更类型及归档行为
| Section | 含义 | 归档时的动作 | 例子 |
|---|---|---|---|
ADDED |
新增行为 | 追加到主 spec | 新加 2FA 功能 |
MODIFIED |
修改已有行为 | 替换原有需求 | 会话超时从 30 分钟改为 15 分钟 |
REMOVED |
移除行为 | 从主 spec 中删除 | 废弃“记住我”功能 |
完整生命周期示例
假设主 spec openspec/specs/auth/spec.md 当前内容为:
1
2
3
4
5
6
7
8
9
10
11
12
# Auth Specification
## Requirements
### Requirement: User Authentication
The system SHALL issue a JWT token upon successful login.
### Requirement: Session Expiration
The system MUST expire sessions after 30 minutes of inactivity.
### Requirement: Remember Me
The system MAY offer a "Remember Me" checkbox.
现在要加 2FA、改超时时间、删掉 Remember Me,AI 生成的 Delta Spec 如上面所示。
执行 /opsx:archive 后,主 spec 变为:
1
2
3
4
5
6
7
8
9
10
11
12
# Auth Specification
## Requirements
### Requirement: User Authentication
The system SHALL issue a JWT token upon successful login.
### Requirement: Two-Factor Authentication
The system MUST support TOTP-based two-factor authentication.
### Requirement: Session Expiration
The system MUST expire sessions after 15 minutes of inactivity.
变更文件夹则被移动到 openspec/changes/archive/2026-05-12-add-2fa/,作为历史记录。
为什么用 Delta 而不是重写整个 Spec?
| 场景 | 重写整个 spec | Delta Spec |
|---|---|---|
| 两个变更同时修改 auth spec | 冲突,往往需要手动合并 | 各写各的 delta,不冲突 |
| 变更回滚 | 不知道究竟改了什么 | 看 delta 就知道改了什么,可精确回滚 |
| 审查变更 | 对比前后两个大文件 | 只看 delta 即可 |
| 并行开发 | 锁定文件或频繁冲突 | 天然支持并行 |
容易混淆的边界
| 容易混淆的对象 | 实际含义 |
|---|---|
| Delta Spec 和 Git diff | 前者描述行为变化,后者描述代码变化,两者粒度不同 |
Delta Spec 和 tasks.md |
前者回答“系统行为变了什么”,后者回答“按什么步骤实现” |
sync / archive 和代码发布 |
二者更新的是规范资产与 change 生命周期,不直接等于线上发布 |
七、Spec 格式
Specs 是行为契约,不是实现细节。使用 需求 + 场景 描述:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Auth Specification
## Purpose
Authentication and session management.
## Requirements
### Requirement: User Authentication
The system SHALL issue a JWT token upon successful login.
#### Scenario: Valid credentials
- GIVEN a user with valid credentials
- WHEN the user submits login form
- THEN a JWT token is returned
- AND the user is redirected to dashboard
#### Scenario: Invalid credentials
- GIVEN invalid credentials
- WHEN the user submits login form
- THEN an error message is displayed
- AND no token is issued
关键点:
- 使用 Given/When/Then 描述场景,每个场景可测试
- 使用 RFC 2119 关键词(MUST/SHALL/SHOULD/MAY)表达需求强度
Spec 写作边界
- spec 关注的是外部可观察行为,不是类图、包结构或数据库实现细节
Scenario的价值在于把需求转成可以验证的条件链,而不是把测试代码直接搬进文档Purpose用来说明这一组规范所覆盖的业务域,避免不同领域的需求堆进同一个 spec 文件- 当一个需求变化只影响内部实现、对外行为没有变化时,可能需要更新
design.md,但不一定需要修改 spec - 当一个 change 同时涉及多个领域时,应优先按领域拆分到多个 spec 文件,而不是把所有变化塞进单个
spec.md
八、命令参考
Slash 命令(AI 助手中使用)
| 命令 | 用途 |
|---|---|
/opsx:explore |
在立项前探索问题、比较方案、澄清边界 |
/opsx:propose <change-id> |
创建变更提案,一次性生成全部四个产物 |
/opsx:update |
在 change 已存在时修订工件,并保持 proposal/specs/design/tasks 一致 |
/opsx:apply |
按 tasks.md 实现代码 |
/opsx:sync |
手动合并 Delta Spec(不归档) |
/opsx:archive |
归档完成的变更 |
默认 core profile 更适合快速路径;如果需要逐步生成工件或更强的审查节奏,再切换到 expanded workflow。
扩展命令(需切换 profile):
| 命令 | 用途 |
|---|---|
/opsx:new |
仅创建文件夹,不生成产物(手动节奏) |
/opsx:continue |
按依赖顺序生成下一个产物(逐步审查) |
/opsx:ff |
快进,一次生成所有产物 |
/opsx:verify |
验证实现是否匹配规范 |
/opsx:bulk-archive |
批量归档多个变更 |
/opsx:onboard |
使用现有代码库完成引导式上手 |
CLI 命令(终端中使用)
| 类别 | 命令 | 用途 |
|---|---|---|
| 初始化与刷新 | openspec init、openspec update |
初始化项目,或在升级 CLI / 切换 profile 后刷新指令文件 |
| 浏览与校验 | openspec list、openspec show <change-id>、openspec view、openspec validate <change-id> |
查看 change、spec 和校验结果 |
| 工作流支撑 | openspec new change <id>、openspec status、openspec instructions、openspec templates、openspec schemas |
辅助 artifact-driven workflow 的落地 |
| 配置与 schema | openspec config、openspec config profile、openspec schema init <name>、openspec schema fork、openspec schema validate、openspec schema which |
调整 profile 与自定义工作流 |
| Stores / 工作集 | openspec store setup、openspec store register、openspec store list、openspec store doctor、openspec context、openspec workset create |
支撑跨仓规划、共享规范和个人工作视图 |
| 其他工具 | openspec doctor、openspec feedback、openspec completion install |
健康检查、反馈与 shell 补全 |
如果只在单仓内使用 OpenSpec,真正高频的 CLI 往往仍然是 init、update、list、show、validate、status、config 这几类。Stores、context、workset 属于更偏团队协作与跨仓规范管理的能力。
不同 AI 工具中的命令形式
| 工具 | 命令格式 |
|---|---|
| Claude Code | /opsx:propose、/opsx:apply |
| Cursor | /opsx-propose、/opsx-apply |
| Windsurf | /opsx-propose、/opsx-apply |
| GitHub Copilot (IDE) | /opsx-propose、/opsx-apply |
| Codex / Gemini CLI / Amazon Q | 各有独立集成方式 |
不同工具的最终命令前缀和提示词安装路径,建议以项目当前执行 openspec update 后生成的指令文件为准,因为集成方式会随版本演化。
九、Stores 与跨仓协作(Beta)
OpenSpec 的一个重要扩展方向是 Stores。它适合把规范资产放到单独的 OpenSpec 仓库中管理,再让多个代码仓共享这套 planning context。
| 场景 | Stores 的价值 | 需要注意的边界 |
|---|---|---|
| 一个功能横跨多个代码仓 | 让变更计划只维护一份,而不是每个仓各写一套 | 当前仍处于 beta,命令与文件格式可能继续调整 |
| 平台团队维护共享规范 | 业务仓可以只读消费共享 specs,减少“文档和实现各写一份”的漂移 | 引用的是 store 中的规范,不等于直接修改对方仓库 |
| 规划先于代码落地 | 先在 planning repo 中沉淀需求和 change,再逐步落到各代码仓 | 需要明确 store、root、reference 的责任边界 |
与 Stores 配套出现的 store setup/register/list/doctor、context、workset 等命令,本质上都在解决同一个问题:当规范不再只属于单个代码仓时,如何把“当前工作上下文”稳定地组装给人和编码助手。
十、Explore 模式
当需求还不够清晰、需要先调查现有代码或比较多种方案时,可以先使用探索模式:
1
/opsx:explore authentication for mobile app
Explore 不产生产物,重点是先把问题空间压缩清楚,再决定是否进入 change 生命周期。它比较适合下面几类场景:
- 需求本身还模糊,不确定应该先写什么 change
- 已有系统较复杂,需要先看代码结构、边界和依赖关系
- 存在多种可选方案,希望先比较代价、兼容性和迁移路径
- 需要从探索结果自然过渡到
/opsx:propose或 expanded workflow
Explore 的价值不是“多一个聊天命令”,而是把“先调查,再立项”纳入默认工作流,而不是所有事情都从直接开写开始。
十一、Verify 验证
1
/opsx:verify
三个维度的验证:
| 维度 | 检查内容 |
|---|---|
| Completeness(完整性) | 所有任务是否完成?所有需求是否有对应实现? |
| Correctness(正确性) | 实现是否匹配 spec 意图?边界情况是否处理? |
| Coherence(一致性) | 代码是否与 design.md 决策一致?命名是否统一? |
报告分三个级别:CRITICAL、WARNING、SUGGESTION。不阻塞归档,但提醒需要关注的地方。
十二、Schema 自定义
默认的 spec-driven schema 流程:
1
proposal -> specs -> design -> tasks -> implement
可以自定义 schema,例如增加 research 阶段:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# openspec/schemas/research-first/schema.yaml
name: research-first
artifacts:
- id: research
generates: research.md
requires: []
- id: proposal
generates: proposal.md
requires: [research]
- id: tasks
generates: tasks.md
requires: [proposal]
1
openspec schema init research-first
除了 schema init,当前 CLI 还提供 schema fork、schema validate、schema which 等命令,用来复制、校验和定位当前项目采用的 schema。对于需要把评审、研究、合规检查纳入前置工件的团队,自定义 schema 是 OpenSpec 从“个人方法”走向“组织流程”的关键能力。
十三、适用场景与注意事项
适用场景
- 涉及多文件、多模块的功能开发
- 需要技术方案设计的变更
- 团队协作、需求追踪
- 存量项目的增量修改
- 希望把“为什么这样实现”沉淀为长期规范资产的场景
不适用场景
- 改一行 CSS、修一个 typo,直接做通常更合适
- 极其简单、没有持续演化价值的变更
实践观察
- scope 写得越清楚,change 越不容易失控:proposal 中把 in scope / out of scope 写清楚,可以显著减少实现阶段的额外扩展。
- design.md 的价值在于提前暴露不可行方案:很多问题并不是实现难,而是方向选错。设计阶段发现问题,成本远低于写完后推翻。
- tasks.md 让长链路实现更容易恢复:中断后可以直接从任务项恢复上下文,而不必重新回放整段对话。
- 代价是前置规划成本上升:对于极小改动,这种流程可能显得偏重;OpenSpec 更适合值得被记录、追踪和复盘的 change。
十四、多语言配置
默认情况下 OpenSpec 生成的产物(proposal、specs、design、tasks)使用英文。如果希望生成中文产物,可以在 openspec/config.yaml 中添加语言指令:
1
2
3
4
5
# openspec/config.yaml
schema: spec-driven
context: |
语言:中文(简体)
配置 context 字段后,AI 在生成所有产物时都会使用中文(简体)。这个 context 字段本质上是附加给 AI 的全局提示,你也可以写入其他项目级上下文,例如:
1
2
3
4
5
context: |
语言:中文(简体)
项目名称:XX 电商平台
技术栈:Spring Boot + Vue 3 + MySQL
团队约定:所有需求使用 Given/When/Then 格式
这里的 context: 是写入产物生成提示中的项目背景信息,不要和 CLI 里的 openspec context 命令混淆;后者指的是组装当前 root 与引用 stores 后得到的工作上下文。
十五、总结
OpenSpec 不替代编码助手,它做的是把编码前的需求对齐、方案收敛和任务拆解,变成仓库内可以长期维护的规范层。
核心概念回顾:
- Specs:系统行为的 Source of Truth
- Changes:用 Delta Spec 描述某次变更,不直接重写整套主规范
- Artifacts:proposal(为什么)-> specs(变了什么)-> design(怎么做)-> tasks(做什么)
- Workflow:从 explore/propose 到 apply/archive,把计划与实现串成完整生命周期
- Stores:把规范资产从单仓扩展到跨仓共享,是团队协作场景下的重要补充能力
如果把 OpenSpec 只理解为“给 AI 多加几个命令”,很容易低估它的价值。它真正解决的问题,是如何让需求、设计和实现之间形成一条可审查、可回溯、可持续演化的工程链路。