文章

EARS 需求语法详解与示例

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

最近更新:2026年11月2日

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。他们在从适航规章 Certification Specification for Engines(CS-E)第 CS-E 50 节抽取发动机控制需求时建立这些规则。原文把需求、设计指导和注释混在一起。

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

Mavin 自己的指南把 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 需求规范用自己的话说了同一件事:每个 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 的功能规格页面标明更新于 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。

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

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

这项分析是 Kiro 内部的一步。功能规格页面没有把它写成你可以加进自己 CI 的格式检查器。其他工具如何检查规范,见工具指南。两个产品的比较是 SpecScore vs Kiro。

同一条需求写成 SpecScore

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

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

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

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

spec/features/checkout/README.md
---
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 规则拒绝了更短的描述。
---
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。
# 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。
# 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 步骤。

把需求放进 CI 可以拒绝的文件里。

发现翻译问题或有改进此页面的想法?