先问各位一句:用AI写代码时,最担心什么?不是AI写不好代码,而是它最终生成的内容与你期望的结果完全不符。
问题的根源在哪里?需求仅仅停留在聊天记录里。AI只知道你输入了什么,但并不理解你真正关注的重点。它依据一两句话揣测你的意图,最后得出的结果总是与你的预期存在差距。
OpenSpec正是为解决这一痛点而诞生。
介绍
Spec-driven development——一种专为AI编程助手量身打造的规范驱动开发框架。顾名思义,OpenSpec的核心主张是:在编写任何代码之前,先让“人”与“AI”共同确认一份清晰的规范说明(spec),然后严格按照这份规范来驱动实现。这相当于在你和AI之间构建了一层轻量级的规范层,双方协作的起点不再是零散的聊天记录,而是一份共享的、结构化的、可追溯的规范文档。
这个框架的理念非常务实——它拒绝僵化,倡导灵活;它不是瀑布式流程,而是持续迭代;它追求轻量而非复杂;并且它专门为已有项目设计,并非只适用于新项目。
OpenSpec 的本质定位
AI编程助手功能强大,但当需求只存在于聊天记录中时,一切都会变得难以预测。OpenSpec在中间增加了这一层规范,从根本上确保了“先对齐要构建什么”这一前提。
核心流程简洁明了:
/opsx:new
→ /opsx:ff(生成 proposal + specs + design + tasks)
→ /opsx:apply(实现)
→ /opsx:archive
其中 /opsx:ff 这一步,会一次性生成四类文档:
proposal.md——说明做什么、为什么做specs/——明确需求与场景(需求侧最核心的产出)design.md——描绘技术方案tasks.md——列出实现清单
需求侧的应用方式
OpenSpec 可以作为连接需求与开发之间的桥梁,而不仅仅是开发者的规划工具。这里有四种实际可行的方法。
一、需求评审前,使用 /opsx:new 起草 proposal
产品或技术负责人可以在需求评审之前,直接使用 /opsx:new 创建一个变更目录,然后手动编写(或让AI辅助生成)proposal.md,把为什么做、做什么、以及范围界定清楚。这份文档可以直接用作评审材料——它比传统PRD结构更清晰,最关键的是,后续它可以直接被AI用作实现的依据。
二、specs/ 目录承载业务验收标准
/opsx:ff 生成的 specs/ 目录专门用于存放 Given-When-Then 格式的场景描述。需求侧人员——包括产品和测试——可以在这里直接添加或修改验收条件。开发者拿到的不是模糊的需求文档,而是可执行的场景:像 Claude Code 或 Cursor 这类工具可以参照这些场景直接生成测试用例。
三、特别适合 brownfield 场景
OpenSpec 是为 brownfield(已有项目)构建的,并非仅考虑新项目。对于存量功能的改造——例如重构 TradeStateMachine、升级订单状态流转逻辑——这类需求,使用 /opsx:new refactor-trade-state-machine 生成规范之后,新旧行为之间的差异可以在 specs/ 中明确描述出来,避免AI在修改时产生意外的后果。
四、团队协作场景:将 spec 作为沟通媒介
每一个变更都拥有独立的目录,包含 proposal、specs、design 和 tasks。这个目录可以直接提交到 Git 仓库中,前端、后端、测试、产品都能在同一份规范上开展评审和修改。需求的“契约”不再只停留在会议沟通中,而是与代码一同存在于仓库里。
一个具体的落地建议
OpenSpec 可以作为从“需求侧到实现侧”全面打通的典型案例。完整的链路如下:
需求评审(产品)
↓
/opsx:new feature-name(创建 spec 目录)
↓
/opsx:ff(AI 生成 proposal + specs + design + tasks)
↓
需求侧 review specs/(产品 + 测试确认场景)
↓
/opsx:apply(Claude Code 按 spec 实现)
↓
测试按 specs/ 验收
↓
/opsx:archive
在这个链路中,/opsx:ff 之后、/opsx:apply 之前的评审阶段,正是需求侧介入的最佳时机。
需求驱动
一个经典的失控场景
想象一下这个画面:你正在对交易平台的订单状态进行重构。你打开 Claude Code,输入了一条指令:
帮我重构一下订单状态流转逻辑,现在状态太乱了
AI 开始工作。十分钟后,它修改了 TradeStateMachine,顺手调整了 OrderServiceImpl,还把相关的枚举类重命名了。
乍看方向似乎大致正确,但细节上已经完全失去控制——状态流转的边界条件根本没有覆盖你确认过的那个“买家超时未确认”场景;重命名还破坏了另一个服务中对该枚举类的引用;而你原本最想要的那个“状态变更日志”功能,完全不在输出结果中。
问题出在哪里?需求只活在聊天记录里。AI 根本没有能力知道你真正在意的边界条件是什么,它只能凭那一句话去猜测。
核心工作流:以订单状态重构为例
不妨用真实场景来走一遍完整流程。
第一步:创建变更
/opsx:new refactor-trade-state-machine
Claude Code 会在 openspec/changes/refactor-trade-state-machine/ 下创建这个目录结构:
openspec/changes/refactor-trade-state-machine/
├── proposal.md ← 为什么做这件事
├── design.md ← 技术方案
├── tasks.md ← 实现任务清单
└── specs/ ← 需求场景(最重要)
└── trade-order/
└── spec.md
第二步:快进生成所有规划文档
/opsx:ff
这一条命令会让 Claude Code 读取你现有的代码,然后一气呵成生成四份文档。它会扫描 TradeStateMachine.java、OrderServiceImpl.java、相关的枚举和 DTO,理解当前系统状态,再根据变更名称推断意图。
生成的 specs/trade-order/spec.md 大概长这样:
# trade-order Specification
## Purpose
管理游戏账号交易订单的完整生命周期,包括状态流转、超时处理和异常回滚。
## Requirements
### Requirement: 状态流转完整性
系统 SHALL 保证订单状态只能按照预定路径流转。
#### Scenario: 买家超时未确认
- GIVEN 订单处于"待买家确认"状态
- WHEN 超过 48 小时买家未操作
- THEN 系统自动将订单标记为"超时关闭"
- AND 触发退款流程
- AND 发送 RocketMQ 消息通知卖家
#### Scenario: 支付成功后的状态推进
- GIVEN 买家已完成支付
- WHEN 收到支付回调
- THEN 订单状态从"待支付"变更为"交易中"
- AND 记录状态变更日志到 trade_state_log 表
在 /opsx:apply 正式执行之前,你、产品、测试都可以直接评审这份 spec.md。请注意,这里使用的是业务语言,而不是代码。产品可以补充遗漏的场景,测试可以把验收条件直接追加进去,技术负责人可以确认边界条件。
这份文件一旦提交到 Git,就成了一份可追溯的需求契约。
第三步:review 并修改 spec
直接编辑 specs/trade-order/spec.md,把你真正在意的场景补充进去:
#### Scenario: 状态变更审计日志
- GIVEN 任意订单状态发生变更
- WHEN 状态流转执行
- THEN 向 trade_state_log 表写入一条记录
- AND 记录字段包含:操作人、原状态、新状态、时间戳、触发原因
这个补充动作不需要任何工具,就是编写 Markdown。但它在下一步会直接影响 Claude Code 的实现行为。
第四步:按 spec 实现
/opsx:apply
Claude Code 读取 specs/ 里的所有场景,逐条执行 tasks.md 里的任务。每个任务完成后打勾,实现进度一目了然。
因为 spec 里已经明确写了“记录 trade_state_log”,Claude Code 会自动生成对应的实体类、Mapper、以及在状态流转节点插入日志的代码——而不再像之前那样只改了状态机就结束。
第五步:归档
/opsx:archive
变更目录移入 openspec/changes/archive/,同时 openspec/specs/trade-order/spec.md 被更新为最新的系统状态描述。这就是持久化的上下文:spec 和代码共同存在于仓库中,不会因为聊天窗口关闭而消失。
长期价值
随着功能持续迭代,openspec/specs/ 会逐渐积累成这样的结构:
openspec/specs/
├── trade-order/ ← 订单状态与生命周期
├── account-publish/ ← 账号发布审核流程
├── payment-callback/ ← 支付回调处理
├── recommend-feed/ ← 推荐流逻辑
└── user-auth/ ← 登录与权限
新人加入团队,阅读这个目录比阅读代码要快得多——这里写的是系统“应该做什么”,而不是“当前是怎么实现的”。
下一次做相关功能时,Claude Code 启动就会读取已有的 spec,理解系统约束,不会提出与现有逻辑冲突的方案。
与 CLAUDE.md 的协同
OpenSpec 和 CLAUDE.md 是互补的:
- CLAUDE.md 定义的是项目级的永久约束:技术栈、代码规范、禁止行为
- OpenSpec specs/ 定义的是功能级的业务契约:每个能力应该做什么
在 CLAUDE.md 里加一行引用,就能让每次对话都感知到 spec:
## 业务规范
项目的功能规范定义在 openspec/specs/ 目录下。在实现任何涉及订单、账号、支付的功能前,先读取对应的 spec.md 文件。
这样即使不用 /opsx: 命令,Claude Code 在日常对话里也会主动去参考 spec 的约束。
给团队的建议
需求侧介入的最佳节点只有一处:/opsx:ff 之后、/opsx:apply 之前。
整个需求到实现的链路可以这样分工:
开发使用 /opsx:new 和 /opsx:ff 生成 spec 草稿,产品在 specs/ 里确认业务场景并补充遗漏的边界条件,测试把验收标准直接写成 Given-When-Then 格式追加进去,然后提交 PR 评审这份 spec——通过之后才执行 /opsx:apply。
这个流程的核心变化是:需求评审的对象从 PRD 文档变成了 spec 文件,而 spec 文件直接就是 AI 的执行上下文。中间没有“翻译”环节,需求损耗降到最低。
需求生成
OpenSpec 官方 FAQ 明确回应过:他们正在探索从现有代码库生成 spec 的能力,但核心观点是——“试图一次性预先生成所有 spec 是浪费时间,应该按需创建并逐步积累”。
这不是回避问题,而是基于真实工程项目的判断。对于一个代码量在一两万行左右的 brownfield 项目,一次性逆向得出完整的 spec 会产生大量噪音,你根本不可能评审完,更不用说信任它的准确性。
但这不等于“不能从代码生成”,只是方法不同。目前有三条路可走。
/opsx:onboard(官方推荐入口)
对于已有项目,/opsx:onboard 命令会从你现有的代码库生成初始 spec,让 AI 从第一天起就能参考项目上下文。
这是官方专门为 brownfield 场景设计的入口。它会扫描现有代码、理解项目结构,然后为核心能力生成初始 openspec/specs/ 文件。不是全量逆向,而是生成一个“够用的起点”。
在你的交易平台上执行这条命令,Claude Code 会读取 TradeStateMachine、GameAccountServiceImpl、支付回调相关代码,为每个主要能力域生成一份 spec 草稿,你再进行评审和修正。
需要知道的是,/opsx:onboard 被归入了“expanded workflow”。默认安装的 core profile 只包含四条命令:propose、explore、apply、archive。要使用 onboard,需要手动切换 profile 并更新。
具体操作:
openspec config profile
# 选择 expanded(包含 onboard)
openspec update
# 把新命令写入项目
之后 /opsx:onboard 就可以用了。
onboard 现在的实际功能
它是“引导式 onboarding”。流程是:扫描代码库找出改进机会,让你选一个小功能,走一遍完整的 propose → apply → archive 流程,大约需要 15 分钟。
注意这里需要纠正一个认知偏差:之前讨论的“从代码生成 spec 基线”,/opsx:onboard 实际上做的并不是这件事——它的核心目的是教新用户如何使用 OpenSpec,顺便扫描一次代码库找个练手素材,而不是系统性地逆向生成 openspec/specs/ 目录。
那 brownfield 冷启动怎么办:手动引导
官方的建议很务实:一次性预先生成所有 spec 是浪费时间,应该按需创建、边建边积累。
所以针对你的平台,最实际的策略还是那条路——直接对 Claude Code 下指令,按模块逐个生成:
请读取 src/trade/ 目录的代码,按照 openspec/specs//spec.md 的格式,
为订单状态管理这个能力域生成一份 spec,要求:
- 用 Given-When-Then 格式描述每个业务场景
- 只描述当前代码实际实现的行为,不要发明需求
- 按 Requirement → Scenario 层级组织
- 输出到 openspec/specs/trade-order/spec.md
一次只处理一个模块,半天能建起基线。这比运行一个工具然后评审几百行自动生成的内容要可控得多。
这种方式的好处很明显:你可以完全掌控颗粒度(一次只做一个模块),可以在 prompt 里注入业务语言约束,生成结果可以立即评审。
对于 Spring Boot 项目来说,按服务边界逐个进行即可:先 trade-order,再 account-publish,再 payment-callback,每次生成后评审确认,整个过程大约半天能建立起有效的 spec 基线。
spec-gen(社区工具,专门做逆向)
社区里有人专门构建了一个叫 spec-gen 的开源 CLI 工具,通过静态分析结合 LLM 从现有代码库逆向工程出 OpenSpec 兼容的 spec。
它的三步流程是:
spec-gen init(检测项目类型、创建配置)spec-gen analyze(静态分析,不需要 API Key)spec-gen generate(生成 OpenSpec 格式的 spec)
