规范驱动开发框架
是一个规范驱动的开发框架,用于协调人类开发者与 AI 编程助手之间的协作。
https://developer.aliyun.com/article/1687886
这篇文章题为《氛围编程走远,规格驱动开发降临》,作者 reddish 从对“氛围编程”(Vibe Coding)的批判出发,系统分析了当前 AI 编程热潮中存在的问题,并重点介绍了多家科技公司(GitHub、OpenAI、Fission AI、Amazon)在规格驱动开发(Specification-Driven Development)方向上的探索与实践。
一、核心观点:氛围编程不可持续
- 氛围编程指通过自然语言提示快速生成代码,虽具即时满足感,但存在致命缺陷:
- 需求模糊、边界不清:无法准确表达复杂业务逻辑和约束。
- 上下文孤立:对话历史有限,导致代码碎片化、难以维护。
- 其他问题包括:缺乏验证机制、质量不可控、文档缺失、协作困难等。
- 结论:氛围编程适合“起个头”,但无法支撑真实、复杂的软件工程。
二、解决方案:规格驱动开发成为新趋势
作者指出,各大厂正转向以结构化、可执行的规范为核心的新开发范式:
1. GitHub 的 Spec-Kit
- 将自然语言需求转为结构化 Markdown(如用户故事模板)。
- 轻量、易集成,适合小团队。
- 强调“规范即资产”,但存在文档冗长、分支管理混乱等问题。
2. OpenAI 的 Model-Spec
- 构建三层规范框架:目标层、规则层、默认行为层。
- 引入指令优先级机制(Root > System > Developer > User > Guideline),确保伦理安全。
- 侧重模型行为控制,而非完整开发流程支持。
3. Fission AI 的 OpenSpec
- 通过
specs(规范状态) +changes(变更记录)管理 AI 应用生命周期。 - 轻量、支持 CLI 和自然语言,适合已有项目的演进。
- 强调技术决策可追溯,但对全新项目支持较弱。
4. Amazon 的 Kiro(作者认为最务实)
- 三步流程:
- 需求转化:自然语言 → 用户故事 + EARS 验收标准 →
requirements.md - 设计生成:自动生成架构图、接口等 →
design.md - 任务执行:生成带测试的任务清单 →
tasks.md
- 需求转化:自然语言 → 用户故事 + EARS 验收标准 →
- 集成 VSCode,支持自动化钩子(如安全扫描、文档更新)。
- 优点是流程清晰、降低沟通成本;缺点是对简单需求可能过度工程化。
三、总结与展望
- 所有方案都抛弃了“人人可编程”的幻想,回归到严谨的需求定义与规范表达。
- 当前实践仍处于早期阶段,尚未形成通用标准,但都围绕 SRS(软件需求规格说明书)展开。
- 掌握需求分析与 SRS 编写能力,将成为开发者在 AI 时代的核心竞争力。
- 未来,谁能在“规格驱动”领域提供更完整、通用的工具链,谁就可能成为新赛道的领导者。
关键启示:
AI 不会取代程序员,但会淘汰不会写需求的程序员。
规格不是文档,而是可执行的契约,是连接人类意图与机器实现的桥梁。
作者呼吁:开发者应主动学习需求工程知识,提前布局,在 AI 编程浪潮中立于不败之地。
OpenSpec
OpenSpec是一个规范驱动的开发框架,用于协调人类开发者与 AI 编程助手之间的协作。
让输出结果更可预测,也更符合共识,而非通过自然语言生成的模糊代码
OpenSpec 的核心特点
1. 规范驱动开发
- 通过结构化的规范文档管理需求
- 确保开发过程的可预测性和可审查性
- 减少 AI 生成代码的不确定性
2. 变更即代码(Change-as-Code)
- 将软件变更抽象为可版本化、可验证的规范资产
- 确保设计与实现的一致性
3. 轻量级
- 无需 API 密钥
- 安装和使用简单
OpenSpec 的工作流程
- 初始化项目:
openspec init创建规范文档结构 - 创建变更提案:在
openspec/changes/下创建变更文档 - 审查与对齐:团队和 AI 共同审核变更提案
- 实施变更:按照任务列表逐步实现
- 归档变更:使用
openspec archive归档到openspec/specs/
适用场景
- 与 AI 编程助手(如 Cursor、Claude Code)协作开发
- 需要规范化和可验证的开发流程
- 在现有项目基础上进行迭代开发
- 需要持续集成和自动化验证
项目结构示例
项目根目录/
├── openspec/
│ ├── specs/ # 已归档的规范
│ └── changes/ # 新的变更提案
│ ├── proposal.md
│ ├── tasks.md
│ └── specs/
实战
# 1. 检查 Node.js 版本(需要 >= 20.19.0)
node --version
# 2. 全局安装 OpenSpec CLI
npm install -g @fission-ai/openspec@latest
# 3. 进入项目目录并初始化
cd /Users/username/Documents/WorkSpace/taro-test
openspec init
初始化配置文件详解:
<!-- OPENSPEC:START -->
<!-- OPENSPEC:START -->
# OpenSpec Instructions
# OpenSpec 指南
These instructions are for AI assistants working in this project.
这些指南适用于在本项目中工作的 AI 助手。
Always open `@/openspec/AGENTS.md` when the request:
当收到的请求包含以下内容时,请务必打开 `@/openspec/AGENTS.md`:
- Mentions planning or proposals (words like proposal, spec, change, plan)
- 提及规划或提案(例如包含“提案”、“规范”、“变更”、“计划”等词汇)
- Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
- 引入新功能、重大变更、架构调整,或涉及重大的性能/安全工作
- Sounds ambiguous and you need the authoritative spec before coding
- 含义模糊,需要在编码前查阅权威规范
Use `@/openspec/AGENTS.md` to learn:
请使用 `@/openspec/AGENTS.md` 了解:
- How to create and apply change proposals
- 如何创建和应用变更提案
- Spec format and conventions
- 规范的格式和约定
- Project structure and guidelines
- 项目的结构和指导原则
Keep this managed block so 'openspec update' can refresh the instructions.
请保留此受控区块,以便 `openspec update` 能够刷新这些指南。
<!-- OPENSPEC:END -->
<!-- OPENSPEC:END -->
这是一个 OpenSpec 项目管理机制 自动生成的指令块,它的核心作用是:引导 AI 助手在特定场景下查阅权威规范文档,确保开发行为符合项目约定。
具体用途解析:
-
触发条件(When)
当你提出以下类型的请求时,AI 会自动检查@/openspec/AGENTS.md文件:- 涉及 新功能设计(如“我想加个语音识别功能”)
- 需要 架构调整(如“能不能把数据库换成 MongoDB?”)
- 包含 模糊需求(如“优化一下性能”但未说明具体指标)
- 提到 提案/计划/规范 等关键词
-
核心目的(Why)
- ✅ 避免随意变更:防止 AI 在不了解项目约束的情况下生成不符合规范的代码
- ✅ 统一协作标准:所有修改必须遵循
AGENTS.md中定义的流程(如提案模板、评审规则) - ✅ 降低维护成本:通过强制查阅最新规范,减少技术债和返工
-
典型工作流(How)
-
对你的价值
- 如果你是 开发者:能确保你的需求被正确理解和实现
- 如果你是 项目维护者:通过
openspec update命令可一键更新所有 AI 的行为准则 - 如果你是 协作者:所有参与者都遵循同一套变更管理规则
💡 简单来说:这相当于给 AI 装了一个「项目宪法」检查器,任何重大改动前必须先翻宪法(
AGENTS.md),而不是自由发挥。
# OpenSpec Instructions
# OpenSpec 指南
Instructions for AI coding assistants using OpenSpec for spec-driven development.
供使用 OpenSpec 进行“规范驱动开发”的 AI 编程助手的说明。
## TL;DR Quick Checklist
## 简而言之:快速核对清单
- Search existing work: `openspec spec list --long`, `openspec list` (use `rg` only for full-text search)
- 搜索现有工作:`openspec spec list --long`, `openspec list` (仅在全文搜索时使用 `rg`)
- Decide scope: new capability vs modify existing capability
- 确定范围:新增能力 vs 修改现有能力
- Pick a unique `change-id`: kebab-case, verb-led (`add-`, `update-`, `remove-`, `refactor-`)
- 选择一个唯一的 `change-id`:烤肉串命名法(kebab-case),动词开头(`add-`, `update-`, `remove-`, `refactor-`)
- Scaffold: `proposal.md`, `tasks.md`, `design.md` (only if needed), and delta specs per affected capability
- 脚手架:`proposal.md`, `tasks.md`, `design.md` (仅在需要时),以及每个受影响能力的增量规范(delta specs)
- Write deltas: use `## ADDED|MODIFIED|REMOVED|RENAMED Requirements`; include at least one `#### Scenario:` per requirement
- 编写增量:使用 `## ADDED|MODIFIED|REMOVED|RENAMED Requirements`;每个需求至少包含一个 `#### Scenario:`
- Validate: `openspec validate [change-id] --strict` and fix issues
- 验证:`openspec validate [change-id] --strict` 并修复问题
- Request approval: Do not start implementation until proposal is approved
- 请求批准:在提案获批前,不得开始实施
## Three-Stage Workflow
## 三阶段工作流
### Stage 1: Creating Changes
### 阶段一:创建变更
Create proposal when you need to:
当您需要以下操作时,请创建提案:
- Add features or functionality
- 添加功能或特性
- Make breaking changes (API, schema)
- 进行不兼容的变更(API、架构)
- Change architecture or patterns
- 更改架构或模式
- Optimize performance (changes behavior)
- 优化性能(改变行为)
- Update security patterns
- 更新安全模式
Triggers (examples):
触发词(示例):
- "Help me create a change proposal"
- “帮我创建一个变更提案”
- "Help me plan a change"
- “帮我计划一个变更”
- "Help me create a proposal"
- “帮我创建一个提案”
- "I want to create a spec proposal"
- “我想创建一个规范提案”
- "I want to create a spec"
- “我想创建一个规范”
Loose matching guidance:
宽松匹配指南:
- Contains one of: `proposal`, `change`, `spec`
- 包含以下词汇之一:`proposal`, `change`, `spec`
- With one of: `create`, `plan`, `make`, `start`, `help`
- 以及以下词汇之一:`create`, `plan`, `make`, `start`, `help`
Skip proposal for:
以下情况无需创建提案:
- Bug fixes (restore intended behavior)
- 修复 Bug(恢复预期行为)
- Typos, formatting, comments
- 拼写错误、格式调整、注释
- Dependency updates (non-breaking)
- 依赖更新(非破坏性)
- Configuration changes
- 配置变更
- Tests for existing behavior
- 针对现有行为的测试
**Workflow**
**工作流程**
1. Review `openspec/project.md`, `openspec list`, and `openspec list --specs` to understand current context.
1. 查阅 `openspec/project.md`, `openspec list`, 和 `openspec list --specs` 以了解当前上下文。
2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, optional `design.md`, and spec deltas under `openspec/changes/<id>/`.
2. 选择一个唯一的动词开头的 `change-id`,并搭建 `proposal.md`, `tasks.md`, 可选的 `design.md`,以及位于 `openspec/changes/<id>/` 下的规范增量文件。
3. Draft spec deltas using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement.
3. 使用 `## ADDED|MODIFIED|REMOVED Requirements` 起草规范增量,每个需求至少包含一个 `#### Scenario:`。
4. Run `openspec validate <id> --strict` and resolve any issues before sharing the proposal.
4. 运行 `openspec validate <id> --strict` 并在分享提案前解决所有问题。
### Stage 2: Implementing Changes
### 阶段二:实施变更
Track these steps as TODOs and complete them one by one.
将这些步骤作为待办事项(TODO)逐一跟踪并完成。
1. **Read proposal.md** - Understand what's being built
1. **阅读 proposal.md** - 了解正在构建的内容
2. **Read design.md** (if exists) - Review technical decisions
2. **阅读 design.md** (如果存在) - 审查技术决策
3. **Read tasks.md** - Get implementation checklist
3. **阅读 tasks.md** - 获取实施核对清单
4. **Implement tasks sequentially** - Complete in order
4. **按顺序实施任务** - 依序完成
5. **Confirm completion** - Ensure every item in `tasks.md` is finished before updating statuses
5. **确认完成** - 在更新状态前,确保 `tasks.md` 中的每一项都已完成
6. **Update checklist** - After all work is done, set every task to `- [x]` so the list reflects reality
6. **更新核对清单** - 所有工作完成后,将每个任务标记为 `- [x]`,以便列表反映实际情况
7. **Approval gate** - Do not start implementation until the proposal is reviewed and approved
7. **审批关卡** - 在提案经过审查和批准前,不得开始实施
### Stage 3: Archiving Changes
### 阶段三:归档变更
After deployment, create separate PR to:
部署后,创建一个独立的 PR 来:
- Move `changes/[name]/` → `changes/archive/YYYY-MM-DD-[name]/`
- 移动 `changes/[name]/` → `changes/archive/YYYY-MM-DD-[name]/`
- Update `specs/` if capabilities changed
- 如果能力发生变更,更新 `specs/`
- Use `openspec archive <change-id> --skip-specs --yes` for tooling-only changes (always pass the change ID explicitly)
- 对于仅涉及工具的变更,使用 `openspec archive <change-id> --skip-specs --yes` (请始终明确传递变更 ID)
- Run `openspec validate --strict` to confirm the archived change passes checks
- 运行 `openspec validate --strict` 以确认归档的变更通过了检查
## Before Any Task
## 任何任务之前
**Context Checklist:**
**上下文核对清单:**
- Read relevant specs in `specs/[capability]/spec.md`
- 阅读 `specs/[capability]/spec.md` 中的相关规范
- Check pending changes in `changes/` for conflicts
- 检查 `changes/` 中的待处理变更是否存在冲突
- Read `openspec/project.md` for conventions
- 阅读 `openspec/project.md` 了解约定
- Run `openspec list` to see active changes
- 运行 `openspec list` 查看正在进行的变更
- Run `openspec list --specs` to see existing capabilities
- 运行 `openspec list --specs` 查看现有能力
**Before Creating Specs:**
**在创建规范之前:**
- Always check if capability already exists
- 始终检查该能力是否已存在
- Prefer modifying existing specs over creating duplicates
- 优先修改现有规范,而非创建副本
- Use `openspec show [spec]` to review current state
- 使用 `openspec show [spec]` 审查当前状态
- If request is ambiguous, ask 1–2 clarifying questions before scaffolding
- 如果请求含糊不清,在搭建脚手架前提出 1-2 个澄清问题
### Search Guidance
### 搜索指南
- Enumerate specs: `openspec spec list --long` (or `--json` for scripts)
- 列举规范:`openspec spec list --long` (或脚本用 `--json`)
- Enumerate changes: `openspec list` (or `openspec change list --json` - deprecated but available)
- 列举变更:`openspec list` (或 `openspec change list --json` - 已弃用但可用)
- Show details:
- 显示详情:
- Spec: `openspec show <spec-id> --type spec` (use `--json` for filters)
- 规范:`openspec show <spec-id> --type spec` (使用 `--json` 进行过滤)
- Change: `openspec show <change-id> --json --deltas-only`
- 变更:`openspec show <change-id> --json --deltas-only`
- Full-text search (use ripgrep): `rg -n "Requirement:|Scenario:" openspec/specs`
- 全文搜索 (使用 ripgrep):`rg -n "Requirement:|Scenario:" openspec/specs`
## Quick Start
## 快速开始
### CLI Commands
### 命令行界面 (CLI) 命令
```bash
# Essential commands
# 基本命令
openspec list # List active changes
# 列出正在进行的变更
openspec list --specs # List specifications
# 列出规范
openspec show [item] # Display change or spec
# 显示变更或规范
openspec validate [item] # Validate changes or specs
# 验证变更或规范
openspec archive <change-id> [--yes|-y] # Archive after deployment (add --yes for non-interactive runs)
# 部署后归档 (非交互式运行请添加 --yes)
# Project management
# 项目管理
openspec init [path] # Initialize OpenSpec
# 初始化 OpenSpec
openspec update [path] # Update instruction files
# 更新说明文件
# Interactive mode
# 交互模式
openspec show # Prompts for selection
# 提示进行选择
openspec validate # Bulk validation mode
# 批量验证模式
# Debugging
# 调试
openspec show [change] --json --deltas-only
openspec validate [change] --strict
以下是对 OpenSpec 中 proposal.md、design(可选)、spec.md 和 tasks.md 四者关系与工作流 的详细总结,聚焦于它们的定位、作用、依赖关系和协作逻辑。
总体定位:规范驱动开发(Spec-Driven Development)
OpenSpec 的核心理念是:
在写任何代码之前,先和 AI 共同明确“系统应该做什么”。
这一目标通过四个关键文档协同实现,形成一个从“想法”到“实现”的闭环。
举个生活例子
想盖一栋房子:
- 先有建筑图纸(spec)
- 再有施工计划(tasks)和材料清单(design)
- 流程上:图纸 → 施工计划
- 语义上:施工计划 依赖于 图纸的内容(不能乱建)→ 所以说“施工计划依赖图纸”
👉 虽然图纸先画,但施工计划的存在意义完全由图纸决定——这就是“内容依赖”。
回到 OpenSpec
1. 流程依赖
- 必须先写好
spec.md - 才能合理地生成
tasks.md和design - 否则就是“没想清楚就开工”
2. 内容依赖
tasks.md的每一条任务,都指向spec.md中的某个行为design的每一个细节,都服务于spec.md定义的需求- 如果
spec.md改了,tasks.md和design必须跟着改
同理:
tasks.md和design在语义上依赖spec.md的内容约束。
流程顺序(执行时序) 的准确表达:
这表示:先有 spec.md,然后才能生成 design 和 tasks.md —— 这是 开发流程的时间顺序。
1. proposal.md —— 变更的起点:Why?
作用
- 阐述本次变更的背景、目标、业务价值和范围。
- 回答:“为什么要加这个功能?解决了什么问题?”
内容特点
- 简洁、高层、面向业务。
- 不涉及技术细节或具体行为。
- 示例:
## Goal Add a page to show competitor product loss data. ## Motivation Marketing team needs to track which SKUs are losing sales to JD/Taobao.
依赖关系
- 无前置依赖:它是整个变更流程的入口。
- 被
spec.md依赖:spec.md的内容应紧扣 proposal 的目标。
生命周期
- 存在于
changes/<name>/proposal.md - 不会归档到主规范,仅作为变更上下文保留。
2. spec.md —— 核心规范:What?
作用
- 用结构化自然语言定义系统在特定场景下的预期行为。
- 是人类与 AI 对齐需求的唯一事实源(Source of Truth)。
- 回答:“用户做了什么,系统应该如何响应?”
内容特点
- 基于场景(Scenario)组织。
- 使用
WHEN/THEN/AND描述行为(此处略去语法细节)。 - 不包含实现方式(如“用 React”、“调哪个 API”),只关注外部可观测行为。
依赖关系
- 依赖
proposal.md:必须围绕提案目标展开。 - 被
tasks.md和design依赖:所有实现都必须对齐 spec。 - 可引用已有主规范中的模块,支持复用。
生命周期
- 初始位于
changes/<name>/specs/<module>/spec.md - 变更完成后,通过
openspec archive合并到openspec/specs/<module>/spec.md - 成为系统永久、活的需求文档。
💡 这是 OpenSpec 工作流中最关键、不可跳过的一步。
3. design(可选)—— 实现补充:How?(技术/视觉层面)
作用
- 提供
spec.md无法表达的实现约束或设计细节。 - 是对规范的技术注解,而非需求本身。
内容形式(非强制)
- UI 草图、Figma 链接、截图
- API 接口定义(如 OpenAPI YAML)
- 数据库表结构
- 技术栈要求(如“必须使用 TanStack Query”)
- 安全或性能约束
依赖关系
- 依赖
spec.md:design 必须满足 spec 定义的行为。 - 被
tasks.md参考:AI 在生成任务时会结合 design 调整实现细节。
生命周期
- 通常放在
changes/<name>/design/目录下 - 不会归档到主规范,属于过程辅助材料。
- 简单功能可完全省略。
⚠️ 重要原则:
design不能替代spec.mdspec.md说“要筛选”,design说“用 Select 组件”——两者互补,但层级不同。
4. tasks.md —— 执行计划:Steps?
作用
- 将
spec.md中的行为场景拆解为具体的、可执行的开发任务清单。 - 指导 AI 或开发者分步实现功能。
内容特点
- 按模块或技术层组织(如 Frontend / Backend)。
- 每项任务应对应一个或多个 Scenario。
- 支持勾选框
[ ]跟踪进度。 - 示例:
## Frontend - [ ] Create CompetitorLossPage component - [ ] Implement channel filter dropdown ## Backend - [ ] Add /api/loss-data endpoint with channel param
依赖关系
- 强依赖
spec.md:任务必须覆盖所有 spec 场景。 - 可参考
design:用于细化任务技术细节。 - 不依赖
proposal.md(间接通过 spec 依赖)。
生命周期
- 位于
changes/<name>/tasks.md - 不会归档到主规范,属于临时执行计划。
- 可由人类手动调整(如合并任务、指定技术方案)。
协作流程(推荐顺序)
1. 提出想法
↓
2. 生成 proposal.md → 明确 Why
↓
3. 编写/迭代 spec.md → 定义 What(核心!)
↓
4. (可选)提供 design → 补充 How(技术细节)
↓
5. 生成 tasks.md → 拆解 Steps
↓
6. AI/人执行任务写代码
↓
7. 验收后 archive → spec.md 合并到主规范
✅ 必须顺序:
proposal→spec→tasks
✅ design 是可选插件,不影响主干流程
📊 对比总结表
| 文档 | 回答的问题 | 是否必须 | 谁主导 | 是否归档到主规范 | 依赖谁 | 被谁依赖 |
|---|---|---|---|---|---|---|
proposal.md |
Why?(动机) | ✅ 是 | 人类 | ❌ 否 | 无 | spec.md |
spec.md |
What?(行为) | ✅ 是 | 人 + AI 共同 | ✅ 是 | proposal.md |
tasks.md, design |
design |
How?(设计) | ❌ 否 | 人类 | ❌ 否 | spec.md |
tasks.md |
tasks.md |
Steps?(任务) | ✅ 是 | AI(基于 spec) | ❌ 否 | spec.md (+ design) |
Code Implementation |
常见反模式(避免!)
| 错误做法 | 问题 |
|---|---|
跳过 spec.md 直接写代码 |
需求模糊,AI 自由发挥,难以验收 |
在 spec.md 中写“用 useState” |
混淆需求与实现,降低规范可复用性 |
把 design 当作需求文档 |
技术细节掩盖业务目标,团队理解不一致 |
先写 tasks.md 再补 spec.md |
本末倒置,失去规范驱动的意义 |
最佳实践建议
- 始终从
proposal.md开始,哪怕只有一句话。 - 花最多时间打磨
spec.md—— 它是质量的基石。 - 只有复杂功能才需要
design,简单 CRUD 可省略。 tasks.md可手动调整,确保任务粒度合理。- 归档前务必 review
spec.md,因为它将成为系统永久文档。
核心思想再强调
OpenSpec 不是让 AI 写代码的工具,而是让人与 AI 共同定义“正确的事”的协作框架。
spec.md就是这个“正确的事”的书面契约。
通过这四份文档的有序协作,你可以:
- 减少需求误解
- 提升代码准确性
- 积累可维护的活文档
- 实现真正的“AI 辅助开发”而非“AI 猜测开发”
WHEN/THEN/AND
WHEN / THEN / AND 是 OpenSpec(以及其灵感来源——行为驱动开发 BDD)中描述系统行为的核心语法。理解它们的逻辑关系,是写出清晰、可执行规范的关键。
一句话总结
WHEN:描述触发条件(用户做了什么、系统发生了什么)THEN:描述预期结果(系统应该做什么、返回什么)AND:用于补充WHEN或THEN的额外条件或结果,保持语句简洁
详细解释 + 逻辑结构
1. 基本结构(必须有 WHEN + THEN)
- **WHEN** 用户点击“登出”按钮
- **THEN** 系统清除认证 Cookie
✅ 这是一个完整的行为场景(Scenario)。
2. 多个触发条件?用 AND 补充 WHEN
- **WHEN** 用户已登录
- **AND** 当前页面是个人中心
- **THEN** 显示“编辑资料”按钮
👉 这里两个 WHEN 条件缺一不可,用 AND 连接。
💡 逻辑等价于:
WHEN (A 且 B) → THEN C
3. 多个预期结果?用 AND 补充 THEN
- **WHEN** 用户提交表单
- **THEN** 数据保存到数据库
- **AND** 页面跳转到详情页
- **AND** 显示“保存成功”提示
👉 系统必须同时满足这三个结果才算正确。
💡 逻辑等价于:
WHEN A → THEN (B 且 C 且 D)
4. 混合使用:WHEN… AND… THEN… AND…
这是最常见的情况:
- **WHEN** 用户选择“京东自营”渠道
- **AND** 点击“查询”按钮
- **THEN** 系统请求 `/api/loss?channel=jd`
- **AND** 表格只显示京东商品数据
✅ 完全合法,且非常清晰!
🚫 常见误区
❌ 不能只有 AND 开头
- **AND** 清除本地缓存 ❌ 错误!
→ AND 必须跟在 WHEN 或 THEN 之后,不能独立存在。
❌ 不要用 AND 替代 WHEN/THEN
- **AND** 用户点击按钮
- **AND** 系统跳转页面 ❌ 模糊!谁触发?谁响应?
为什么用这种设计?
| 优点 | 说明 |
|---|---|
| ✅ 自然语言可读 | 产品经理、测试、开发者都能看懂 |
| ✅ 机器可解析 | AI 可以提取条件和断言,自动生成测试或代码 |
| ✅ 避免歧义 | 强制区分“输入”和“输出” |
| ✅ 支持组合 | 多个 AND 让复杂场景也能表达 |
最佳实践建议
- 每个 Scenario 从
WHEN开始 THEN紧随其后(即使中间有AND补充WHEN)- 用
AND扩展,不要重复写WHEN/THEN# 好 - **WHEN** A - **AND** B - **THEN** C - **AND** D # 不好(冗余) - **WHEN** A - **WHEN** B ❌ - **THEN** C - **THEN** D ❌ - 一个 Scenario 聚焦一个用户目标,不要塞太多逻辑
与 Gherkin 语法的关系
OpenSpec 的 WHEN/THEN/AND 直接借鉴自 Gherkin(Cucumber 测试框架的语法):
| Gherkin | OpenSpec |
|---|---|
Given |
(隐含在上下文中,OpenSpec 省略) |
When |
WHEN |
Then |
THEN |
And |
AND |
OpenSpec 简化了
Given,因为大多数 Web 应用的“前置状态”可以通过WHEN描述(如“用户已登录”)。
总结
| 关键词 | 作用 | 能否开头? | 示例 |
|---|---|---|---|
WHEN |
触发条件 | ✅ 必须开头 | WHEN 用户点击按钮 |
THEN |
预期结果 | ❌ 不能开头 | THEN 显示成功消息 |
AND |
补充条件/结果 | ❌ 不能开头 | AND 清除缓存 |
✅ 正确模式:
WHEN ... [AND ...]* THEN ... [AND ...]*
这样写出来的 spec.md,既能让人看懂,也能让 AI 精准实现!
更多推荐

所有评论(0)