很多人第一次接触 OpenSpec,会误以为它适合"需求已经很清楚"的项目。其实恰恰相反,它最有价值的场景之一,就是你只有一个模糊目标,却还不知道系统到底该怎么做。
这时候,OpenSpec 不是要求你一开始就写出完美 spec,而是帮你把"模糊问题"一步步压缩成"可验证行为"。
先理解一个误区
很多项目失败,不是因为没人写需求,而是因为一开始就把"想法"当成了"需求",又把"需求"当成了"实现方案"。
比如一句话:"做一个审批系统。"这其实什么都没说清楚。谁发起,谁审批,驳回后怎么办,通知谁,异常怎么处理,全都还是空白。
OpenSpec 的作用,不是替你凭空补完这些细节,而是给你一个结构,让你有地方承认"不确定",并把这些不确定逐步消化掉。
OpenSpec 在这个场景里的角色
如果一句话概括:
- proposal 用来承认你现在知道什么、不知道什么。
- spec 用来定义系统必须如何表现。
- design 用来解释准备如何实现。
- tasks 用来把事情拆成可以执行的步骤。
所以,OpenSpec 不是一份文档,而是一套"从模糊到清晰"的工作流。
最常见的问题
当一个需求刚出现时,很多人会卡在这里:
- 业务目标模糊。
- 用户场景不完整。
- 异常情况没想过。
- 规则边界不明确。
- 技术方案也没谱。
这时如果直接让 AI 写代码,结果往往是"看起来能跑,但和真正要的东西不一致"。
因为 AI 最擅长补全,而你最怕的恰恰是它在你没定义清楚时替你做了错误补全。
所以,第一原则不是"赶紧实现",而是"先把错误自由度压下去"。
Skill 1:先写问题,不急着写答案
当你还不清楚怎么做时,第一步不要写 spec,先写一个最小 proposal。
你可以用下面这个模板:
md
## Why
我们要解决什么问题?
## Goal
这一期最小目标是什么?
## In Scope
这次明确要做什么?
## Out of Scope
这次明确不做什么?
## Open Questions
还有哪些关键问题没想清楚?
比如你收到一个需求:
"做一个请假审批能力。"
不要马上进入实现,先写:
md
## Why
员工请假目前靠线下沟通,流程不可追踪,统计困难。
## Goal
实现最小可用的线上请假审批流程。
## In Scope
员工提交请假申请;
主管审批;
审批结果通知员工。
## Out of Scope
暂不支持转签、加签、抄送、销假。
## Open Questions
超过几天是否需要二级审批?
驳回后是否允许修改重提?
通知方式是站内信还是邮件?
这一步非常关键,因为它把"没想清楚"从脑子里拿到了文档里。
一旦未知被列出来,需求就开始变得可讨论。
Skill 2:不要问"需求够不够细",要问"能不能验证"
很多人写需求时会问:
"这够不够细?"
其实更有用的问题是:
"别人能不能根据这段话判断系统是否做对了?"
这就是 OpenSpec 的核心转折点:从描述想法,转向描述行为。
比如:
不好:
md
系统支持请假审批。
这个说法太空。
你根本无法据此判断系统做得对不对。
更好:
md
### Requirement: Submit Leave Request
系统 SHALL 允许员工提交请假申请。
#### Scenario: 提交成功
- WHEN 员工填写请假日期和原因并提交
- THEN 系统创建一条请假记录
- AND 状态为 PENDING_APPROVAL
为什么这个更好?
因为它已经可以验收了。你可以看结果、测状态、验证流程。
所以,需求细化的本质不是"写得更长",而是"写得更可验证"。
Skill 3:用场景把细节逼出来
如果你不知道还缺什么,不要发呆,直接写场景。
最少先写三类场景:
- 成功场景。
- 失败场景。
- 边界场景。
继续用请假审批举例。
成功场景
md
#### Scenario: 提交成功
- WHEN 员工填写完整信息并提交
- THEN 系统创建请假单
- AND 状态为 PENDING_MANAGER_APPROVAL
失败场景
md
#### Scenario: 缺少原因
- WHEN 员工未填写请假原因就提交
- THEN 系统拒绝提交
- AND 提示原因不能为空
边界场景
md
#### Scenario: 超过三天
- WHEN 员工提交超过 3 天的请假
- THEN 系统在主管同意后进入二级审批
你会发现,一旦你开始写场景,需求细节会自动浮现出来:
- 原因是否必填?
- 3 天是自然日还是工作日?
- 谁是二级审批人?
- 二级审批通过后状态是什么?
- 驳回时是否必须填写理由?
也就是说,细节很多时候不是"凭空想出来"的,而是"在写场景时暴露出来"的。
Skill 4:区分 spec 和 design
这是很多人用 OpenSpec 时最容易混乱的地方。
spec 管什么
spec 管的是:
- 系统行为。
- 业务规则。
- 权限约束。
- 状态变化。
- 验收条件。
例如:
- 超过 3 天需要二级审批。
- 驳回时必须填写原因。
- 审批完成后通知申请人。
这些都应写进 spec。
design 管什么
design 管的是:
- 状态机怎么设计。
- 用几张表。
- 审批链怎么查。
- 通知通过什么机制发送。
- 如何做幂等与补偿。
例如:
- 使用 leave_requests 和 approval_records 两张表。
- 审批流由状态机驱动。
- 通知走异步消息队列。
- 主管关系从组织架构服务实时查询。
这些更适合写到 design。
一句话区分:
- spec:系统应该怎么表现。
- design:系统准备怎么实现。
当你不清楚需求时,先别急着做 design。
因为你连"应该怎么表现"都没定,技术方案很容易提前跑偏。
Skill 5:复杂需求不要写成一个大块
很多需求之所以越写越乱,是因为试图用一份大文档把所有问题一次说完。
OpenSpec 更好的方法是拆分。
还是请假系统,可以拆成这些 Requirement:
- Submit Leave Request
- Manager Approval
- Department Approval
- Rejection Handling
- Notification
每个 Requirement 下再写自己的 Scenario。
这样你不会面对一坨"审批系统需求说明",而是在处理一组可管理的行为单元。
这对 AI 也非常重要。
因为 AI 对局部、明确、结构化的约束响应得更稳定,对大段模糊描述的理解则更容易漂移。
Skill 6:允许"带问号的规范"存在
很多人卡住,是因为总觉得"没想清楚就不能写"。
其实恰恰应该反过来:因为没想清楚,所以更要写。
你可以在 proposal 或 design 里显式保留未决项:
md
## Open Questions
- 请假时长计算按自然日还是工作日?
- 驳回后是否允许修改原单重提?
- 二级审批是否需要按部门配置?
这不是不专业,而是专业。
因为你把风险和认知空洞前置暴露了,而不是把它们留给后续实现阶段爆炸。
Skill 7:从"需求描述"升级到"验收语言"
如果你想让 OpenSpec 真正落地,最关键的一步是:
不要只写"系统要支持什么",而要写"做到什么算完成"。
比如:
普通写法:
md
支持消息通知。
更好的写法:
md
### Requirement: Approval Notification
系统 SHALL 在审批结束后通知申请人。
#### Scenario: 审批通过通知
- WHEN 请假单状态变为 APPROVED
- THEN 系统向申请人发送审批通过通知
#### Scenario: 审批驳回通知
- WHEN 请假单状态变为 REJECTED
- THEN 系统向申请人发送驳回通知
- AND 通知中包含驳回原因
这种写法的价值在于:
- 产品能看懂。
- 开发能实现。
- 测试能验收。
- AI 不容易自由发挥。
这就是 OpenSpec 真正的协作价值。
一个可直接套用的实操流程
当你拿到一个模糊需求时,可以直接按下面这套走。
第一步:写最小 proposal
目标是把模糊问题装进结构里,不追求完整,只追求边界清晰。
模板:
md
## Why
## Goal
## In Scope
## Out of Scope
## Open Questions
第二步:列核心动作
问自己:用户和系统之间最核心的动作有哪些?
例如请假审批:
- 提交申请
- 审批申请
- 驳回申请
- 通知结果
每个动作先单独成一个 Requirement。
第三步:每个动作写 3 个场景
至少写:
- 正常成功。
- 常见失败。
- 一个边界情况。
这是最容易逼出需求细节的步骤。
第四步:把实现细节移到 design
一旦你开始写:
- 数据库结构
- 服务边界
- 状态机
- 消息机制
- 重试与补偿
说明你进入 design 了,不要再混在 spec 里。
第五步:拆任务
把已经明确的内容拆成 tasks:
md
- [ ] 建请假单表
- [ ] 新增提交申请接口
- [ ] 增加主管审批接口
- [ ] 增加驳回原因校验
- [ ] 实现审批完成通知
- [ ] 编写接口测试
这样需求才真正开始可执行。
一个最小完整示例
下面给你一个非常小的完整例子。
proposal.md
md
## Why
员工请假流程目前依赖线下沟通,无法追踪审批状态。
## Goal
上线最小可用的请假审批功能。
## In Scope
员工提交请假;
主管审批;
结果通知。
## Out of Scope
不支持转签、加签、抄送。
## Open Questions
超过几天需要二审?
驳回后是否允许修改后重提?
spec.md
md
### Requirement: Submit Leave Request
系统 SHALL 支持员工提交请假申请。
#### Scenario: 提交成功
- WHEN 员工填写请假日期和原因并提交
- THEN 系统创建请假单
- AND 状态为 PENDING_MANAGER_APPROVAL
#### Scenario: 缺少原因
- WHEN 员工未填写原因提交
- THEN 系统拒绝提交
- AND 返回错误提示
### Requirement: Manager Approval
系统 SHALL 支持直属主管审批请假申请。
#### Scenario: 审批通过
- WHEN 主管批准申请
- THEN 系统将状态更新为 APPROVED
#### Scenario: 审批驳回
- WHEN 主管驳回申请
- THEN 系统将状态更新为 REJECTED
- AND 记录驳回原因
design.md
md
## Data Model
leave_requests
approval_records
## Decisions
审批状态使用状态机管理。
通知采用异步发送。
驳回原因字段为必填。
tasks.md
md
- [ ] 创建请假单表
- [ ] 创建审批记录表
- [ ] 开发提交申请接口
- [ ] 开发主管审批接口
- [ ] 增加驳回原因校验
- [ ] 增加审批结果通知
- [ ] 编写测试
这个例子不复杂,但已经展示出一个重要原则:
你不需要一开始什么都想清楚,才能开始写 OpenSpec。
你可以在写的过程中,把模糊的需求逐层压实。
最后的方法论
如果把这篇文章压缩成一句工作原则,就是:
OpenSpec 不是用来记录"我已经想清楚的需求",而是用来帮助我把"还没想清楚的需求"逐步想清楚。
真正实操时,记住这 4 句话就够了:
- 先写问题,不急着写方案。
- 先写行为,不急着写实现。
- 先写场景,用场景逼出细节。
- 把未知显式列出来,而不是藏在脑子里。
可复制模板
你可以把下面这段直接当作一个 skill 使用。
模糊需求细化模板
md
# 1. Proposal
## Why
要解决什么问题?
## Goal
本期最小目标是什么?
## In Scope
这次确定做什么?
## Out of Scope
这次明确不做什么?
## Open Questions
还有哪些关键问题没想清楚?
# 2. Spec
### Requirement: [核心动作1]
系统 SHALL ...
#### Scenario: 成功
- WHEN ...
- THEN ...
#### Scenario: 失败
- WHEN ...
- THEN ...
#### Scenario: 边界
- WHEN ...
- THEN ...
### Requirement: [核心动作2]
系统 SHALL ...
# 3. Design
## Data Model
## State Machine
## API Design
## Risks
## Decisions
# 4. Tasks
- [ ] ...
- [ ] ...
- [ ] ...
适合放进项目的说明
你也可以把下面这段写进团队规范里:
当需求不清晰时,不直接进入编码。
先用 proposal 明确目标、范围和未决问题;
再用 spec 定义行为和场景;
复杂实现细节进入 design;
最后通过 tasks 驱动实现。