# EARS 需求語法詳解與範例

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

最近更新：2026年11月2日

[EARS](https://alistairmavin.com/ears/)（Easy Approach to Requirements Syntax）是一種需求記法：一小套英語句式，也叫 EARS 語法，把條件、觸發和系統回應固定在同一順序裡。需求是系統必須滿足的一條可檢驗義務。[規範驅動開發](https://specscore.md/zh-tw/spec-driven-development/)（SDD，spec-driven development）是在寫程式之前把這條義務寫進規範，並把規範當作事實來源。產品需求文件（PRD，product requirements document）是在把工作拆成任務之前，用散文說明問題和範圍。在 [SpecScore](https://specscore.md/) 裡，需求（REQ）是功能內部一條有名字的規則，驗收準則（AC，acceptance criterion）是可選的抽象條件，指向其中一條或多條規則。[持續整合](https://specscore.md/zh-tw/validators/)（CI，continuous integration）是對每一項提議變更的自動檢查。這項檢查是[命令列介面](https://specscore.md/zh-tw/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-tw/spec-driven-development/tools/)。兩個產品的比較是 [SpecScore vs Kiro](https://specscore.md/zh-tw/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-tw/articles/feature-spec-template/)
- [在 CI 中用規格檢查器檢查規格](https://specscore.md/zh-tw/articles/lint-specs-in-ci/)
- [寫出 AI 代理驗得過的驗收標準](https://specscore.md/zh-tw/articles/acceptance-criteria/)
- [SpecScore vs Kiro](https://specscore.md/zh-tw/vs/kiro/)
- [規範驅動開發工具](https://specscore.md/zh-tw/spec-driven-development/tools/)
- [規範驅動開發](https://specscore.md/zh-tw/spec-driven-development/)
- [需求規範](https://specscore.md/requirement-specification)
- [驗收準則規範](https://specscore.md/acceptance-criteria-specification)
- [功能規範](https://specscore.md/feature-specification)
- [校驗器與 CI](https://specscore.md/zh-tw/validators/)
