OpenSpec 的 Change 本质上是人类与 AI 之间的契约层——一个结构化的、持久化的、可版本控制的"工作说明书",解决了 AI 编程中最根本的问题:如何让 AI 准确理解并执行人类的意图。
传统 AI 编程:
人类 ──(模糊的聊天)──► AI ──(不可预测的代码)──► 代码库
↑
上下文丢失
意图漂移
无法追溯
OpenSpec 模式:
人类 ──► Change(契约) ──► AI ──► 代码库
│ │
└────── 对齐 ────────┘
传统的软件开发流程强调阶段门控:需求 → 设计 → 开发 → 测试。一旦进入下一阶段,就很难回头。
Change 采用完全不同的理念:依赖是启用器,而非门槛。
传统瀑布模式:
PLANNING ────────► IMPLEMENTING ────────► DONE
│ │
│ "不能回头" │
└────────────────────┘
Change 的流动模式:
proposal ◄──► specs ◄──► design ◄──► tasks ◄──► implement
│ │ │ │ │
└───────────┴──────────┴──────────┴───────────┘
随时可以回溯和修改
这意味着:
Change 承认一个现实:我们对问题的理解会随着工作深入而演进。
# 初始理解
proposal.md: "添加深色模式"
# 实现中发现
design.md: "需要 CSS 变量系统,比预想复杂"
# 继续深入
tasks.md: "拆分为 3 个子任务,先做基础设施"
# 最终交付
archive/: 完整的决策记录,包含演进过程
每个 artifact 都可以随时更新,Change 记录的是思考的演进,而非一次性的规划。
Change 的结构极其简单:
openspec/changes/<name>/
├── proposal.md # 为什么做(1页)
├── specs/ # 做什么(可测试的场景)
├── design.md # 怎么做(技术决策)
└── tasks.md # 具体步骤(可勾选)
没有复杂的元数据、没有强制的格式、没有繁琐的工具链。Markdown 就是全部。
这种简单性带来几个好处:
大多数软件工作不是从零开始,而是修改现有系统。Change 的 Delta Specs 设计专门解决这个问题:
## ADDED Requirements
### Requirement: 双因素认证
...
## MODIFIED Requirements
### Requirement: 会话过期
(原来是 30 分钟,改为 15 分钟)
...
## REMOVED Requirements
### Requirement: 记住我
(已废弃,迁移到新的认证流程)
Delta 表达的是变化,而非全量状态。这让:
/opsx:new add-dark-mode
一个 Change 从一个意图开始。这个意图可能模糊("改善用户体验")或具体("添加深色模式切换"),但它必须存在。
创建 Change 的行为本身就是一种承诺:我们要认真对待这个工作,而不是随便写几行代码。
proposal (为什么)
↓
specs (做什么)
↓
design (怎么做)
↓
tasks (具体步骤)
每个 artifact 都在回答一个问题,每个问题的答案都为下一个问题提供上下文。
关键洞察:这个顺序不是强制的,而是推荐的思考路径。你可以:
/opsx:apply
当 AI 执行 /opsx:apply 时,它不是在"猜测"用户想要什么,而是在执行一份明确的契约:
这种模式让 AI 的行为可预测、可追溯、可验证。
/opsx:archive
归档不是简单的"删除"或"移动",而是知识的沉淀:
归档前:
openspec/
├── specs/auth/spec.md # 当前状态
└── changes/add-2fa/ # 进行中的变更
└── specs/auth/spec.md # Delta
归档后:
openspec/
├── specs/auth/spec.md # 合并后的新状态
└── changes/archive/
└── 2025-01-24-add-2fa/ # 完整的决策记录
├── proposal.md # 为什么做
├── design.md # 怎么做
├── tasks.md # 做了什么
└── specs/ # 改了什么
归档后,你可以回答这些问题:
| 维度 | Git Commit | Change |
|---|---|---|
| 粒度 | 代码变更 | 逻辑变更单元 |
| 内容 | diff | 意图 + 设计 + 需求 + 任务 |
| 时机 | 代码写完后 | 代码写之前 |
| 目的 | 版本控制 | 意图对齐 |
一个 Change 可能对应多个 Git Commit,但它们服务于同一个逻辑目标。
| 维度 | Jira Issue | Change |
|---|---|---|
| 存储 | 外部系统 | 代码仓库内 |
| 内容 | 描述 + 状态 | 完整的实现蓝图 |
| 受众 | 人类团队 | 人类 + AI |
| 版本化 | 独立于代码 | 与代码同源 |
Change 可以看作是 Jira Issue 的"实现规格"——Issue 说"做什么",Change 说"怎么让 AI 正确地做"。
| 维度 | 传统文档 | Change |
|---|---|---|
| 格式 | 自由格式 | 结构化模板 |
| 更新 | 经常过时 | 随代码演进 |
| 粒度 | 通常较大 | 聚焦单一变更 |
| 可执行性 | 人类解读 | AI 可直接执行 |
Change 是可执行的文档——它的结构专门设计为 AI 可以理解和执行。
Change 的 artifact 结构体现了一种分工:
人类主导:
├── proposal.md # 为什么做这个?(战略判断)
└── specs/ # 要达到什么效果?(需求定义)
AI 可以辅助,人类审核:
├── design.md # 技术方案(AI 建议,人类决策)
└── tasks.md # 实现步骤(AI 生成,人类确认)
AI 执行:
└── /opsx:apply # 按照 tasks 写代码
这种分工让人类保持对意图的控制,同时将执行委托给 AI。
传统 AI 编程中,很多假设是隐式的:
Change 强制将这些假设显式化:
## Context (config.yaml)
Tech stack: TypeScript, React, Node.js
Testing: Jest + React Testing Library
## Specs
#### Scenario: 无效输入
- WHEN 用户输入空字符串
- THEN 显示错误提示"请输入有效内容"
显式化带来的好处:
Change 鼓励小的、聚焦的变更:
不好的做法:
changes/
└── big-refactor-and-new-features/ # 范围太大,难以管理
好的做法:
changes/
├── refactor-auth-module/ # 聚焦:重构认证
├── add-2fa/ # 聚焦:添加双因素
└── improve-login-ux/ # 聚焦:改善登录体验
小的 Change 更容易:
Change 不仅仅是达到目标的手段,Change 本身就是有价值的产出:
当 Change 归档后,这些 artifact 成为项目的知识资产,帮助未来的开发者(人类或 AI)理解系统是如何演进到当前状态的。
应该创建:
不需要创建:
问自己这些问题:
如果答案是"否",考虑拆分。
| 情况 | 操作 |
|---|---|
| 同样的意图,细化执行 | 更新现有 Change |
| 范围缩小(先做 MVP) | 更新,完成后归档,再新建 |
| 意图根本改变 | 新建 Change |
| 范围爆炸 | 归档已完成部分,新建 |
Change 的设计哲学可以归结为一句话:
让 AI 编程从"对话"变成"契约",从"猜测"变成"执行",从"一次性"变成"可追溯"。
它不是要增加流程的负担,而是要降低 AI 编程的不确定性。通过一个轻量级的结构化层,让人类和 AI 在"做什么"上达成一致,然后让 AI 专注于"怎么做"。
这就是 Change 的本质:人机协作的契约,知识沉淀的载体,可预测 AI 编程的基础。