OPSX 工作流
欢迎在 Discord 上提供反馈。
这是什么?
OPSX 现在是 OpenSpec 的标准工作流。
它是一种流畅、迭代的工作流,用于处理 OpenSpec 的变更。不再有僵化的阶段——只有您可以随时采取的行动。
存在意义
旧版 OpenSpec 工作流虽然可用,但存在封闭性问题:
- 指令硬编码 — 深埋于 TypeScript 中,无法修改
- 全有或全无 — 单条命令创建所有内容,无法单独测试
- 固定结构 — 所有人使用相同工作流,无法自定义
- 黑箱操作 — 当 AI 输出不佳时,无法调整提示词
OPSX 将其开放化。 现在任何人都可以:
- 实验指令 — 编辑模板,观察 AI 是否表现更佳
- 细粒度测试 — 独立验证每个产物的指令
- 自定义工作流 — 定义专属产物及其依赖关系
- 快速迭代 — 修改模板后立即测试,无需重新构建
旧版工作流: OPSX:
┌────────────────────────┐ ┌────────────────────────┐
│ 硬编码于包内 │ │ schema.yaml │◄── 您可编辑此文件
│ (无法修改) │ │ templates/*.md │◄── 或此文件
│ ↓ │ │ ↓ │
│ 等待新版本发布 │ │ 即时生效 │
│ ↓ │ │ ↓ │
│ 祈祷效果更好 │ │ 自行测试验证 │
└────────────────────────┘ └────────────────────────┘适用于所有人:
- 团队 — 创建符合实际工作方式的工作流
- 高级用户 — 调整提示词以获得更佳的代码库 AI 输出
- OpenSpec 贡献者 — 无需发布新版本即可实验新方案
我们都在探索最佳实践。OPSX 让我们共同学习。
用户体验
线性工作流的问题: 您处于"规划阶段",然后进入"实施阶段",最后"完成"。但实际工作并非如此。实施过程中发现设计有误,需要更新规格,再继续实施。线性阶段划分与实际工作方式相冲突。
OPSX 方案:
- 操作而非阶段 — 创建、实施、更新、归档 — 可随时执行任意操作
- 依赖关系是使能器 — 它们展示可能性,而非强制下一步
提案 ──→ 规格 ──→ 设计 ──→ 任务 ──→ 实施安装配置
bash
# 确保已安装 openspec — 技能将自动生成
openspec init此命令会在 .claude/skills/(或等效目录)中创建技能文件,供 AI 编程助手自动检测。
默认情况下,OpenSpec 使用 core 工作流配置(propose、explore、apply、archive)。如需扩展工作流命令(new、continue、ff、verify、sync、bulk-archive、onboard),请通过 openspec config profile 配置,并使用 openspec update 应用。
安装过程中,系统会提示创建项目配置(openspec/config.yaml)。此为可选操作,但推荐设置。
项目配置
项目配置允许您设置默认值,并将项目特定上下文注入所有产物。
创建配置
配置在 openspec init 时创建,或手动创建:
yaml
# openspec/config.yaml
schema: spec-driven
context: |
技术栈:TypeScript、React、Node.js
API 规范:RESTful、JSON 响应
测试:Vitest 用于单元测试,Playwright 用于端到端测试
代码风格:ESLint 配合 Prettier,严格 TypeScript
rules:
proposal:
- 包含回滚计划
- 识别受影响团队
specs:
- 场景使用 Given/When/Then 格式
design:
- 复杂流程包含序列图配置字段
| 字段 | 类型 | 描述 |
|---|---|---|
schema | string | 新变更的默认架构(如 spec-driven) |
context | string | 注入所有产物指令的项目上下文 |
rules | object | 按产物 ID 分组的规则 |
工作原理
架构优先级(从高到低):
- CLI 标志(
--schema <名称>) - 变更元数据(变更目录中的
.openspec.yaml) - 项目配置(
openspec/config.yaml) - 默认值(
spec-driven)
上下文注入:
- 上下文会添加到每个产物指令的开头
- 包裹在
<context>...</context>标签中 - 帮助 AI 理解项目规范
规则注入:
- 仅对匹配的产物注入规则
- 包裹在
<rules>...</rules>标签中 - 位于上下文之后、模板之前
各架构的产物 ID
spec-driven(默认):
proposal— 变更提案specs— 规格说明design— 技术设计tasks— 实施任务
配置验证
rules中未知的产物 ID 会生成警告- 架构名称会根据可用架构进行验证
- 上下文大小限制为 50KB
- 无效 YAML 会报告行号
故障排除
"规则中存在未知产物 ID:X"
- 检查产物 ID 是否匹配您的架构(参见上方列表)
- 运行
openspec schemas --json查看各架构的产物 ID
配置未生效:
- 确保文件位于
openspec/config.yaml(非.yml) - 使用验证器检查 YAML 语法
- 配置更改立即生效(无需重启)
上下文过大:
- 上下文限制为 50KB
- 请进行总结或链接到外部文档
命令
| 命令 | 功能 |
|---|---|
/opsx:propose | 创建变更并一步生成规划产物(默认快速路径) |
/opsx:explore | 构思想法、调研问题、明确需求 |
/opsx:new | 启动新变更框架(扩展工作流) |
/opsx:continue | 创建下一个产物(扩展工作流) |
/opsx:ff | 快速生成规划产物(扩展工作流) |
/opsx:apply | 实施任务,按需更新产物 |
/opsx:verify | 根据产物验证实施效果(扩展工作流) |
/opsx:sync | 将增量规格同步至主分支(扩展工作流,可选) |
/opsx:archive | 完成后归档 |
/opsx:bulk-archive | 批量归档多个已完成变更(扩展工作流) |
/opsx:onboard | 端到端变更引导式演练(扩展工作流) |
使用方法
探索想法
/opsx:explore构思想法、调研问题、比较方案。无需结构化 — 仅作为思考伙伴。当想法成熟时,可转换至 /opsx:propose(默认)或 /opsx:new//opsx:ff(扩展)。
启动新变更
/opsx:propose创建变更并生成实施前所需的规划产物。
如已启用扩展工作流,可改用:
text
/opsx:new # 仅创建框架
/opsx:continue # 逐个创建产物
/opsx:ff # 一次性创建所有规划产物创建产物
/opsx:continue根据依赖关系显示可创建的产物,然后创建一个。重复使用可逐步构建变更。
/opsx:ff add-dark-mode一次性创建所有规划产物。当您对构建内容有清晰构想时使用。
实施(灵活部分)
/opsx:apply处理任务并逐项完成。如需处理多个变更,可运行 /opsx:apply <名称>;否则系统会根据对话推断,无法判断时会提示选择。
完成收尾
/opsx:archive # 完成后移至归档(如需同步规格会提示)何时更新 vs. 全新开始
实施前您始终可以编辑提案或规格。但何时精炼会变成"这是不同的工作"?
提案包含的内容
提案定义三要素:
- 意图 — 您要解决什么问题?
- 范围 — 包含/排除哪些内容?
- 方案 — 如何解决?
关键问题是:哪项发生了变化?变化程度如何?
以下情况更新现有变更:
相同意图,精炼执行
- 发现未考虑的边界情况
- 方案需调整但目标不变
- 实施表明设计略有偏差
范围收窄
- 发现完整范围过大,希望先发布最小可行产品
- "添加深色模式" → "添加深色模式切换(系统偏好设置在 v2 实现)"
学习驱动的修正
- 代码库结构与预期不符
- 依赖项未按预期工作
- "使用 CSS 变量" → "改用 Tailwind 的 dark: 前缀"
以下情况启动新变更:
意图根本改变
- 问题本身已不同
- "添加深色模式" → "添加包含自定义颜色、字体、间距的完整主题系统"
范围爆炸
- 变更增长至本质不同的工作
- 更新后原始提案将面目全非
- "修复登录错误" → "重写认证系统"
原始变更可完成
- 原始变更可标记为"完成"
- 新工作独立存在,非精炼性质
- 完成"添加深色模式 MVP" → 归档 → 新变更"增强深色模式"
启发式方法
┌─────────────────────────────────────┐
│ 这是同一项工作吗? │
└──────────────┬──────────────────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
▼ ▼ ▼
相同意图? >50% 重叠? 原始变更能否
相同问题? 相同范围? 无需这些更改
│ │ 就"完成"?
│ │ │
┌────────┴────────┐ ┌──────┴──────┐ ┌───────┴───────┐
│ │ │ │ │ │
是 否 是 否 否 是
│ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼
更新 新建 更新 新建 更新 新建| 测试项 | 更新 | 新建变更 |
|---|---|---|
| 同一性 | "同一事物,精炼版" | "不同工作" |
| 范围重叠 | >50% 重叠 | <50% 重叠 |
| 完成度 | 无这些更改无法"完成" | 可完成原始工作,新工作独立存在 |
| 叙事性 | 更新链讲述连贯故事 | 修补会比澄清更令人困惑 |
原则
更新保留上下文。新建变更提供清晰度。
当思考历史有价值时选择更新。 当全新开始比修补更清晰时选择新建。
可将其类比为 Git 分支:
- 处理同一功能时持续提交
- 当确实是新工作时创建新分支
- 有时合并部分功能,为第二阶段全新开始
有何不同?
传统方式 (/openspec:proposal) | OPSX (/opsx:*) | |
|---|---|---|
| 结构 | 一个大型提案文档 | 具有依赖关系的离散构件 |
| 工作流 | 线性阶段:计划 → 实施 → 归档 | 流动操作——随时可执行任何任务 |
| 迭代 | 回溯修改较为困难 | 随认知更新而调整构件 |
| 定制化 | 固定结构 | 基于模式驱动(可自定义构件) |
核心洞见: 工作并非线性进行。OPSX 不再假装它是线性的。
架构深入解析
本节解释 OPSX 的底层工作原理,以及它与传统工作流的对比。 本节中的示例使用了扩展命令集(new、continue 等);默认的 core 用户可以将相同的流程映射为 propose → apply → archive。
理念:阶段与动作
┌─────────────────────────────────────────────────────────────────────────────┐
│ 传统工作流 │
│ (阶段锁定,全有或全无) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 规划阶段 │ ───► │ 实施阶段 │ ───► │ 归档阶段 │ │
│ │ │ │ │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ /openspec:proposal /openspec:apply /openspec:archive │
│ │
│ • 一次性创建所有工件 │
│ • 实施期间无法回头更新规范 │
│ • 阶段门控强制线性推进 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ OPSX 工作流 │
│ (流畅动作,迭代式) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ 动作(而非阶段) │ │
│ │ │ │
│ │ new ◄──► continue ◄──► apply ◄──► archive │ │
│ │ │ │ │ │ │ │
│ │ └──────────┴───────────┴───────────┘ │ │
│ │ 任意顺序 │ │
│ └────────────────────────────────────────────┘ │
│ │
│ • 逐个创建工件或快速前进 │
│ • 实施期间可更新规范/设计/任务 │
│ • 依赖关系驱动进度,阶段不存在 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘组件架构
传统工作流使用 TypeScript 中的硬编码模板:
┌─────────────────────────────────────────────────────────────────────────────┐
│ 传统工作流组件 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 硬编码模板 (TypeScript 字符串) │
│ │ │
│ ▼ │
│ 工具特定的配置器/适配器 │
│ │ │
│ ▼ │
│ 生成的命令文件 (.claude/commands/openspec/*.md) │
│ │
│ • 结构固定,无工件感知 │
│ • 更改需要修改代码并重新构建 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘OPSX使用外部模式和依赖图引擎:
┌─────────────────────────────────────────────────────────────────────────────┐
│ OPSX 组件 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 模式定义 (YAML) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ name: spec-driven │ │
│ │ artifacts: │ │
│ │ - id: proposal │ │
│ │ generates: proposal.md │ │
│ │ requires: [] ◄── 依赖关系 │ │
│ │ - id: specs │ │
│ │ generates: specs/**/*.md ◄── Glob 模式 │ │
│ │ requires: [proposal] ◄── 在 proposal 之后启用 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 工件图引擎 │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ • 拓扑排序(依赖排序) │ │
│ │ • 状态检测(文件系统存在性) │ │
│ │ • 丰富的指令生成(模板 + 上下文) │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 技能文件 (.claude/skills/openspec-*/SKILL.md) │
│ │
│ • 跨编辑器兼容 (Claude Code, Cursor, Windsurf) │
│ • 技能通过 CLI 查询结构化数据 │
│ • 通过模式文件完全可定制 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘依赖图模型
工件构成一个有向无环图 (DAG)。依赖关系是启用者,而非门控:
proposal
(根节点)
│
┌─────────────┴─────────────┐
│ │
▼ ▼
specs design
(requires: (requires:
proposal) proposal)
│ │
└─────────────┬─────────────┘
│
▼
tasks
(requires:
specs, design)
│
▼
┌──────────────┐
│ 应用阶段 │
│ (requires: │
│ tasks) │
└──────────────┘状态转换:
阻塞 ────────────────► 就绪 ────────────────► 完成
│ │ │
缺失依赖 所有依赖项 文件存在于
均已完成 文件系统上信息流
传统工作流 — 代理接收静态指令:
用户: "/openspec:proposal"
│
▼
┌─────────────────────────────────────────┐
│ 静态指令: │
│ • 创建 proposal.md │
│ • 创建 tasks.md │
│ • 创建 design.md │
│ • 创建 specs/<capability>/spec.md │
│ │
│ 不感知已存在的内容或 │
│ 工件之间的依赖关系 │
└─────────────────────────────────────────┘
│
▼
代理一次性创建所有工件OPSX — 代理查询丰富上下文:
用户: "/opsx:continue"
│
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ 步骤 1: 查询当前状态 │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ $ openspec status --change "add-auth" --json │ │
│ │ │ │
│ │ { │ │
│ │ "artifacts": [ │ │
│ │ {"id": "proposal", "status": "done"}, │ │
│ │ {"id": "specs", "status": "ready"}, ◄── 首个就绪 │ │
│ │ {"id": "design", "status": "ready"}, │ │
│ │ {"id": "tasks", "status": "blocked", "missingDeps": ["specs"]}│ │
│ │ ] │ │
│ │ } │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│ │
│ 步骤 2: 获取就绪工件的丰富指令 │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ $ openspec instructions specs --change "add-auth" --json │ │
│ │ │ │
│ │ { │ │
│ │ "template": "# Specification\n\n## ADDED Requirements...", │ │
│ │ "dependencies": [{"id": "proposal", "path": "...", "done": true}│ │
│ │ "unlocks": ["tasks"] │ │
│ │ } │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│ │
│ 步骤 3: 读取依赖 → 创建一个工件 → 显示解锁内容 │
└──────────────────────────────────────────────────────────────────────────┘迭代模型
传统工作流 — 迭代不便:
┌─────────┐ ┌─────────┐ ┌─────────┐
│/proposal│ ──► │ /apply │ ──► │/archive │
└─────────┘ └─────────┘ └─────────┘
│ │
│ ├── "等等,设计错了"
│ │
│ ├── 选项:
│ │ • 手动编辑文件(破坏上下文)
│ │ • 放弃并重新开始
│ │ • 强行推进,稍后修复
│ │
│ └── 没有官方的“回退”机制
│
└── 一次性创建所有工件OPSX — 自然迭代:
/opsx:new ───► /opsx:continue ───► /opsx:apply ───► /opsx:archive
│ │ │
│ │ ├── "设计错了"
│ │ │
│ │ ▼
│ │ 直接编辑 design.md
│ │ 然后继续!
│ │ │
│ │ ▼
│ │ /opsx:apply 从上次中断处继续
│ │
│ └── 创建一个工件,显示解锁内容
│
└── 搭建变更框架,等待指示自定义模式
使用模式管理命令创建自定义工作流:
bash
# 从头创建新模式(交互式)
openspec schema init my-workflow
# 或者 fork 一个现有模式作为起点
openspec schema fork spec-driven my-workflow
# 验证你的模式结构
openspec schema validate my-workflow
# 查看模式解析自何处(调试时有用)
openspec schema which my-workflow模式存储在 openspec/schemas/(项目本地,版本控制)或 ~/.local/share/openspec/schemas/(用户全局)。
模式结构:
openspec/schemas/research-first/
├── schema.yaml
└── templates/
├── research.md
├── proposal.md
└── tasks.md示例 schema.yaml:
yaml
name: research-first
artifacts:
- id: research # 在 proposal 之前添加
generates: research.md
requires: []
- id: proposal
generates: proposal.md
requires: [research] # 现在依赖于 research
- id: tasks
generates: tasks.md
requires: [proposal]依赖图:
research ──► proposal ──► tasks总结
| 方面 | 传统 | OPSX |
|---|---|---|
| 模板 | 硬编码 TypeScript | 外部 YAML + Markdown |
| 依赖关系 | 无(一次性全部) | 带拓扑排序的 DAG |
| 状态 | 基于阶段的心智模型 | 文件系统存在性 |
| 定制化 | 编辑源码,重新构建 | 创建 schema.yaml |
| 迭代 | 阶段锁定 | 流畅,可编辑任何内容 |
| 编辑器支持 | 工具特定的配置器/适配器 | 单一技能目录 |
模式
模式定义了存在的工件及其依赖关系。当前可用:
- 规格驱动(默认):提案 → 规格 → 设计 → 任务
bash
# 列出可用模式
openspec schemas
# 查看所有模式及其解析来源
openspec schema which --all
# 交互式创建新模式
openspec schema init my-workflow
# 分叉现有模式以进行自定义
openspec schema fork spec-driven my-workflow
# 使用前验证模式结构
openspec schema validate my-workflow提示
- 使用
/opsx:explore在提交更改前思考一个想法 - 当你知道想要什么时使用
/opsx:ff,探索时使用/opsx:continue - 在
/opsx:apply期间,如果出现问题——修复工件,然后继续 - 任务通过
tasks.md中的复选框跟踪进度 - 随时检查状态:
openspec status --change "name"
反馈
这很粗糙。这是有意的——我们正在学习什么有效。