OPSX 工作流
欢迎在 Discord 上提供反馈。
简介
OPSX 现已成为 OpenSpec 的标准工作流。
它是一种灵活、迭代的工作流,用于 OpenSpec 变更。不再有僵化的阶段划分——你可以随时执行任何操作。
为什么需要它
传统的 OpenSpec 工作流虽然可用,但它被锁死了:
- 指令是硬编码的 — 埋在 TypeScript 中,你无法修改
- 全有或全无 — 一条大命令创建所有内容,无法单独测试各个部分
- 固定结构 — 所有人使用相同的工作流,无法自定义
- 黑盒 — 当 AI 输出质量不佳时,你无法调整提示词
OPSX 打开了它。 现在任何人都可以:
- 实验指令 — 编辑模板,看看 AI 是否能做得更好
- 细粒度测试 — 独立验证每个产物的指令
- 自定义工作流 — 定义你自己的产物和依赖关系
- 快速迭代 — 修改模板,立即测试,无需重新构建
传统工作流: OPSX:
┌────────────────────────┐ ┌────────────────────────┐
│ 硬编码在包中 │ │ schema.yaml │◄── 你编辑这个
│ (无法修改) │ │ templates/*.md │◄── 或者这个
│ ↓ │ │ ↓ │
│ 等待新版本发布 │ │ 即时生效 │
│ ↓ │ │ ↓ │
│ 希望它更好 │ │ 自己测试 │
└────────────────────────┘ └────────────────────────┘这适用于所有人:
- 团队 — 创建与实际工作方式相匹配的工作流
- 高级用户 — 调整提示词以获得更适合你代码库的 AI 输出
- OpenSpec 贡献者 — 无需发布即可实验新方法
我们所有人仍在探索什么效果最好。OPSX 让我们一起学习。
用户体验
线性工作流的问题: 你处于"规划阶段",然后"实施阶段",然后"完成"。但实际工作并非如此。你实施了一些东西,发现设计有误,需要更新规格,继续实施。线性阶段与实际工作方式相悖。
OPSX 方法:
- 操作而非阶段 — 创建、实施、更新、归档 — 随时执行任何操作
- 依赖关系是使能器 — 它们展示什么可行,而非下一步必须做什么
proposal ──→ specs ──→ design ──→ tasks ──→ implement设置
# 确保已安装 openspec — skills 会自动生成
openspec init这会在 .claude/skills/(或等效目录)中创建 skills,AI 编码助手会自动检测。
默认情况下,OpenSpec 使用 core 工作流配置(propose、explore、apply、update、sync、archive)。如果你需要扩展的工作流命令(new、continue、ff、verify、bulk-archive、onboard),请使用 openspec config profile 进行配置,并通过 openspec update 应用。
在设置过程中,系统会提示你创建项目配置(openspec/config.yaml)。这是可选的,但推荐创建。
项目配置
项目配置允许你设置默认值,并将项目特定的上下文注入到所有产物中。
创建配置
配置在 openspec init 期间创建,也可以手动创建:
# openspec/config.yaml
schema: spec-driven
context: |
Tech stack: TypeScript, React, Node.js
API conventions: RESTful, JSON responses
Testing: Vitest for unit tests, Playwright for e2e
Style: ESLint with Prettier, strict TypeScript
rules:
proposal:
- Include rollback plan
- Identify affected teams
specs:
- Use Given/When/Then format for scenarios
design:
- Include sequence diagrams for complex flows配置字段
| 字段 | 类型 | 描述 |
|---|---|---|
schema | string | 新变更的默认 schema(例如 spec-driven) |
context | string | 注入到所有产物指令中的项目上下文 |
rules | object | 按产物 ID 索引的每个产物的规则 |
工作原理
Schema 优先级(从高到低):
- CLI 标志(
--schema <name>) - 变更元数据(变更目录中的
.openspec.yaml) - 项目配置(
openspec/config.yaml) - 默认值(
spec-driven)
上下文注入:
- 上下文会添加到每个产物指令的开头
- 包裹在
<context>...</context>标签中 - 帮助 AI 理解你项目的约定
规则注入:
- 规则仅注入到匹配的产物中
- 包裹在
<rules>...</rules>标签中 - 出现在上下文之后、模板之前
各 Schema 的产物 ID
spec-driven(默认):
proposal— 变更提案specs— 规格说明design— 技术设计tasks— 实施任务
配置验证
rules中未知的产物 ID 会生成警告- Schema 名称会与可用 schema 进行验证
- 上下文有 50KB 大小限制
- 无效的 YAML 会报告行号
故障排除
"rules 中未知的产物 ID: X"
- 检查产物 ID 是否与你的 schema 匹配(参见上方列表)
- 运行
openspec schemas --json查看每个 schema 的产物 ID
配置未生效:
- 确保文件位于
openspec/config.yaml(不是.yml) - 使用验证工具检查 YAML 语法
- 配置更改即时生效(无需重启)
上下文过大:
- 上下文限制为 50KB
- 请摘要或链接到外部文档
命令
| 命令 | 功能 |
|---|---|
/opsx:propose | 一步创建变更并生成规划产物(默认快速路径) |
/opsx:explore | 思考想法、调查问题、澄清需求 |
/opsx:new | 开始新的变更脚手架(扩展工作流) |
/opsx:continue | 创建下一个产物(扩展工作流) |
/opsx:ff | 快进规划产物(扩展工作流) |
/opsx:apply | 实施任务,按需更新产物 |
/opsx:update | 修订变更的规划产物并保持其一致性 |
/opsx:verify | 根据产物验证实施(扩展工作流) |
/opsx:sync | 将增量规格合并到主规格中(可选) |
/opsx:archive | 完成后归档 |
/opsx:bulk-archive | 归档多个已完成的变更(扩展工作流) |
/opsx:onboard | 端到端变更的引导式演练(扩展工作流) |
使用
探索想法
/opsx:explore思考想法、调查问题、比较方案。无需结构 — 只是一个思考伙伴。当洞察逐渐清晰时,可以转向 /opsx:propose(默认)或 /opsx:new//opsx:ff(扩展)。
开始新变更
/opsx:propose创建变更并生成实施前所需的规划产物。
如果你已启用扩展工作流,也可以改用:
/opsx:new # 仅创建脚手架
/opsx:continue # 一次创建一个产物
/opsx:ff # 一次性创建所有规划产物创建产物
/opsx:continue根据依赖关系显示哪些可以创建,然后创建一个产物。重复使用以逐步构建你的变更。
/opsx:ff add-dark-mode一次性创建所有规划产物。适用于你对要构建的内容已有清晰认识时。
实施(灵活的部分)
/opsx:apply逐步处理任务,完成时勾选。如果你同时在处理多个变更,可以运行 /opsx:apply <name>;否则它应该从对话中推断,如果无法判断则会提示你选择。
更新变更
/opsx:update add-dark-mode - we're storing the theme in a cookie now修订变更的现有规划产物并保持其一致性 — 任何方向都可以(设计编辑可能会回溯影响提案)。仅限规划产物:它从不编辑代码,也从不创建缺失的产物(那是 /opsx:continue 的工作)。每次编辑都会先与你确认。如果变更已经实施,它会建议使用 /opsx:apply 让代码跟上修订后的计划。如果你的修订改变了变更的意图,请重新开始 — 参见何时更新 vs. 重新开始。
同步增量规格
/opsx:sync将当前变更的增量规格合并到主 openspec/specs/ 中而不归档 — 变更保持活跃状态。它会应用整个增量:## REMOVED 下的需求会从主规格中删除,重命名的需求会在原地重新命名,而增量未提及的内容保持不变。同步是可选的 — 如果你还没有同步,归档时会提示你先同步。当你想在归档前更新主规格、当并行变更需要基于此变更刚添加的规格构建、或者当你想在归档前审查合并后的主规格时,请使用它。
收尾
/opsx:archive # 完成后移至归档(如有需要会提示同步规格)何时更新 vs. 重新开始
你总是可以在实施前编辑提案或规格。但什么时候"完善"变成了"这是不同的工作"?
提案捕获的内容
提案定义了三个要素:
- 意图 — 你在解决什么问题?
- 范围 — 什么在范围内/范围外?
- 方法 — 你将如何解决?
问题是:哪个变了,变了多少?
以下情况更新现有变更:
意图相同,执行方式优化
- 你发现了之前未考虑的边界情况
- 方法需要微调但目标不变
- 实施中发现设计略有偏差
范围缩小
- 你意识到完整范围太大,想先发布 MVP
- "添加暗色模式" → "添加暗色模式切换(系统偏好设置放到 v2)"
学习驱动的修正
- 代码库结构与你想象的不同
- 某个依赖项表现不符合预期
- "使用 CSS 变量" → "改用 Tailwind 的 dark: 前缀"
以下情况开始新变更:
意图根本改变
- 问题本身已经不同了
- "添加暗色模式" → "添加包含自定义颜色、字体、间距的综合主题系统"
范围爆炸
- 变更增长到本质上已是不同的工作
- 原始提案在更新后将无法辨认
- "修复登录 bug" → "重写认证系统"
原始变更可以完成
- 原始变更可以标记为"完成"
- 新工作独立存在,不是完善
- 完成"添加暗色模式 MVP" → 归档 → 新变更"增强暗色模式"
判断标准
┌─────────────────────────────────────┐
│ 这是同一项工作吗? │
└──────────────┬──────────────────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
▼ ▼ ▼
意图相同? >50% 重叠? 原始变更能否
问题相同? 范围相同? 在没有这些变更
│ │ 的情况下"完成"?
│ │ │
┌────────┴────────┐ ┌──────┴──────┐ ┌───────┴───────┐
│ │ │ │ │ │
是 否 是 否 否 是
│ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼
更新 新建 更新 新建 更新 新建| 测试 | 更新 | 新变更 |
|---|---|---|
| 身份 | "同一件事,优化了" | "不同的工作" |
| 范围重叠 | >50% 重叠 | <50% 重叠 |
| 完成度 | 没有这些变更无法"完成" | 可以完成原始变更,新工作独立存在 |
| 叙事 | 更新链讲述连贯的故事 | 补丁会比澄清带来更多困惑 |
原则
更新保留上下文。新变更提供清晰度。
当你思考的历史有价值时,选择更新。 当重新开始比打补丁更清晰时,选择新建。
可以把它想象成 git 分支:
- 在同一功能上工作时继续提交
- 当确实是新工作时开始新分支
- 有时合并部分功能,然后为第二阶段重新开始
有何不同?
旧版(/openspec:proposal) | OPSX(/opsx:*) | |
|---|---|---|
| 结构 | 一份大型提案文档 | 具有依赖关系的独立工件 |
| 工作流 | 线性阶段:规划 → 实现 → 归档 | 灵活操作 — 随时执行任何操作 |
| 迭代 | 难以回退 | 随着学习不断更新工件 |
| 自定义 | 固定结构 | 模式驱动(自定义工件) |
核心洞察: 工作并非线性的。OPSX 不再假装它是线性的。
架构深度解析
本节介绍 OPSX 的内部工作原理,以及它与传统工作流的对比。本节中的示例使用扩展命令集(new、continue 等);默认的 core 用户可以将相同流程映射到 propose → apply → sync → archive。
理念:阶段与动作
┌─────────────────────────────────────────────────────────────────────────────┐
│ LEGACY WORKFLOW │
│ (Phase-Locked, All-or-Nothing) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ PLANNING │ ───► │ IMPLEMENTING │ ───► │ ARCHIVING │ │
│ │ PHASE │ │ PHASE │ │ PHASE │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ /openspec:proposal /openspec:apply /openspec:archive │
│ │
│ • Creates ALL artifacts at once │
│ • Can't go back to update specs during implementation │
│ • Phase gates enforce linear progression │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ OPSX WORKFLOW │
│ (Fluid Actions, Iterative) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ ACTIONS (not phases) │ │
│ │ │ │
│ │ new ◄──► continue ◄──► apply ◄──► archive │ │
│ │ │ │ │ │ │ │
│ │ └──────────┴───────────┴───────────┘ │ │
│ │ any order │ │
│ └────────────────────────────────────────────┘ │
│ │
│ • Create artifacts one at a time OR fast-forward │
│ • Update specs/design/tasks during implementation │
│ • Dependencies enable progress, phases don't exist │
│ │
└─────────────────────────────────────────────────────────────────────────────┘组件架构
传统工作流 使用 TypeScript 中硬编码的模板:
┌─────────────────────────────────────────────────────────────────────────────┐
│ LEGACY WORKFLOW COMPONENTS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Hardcoded Templates (TypeScript strings) │
│ │ │
│ ▼ │
│ Tool-specific configurators/adapters │
│ │ │
│ ▼ │
│ Generated Command Files (.claude/commands/openspec/*.md) │
│ │
│ • Fixed structure, no artifact awareness │
│ • Change requires code modification + rebuild │
│ │
└─────────────────────────────────────────────────────────────────────────────┘OPSX 使用外部模式和依赖图引擎:
┌─────────────────────────────────────────────────────────────────────────────┐
│ OPSX COMPONENTS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Schema Definitions (YAML) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ name: spec-driven │ │
│ │ artifacts: │ │
│ │ - id: proposal │ │
│ │ generates: proposal.md │ │
│ │ requires: [] ◄── Dependencies │ │
│ │ - id: specs │ │
│ │ generates: specs/**/*.md ◄── Glob patterns │ │
│ │ requires: [proposal] ◄── Enables after proposal │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ Artifact Graph Engine │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ • Topological sort (dependency ordering) │ │
│ │ • State detection (filesystem existence) │ │
│ │ • Rich instruction generation (templates + context) │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ Skill Files (.claude/skills/openspec-*/SKILL.md) │
│ │
│ • Cross-editor compatible (Claude Code, Cursor, Devin) │
│ • Skills query CLI for structured data │
│ • Fully customizable via schema files │
│ │
└─────────────────────────────────────────────────────────────────────────────┘依赖图模型
工件形成有向无环图(DAG)。依赖是使能器,而非门禁:
proposal
(root node)
│
┌─────────────┴─────────────┐
│ │
▼ ▼
specs design
(requires: (requires:
proposal) proposal)
│ │
└─────────────┬─────────────┘
│
▼
tasks
(requires:
specs, design)
│
▼
┌──────────────┐
│ APPLY PHASE │
│ (requires: │
│ tasks) │
└──────────────┘状态转换:
BLOCKED ────────────────► READY ────────────────► DONE
│ │ │
Missing All deps File exists
dependencies are DONE on filesystem信息流
传统工作流 — 智能体接收静态指令:
User: "/openspec:proposal"
│
▼
┌─────────────────────────────────────────┐
│ Static instructions: │
│ • Create proposal.md │
│ • Create tasks.md │
│ • Create design.md │
│ • Create delta spec files │
│ │
│ No awareness of what exists or │
│ dependencies between artifacts │
└─────────────────────────────────────────┘
│
▼
Agent creates ALL artifacts in one goOPSX — 智能体查询丰富上下文:
User: "/opsx:continue"
│
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ Step 1: Query current state │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ $ openspec status --change "add-auth" --json │ │
│ │ │ │
│ │ { │ │
│ │ "artifacts": [ │ │
│ │ {"id": "proposal", "status": "done"}, │ │
│ │ {"id": "specs", "status": "ready"}, ◄── First ready │ │
│ │ {"id": "design", "status": "ready"}, │ │
│ │ {"id": "tasks", "status": "blocked", │ │
│ │ "missingDeps": ["specs", "design"]} │ │
│ │ ] │ │
│ │ } │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│ │
│ Step 2: Get rich instructions for ready artifact │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ $ openspec instructions specs --change "add-auth" --json │ │
│ │ │ │
│ │ { │ │
│ │ "template": "# Specification\n\n## ADDED Requirements...", │ │
│ │ "dependencies": [{"id": "proposal", "path": "...", "done": true}│ │
│ │ "unlocks": ["tasks"] │ │
│ │ } │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│ │
│ Step 3: Read dependencies → Create ONE artifact → Show what's unlocked │
└──────────────────────────────────────────────────────────────────────────┘迭代模型
传统工作流 — 迭代不便:
┌─────────┐ ┌─────────┐ ┌─────────┐
│/proposal│ ──► │ /apply │ ──► │/archive │
└─────────┘ └─────────┘ └─────────┘
│ │
│ ├── "Wait, the design is wrong"
│ │
│ ├── Options:
│ │ • Edit files manually (breaks context)
│ │ • Abandon and start over
│ │ • Push through and fix later
│ │
│ └── No official "go back" mechanism
│
└── Creates ALL artifacts at onceOPSX — 自然迭代:
/opsx:new ───► /opsx:continue ───► /opsx:apply ───► /opsx:archive
│ │ │
│ │ ├── "The design is wrong"
│ │ │
│ │ ▼
│ │ Just edit design.md
│ │ and continue!
│ │ │
│ │ ▼
│ │ /opsx:apply picks up
│ │ where you left off
│ │
│ └── Creates ONE artifact, shows what's unlocked
│
└── Scaffolds change, waits for direction自定义模式
使用模式管理命令创建自定义工作流:
# Create a new schema from scratch (interactive)
openspec schema init my-workflow
# Or fork an existing schema as a starting point
openspec schema fork spec-driven my-workflow
# Validate your schema structure
openspec schema validate my-workflow
# See where a schema resolves from (useful for debugging)
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:
name: research-first
artifacts:
- id: research # Added before proposal
generates: research.md
requires: []
- id: proposal
generates: proposal.md
requires: [research] # Now depends on research
- id: tasks
generates: tasks.md
requires: [proposal]依赖图:
research ──► proposal ──► tasks总结
| 方面 | Legacy | OPSX |
|---|---|---|
| 模板 | 硬编码 TypeScript | 外部 YAML + Markdown |
| 依赖 | 无(一次性) | 带拓扑排序的 DAG |
| 状态 | 基于阶段的思维模型 | 文件系统存在性 |
| 自定义 | 修改源代码并重建 | 创建 schema.yaml |
| 迭代 | 阶段锁定 | 灵活,可编辑任何内容 |
| 编辑器支持 | 工具专用配置器/适配器 | 单一技能目录 |
模式 (Schemas)
模式定义了存在的工件及其依赖关系。当前可用的模式:
- spec-driven(默认):提案 → 规范 → 设计 → 任务
# 列出可用模式
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"
反馈
目前还比较粗糙。这是有意为之——我们正在学习哪些方法有效。