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(作者认为最务实)
  • 三步流程:
    1. 需求转化:自然语言 → 用户故事 + EARS 验收标准 → requirements.md
    2. 设计生成:自动生成架构图、接口等 → design.md
    3. 任务执行:生成带测试的任务清单 → tasks.md
  • 集成 VSCode,支持自动化钩子(如安全扫描、文档更新)。
  • 优点是流程清晰、降低沟通成本;缺点是对简单需求可能过度工程化。

三、总结与展望

  • 所有方案都抛弃了“人人可编程”的幻想,回归到严谨的需求定义与规范表达
  • 当前实践仍处于早期阶段,尚未形成通用标准,但都围绕 SRS(软件需求规格说明书)展开。
  • 掌握需求分析与 SRS 编写能力,将成为开发者在 AI 时代的核心竞争力。
  • 未来,谁能在“规格驱动”领域提供更完整、通用的工具链,谁就可能成为新赛道的领导者。

关键启示:

AI 不会取代程序员,但会淘汰不会写需求的程序员。
规格不是文档,而是可执行的契约,是连接人类意图与机器实现的桥梁。


作者呼吁:开发者应主动学习需求工程知识,提前布局,在 AI 编程浪潮中立于不败之地。


OpenSpec

OpenSpec是一个规范驱动的开发框架,用于协调人类开发者与 AI 编程助手之间的协作。

让输出结果更可预测,也更符合共识,而非通过自然语言生成的模糊代码

OpenSpec 的核心特点

1. 规范驱动开发

  • 通过结构化的规范文档管理需求
  • 确保开发过程的可预测性和可审查性
  • 减少 AI 生成代码的不确定性

2. 变更即代码(Change-as-Code)

  • 将软件变更抽象为可版本化、可验证的规范资产
  • 确保设计与实现的一致性

3. 轻量级

  • 无需 API 密钥
  • 安装和使用简单

OpenSpec 的工作流程

  1. 初始化项目:openspec init 创建规范文档结构
  2. 创建变更提案:在 openspec/changes/ 下创建变更文档
  3. 审查与对齐:团队和 AI 共同审核变更提案
  4. 实施变更:按照任务列表逐步实现
  5. 归档变更:使用 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 助手在特定场景下查阅权威规范文档,确保开发行为符合项目约定


具体用途解析:

  1. 触发条件(When)
    当你提出以下类型的请求时,AI 会自动检查 @/openspec/AGENTS.md 文件:

    • 涉及 新功能设计(如“我想加个语音识别功能”)
    • 需要 架构调整(如“能不能把数据库换成 MongoDB?”)
    • 包含 模糊需求(如“优化一下性能”但未说明具体指标)
    • 提到 提案/计划/规范 等关键词
  2. 核心目的(Why)

    • 避免随意变更:防止 AI 在不了解项目约束的情况下生成不符合规范的代码
    • 统一协作标准:所有修改必须遵循 AGENTS.md 中定义的流程(如提案模板、评审规则)
    • 降低维护成本:通过强制查阅最新规范,减少技术债和返工
  3. 典型工作流(How)

    用户提出需求

    是否涉及变更/新功能?

    AI 自动加载 AGENTS.md

    按规范生成提案或拒绝请求

    直接处理常规任务

  4. 对你的价值

    • 如果你是 开发者:能确保你的需求被正确理解和实现
    • 如果你是 项目维护者:通过 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.mddesign(可选)、spec.mdtasks.md 四者关系与工作流 的详细总结,聚焦于它们的定位、作用、依赖关系和协作逻辑。


总体定位:规范驱动开发(Spec-Driven Development)

OpenSpec 的核心理念是:

在写任何代码之前,先和 AI 共同明确“系统应该做什么”
这一目标通过四个关键文档协同实现,形成一个从“想法”到“实现”的闭环。


举个生活例子

想盖一栋房子:

  • 先有建筑图纸(spec)
  • 再有施工计划(tasks)和材料清单(design)
  • 流程上:图纸 → 施工计划
  • 语义上:施工计划 依赖于 图纸的内容(不能乱建)→ 所以说“施工计划依赖图纸”

👉 虽然图纸先画,但施工计划的存在意义完全由图纸决定——这就是“内容依赖”。


回到 OpenSpec

1. 流程依赖

  • 必须先写好 spec.md
  • 才能合理地生成 tasks.mddesign
  • 否则就是“没想清楚就开工”

2. 内容依赖

  • tasks.md 的每一条任务,都指向 spec.md 中的某个行为
  • design 的每一个细节,都服务于 spec.md 定义的需求
  • 如果 spec.md 改了,tasks.mddesign 必须跟着改

同理:

tasks.mddesign 在语义上依赖 spec.md 的内容约束。


流程顺序(执行时序) 的准确表达:

1. proposal.md
2. spec.md
3. design 可选
4. tasks.md
5. Code Implementation

这表示:先有 spec.md,然后才能生成 designtasks.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.mddesign 依赖:所有实现都必须对齐 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.md
  • spec.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 合并到主规范

必须顺序proposalspectasks
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 本末倒置,失去规范驱动的意义

最佳实践建议

  1. 始终从 proposal.md 开始,哪怕只有一句话。
  2. 花最多时间打磨 spec.md —— 它是质量的基石。
  3. 只有复杂功能才需要 design,简单 CRUD 可省略。
  4. tasks.md 可手动调整,确保任务粒度合理。
  5. 归档前务必 review spec.md,因为它将成为系统永久文档。

核心思想再强调

OpenSpec 不是让 AI 写代码的工具,而是让人与 AI 共同定义“正确的事”的协作框架。
spec.md 就是这个“正确的事”的书面契约。

通过这四份文档的有序协作,你可以:

  • 减少需求误解
  • 提升代码准确性
  • 积累可维护的活文档
  • 实现真正的“AI 辅助开发”而非“AI 猜测开发”

WHEN/THEN/AND

WHEN / THEN / AND 是 OpenSpec(以及其灵感来源——行为驱动开发 BDD)中描述系统行为的核心语法。理解它们的逻辑关系,是写出清晰、可执行规范的关键。


一句话总结

  • WHEN:描述触发条件(用户做了什么、系统发生了什么)
  • THEN:描述预期结果(系统应该做什么、返回什么)
  • AND:用于补充 WHENTHEN额外条件或结果,保持语句简洁

详细解释 + 逻辑结构

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 必须跟在 WHENTHEN 之后,不能独立存在。

❌ 不要用 AND 替代 WHEN/THEN
- **AND** 用户点击按钮  
- **AND** 系统跳转页面   ❌ 模糊!谁触发?谁响应?

为什么用这种设计?

优点 说明
自然语言可读 产品经理、测试、开发者都能看懂
机器可解析 AI 可以提取条件和断言,自动生成测试或代码
避免歧义 强制区分“输入”和“输出”
支持组合 多个 AND 让复杂场景也能表达

最佳实践建议

  1. 每个 Scenario 从 WHEN 开始
  2. THEN 紧随其后(即使中间有 AND 补充 WHEN
  3. AND 扩展,不要重复写 WHEN/THEN
    # 好
    - **WHEN** A
    - **AND** B
    - **THEN** C
    - **AND** D
    
    # 不好(冗余)
    - **WHEN** A
    - **WHEN** B   ❌
    - **THEN** C
    - **THEN** D   ❌
    
  4. 一个 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 精准实现!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐