# EARS 需求语法详解与示例

Canonical: https://specscore.md/zh-cn/articles/ears-requirements/

最近更新：2026年11月2日

[EARS](https://alistairmavin.com/ears/)（Easy Approach to Requirements Syntax）是一种需求记法：一小套英语句式，也叫 EARS 语法，把条件、触发和系统响应固定在同一顺序里。需求是系统必须满足的一条可检验义务。[规范驱动开发](https://specscore.md/zh-cn/spec-driven-development/)（SDD，spec-driven development）是在写代码之前把这条义务写进规范，并把规范当作事实来源。产品需求文档（PRD，product requirements document）是在把工作拆成任务之前，用散文说明问题和范围。在 [SpecScore](https://specscore.md/) 里，需求（REQ）是功能内部一条有名字的规则，验收准则（AC，acceptance criterion）是可选的抽象条件，指向其中一条或多条规则。[持续集成](https://specscore.md/zh-cn/validators/)（CI，continuous integration）是对每一项提议变更的自动检查。这项检查是[命令行界面](https://specscore.md/zh-cn/cli/)（CLI，command-line interface）命令 `specscore spec lint`。[Kiro](https://kiro.dev/) 是 Amazon Web Services（AWS）的智能体集成开发环境（IDE，integrated development environment），它写这些句式中的一种。该记法由 Alistair Mavin 与 Rolls-Royce 的同事在 2009 年 Institute of Electrical and Electronics Engineers（IEEE）需求工程会议上首次发表。

## EARS 从哪里来

当时在 Rolls-Royce PLC 的 Alistair Mavin、Philip Wilkinson、Adrian Harwood 和 Mark Novak，于 2009 年在 17th IEEE International Requirements Engineering Conference 发表 “Easy Approach to Requirements Syntax (EARS)”。文献标识是 [10.1109/RE.2009.9](https://doi.org/10.1109/RE.2009.9)。他们在从适航规章 Certification Specification for Engines（CS-E）第 CS-E 50 节抽取发动机控制需求时建立这些规则。原文把需求、设计指导和注释混在一起。

论文点出不受约束的自然语言的八个问题：歧义、含糊、复杂、遗漏、重复、冗长、不恰当的实现、无法测试。一小套规则要让每一条这样的需求使用五种模板之一。作者说这种记法适合高层干系人需求，并不声称它覆盖系统分解的每一层。

[Mavin 自己的指南](https://alistairmavin.com/ears/)把 EARS 描述为温和约束文本需求的方法。子句保持一个顺序，他称之为时序逻辑：先是任何前置条件，然后是触发，然后是系统名称和响应。规则是零个或多个前置条件、零个或一个触发、一个系统名称、一个或多个响应。2009 年的论文把这个形状分成五种模板。同一份指南也命名了组合这些关键词的复杂需求。

在论文的案例里，原始摘录有 36 条需求，改写后的集合有 47 条。平均长度从 36.9 个词降到 25.6 个词。作者报告，在那项研究里，复杂、遗漏、重复、不恰当的实现和无法测试在改写后的集合中不存在，歧义、含糊和冗长减少了但没有消除。他们也列出限度：样本小、只有高层安全需求、含糊的分类含有判断。这些数字是那篇论文对那一份文件的数字。

## EARS 句式

关键词来自 2009 年的论文和 Mavin 的指南。论文也允许在表示状态时用 *During* 代替 *While*，意思相同，只为读起来更顺。示例句子说明模板，不是论文引文。Kiro 用全大写写事件驱动句式；原始记法在句首用大写。示例保持英语，因为 EARS 语法是英语。

### 始终有效

`The <system name> shall <system response>`

始终有效。没有 EARS 关键词，因为没有前置条件，也没有触发。2009 年论文自己的例子是：控制系统应当防止发动机超速。

**示例:** The checkout system shall keep the order total equal to the sum of its line items.

### 事件驱动

`When <trigger>, the <system name> shall <system response>`

只有在系统边界检测到触发时才需要该响应。关键词是 *When*。

**示例:** When a shopper submits the checkout form with invalid data, the checkout system shall show a validation error next to the invalid field.

### 状态驱动

`While <precondition>, the <system name> shall <system response>`

只要系统停留在所点名的状态，就需要该响应。关键词是 *While*。

**示例:** While the cart is empty, the checkout system shall keep the pay button disabled.

### 不希望的行为

`If <trigger>, then the <system name> shall <system response>`

响应处理故障、扰动、偏离或其他不希望的行为。关键词是 *If* 和 *then*。论文给这个句式单独的词，好让这些需求保持可见。作者指出，希望与不希望有时是视角问题。

**示例:** If the submitted email is not a valid address, then the checkout system shall reject the form.

### 可选特性

`Where <feature is included>, the <system name> shall <system response>`

只有产品包含所点名的特性时，响应才适用。关键词是 *Where*。

**示例:** Where the shop includes gift wrapping, the checkout system shall offer gift wrapping on the order review step.

### 复合

`While <precondition>, when <trigger>, the <system name> shall <system response>`

多于一个关键词。Mavin 的指南保持同一子句顺序：前置条件用 *While*，触发用 *When*，然后是系统响应。2009 年的论文也把 *While* 与 *If / then* 组合起来，表示某一状态下的不希望行为。这个组合的一个说明：While the shopper is signed out, if the shopper submits the checkout form, then the checkout system shall refuse the order.

**示例:** While the shopper is signed in, when the shopper submits a valid checkout form, the checkout system shall place the order.

## 常见错误

### 一句话里有多项义务

论文把复合句当作复杂问题并拆开。[SpecScore 需求规范](https://specscore.md/requirement-specification)用自己的话说了同一件事：每个 `REQ` 必须表达恰好一条可检验义务。

### 把不希望的行为藏进 When

*When* 用于预期中的触发。*If / then* 用于你宁可不要遇到的行为。两者共用一个词，会让不希望的情况看起来像正常情况。这就是论文指出的遗漏问题。

### 写成实现

“The checkout system shall store the flag in Redis” 点出了一种设计。论文称之为不恰当的实现。响应应当说系统必须达成什么，而不是哪个部件来做。

### 没有系统名称

“When the form is submitted, shall show an error” 没有主语。Mavin 的规则要求一个系统名称。

### 触发写在响应后面

“The checkout system shall show an error when the form is submitted” 把触发放在末尾。已发表的顺序是前置条件，然后触发，然后响应。

### 把 Kiro 的一行当成全部 EARS

Kiro 的功能规格页面只发表一种句式：`WHEN … THE SYSTEM SHALL …`。始终有效、*While*、*If / then*、*Where* 和复合组合，是论文和 Mavin 指南里的记法。那一页 Kiro 文档里没有。

## Kiro 如何使用 EARS

[Kiro 的功能规格页面](https://kiro.dev/docs/specs/feature-specs/)标明更新于 2026年8月4日，本文于 2026年11月2日阅读。该页说 `requirements.md` 使用 EARS。印出的句式是 `WHEN [condition/event]`，接着 `THE SYSTEM SHALL [expected behavior]`。页面示例是：WHEN a user submits a form with invalid data, THE SYSTEM SHALL display validation errors next to the relevant fields。

[需求优先页面](https://kiro.dev/docs/specs/feature-specs/requirements-first/)说，生成的 `requirements.md` 包含带验收准则的用户故事，以及同一 WHEN … THE SYSTEM SHALL … 形式的系统行为。注册示例是三句：有效注册数据创建账户，已存在的邮箱显示 “Email already registered”，无效邮箱格式显示校验错误。

进入设计之前，Analyze Requirements 查找逻辑不一致、歧义、相互冲突的约束和缺口。功能规格页面说，需求生成之后，从聊天选项或编辑器里的 Continue 菜单选择它。`design.md` 和 `tasks.md` 放在需求旁边。Quick Spec 连续跑需求、设计和任务，中间没有批准停顿。

这项分析是 Kiro 内部的一步。功能规格页面没有把它写成你可以加进自己 CI 的格式检查器。其他工具如何检查规范，见[工具指南](https://specscore.md/zh-cn/spec-driven-development/tools/)。两个产品的比较是 [SpecScore vs Kiro](https://specscore.md/zh-cn/vs/kiro/)。

## 同一条需求写成 SpecScore

SpecScore 不检查一句话是否符合 EARS 模板。来自 [specscore-cli](https://github.com/specscore/specscore-cli) 仓库的 `specscore spec lint` 检查结构。它的帮助文字点名 README 文件、Open Questions 节、标题层级、功能引用、内部链接和索引条目。一句 EARS 可以是 `REQ` 标题下的散文。检查器不给英语打分。

[需求规范](https://specscore.md/requirement-specification)把每条需求放在 `## Behavior` 里某个主题标题之下，低一层，通常是 `#### REQ: slug`。slug 使用小写字母、数字和连字符。标识是 `{feature-path}#req:{slug}`。规范说需求应当使用 RFC 2119（Request for Comments 2119）关键词：MUST、MUST NOT、SHOULD、SHOULD NOT 和 MAY。下面的对应里，EARS 的 *shall* 写成 MUST。

[验收准则](https://specscore.md/acceptance-criteria-specification)是可选的。使用时，它是 `## Acceptance Criteria` 里的 `### AC: slug`，下一行是带这些标识的 `**Requirements:**`。验收准则规范说，AC 陈述抽象条件，不得包含 Given/When/Then 步骤、具体输入或实现细节。具体流程是功能 `_tests/` 目录里的[场景](https://specscore.md/scenario-specification)。[功能规范](https://specscore.md/feature-specification)还要求状态、摘要、问题、行为、验收准则、未决问题和遵循页脚。

下面的文件是一个结账功能。`show-field-error` 是事件驱动示例。`reject-invalid-email` 是不希望行为的示例。2026年11月2日，`specscore spec lint` 对这棵树报告 0 项违规：一次用 2026年10月30日发布的最新版本 specscore 0.55.1，一次用 [dogfood.yml](https://github.com/specscore/specscore/blob/main/.github/workflows/dogfood.yml) 里固定的 specscore 0.39.1。[格式仓库](https://github.com/specscore/specscore)是该工作流所在之处。

### spec/features/checkout/README.md

```markdown
---
format: https://specscore.md/feature-specification
status: Draft
---

# Feature: Checkout validation

> [SpecScore.**Studio**](https://specscore.studio): | [Explore](https://specscore.studio/app/github.com/example/checkout/spec/features/checkout?op=explore) | [Edit](https://specscore.studio/app/github.com/example/checkout/spec/features/checkout?op=edit) | [Ask question](https://specscore.studio/app/github.com/example/checkout/spec/features/checkout?op=ask) | [Request change](https://specscore.studio/app/github.com/example/checkout/spec/features/checkout?op=request-change) |

**Status:** Draft
**Source Ideas:** —

## Summary

The checkout form shows a validation error next to a field when the shopper submits invalid data, and it rejects an email that is not a valid address.

## Problem

A vague sentence such as "the form should handle bad input" does not say which event causes which response. Checkout needs those obligations written so a reviewer and a linter can point at them.

## Behavior

### Field validation

The checkout system checks the form when the shopper submits it.

#### REQ: show-field-error

When a shopper submits the checkout form with invalid data, the checkout system MUST show a validation error next to the invalid field.

#### REQ: reject-invalid-email

If the submitted email is not a valid address, then the checkout system MUST reject the form.

## Acceptance Criteria

### AC: invalid-submission

**Requirements:** checkout#req:show-field-error, checkout#req:reject-invalid-email

Submitting the checkout form with invalid data shows a validation error next to the invalid field, and an email that is not a valid address is rejected.

## Open Questions

None at this time.

---
*This document follows the https://specscore.md/feature-specification*
```

### spec/features/README.md — 描述单元格就是功能的摘要句。检查器的 feature-index-row-sync 规则拒绝了更短的描述。

```markdown
---
format: https://specscore.md/features-index-specification
---

# Features

| Feature | Status | Description |
|---|---|---|
| [Checkout validation](checkout/README.md) | Draft | The checkout form shows a validation error next to a field when the shopper submits invalid data, and it rejects an email that is not a valid address. |

## Open Questions

None at this time.

---
*This document follows the https://specscore.md/features-index-specification*
```

### spec/README.md — 去掉 Open Questions 节会得到 oq-section: Open Questions section not found。

```markdown
# Checkout specification

## Open Questions

None at this time.
```

### specscore.yaml — project.host、project.org 和 project.repo 是用来核对 studio-toolbar 那一行的值。没有它们时，检查器报告 studio-toolbar: studio toolbar requires project host/org/repo。

```yaml
# SpecScore Repo Config Schema: https://specscore.md/repo-config

project:
  title: Checkout sample
  host: github.com
  org: example
  repo: checkout
```

把这个示例做成能通过时，还出现过两个错误，都已在上面的文件里改正。没有 `**Source Ideas:**` 的功能会因 `feature-source-ideas-required` 失败；空值是 `—`。功能索引还需要前言字段 `format: https://specscore.md/features-index-specification`。

检查器通过，表示文件符合这些结构规则。它不表示这些句子是好的 EARS，也不表示结账产品存在。这个行为的 Given/When/Then 应是 `spec/features/checkout/_tests/` 下的场景文件，而不是 AC 里的另一段。

## 问题

### EARS 是什么的缩写？

Easy Approach to Requirements Syntax。它是一套需求句式，由 Rolls-Royce 的 Alistair Mavin、Philip Wilkinson、Adrian Harwood 和 Mark Novak 在 2009 年 17th IEEE International Requirements Engineering Conference 发表，并在 Mavin 的网站上说明。

### Kiro 的记法是不是全部 EARS？

Kiro 的功能规格页面规定一种句式：WHEN … THE SYSTEM SHALL …。2009 年的论文和 Mavin 的指南还定义始终有效的需求、状态驱动的 While、不希望行为的 If/then、可选特性的 Where，以及这些关键词的复合组合。

### SpecScore 会校验 EARS 语法吗？

不会。`specscore spec lint` 校验 SpecScore 文件结构。一句 EARS 可以是 `REQ` 的散文。检查器不给英语打分。

### Given/When/Then 示例写在哪里？

写在功能 `_tests/` 目录下的场景里。验收准则保持为抽象条件，验收准则规范规定它不得包含 Given/When/Then 步骤。

## 来源

阅读日期为 2026年11月2日；页面自己印有更新日期的，以该日期为准。Kiro 功能规格页面写明更新于 2026年8月4日。

- [Mavin、Wilkinson、Harwood 与 Novak — Easy Approach to Requirements Syntax (EARS)，17th IEEE International Requirements Engineering Conference，2009，DOI 10.1109/RE.2009.9](https://doi.org/10.1109/RE.2009.9)
- [Alistair Mavin — EARS 指南](https://alistairmavin.com/ears/)
- [Kiro 文档 — 功能规格与 EARS（页面更新于 2026年8月4日）](https://kiro.dev/docs/specs/feature-specs/)
- [Kiro 文档 — 需求优先流程](https://kiro.dev/docs/specs/feature-specs/requirements-first/)
- [specscore/specscore — 需求规范](https://github.com/specscore/specscore/blob/main/spec/features/requirement/README.md)
- [specscore/specscore — 验收准则规范](https://github.com/specscore/specscore/blob/main/spec/features/acceptance-criteria/README.md)
- [specscore/specscore — 场景规范](https://github.com/specscore/specscore/blob/main/spec/features/scenario/README.md)
- [specscore/specscore — 功能规范](https://github.com/specscore/specscore/blob/main/spec/features/feature/README.md)
- [specscore/specscore — dogfood CI 工作流](https://github.com/specscore/specscore/blob/main/.github/workflows/dogfood.yml)
- [specscore/specscore-cli](https://github.com/specscore/specscore-cli)
- [specscore/specscore](https://github.com/specscore/specscore)

## 相关

- [面向 AI 编程的 Markdown PRD 模板](https://specscore.md/zh-cn/articles/feature-spec-template/)
- [在 CI 中用规格检查器检查规格](https://specscore.md/zh-cn/articles/lint-specs-in-ci/)
- [怎样写出 AI 代理能够验证的验收标准](https://specscore.md/zh-cn/articles/acceptance-criteria/)
- [SpecScore vs Kiro](https://specscore.md/zh-cn/vs/kiro/)
- [规范驱动开发工具](https://specscore.md/zh-cn/spec-driven-development/tools/)
- [规范驱动开发](https://specscore.md/zh-cn/spec-driven-development/)
- [需求规范](https://specscore.md/requirement-specification)
- [验收准则规范](https://specscore.md/acceptance-criteria-specification)
- [功能规范](https://specscore.md/feature-specification)
- [校验器与 CI](https://specscore.md/zh-cn/validators/)
