为什么需要 OpenSpec

在 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. 再让 AI 按任务清单实现代码
  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 核对实现与工件的一致性 apply 之后、archive 之前 completeness / correctness / coherence 报告
/opsx:sync 将 Delta Specs 合并进主 Specs 想把新事实沉淀到 specs/ 更新后的主 Specs
/opsx:archive 检查完成度并归档 change 一个变更收口时 归档后的历史目录

推荐理解:把命令看成“动作”,不要看成“关卡”

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

  • propose 负责形成可讨论、可审查的变更表达;
  • explore 负责澄清不确定性,而不是抢先写代码;
  • apply 负责把已确认的规范转成实现;
  • verify 负责检查“做出来的东西”是否真的对齐“说清楚的东西”;
  • syncarchive 负责把本次变更沉淀为长期上下文。

因此,更稳妥的默认习惯是:propose → review → apply → verify → sync → archive。如果你把这条主线记住,后面的大部分细节都会自然落位。

核心概念

要把 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:把一个 change 目录作为历史记录收口归档。

因此,较准确的理解是:

  • sync 负责更新事实
  • archive 负责保留历史

archive 过程中通常会检查工件完整度、任务完成度,以及是否需要先执行 sync,但两者在语义上并不是同一个动作。归档之后,proposal、design、tasks、delta specs 也会随整个 change 目录一起进入 archive,而不是只剩下一部分。

6. config.yaml:可选的项目上下文入口

openspec/config.yaml 不是强制前置条件,但它通常值得填写。它用来提供两类信息:

  • context:项目背景、技术栈、架构模式、领域信息;
  • rules:团队规则、接口约束、错误处理约定等。

例如:

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 }"

它的意义并不神秘:给 AI 一个结构化、稳定、可复用的项目上下文。如果项目简单,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 一件件补齐。

步骤三:审查 proposal、spec、design、tasks

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

  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/。重点不是整文件覆盖,而是按意图更新主规范。

步骤七:归档本次变更

1
/opsx:archive add-create-order

归档意味着这次变更结束了,但它不会抹去上下文。相反,整个 change 目录会进入 changes/archive/,成为以后回溯“为什么这么改”的历史依据。

到这里,一个完整的 change 才算真正闭环:

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 混为一谈

更稳妥的习惯是:verify → sync → archive。这样既更新了主事实,也保留了完整历史。

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

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

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

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

它能显著提升 proposal 质量,尤其在复杂项目中更明显;但 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 往往会以两种形态出现:

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

两者并不是两套系统,而是同一工作流的两种入口:

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

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

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

三个最容易讲错的点

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

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

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

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

/opsx:archive 不是“自动完成所有沉淀动作”的别名

archive 的意义是收口与保留历史,而主 Specs 的事实更新仍然应该由 sync 明确承担。

项目配置搭配建议

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

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

1. AI 工具层

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

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

它们回答的问题更像是:

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

2. OpenSpec 上下文层

主要是 openspec/config.yaml。它负责:

  • 提供项目背景;
  • 提供规则与约束;
  • 改善 proposal 的生成质量。

它回答的问题是:

这个项目是什么样的?

3. OpenSpec 规范层

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

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

它回答的问题是:

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

推荐搭配方式

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

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

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

参考资料