随着 Claude Code、Codex、Cursor 等 AI 编程工具越来越强,现在让 AI 完成一个完整功能已经不是什么难事。

麻烦反而变成了:

AI 写代码很快,但它不一定真正理解你想做什么。

比如我们直接告诉 AI:

1
给这个项目增加用户登录功能。

AI 很可能马上开始创建接口、修改数据库、增加依赖、设计 Token 机制。

等它全部写完以后,你才发现:

1
2
3
4
5
登录方式不是你想要的
数据库字段设计不合理
Token 生命周期不符合需求
接口路径和现有项目风格不一致
甚至修改了本来不应该修改的代码

这是目前 AI Coding 中很典型的问题。

而 OpenSpec 想解决的,就是让:

1
需求 → 代码

变成:

1
2
3
4
5
6
7
8
9
10
11
12
13
需求
↓
分析
↓
规范
↓
设计
↓
任务
↓
实现
↓
验证

也就是所谓的:

1
2
Spec-Driven Development
规范驱动开发

OpenSpec 并不是一个新的 Web 框架,也不会替代 Claude Code、Codex 或 Cursor。

它更像是开发者和 AI 编码助手之间的一层“协议”。

开发之前,先把:

1
2
3
4
5
为什么做
做什么
系统最终应该是什么样
准备怎么实现
具体需要完成哪些任务

全部明确下来。

然后再允许 AI 开始修改代码。

这样,AI Coding 就不再是:

1
2
3
给一句 Prompt
↓
AI 自由发挥

而变成:

1
2
3
先定义正确答案
↓
再让 AI 实现

一、OpenSpec 是什么,以及为什么需要它

传统 AI Coding 的基本流程通常是:

1
2
3
4
5
6
7
开发者
↓
Prompt
↓
AI
↓
代码

比如:

1
给系统增加 API 限流。

听起来很简单,但实际上里面包含大量没有明确的信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
对谁限流?

IP?
用户?
API Key?

限流多少?

100 次 / 分钟?
1000 次 / 小时?

哪些接口限流?

全部接口?
公开 API?
登录接口?

超过限制怎么办?

HTTP 429?
排队?
直接丢弃?

限流状态放在哪里?

Redis?
数据库?
内存?

如果这些问题没有提前说明,AI 就必须自己猜。

而 OpenSpec 的思路是:

1
不要直接 Coding

先建立一个 Change:

1
我要修改什么?

然后逐步生成:

1
2
3
4
Proposal
Spec
Design
Tasks

最终再开始实现。

整个流程大致如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
开发者提出需求
↓
AI Explore
↓
分析现有代码
↓
Proposal
↓
Specification
↓
Design
↓
Tasks
↓
人工 Review
↓
AI Apply
↓
Test / Verify
↓
Archive

所以 OpenSpec 要解决的问题是:

1
AI 写代码之前缺少明确约束。

对于简单 Demo,这种约束可能不重要。

但项目一旦变成:

1
2
3
4
5
6
长期维护
多人协作
几十个模块
大量 AI Coding
复杂业务逻辑
Agent 一次修改十几个甚至几十个文件

需求规范就会越来越重要。

OpenSpec 中最重要的两个概念

理解 OpenSpec,其实只需要先搞懂两个东西:

1
2
Spec
Change

Spec:系统现在应该是什么样

OpenSpec 中:

1
openspec/specs/

保存的是当前系统已经确认的正式规范。

例如:

1
2
3
4
5
6
7
8
9
10
openspec/specs/

├── user-auth/
│ └── spec.md
│
├── document-upload/
│ └── spec.md
│
└── api-rate-limit/
└── spec.md

分别可能描述:

1
2
3
用户认证如何工作
文档上传如何工作
API 限流如何工作

因此可以把:

1
openspec/specs/

理解成:

当前项目行为的长期知识库。

半年以后即使换了开发人员,甚至换了 AI Agent,只要读取 Specs,就应该能够知道:

1
这个系统目前应该怎么运行。

Change:系统准备发生什么变化

假设当前系统已经支持:

1
用户登录

现在准备增加:

1
用户退出登录

OpenSpec 不会立刻修改主 Spec。

而是先创建:

1
openspec/changes/add-user-logout/

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
openspec/
│
├── specs/
│ └── user-auth/
│ └── spec.md
│
└── changes/
└── add-user-logout/
├── proposal.md
├── design.md
├── tasks.md
│
└── specs/
└── user-auth/
└── spec.md

其中:

1
openspec/specs/user-auth/spec.md

表示:

1
当前系统正式规范

而:

1
openspec/changes/add-user-logout/specs/user-auth/spec.md

表示:

1
这次修改准备让 user-auth 发生什么变化

这部分也叫:

1
Delta Spec

Delta 就是:

1
变化量

所以可以简单理解:

1
2
3
4
5
6
7
Specs
=
系统现在是什么

Changes
=
系统准备变成什么

二、安装 OpenSpec 并初始化项目

OpenSpec 本身是一个 CLI 工具,因此首先需要 Node.js。

可以检查当前版本:

1
node --version

如果得到类似:

1
v22.23.0

就可以正常使用。

然后安装 OpenSpec:

1
npm install -g @fission-ai/openspec@latest

如果使用 pnpm:

1
pnpm add -g @fission-ai/openspec@latest

安装完成以后:

1
openspec --version

能够正常显示版本号,就说明安装成功。

初始化现有项目

假设项目结构:

1
my-project/

进入:

1
cd my-project

执行:

1
openspec init

OpenSpec 会让你选择使用的 AI Coding 工具。

比如:

1
2
3
Claude Code
Codex
Cursor

选择以后,OpenSpec 会自动生成对应 Agent 所需要的:

1
2
3
Commands
Skills
Workflow

例如 Claude Code 项目中可能出现:

1
2
3
.claude/
├── commands/
└── skills/

同时项目会增加:

1
openspec/

目录。

基础结构一般类似:

1
2
3
4
5
6
7
8
9
10
11
my-project/
│
├── src/
├── tests/
│
├── openspec/
│ ├── config.yaml
│ ├── specs/
│ └── changes/
│
└── ...

如果希望指定 Agent,也可以:

1
openspec init --tools claude,cursor

如果暂时不需要绑定任何 Agent:

1
openspec init --tools none

后续 OpenSpec 更新以后,可以在项目中运行:

1
openspec update

更新项目中的 Agent Skill 和 Command。

一定要区分两种命令

第一次使用 OpenSpec 最容易踩的坑,就是混淆:

1
openspec xxx

和:

1
/opsx:xxx

前者属于:

1
终端命令

比如:

1
2
3
4
5
openspec init
openspec list
openspec validate --all
openspec show
openspec archive

这些应该输入:

1
2
3
4
5
PowerShell
CMD
Terminal
Warp
Linux Shell

而:

1
2
3
/opsx:explore
/opsx:propose
/opsx:apply

属于:

1
AI Coding Agent

应该输入:

1
2
3
Claude Code
Cursor
Codex

等 AI 工具。

可以这样记:

1
2
3
4
5
6
openspec xxx
↓
Terminal
/opsx:xxx
↓
AI Chat

另外,不同 AI 工具对 OpenSpec Workflow 的展示方式可能不完全相同。

有的使用:

1
/opsx:propose

有的可能展示成:

1
/opsx-propose

还有一些 Agent 会直接通过 Skill 调用。

因此初始化完成以后,最好以:

1
openspec init

生成的实际提示为准。

三、OpenSpec 的完整开发工作流

OpenSpec 的流程可以概括为:

1
2
3
4
5
6
7
8
9
10
11
Explore
↓
Propose
↓
Review
↓
Apply
↓
Verify
↓
Archive

其中日常用得最多的是:

1
2
3
4
Explore
Propose
Apply
Archive

如果是比较重要的功能,则推荐完整使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Explore

↓

Propose

↓

人工检查规范

↓

Validate

↓

Apply

↓

Test

↓

Verify

↓

Archive

下面用:

1
增加 API 限流

作为例子完整走一遍。

Explore:先分析,不要急着写代码

首先进入 Claude Code、Codex 或 Cursor。

执行:

1
/opsx:explore

然后描述需求:

1
2
3
4
5
6
7
8
9
10
11
12
13
我准备给项目增加 API 限流功能。

公开 API 需要限流。

普通客户端限制为每分钟 100 次请求。

超过限制返回 HTTP 429。

希望使用 Redis 保存限流状态。

请先分析当前项目结构、API 组织方式、Redis 使用情况以及适合的实现方案。

暂时不要修改代码。

Explore 的特点是:

1
2
只分析
不实施

AI 可以先研究:

1
2
3
4
5
6
7
8
项目结构
路由层
认证逻辑
Redis 是否已经存在
中间件体系
公共 API 如何识别
错误处理方式
测试框架

然后告诉你:

1
2
3
4
应该在哪一层实现
会影响哪些文件
有什么技术风险
有没有更合适的方案

这一步看起来会多花几分钟,但经常能够避免后面大量返工。AI Coding 里最浪费时间的,往往是方向写错以后的推倒重来,而代码写得慢反倒是小事。

Propose:把需求正式变成 Change

需求分析完成后执行:

1
/opsx:propose add-api-rate-limit

也可以直接描述:

1
/opsx:propose 为公开 API 增加基于 Redis 的限流机制,每个客户端每分钟最多请求 100 次,超过以后返回 HTTP 429

然后 OpenSpec 会生成:

1
openspec/changes/add-api-rate-limit/

一般包含:

1
2
3
4
5
6
7
8
9
add-api-rate-limit/
│
├── proposal.md
├── design.md
├── tasks.md
│
└── specs/
└── api-rate-limit/
└── spec.md

这几个文件分别负责不同内容:

文件 作用
proposal.md 为什么做、准备改变什么
specs/*/spec.md 最终系统应该有什么行为
design.md 技术上如何实现
tasks.md AI 接下来要完成哪些任务

它们之间可以理解成:

1
2
3
4
5
6
7
8
9
10
11
proposal
│
├──── specs
│
└──── design
│
▼
tasks
│
▼
apply

Proposal 负责:

1
2
Why
What

Spec 负责:

1
Behavior

Design 负责:

1
How

Tasks 负责:

1
Execution

四、Proposal、Spec、Design 和 Tasks 应该怎么写

这四个文件看起来都在描述需求,但各有分工,混在一起写就失去了拆分的意义。

Proposal:说明为什么做,以及准备改变什么

例如:

1
openspec/changes/add-api-rate-limit/proposal.md

可以类似:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Add API Rate Limiting

## Why

Public APIs currently have no request rate limits.
A single client can consume excessive server resources.

## What Changes

- Add rate limiting for public API endpoints
- Limit clients to 100 requests per minute
- Return HTTP 429 when the limit is exceeded
- Store rate limit state in Redis

## Impact

- API middleware
- Redis
- Public API endpoints

Proposal 要回答的是:

1
2
3
4
5
为什么要做?

准备改变什么?

影响哪些模块?

不要在这里写大量:

1
2
3
4
5
Redis Lua 脚本
具体类名
函数设计
数据库字段
Middleware 实现

这些属于 Design。

所以可以记成:

1
Proposal = Why + What

Spec:定义什么叫“正确”

Spec 是 OpenSpec 最重要的部分。

例如:

1
openspec/changes/add-api-rate-limit/specs/api-rate-limit/spec.md

可以写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Spec Delta

## ADDED Requirements

### Requirement: Public API rate limiting

The system SHALL limit each public API client to 100 requests per minute.

#### Scenario: Request within limit

- **WHEN** a client sends fewer than 100 requests within one minute
- **THEN** the system SHALL process the request normally

#### Scenario: Request exceeds limit

- **WHEN** a client exceeds 100 requests within one minute
- **THEN** the system SHALL reject the request
- **THEN** the system SHALL return HTTP status 429

这里完全没有规定:

1
2
3
必须使用 Redis SETEX
必须使用某个 Middleware
必须使用某个类

它只规定:

1
系统最终必须表现成什么样。

这是 Spec 和 Design 的区别所在。

Spec 很接近:

1
验收标准

甚至可以直接对应测试。

例如:

1
2
3
4
5
6
7
WHEN

第 101 个请求到达

THEN

返回 HTTP 429

以后可以直接转成 Integration Test。

所以 OpenSpec 的思路是:

1
2
3
4
5
先定义什么叫做对

↓

再让 AI 去实现这个正确结果

不用等 AI 写完以后再去判断它写得对不对。

Spec 中的 ADDED、MODIFIED、REMOVED

OpenSpec 的 Delta Spec 中常见:

1
## ADDED Requirements

表示新增。

1
## MODIFIED Requirements

表示修改。

1
## REMOVED Requirements

表示删除。

例如已有:

1
2
3
### Requirement: User Login

The system SHALL authenticate users using email and password.

现在增加 Google 登录。

如果原来的邮箱登录没有改变:

1
2
3
4
5
## ADDED Requirements

### Requirement: Google Login

The system SHALL allow users to authenticate using Google OAuth.

而如果原来:

1
Session 7 天过期

现在修改成:

1
Session 30 天过期

这才属于:

1
## MODIFIED Requirements

还有一条规则要注意:

MODIFIED 应该写修改后的完整 Requirement,而不是只写变化的那一句。

否则归档时容易造成原有规范信息缺失。

Requirement 和 Scenario 的结构

OpenSpec Spec 中一般使用:

1
### Requirement: Name

Requirement 下至少应该存在一个:

1
#### Scenario: Name

例如:

1
2
3
4
5
6
7
8
### Requirement: PDF Upload

The system SHALL allow users to upload PDF documents.

#### Scenario: Upload valid PDF

- **WHEN** the user uploads a valid PDF file
- **THEN** the system SHALL save the document

这里要特别注意标题层级:

1
2
3
4
5
6
7
Requirement
=
###

Scenario
=
####

Scenario 不是三级标题。

另外规范最好使用:

1
2
SHALL
MUST

这类明确表达。

少写:

1
2
3
4
5
最好
可能
应该尽量
maybe
usually

因为 Spec 必须:

1
2
3
可以判断
可以测试
可以验证

例如:

1
系统应该拥有良好的性能。

就不是很好的规范。

因为:

1
什么叫良好?

没法测试。

更好的写法:

1
The search API SHALL return within 500 ms for 95% of requests under the defined test workload.

至少它可以被验证。

Design:描述技术实现方式

如果 Proposal 解决:

1
2
为什么
做什么

Spec 解决:

1
系统最终应该怎么表现

那么 Design 解决:

1
怎么实现

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Design

## Context

The backend uses FastAPI and Redis is already available.

## Goals

- Support distributed API rate limiting
- Work across multiple backend instances
- Avoid database writes

## Decisions

Use Redis fixed-window counters.

Each client uses a Redis key in the following format:

rate-limit:{client_id}:{minute}

The counter expires after 60 seconds.

## Risks

If Redis becomes unavailable, rate limiting temporarily fails open and the failure is logged.

## Migration

No database migration is required.

如果涉及以下内容,Design 需要写得比较详细:

1
2
3
4
5
6
7
8
9
10
数据库改动
系统架构
跨多个模块
新依赖
性能
安全
迁移方案
兼容性
缓存策略
消息队列

而如果只是:

1
2
3
修改按钮文字
简单 CSS
修一个小 Bug

Design 就可以相对简单。

Tasks:把规范拆成 AI 能执行的工作

最后生成:

1
tasks.md

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Tasks

## 1. Rate Limiter

- [ ] 1.1 Create rate limiter service
- [ ] 1.2 Implement Redis counter
- [ ] 1.3 Add TTL handling

## 2. Middleware

- [ ] 2.1 Add API rate limit middleware
- [ ] 2.2 Resolve client identifier
- [ ] 2.3 Return HTTP 429

## 3. Tests

- [ ] 3.1 Test requests within limit
- [ ] 3.2 Test requests exceeding limit
- [ ] 3.3 Test Redis unavailable scenario

Tasks 最好使用:

1
- [ ]

而不是:

1
-

因为 OpenSpec 可以通过 Checkbox 判断任务完成情况。

完成后:

1
- [x]

这样以后运行:

1
openspec list

就能看到类似:

1
add-api-rate-limit    8/10 tasks

五、Apply、Validate、Verify 和 Archive

Proposal、Spec、Design、Tasks 全部确认以后,才真正进入编码阶段。

这一步叫:

1
Apply

执行:

1
/opsx:apply

AI 会读取:

1
2
3
4
proposal.md
spec.md
design.md
tasks.md

然后开始按照 Tasks 修改项目。

此时 AI 只需要按照已经确认的规范完成实现,不用再自己琢磨该怎么做。这也是 OpenSpec 和普通 Prompt Coding 的主要区别。

不要 Propose 完就直接 Apply

一个很常见的错误是:

1
2
3
4
5
6
7
8
9
Propose

↓

完全不看

↓

Apply

这样其实会让 OpenSpec 退化成:

1
2
AI 写代码之前
顺便多生成几份 Markdown

推荐的做法是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Propose

↓

检查 proposal.md

↓

检查 spec.md

↓

检查 design.md

↓

检查 tasks.md

↓

发现问题就修改

↓

Apply

OpenSpec 的用处就在这里:

代码还没写,你就能发现 AI 理解错了。

修改已经生成的 Change

如果原来 Spec 写的是:

1
100 requests/minute

后来决定改成:

1
300 requests/minute

最好不要直接修改代码。

应该先更新 OpenSpec。

例如让 AI:

1
2
3
把当前 API Rate Limit Change 修改为每分钟 300 次。

同步更新 Proposal、Spec、Design 和 Tasks 中受影响的内容。

也可以使用:

1
/opsx:update

这样可以尽量保证几个 Artifact 之间保持一致。

Validate:检查规范有没有问题

日常推荐执行:

1
openspec validate --all

它可以检查:

1
2
3
4
5
6
Spec 格式
Requirement
Scenario
Delta Spec
Tasks
Archive 冲突

例如某个 Requirement 没有 Scenario:

1
ADDED "Rate limiting" must include at least one scenario

或者 Scenario 标题层级写错,也可能被发现。

如果希望更严格:

1
openspec validate --all --strict

我的推荐是至少在两个阶段执行:

1
2
3
Apply 之前

Archive 之前

也就是:

1
2
3
4
5
6
7
Propose
↓
Review
↓
Validate
↓
Apply

然后:

1
2
3
4
5
6
7
8
9
Apply
↓
Test
↓
Verify
↓
Validate
↓
Archive

Verify:检查实现是否真的符合规范

代码写完只是:

1
Implementation Complete

不代表:

1
Requirement Complete

例如 Spec 写:

1
超过限制返回 HTTP 429

结果 AI 实现成:

1
HTTP 403

代码可能:

1
2
没有报错
测试甚至能跑

但是:

1
实现 != Spec

Verify 就是用来检查这种问题。

如果当前 OpenSpec Profile 中启用了 Verify Workflow(默认的 core Profile 不包含它,属于扩展 Workflow),可以使用:

1
/opsx:verify

让 Agent 对照:

1
2
3
4
Proposal
Spec
Design
Tasks

检查代码是否满足要求。

如果没有 Verify,可以运行下面的命令选择要启用的 Workflow:

1
openspec config profile

调整以后:

1
openspec update

重新生成 Agent 工作流。

对于复杂项目,我建议保留 Verify。

Sync 和 Archive 的区别

OpenSpec 还有:

1
/opsx:sync

它主要用于:

1
2
把当前 Change 中的 Delta Spec
同步到 openspec/specs/

但 Change 本身仍然保持 Active。

也就是说:

1
2
3
4
Sync
=
更新主 Spec
但不结束 Change

而:

1
2
3
4
Archive
=
完成 Change
并归档

绝大多数普通功能开发可以直接:

1
Archive

只有 Change 生命周期很长,而中间已经有一部分稳定规范需要同步时,Sync 才用得上。

Archive:完成一次 OpenSpec 生命周期

功能完成以后:

1
/opsx:archive

或者终端:

1
openspec archive add-api-rate-limit

自动确认:

1
openspec archive add-api-rate-limit -y

Archive 通常会:

1
2
3
4
5
6
7
合并 Delta Spec
↓
更新 openspec/specs/
↓
移动 Change
↓
openspec/changes/archive/

例如:

1
openspec/changes/add-api-rate-limit/

最终变成:

1
openspec/changes/archive/2026-10-04-add-api-rate-limit/

此时:

1
Change

已经变成:

1
历史开发记录

而最终规范:

1
api-rate-limit

进入:

1
openspec/specs/

成为:

1
当前系统事实

OpenSpec 的整个生命周期可以概括成:

1
2
3
4
5
6
7
8
9
Change
↓
Implement
↓
Verify
↓
Archive
↓
Spec

六、Claude Code、Codex 和 Cursor 中如何实际使用

OpenSpec 最适合和 AI Coding Agent 一起使用。

假设使用 Claude Code。

首先:

1
cd my-project

启动:

1
claude

然后:

1
/opsx:explore

告诉 Claude:

1
2
3
4
5
6
7
我准备增加文档搜索功能。

用户提交关键词以后,需要在已有文档中搜索相关内容。

先分析当前项目的数据库结构、文档模型、搜索接口和现有技术栈。

不要修改代码。

讨论完成以后:

1
/opsx:propose add-document-search

然后人工检查:

1
openspec/changes/add-document-search/

重点查看:

1
2
3
4
proposal.md
specs/
design.md
tasks.md

终端运行:

1
openspec validate add-document-search

确认没有问题:

1
/opsx:apply

实现完成以后运行项目测试:

1
pytest

或者:

1
npm test

然后:

1
/opsx:verify

最后:

1
/opsx:archive

完整流程就是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
需求
↓
Explore
↓
分析项目
↓
Propose
↓
人工审核
↓
Validate
↓
Apply
↓
Test
↓
Verify
↓
Archive

Codex 和 Cursor 的逻辑一样,区别只在于:

1
OpenSpec Workflow 如何暴露给 Agent

某些工具会使用:

1
Slash Commands

有的则会通过:

1
Skills

调用。

因此最稳妥的方法是:

1
2
3
4
5
6
7
8
9
运行 openspec init

↓

选择当前 AI Agent

↓

按照生成的提示使用

而不是死记某一种固定 Command。

七、项目中的推荐实践

光会敲几条命令还用不好 OpenSpec,需要建立一套比较稳定的开发习惯。

一个 Change 尽量只解决一个问题

例如:

1
2
3
4
5
6
重构系统架构
增加权限
增加支付
增加消息通知
优化 UI
提高性能

如果全部写进:

1
one-big-change

后面一定很难维护。

更合理:

1
2
3
4
5
6
7
8
9
add-rbac

add-payment

add-notification

refactor-auth-service

optimize-document-query

也就是尽量保持:

1
2
3
One Change
=
One Clear Goal

这样:

1
2
3
4
Proposal 更清晰
Spec 更容易验证
Task 更容易执行
Archive 历史也更好读

Spec 写行为,Design 写实现

这是最值得记住的一条。

错误的 Spec:

1
The system SHALL use Redis SETEX to store rate limit keys.

这实际上是在规定技术实现。

更好的 Spec:

1
The system SHALL limit each public client to 100 requests per minute.

然后 Design 再写:

1
Use Redis fixed-window counters.

因此:

1
2
3
4
5
6
Spec
=
What the system does
Design
=
How the system does it

以后即使从 Redis 换成其他存储:

1
2
Spec 可能完全不用改
Design 才需要调整

已经开发一半的大项目,不要一次性补全部 Specs

很多人第一次给已有项目接 OpenSpec,会想:

1
2
让 AI 扫描整个项目
然后生成全部 Specs

如果项目有几十万行代码,结果往往是:

1
2
3
4
5
文档很多

但质量不高

没人愿意维护

更推荐渐进式建立。

比如当前准备改:

1
Authentication

那就先完善:

1
user-auth

下一次修改:

1
Document Upload

再完善:

1
document-upload

随着项目持续开发:

1
openspec/specs/

会逐渐覆盖真正重要和活跃的功能。

纯重构不一定需要 Spec

例如:

1
2
3
4
5
6
7
重命名变量
调整文件目录
代码格式化
升级 ESLint
修改 CI
内部重构
README 更新

如果对:

1
用户可观察行为

没有任何变化,就没有必要硬写 Requirement。

这种 Change 可以在它的 .openspec.yaml(位于 openspec/changes/<change-name>/ 下)中配置:

1
2
schema: spec-driven
skip_specs: true

表示:

1
这个 Change 没有 Spec-Level Behavior Change

但不要为了省时间,在真正存在行为变化时也跳过 Specs。

OpenSpec 最好和 Git 一起使用

比如:

1
git switch -c feat/api-rate-limit

创建 Change:

1
/opsx:propose add-api-rate-limit

先提交规范:

1
2
git add .
git commit -m "docs: propose api rate limiting"

然后:

1
/opsx:apply

开发完成:

1
2
git add .
git commit -m "feat: implement api rate limiting"

然后:

1
/opsx:verify

最后:

1
/opsx:archive

提交归档:

1
2
git add .
git commit -m "docs: archive api rate limiting change"

这样:

1
Git

记录:

1
代码什么时候变了

而:

1
OpenSpec

记录:

1
2
3
4
为什么变
要求是什么
设计是什么
最终行为是什么

两者互补。

PR Review 时也可以:

1
2
3
4
5
6
7
先看 proposal.md
↓
看 spec.md
↓
看 design.md
↓
最后看代码 Diff

理解成本会明显降低。

八、一个完整实战示例

假设当前正在开发一个 RAG 项目,现在准备新增:

1
删除文档

表面看只是:

1
DELETE /documents/{id}

但实际涉及:

1
2
3
4
5
关系数据库
对象存储
向量数据库
权限
异常一致性

如果直接告诉 AI:

1
增加删除文档功能。

它很容易漏掉其中某一步。

使用 OpenSpec,可以先:

1
/opsx:explore

输入:

1
2
3
4
5
6
7
8
9
10
11
我准备给项目增加文档删除功能。

要求:

1. 用户只能删除自己的文档
2. 删除数据库中的文档记录
3. 删除对象存储中的原始文件
4. 删除向量数据库对应的 Embedding
5. 如果外部资源删除失败,需要避免产生无法追踪的数据不一致

先分析项目现有结构和实现方案,不要修改代码。

AI 分析完成以后:

1
/opsx:propose add-document-delete

然后:

1
openspec/changes/add-document-delete/

可能出现:

1
2
3
4
5
6
proposal.md
design.md
tasks.md
specs/
└── document-delete/
└── spec.md

Spec 可以包含:

1
2
3
4
5
6
7
8
9
10
11
12
## ADDED Requirements

### Requirement: Delete owned document

The system SHALL allow a user to delete a document they own.

#### Scenario: Delete owned document

- **WHEN** the authenticated user deletes a document they own
- **THEN** the database record SHALL be removed
- **THEN** the original stored file SHALL be removed
- **THEN** the associated vector records SHALL be removed

还可以增加权限场景:

1
2
3
4
5
6
7
8
### Requirement: Reject unauthorized deletion

The system SHALL prevent users from deleting documents owned by other users.

#### Scenario: Delete another user's document

- **WHEN** a user attempts to delete a document owned by another user
- **THEN** the system SHALL reject the request

Design 则可以描述:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
先验证 Owner

↓

标记删除状态

↓

删除 Object Storage

↓

删除 Vector Records

↓

删除数据库记录

↓

失败时记录 Cleanup Job

Tasks 则拆成:

1
2
3
4
5
6
7
8
9
10
11
12
13
- [ ] Add ownership validation

- [ ] Add document delete service

- [ ] Remove object storage file

- [ ] Remove vector database entries

- [ ] Add cleanup failure handling

- [ ] Add authorization tests

- [ ] Add integration tests

然后执行:

1
openspec validate add-document-delete

没有问题后:

1
/opsx:apply

让 AI 开始开发。

实现完成后运行:

1
pytest

或者项目自己的:

1
npm test

随后:

1
/opsx:verify

最后:

1
/opsx:archive

这样一次开发完成以后,项目除了得到:

1
删除文档功能代码

还保存了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
为什么增加这个功能

↓

它应该如何表现

↓

使用什么设计

↓

具体开发了哪些任务

↓

最终系统规范是什么

常用命令速查

命令 作用
openspec init 初始化 OpenSpec
openspec update 更新 Agent Workflow
openspec list 查看当前 Changes
openspec list --specs 查看现有 Specs
openspec view 查看 OpenSpec 状态
openspec show <name> 查看某个 Change 或 Spec
openspec validate <name> 验证指定 Change
openspec validate --all 验证全部 OpenSpec 内容
openspec validate --all --strict 严格验证
openspec archive <change> 归档 Change
openspec status 查看状态
openspec schemas 查看 Schema
openspec config 管理配置

AI Agent 中常用的命令:

1
/opsx:explore

分析需求。

1
/opsx:propose

建立 Change。

1
/opsx:update

修改规划。

1
/opsx:apply

正式实现。

1
/opsx:verify

检查代码是否满足规范。

1
/opsx:archive

结束并归档 Change。

如果只想记一套工作流,可以记:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Explore

↓

Propose

↓

Review

↓

Validate

↓

Apply

↓

Test

↓

Verify

↓

Archive

总结

OpenSpec 的作用不在于让 AI 写代码更快,而是:

1
让 AI 更少把代码写错方向。

传统 AI Coding:

1
2
3
Prompt
↓
Code

而 OpenSpec:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Idea
↓
Explore
↓
Proposal
↓
Specification
↓
Design
↓
Tasks
↓
Implementation
↓
Verification
↓
Archive

当 Claude Code、Codex 这种 Agent 越来越强以后,代码生成能力已经不稀缺了,稀缺的是:

1
2
3
4
5
需求边界
系统规范
架构约束
长期上下文
验收标准

如果没有这些东西,AI 越强,甚至可能:

1
越快地把错误方向实现完整。

OpenSpec 做的事情,就是在:

1
人类需求

和:

1
AI 实现

之间建立一层可以长期保存、可以验证的规范。

第一次使用 OpenSpec,其实不用学得太复杂。

安装:

1
npm install -g @fission-ai/openspec@latest

进入项目:

1
cd your-project

初始化:

1
openspec init

然后进入 Claude Code、Codex 或 Cursor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/opsx:explore

↓

/opsx:propose add-your-feature

↓

检查 Proposal / Spec / Design / Tasks

↓

/opsx:apply

↓

/opsx:verify

↓

/opsx:archive

过程中用下面的命令检查规范:

1
openspec validate --all