为什么需要 OpenSpec

在 AI 编程时代,真正的难点往往不是“AI 会不会写代码”,而是“AI 能不能稳定写出你真正想要的代码”。问题往往不在模型能力,而在于需求、边界、约束和验收标准没有被稳定地表达出来。当意图没有沉淀为可复用的工程事实,AI 就只能在模糊上下文里“猜”。

OpenSpec 解决的正是这个问题。它的核心思想可以概括成一句话:先对齐规范,再生成代码(align before code)。与其把 AI 当成一个只看提示词的即时执行器,不如把它放进一套可追溯、可迭代、可沉淀的规范工作流里。

OpenSpec 既不是重量级流程平台,也不是传统瀑布式文档系统。从实践上看,它更像一套轻量的仓库内协议:

  • specs/ 保存系统当前已经成立的事实;
  • changes/ 保存本次准备引入的未来变化;
  • 用 proposal、spec、design、tasks 把“为什么改、改成什么、怎么实现”拆开表达;
  • 用 sync 和 archive 把一次变更逐步沉淀为下一次变更的上下文。

它的设计哲学,基本可以概括为四点:

  • Fluid not rigid:规范是活文档,不是一次性文书。
  • Iterative not waterfall:支持边做边校正,而不是阶段锁死。
  • Easy not complex:只保留真正影响实现质量的文档。
  • Brownfield-first:优先服务已有项目,而非只适配全新仓库。

这也是 OpenSpec 最值得重视的地方:它不要求团队先建立一套庞大的流程,再允许 AI 参与;它的目标恰恰相反——用最小的文档负担,换取更稳定的人机对齐质量

命令分工与推荐工作流

如果只先记一条主线,记住下面这条工作流就够了:

1
2
3
4
5
6
7
8
9
10
11
12
13
init

propose / new → continue

[人工审查 proposal / spec / design / tasks]

apply

verify

sync

archive

这条主线概括了 OpenSpec 中较常见的一种节奏:

  1. 先建立工作目录
  2. 再为一次变更生成工件
  3. 在实现前完成人类审查
  4. 随后按任务清单实现代码
  5. 最后按需校验、沉淀并归档

安装与初始化

1
2
3
npm install -g @fission-ai/openspec@latest
cd your-project
openspec init

初始化后,项目里通常会出现一个 openspec/ 工作目录:

1
2
3
4
5
your-project/
└── openspec/
├── config.yaml # 可选的项目上下文与规则
├── specs/ # 主 Specs:当前事实
└── changes/ # 变更目录:未来变化

有些 AI 工具还会在仓库根目录维护自己的配置文件,例如 AGENTS.mdCLAUDE.md。这类文件更适合视为AI 工具层配置,而不是 OpenSpec 自身的流程工件。它们可以和 openspec/ 共存,但职责不同,后文会单独说明。

核心命令怎么分工

命令 作用 何时使用 典型产出
openspec init 初始化工作目录 第一次接入 OpenSpec openspec/ 基础骨架
/opsx:new 创建 change 容器并给出首个工件模板 想逐步推进时 一个新的 change 目录
/opsx:continue 按依赖顺序继续生成下一个工件 new 之后继续补齐工件 单个新增工件
/opsx:propose 一次生成到可实现状态 需求比较清楚,想快速进入审查 proposal.mdspecs/design.mdtasks.md
/opsx:ff 快速生成到 apply-ready 与 propose 类似,强调更快进入实现 同上
/opsx:explore 通常用于调研、澄清、比较方案,可按需回写工件 需求不清、方案摇摆、边界不明 分析结论,可选的工件更新
/opsx:apply 按任务清单实现代码 工件已审查通过后 代码变更、任务勾选
/opsx:verify 扩展工作流中的一致性核对动作 希望在归档前补充核查时 completeness / correctness / coherence 报告
/opsx:sync 扩展工作流中的 spec 合并动作 想在归档前单独预览或执行 spec 合并时 更新后的主 Specs
/opsx:archive 默认工作流里的收口动作:验证变更、更新主 Specs 并归档 change 一个变更收口时 更新后的主 Specs + 归档目录

更稳妥的理解:命令是动作,不是关卡

OpenSpec 的强项不在于把你锁进固定阶段,而在于把一次变更拆成几个可回退、可重做、可校正的动作:

  • propose 负责形成可讨论、可审查的变更表达;
  • explore 通常用于澄清不确定性、调查问题和比较方案;
  • apply 负责把已确认的规范转成实现;
  • verify 负责检查“做出来的东西”是否真的对齐“说清楚的东西”;
  • archive 负责完成一次变更的收口;在扩展工作流里,sync 可以作为单独的 spec 合并动作提前执行。

因此,更稳妥的理解是:默认主流程通常围绕 propose → explore/apply → archive 展开;如果你希望在归档前补充核查或单独处理 spec 合并,则可以再引入 verifysync。如果你把这条主线记住,后面的大部分细节都会自然落位。

核心概念

要真正把 OpenSpec 用顺,需要抓住的其实只有三组概念:当前事实与未来变化、变更工件、沉淀动作

1. specs/:系统当前事实

openspec/specs/ 存放的是系统已经成立的行为契约。它回答的问题是:

这个系统现在已经具备什么能力?

典型写法会使用 SHALL / MUST 一类语义约束词,再配合 Gherkin 风格场景描述行为边界:

1
2
3
4
5
6
7
8
9
10
## Requirement: Create Order
The system SHALL accept POST /orders requests and create an order record.

### Scenario: Successful order creation
- **WHEN** user submits a valid order with sufficient inventory
- **THEN** the system creates the order and returns HTTP 201 with order details

### Scenario: Insufficient inventory
- **WHEN** inventory service returns insufficient stock
- **THEN** the system returns HTTP 409 and does NOT create an order record

这里描述的不是“打算做什么”,而是“已经应该成立的行为”。因此,specs/ 更像长期知识库,而不是临时草稿区。

2. changes/:本次准备引入的未来变化

openspec/changes/ 不是单个文件,而是一组变更目录。每一个 change 目录代表一次独立的需求、重构或能力调整。对应地,它回答的问题是:

这次准备把系统改成什么样?

可以把两者记成一句话:

  • specs/ = current truth
  • changes/ = proposed future state

这也是 OpenSpec 区别于很多“需求文档 + 代码实现”松散流程的关键:它把当前事实未来变更明确分层了。

3. change 目录里的四类工件

一个典型的 change 目录通常长这样:

1
2
3
4
5
6
7
8
9
openspec/
└── changes/
└── add-create-order/
├── proposal.md
├── design.md
├── tasks.md
└── specs/
└── order-creation/
└── spec.md

四类工件的职责分别是:

工件 作用 重点问题
proposal.md 说明为什么改、改什么、影响什么 Why / What / Impact
specs/.../spec.md 把需求翻译成可验证的行为契约 系统应该如何表现
design.md 记录实现方案、技术权衡、关键设计 准备怎么做
tasks.md 把实现拆成 AI 可执行任务清单 先做什么,后做什么

一个常见误解,是把 proposal、spec、tasks 当成彼此重复的文档。实际上,它们承担的是不同语义:

1
2
proposal.md   →   specs/   →   tasks.md
为什么改 改成什么 怎么落地

OpenSpec 之所以通常先产出 proposal,再产出 spec 和 tasks,不是因为 spec 不重要,而是因为没有先对齐方向,再精确描述行为,往往只会得到“方向错误但表达严谨”的产物

4. Delta Specs:只描述这次变更的增量

change 目录里的 specs/ 不是主 Specs 的完整拷贝,而是增量规范。它通常围绕三类动作展开:

  • ADDED:新增需求
  • MODIFIED:修改需求
  • REMOVED:删除需求

这种设计有两个直接好处:

  1. 一次变更的边界更清楚;
  2. AI 更容易理解“这次到底改哪里”。

5. syncarchive 的关系

这是全文里最容易混淆的一组动作。

  • /opsx:sync:在扩展工作流中,单独把 change 中的 Delta Specs 合并进主 specs/
  • /opsx:archive:在默认收口流程中,验证变更、更新主 Specs,并把 change 目录归档为历史记录。

因此,较准确的理解是:sync 可以被理解为把 spec 合并动作单独拿出来;而 archive 则是默认收口动作,既处理归档,也会把 future-state specs 合并进主 specs/。归档之后,proposal、design、tasks、delta specs 也会随整个 change 目录一起进入 archive,而不是只剩下一部分。

6. config.yaml:可选的项目配置入口

openspec/config.yaml 不是强制前置条件,但它通常值得填写。官方文档里,它不只是项目上下文入口,还常用于补充 schema 与工件规则。常见用途包括:

  • context:项目背景、技术栈、架构模式、领域信息;
  • rules:团队规则、接口约束、错误处理约定等;
  • schema 相关配置:为生成工件提供默认结构或约束。

例如:

1
2
3
4
5
6
7
8
9
context:
description: "订单服务,负责订单全生命周期管理"
tech_stack: "Spring Boot 3.x, Java 17, MySQL 8.0"
architecture: "微服务架构,Controller-Service-DAO 分层"

rules:
- "Controller 层只做参数校验和响应封装"
- "统一异常处理通过 GlobalExceptionHandler"
- "响应格式:{ code, message, data }"

它的作用并不神秘:为 OpenSpec 工作流提供结构化、稳定、可复用的项目配置。如果项目简单,AI 也许能从代码库自行推断出足够信息;如果项目复杂,config.yaml 往往能明显改善 proposal 或其他工件草案的质量。

7. 目录结构应该怎么读

把前面的概念合起来,OpenSpec 目录可以这样理解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
your-project/
└── openspec/
├── config.yaml # 可选:项目上下文与规则
├── specs/ # 主 Specs:系统当前事实
│ └── <capability>/
│ ├── spec.md
│ └── design.md # 可选
└── changes/ # 变更目录:未来变化
├── <change-id>/
│ ├── proposal.md
│ ├── design.md
│ ├── tasks.md
│ └── specs/
└── archive/

如果只用一句话总结:specs/ 是沉淀层,changes/ 是工作层,config.yaml 是上下文层。

完整实操步骤(以“新增下单接口”为例)

把前面的概念放进一次具体变更里,整条链路就会清楚很多。下面用一个常见的后端需求演示一遍:新增 POST /orders 接口,下单时同步扣减库存,库存不足返回 409

步骤一:初始化并补充上下文

先执行:

1
openspec init

如果项目已经比较复杂,建议补充 config.yaml。你可以让 AI 先生成初稿,再手动审查:

1
2
请根据当前项目代码结构,帮我补充 openspec/config.yaml,
包括项目描述、技术栈、架构模式和关键规则。

这一步的目标不是“写文档”,而是减少后续 proposal 的理解偏差。

步骤二:创建 change

如果你想一步到位生成主要工件,可以直接使用 /opsx:propose

1
2
3
帮我创建一个 OpenSpec 变更提案:
新增用户下单接口(POST /orders),
下单时同步调用库存服务扣减库存,库存不足时返回 409,订单不创建。

生成后的 change 目录可能类似这样:

1
2
3
4
5
6
openspec/changes/add-create-order/
├── proposal.md
├── design.md
├── tasks.md
└── specs/
└── order-creation/spec.md

如果你更想逐步控制,也可以先 /opsx:new,再通过 /opsx:continue 一件件补齐。

步骤三:审查工件

这是整条链路中最关键的人类审查节点。在这里不要急着进入实现,而是先问四个问题:

  1. proposal.md 是否把范围和影响说清楚了?
  2. spec.md 是否覆盖了关键场景和边界情况?
  3. design.md 是否解释了关键技术选择?
  4. tasks.md 是否足够具体,能被 AI 顺序执行?

例如,一个简洁的 proposal.md 可以长这样:

1
2
3
4
5
6
7
8
9
10
11
## Why
当前系统支持订单查询,但缺少订单创建能力。

## What Changes
- 新增 POST /orders 接口
- 下单时同步调用库存服务扣减库存
- 库存不足时返回 409,订单不创建

## Impact
- Affected specs: order-creation
- Affected code: OrderController, OrderService, InventoryClient

对应的增量 spec 可以这样表达:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## ADDED Requirements

### Requirement: Create Order
The system SHALL accept POST /orders requests and create an order record.

#### Scenario: Successful order creation
- **WHEN** user submits a valid order with sufficient inventory
- **THEN** the system creates the order and returns HTTP 201 with order details

#### Scenario: Insufficient inventory
- **WHEN** inventory service returns insufficient stock
- **THEN** the system returns HTTP 409 and does NOT create an order record

#### Scenario: Missing required fields
- **WHEN** required parameters are missing from the request
- **THEN** the system returns HTTP 400 with validation error details

tasks.md 则应该把实现拆成可执行步骤:

1
2
3
4
5
6
7
8
9
10
11
## 1. Implementation
- [ ] 1.1 创建 CreateOrderRequest DTO
- [ ] 1.2 创建 OrderController,暴露 POST /orders
- [ ] 1.3 创建 OrderService,编排下单逻辑
- [ ] 1.4 集成 InventoryClient,执行库存扣减
- [ ] 1.5 实现库存不足时返回 409

## 2. Tests
- [ ] 2.1 测试库存充足时下单成功
- [ ] 2.2 测试库存不足时返回 409
- [ ] 2.3 测试参数缺失时返回 400

如果这里发现问题,先修工件,再进入实现。不要把这一步省略掉。

步骤四:执行实现

确认工件可接受之后,再进入 apply

1
/opsx:apply

或者直接用自然语言告诉 AI:

1
请按照 openspec/changes/add-create-order/ 中的 proposal.md 和 tasks.md 实现代码。

这时 AI 的工作重点,不再是“理解需求”,而是“按已确认的任务清单落地实现”。这也正是前面先补齐 proposal、spec、tasks 的价值。

步骤五:在需要时补充实现对账

如果你希望在归档前额外做一次结构化核对,可以执行:

1
/opsx:verify add-create-order

verify 更适合被理解为扩展工作流里的核对动作。它关注的不是单纯“测试跑没跑”,而是至少三个维度:

  • Completeness:任务与需求是否完整落地;
  • Correctness:实现是否偏离 spec;
  • Coherence:实现是否违背设计或项目既有模式。

如果报告中还有关键问题,先修掉,再进入下一步。

步骤六:在需要时单独同步主 Specs

1
/opsx:sync add-create-order

这一步会把 changes/add-create-order/specs/ 中的 Delta Specs 合并进主 openspec/specs/。它更适合在你希望不归档、只先处理 spec 合并时使用。重点不是整文件覆盖,而是按意图更新主规范。

步骤七:归档本次变更

1
/opsx:archive add-create-order

归档意味着这次变更结束了,但它不会抹去上下文。相反,整个 change 目录会进入 changes/archive/,成为以后回溯“为什么这么改”的历史依据;与此同时,future-state specs 也会在归档过程中并入主 specs/,成为新的 current truth。

到这里,一个完整的 change 才算真正闭环。若采用默认主流程,可以理解为:

1
proposal → review → apply → archive

如果团队需要更强的中间检查,也可以在归档前补充:

1
proposal → review → apply → verify → sync → archive

人机交互边界与修正工作流

要把 OpenSpec 用稳,关键不在于第一次 propose 是否成功,而在于发现问题后能否按正确顺序回退和修正。最常见的问题不是命令不会用,而是:

  • proposal / spec 有问题时该改哪里;
  • apply 之后发现结果不对,应该先改代码还是先改 spec;
  • 人到底能不能直接改这些 Markdown 工件。

原则一:人负责意图与判断,AI 负责结构化与执行

在 propose 阶段,更合理的协作边界是:

  • 人类提供目标、上下文、约束、边界和取舍;
  • AI把这些信息整理成 proposal、spec、design、tasks;
  • 人类再审查这些工件是否真的表达了自己的意图。

因此,proposal、spec、design、tasks 都不是神圣不可改的中间产物,而是可迭代的人机协作载体。

原则二:发现问题时,先分清是“实现问题”还是“规范问题”

apply 之后如果出现缺陷,根因通常只有两类:

1
2
3
4
5
发现缺陷
├── 实现偏离了 spec
│ └── spec 是对的,代码写错了
└── spec 本身就有缺陷
└── spec 漏了场景、描述不精确,或逻辑定义错误

这个区分非常重要,因为它直接决定修复顺序。

三种常见修正路径

1. 用 /opsx:explore 先澄清,再决定是否回写工件

当问题本质上是“需求没想清楚”或“方案还在摇摆”时,/opsx:explore 是很自然的入口。官方文档对它的强调重点是思考、调研、澄清和收敛问题,因此更稳妥的理解是:它通常先服务于分析与澄清,而不是把它当作默认实现入口。

典型场景包括:

  • 需求范围需要收缩或扩展;
  • 某个边界场景在 proposal / spec 中表达得不够准确;
  • 技术方案需要先比较几种实现路径;
  • apply 前审查发现工件之间存在不一致。

如果 explore 的结论稳定了,再让 AI 把结论落实到 proposal、spec、design、tasks 中。

2. 用自然语言直接更新特定工件

如果你已经很明确知道问题在哪里,也可以直接告诉 AI 修改具体文件,例如:

1
2
3
请更新 openspec/changes/add-create-order/specs/order-creation/spec.md,
新增“库存服务超时时返回 503,订单不创建”的场景,
并同步检查 design.md 与 tasks.md 是否需要更新。

这种方式的优点是精确,缺点是你需要主动关注跨文件一致性。

3. 人工直接编辑 Markdown

这也是允许的。OpenSpec 的工件本质上就是普通 Markdown 文件,你完全可以手工修改它们。更稳妥的做法是:

  1. 先明确你改动了哪些工件;
  2. 再让 AI 检查 proposal / spec / design / tasks 是否仍然一致;
  3. 在实现后用 verify 再做一次对账。

Apply 后的正确修复顺序

如果问题来自实现偏离 spec,那就直接修代码即可。

但如果问题来自spec 本身有缺陷,顺序必须反过来:

1
2
3
4
5
先修 spec
→ 必要时修 design
→ 更新 tasks
→ 再修代码
→ verify

例如,下单接口最初只定义了“库存充足”和“库存不足”两个场景。后来测试发现:库存服务超时时,系统仍然创建了订单。此时真正的问题,不一定是代码写错,而可能是 spec 根本没有定义“库存服务超时”这个行为。

这类情况下,先补 spec 才有意义:

1
2
3
4
#### Scenario: Inventory service timeout
- **WHEN** inventory service does not respond within 3 seconds
- **THEN** the system returns HTTP 503
- **AND** the order is NOT created

然后再去更新 design、tasks 和实现代码。原因很简单:spec 是 AI 后续工作的标准答案。如果你只改了代码,却不改 spec,那么下次 AI 再读规范时,仍然会基于错误前提继续工作。这就是典型的 spec drift。

一条更实用的修正循环

把上面的原则浓缩起来,更实用的修正循环其实很简单:

1
2
3
4
5
6
7
8
9
10
review / test 发现问题

先判断:实现错了,还是规范错了?

规范错了:先修 spec / design / tasks,再修代码
实现错了:直接修代码

verify

通过后再 sync / archive

OpenSpec 的价值,不只是“帮助 AI 开工”,更在于帮助你在问题暴露后,仍然用同一套规范体系把事情收回来。

什么时候看哪些文件,什么时候改哪些文件

这一节可以当作速查表使用。

生命周期速查表

阶段 重点文件 你要做什么
初始化 openspec/config.yaml 可选地补充项目上下文与规则
理解现状 openspec/specs/*/spec.md 了解系统当前已经承诺的行为
创建提案 changes/<id>/proposal.md 审查变更范围、动机与影响
审查需求 changes/<id>/specs/**/spec.md 审查新增或修改的行为场景
审查方案 changes/<id>/design.md 审查关键设计和实现权衡
审查执行计划 changes/<id>/tasks.md 确认任务拆分是否足够具体
实现 代码文件 + tasks.md 让 AI 按任务顺序落地并更新勾选状态
对账 verify 报告 判断实现是否完整、正确、一致
沉淀 specs/ + changes/archive/ sync 更新事实,archive 保留历史

决策速查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
想了解系统现状?
→ 读 openspec/specs/

想开始一个新功能?
→ /opsx:propose
或 /opsx:new → /opsx:continue

想澄清需求或比较方案?
→ /opsx:explore

想让 AI 真正开始实现?
→ /opsx:apply

实现完了想检查是否对齐?
→ /opsx:verify

想把本次变更沉淀为长期事实?
→ /opsx:sync → /opsx:archive

注意事项与最佳实践

1. 不要跳过人工审查

OpenSpec 的核心收益来自“在编码前对齐”。如果 proposal 和 spec 没看就直接 apply,本质上仍然是在让 AI 自由发挥,只是多绕了一层目录结构。

2. 不要把 syncarchive 混为一谈

更稳妥的理解是:archive 本身就是默认收口动作;如果你希望在归档前先单独核查或单独合并 specs,再引入 verifysync。这样既能适配默认工作流,也能覆盖扩展工作流。

3. 不要混用不同工件的时态

  • specs/ 讲的是当前事实;
  • proposal.md 讲的是本次准备做什么;
  • tasks.md 讲的是实现步骤。

一旦把“未来工作项”写进主 spec,或者把“系统现状”写进 tasks,AI 和人都会很难读懂上下文。

4. config.yaml 很重要,但不是绝对前提

它常用于补充项目上下文、默认 schema 和工件规则,在复杂项目中尤其有价值;但 OpenSpec 的工作流不应被误解为“没有 config.yaml 就无法启动”。

5. 用渐进式方式接入 OpenSpec

没有必要一夜之间把整个项目重写成 Spec。更现实的方式,是从新功能、关键接口、经常变动的模块开始,让 specs/ 随着一次次 sync 慢慢沉淀起来。

6. 警惕 spec drift

只修代码、不修规范,短期看起来省事,长期会不断制造重复劳动。每当 AI 下一次再读取过时的 spec,旧问题就会重新出现。

7. 把 archive 当成历史资产,而不是回收站

归档目录里保存的是一次变更完整的上下文:为什么改、怎么设计、怎么拆任务、最后沉淀了哪些规范。它对回溯设计决策非常有价值。

验收标准与 ATDD:让 Spec 真正可测试

OpenSpec 的 spec 非常适合描述行为,但要把规范真正变成可执行验收标准,仍然需要进一步思考一个问题:

“可读的场景”如何变成“可验证的标准”?

Gherkin 场景擅长行为,不天然擅长量化指标

例如,下面这种写法表达了目标,但仍然不够可测:

1
2
3
#### Scenario: 整体响应时间不超过 5 秒
- **WHEN** 客户端请求 `/res/v1/health/custom`
- **THEN** API 响应时间不超过 5 秒

问题在于:

  1. 没说明是单次请求、平均值,还是 P95 / P99;
  2. 没说明并发与负载条件;
  3. AI 也很难直接据此生成精确断言。

更实用的做法:分层表达验收标准

比较稳妥的实践是把验收标准拆成三层:

  1. spec.md:描述功能行为和关键场景;
  2. spec.md 的 Acceptance Criteria 章节:补充结构化、量化的验收指标;
  3. design.md:说明这些指标应如何被测试框架验证。

例如:

1
2
3
4
5
6
7
## Acceptance Criteria

| ID | 指标 | 条件 | 阈值 | 测试方法 |
|----|------|------|------|----------|
| NFR-001 | 响应时延 P95 | 并发 ≤ 100 | ≤ 200ms | Gatling |
| NFR-002 | 响应时延 P99 | 并发 ≤ 100 | ≤ 500ms | Gatling |
| NFR-003 | 错误率 | 并发 ≤ 100 | < 0.1% | Gatling |

然后在 design.md 中说明测试策略,例如使用 Gatling 做压测、用 JUnit 覆盖功能场景。这样做的好处是:

  • 行为契约仍然留在 spec;
  • 量化目标有明确归属;
  • AI 在 apply 阶段更容易同时生成功能代码与测试代码。

ATDD 在 OpenSpec 里的落点

如果把验收测试驱动开发(ATDD)放进 OpenSpec 语境里,可以把它理解成:

1
2
3
4
5
6
7
先在 spec 中定义行为

再用 Acceptance Criteria 定义可测标准

再在 design / tasks 中说明如何验证

最后让 AI 按这些标准实现与测试

也就是说,OpenSpec 最适合作为 ATDD 的上游规范层。它不替代测试框架,但它能让测试目标在编码前就变得清晰。

OpenSpec Commands / Skills:如何理解这套生态

在支持 AI 命令和技能机制的工具里,OpenSpec 常常会以命令、skills 或两者结合的方式交付:

  • 显式命令:例如 /opsx:propose/opsx:apply/opsx:archive
  • 自动激活的 skills:当你用自然语言描述意图时,AI 工具可按其集成方式匹配对应能力。

更稳妥的理解是:它们常常服务于同一套工作流,但具体呈现方式取决于工具集成与交付配置:

  • 命令更适合显式控制、重复执行和标准化步骤;
  • skills 更适合自然语言驱动和低摩擦交互。

一个很实用的理解方式是:

  • 新手阶段优先用显式命令,因为边界更清楚;
  • 熟练阶段可以更多使用自然语言,让 AI 自动匹配;
  • 复杂场景常常是两者混用:先用自然语言澄清问题,再用显式命令推进关键步骤。

三个最容易讲错的点

/opsx:new 不是“一次生成所有工件”

它更像“建立 change 容器并开始第一步”,适合想自己掌控生成节奏的人。

/opsx:explore 不是“提前开始实现”

它的价值在于思考、调研、比较、澄清,以及在必要时把结论回写到工件,而不是直接产出业务代码。

/opsx:archive 不是“只做历史归档”的别名

archive 的意义是收口与保留历史,同时在默认流程里也会更新主 Specs;sync 更适合在需要时把 spec 合并动作单独拿出来执行。

项目配置搭配建议

把 OpenSpec 放进真实项目时,最容易困惑的一点是:AGENTS.mdCLAUDE.md、规则文件、openspec/ 到底是什么关系。

最简单的理解方式是把它们分成三层:

1. AI 工具层

例如 AGENTS.mdCLAUDE.md 或某些工具自己的 rules 文件。它们主要负责:

  • 项目级提示;
  • Agent 行为约束;
  • 编码规范、协作规则、调用策略。

它们回答的问题更像是:

AI 在这个仓库里应当如何工作?

2. OpenSpec 上下文层

主要是 openspec/config.yaml。它常用于:

  • 提供项目背景;
  • 提供规则与约束;
  • 提供默认 schema 或工件级规则,并改善 proposal 等工件草案的质量。

它回答的问题是:

这个项目是什么样的?

3. OpenSpec 规范层

主要是 openspec/specs/openspec/changes/。它们负责:

  • 描述当前事实;
  • 表达本次变更;
  • 沉淀历史与知识。

它回答的问题是:

系统现在是什么,以及这次准备把它改成什么?

推荐搭配方式

如果你只想用一句话记住:

  • AI 工具层负责“怎么协作”;
  • OpenSpec 上下文层负责“项目是什么”;
  • OpenSpec 规范层负责“系统行为与变更是什么”。

三者并不冲突,反而是互补关系。对复杂项目来说,这种分层往往比把所有信息都塞进同一个 Markdown 文件里更稳定。

参考资料