---
title: "EARS記法とは？読み方と5つの基本型の書き方を日本語例文で解説【Kiro対応】"
url: "https://www.issoh.co.jp/tech/details/11489/"
published: 2026-03-24
updated: 2026-10-13
categories: ["開発"]
publisher: "株式会社一創"
---

# EARS記法とは？読み方と5つの基本型の書き方を日本語例文で解説【Kiro対応】

EARS記法（Easy Approach to Requirements Syntax、読み方は「イヤーズ」）は、要件を自然言語のまま書きつつ、**節の順序と少数のキーワード（While・When・Where・If-Then）、義務を表す「shall」で文型を固定する**書き方です。「EARS形式」「EARS構文」と呼ばれることもあり、指しているものは同じです。2009年に英ロールス・ロイスの技術者4人が、航空エンジン制御システムの要件を整理する中でまとめ、国際会議RE’09で発表しました。AWSのAI IDE「Kiro」は、仕様書（requirements.md）の受け入れ基準をEARSで書きます。

本記事では、[原論文](https://doi.org/10.1109/RE.2009.9)と考案者アリスター・メイヴィン（Alistair Mavin）氏の[公式サイト](https://alistairmavin.com/ears/)、Kiroの[公式ドキュメント](https://kiro.dev/docs/specs/feature-specs/)（いずれも2026年10月13日に確認）をもとに、構文の規則と5つの基本型、日本語での書き分け、曖昧な要件の書き直し方、型ごとのテストの作り方を整理します。テストのコードと、型に沿っているかを判定するスクリプトは、どちらも手元で実行した結果を載せています。

## まとめ：EARS記法の要点

- EARSの基本形は「While 〈前提〉, when 〈契機〉, the 〈システム名〉 shall 〈応答〉」の1本です。前提と契機は省略できますが、節の順序は変えません。
- 原論文の分類は**5つの基本型**（常時・イベント駆動・不要動作・状態駆動・オプション）と、それらを組み合わせた複合形です。「6つの型」と数える解説は、複合形を1行として数えています。
- 日本語で書くときは、「〜場合」をやめて条件を4つに書き分けます。状態は「〜の間」、契機は「〜とき」、異常は「もし〜ならば」、機能の有無は「〜を備える構成では」です。
- 型が分かると、テストで確かめることの見当が付きます。閾値のある不要動作なら手前と到達の両方、状態駆動なら状態が続く間の繰り返し、オプションなら機能の有無の両構成です。
- Gherkinは具体例（シナリオ）を書いてテストとして実行する記法、EARSは要件そのものを1文で書く記法です。Kiroのrequirements.mdは「WHEN … THE SYSTEM SHALL …」の形を使います。

## EARS記法の定義と、ロールス・ロイスで生まれた経緯

考案者サイトはEARSを「a mechanism to gently constrain textual requirements」（文章で書く要件を、ゆるやかに制約する仕組み）と説明しています。UMLや形式手法のような別の記法に置き換えるのではなく、英語の文のまま語順と語彙を縛るのが特徴です。原論文は、自然言語以外の記法を使うと元の要件からの翻訳が必要になり、そこで新たな誤りが入ること、新しい記法には教育の負担がかかることを、EARSを作った理由に挙げています。

### EARSの正式名称と読み方

EARSはEasy Approach to Requirements Syntaxの頭字語で、英単語のears（耳）と同じ綴りです。考案者は日本語のカタカナ表記を定めておらず、日本語の記事では「イヤーズ」と書かれるのが一般的です。

### 航空エンジンの認証基準CS-Eから生まれた経緯

原論文の著者は、ロールス・ロイスでFADEC（航空エンジンのデジタル制御装置）を開発していたMavin、Wilkinson、Harwood、Novakの4人です。題材は、航空エンジンの認証基準であるCS-E（Certification Specification for Engines）のうち、エンジン制御システムに関わる**CS-E 50**でした。規則の文章には、要件と設計指針、説明文が混在していました。これを要件として抜き出して書き直す中で、要件文がどれも似た構造をしていて、節の順序がそろっているときに最も読みやすいことに気づき、規則として固めたのがEARSです。

考案者サイトは、利用組織としてAirbus、Bosch、Dyson、Honeywell、Intel、NASA、Rolls-Royce、Siemensを挙げ、英語を母語としない書き手が英語で要件を書く場合に特に効果があると書いています。

## EARSの基本構文：節の順序と4つの規則

EARSの要件はすべて、次の1本の型から作られます。

```
While <optional pre-condition>, when <optional trigger>, the <system name> shall <system response>
```

考案者サイトは、1つの要件が持つ要素の数を次のように定めています。

- 前提条件（precondition）：0個以上
- 契機（trigger）：0個または1個
- システム名：1個
- システムの応答：1個以上

節の順序は時間の流れに沿っています。原論文の説明では、前提が満たされていなければ要件は有効にならず、前提が満たされた状態で契機が起きたときに初めて「発火」し、その場合に限ってシステムは応答を実現しなければなりません。「〈応答〉する。ただし〈条件〉のときに限る」のように条件を後ろに回す書き方は、この順序に反します。

主語は「システム」ではなく、**要件を満たす責任を持つシステムの名前**を書きます。原論文の例は「the control system」、考案者サイトの例は「the ATM」「the laptop」です。1つの文書に複数のサブシステムが出てくるときに、どれが応答するのかが曖昧になりません。

## 5つの基本型と複合型のテンプレート

基本形から使う節の組み合わせによって、要件は次の型に分かれます。

| 型                        | キーワード     | 有効になる条件         |
| ------------------------ | --------- | --------------- |
| 常時（Ubiquitous）           | なし        | いつでも            |
| 状態駆動（State-driven）       | While     | 指定した状態が続く間      |
| イベント駆動（Event-driven）     | When      | 契機となる事象が起きたとき   |
| オプション（Optional feature）  | Where     | その機能を備える製品のみ    |
| 不要動作（Unwanted behaviour） | If … then | 望ましくない事象が起きたとき  |
| 複合（Complex）              | 上の組み合わせ   | 組み合わせた条件が成立したとき |

英語のテンプレートは次のとおりです（考案者サイトの表記）。

```
The <system name> shall <system response>                                  # 常時
While <precondition(s)>, the <system name> shall <system response>          # 状態駆動
When <trigger>, the <system name> shall <system response>                   # イベント駆動
Where <feature is included>, the <system name> shall <system response>      # オプション
If <trigger>, then the <system name> shall <system response>                # 不要動作
While <precondition(s)>, When <trigger>, the <system name> shall <system response>  # 複合
```

### 考案者サイトの例文と和訳

- 常時：The mobile phone shall have a mass of less than XX grams.（携帯電話の質量はXXグラム未満でなければならない）
- 状態駆動：While there is no card in the ATM, the ATM shall display “insert card to begin”.（ATMにカードが入っていない間、ATMは「カードを挿入してください」と表示しなければならない）
- イベント駆動：When “mute” is selected, the laptop shall suppress all audio output.（ミュートが選択されたとき、ノートPCはすべての音声出力を止めなければならない）
- オプション：Where the car has a sunroof, the car shall have a sunroof control panel on the driver door.（サンルーフを備える車では、運転席ドアにサンルーフの操作パネルを設けなければならない）
- 不要動作：If an invalid credit card number is entered, then the website shall display “please re-enter credit card details”.（無効なカード番号が入力されたら、Webサイトはカード情報の再入力を求める表示をしなければならない）
- 複合：While the aircraft is on ground, when reverse thrust is commanded, the engine control system shall enable reverse thrust.（航空機が地上にある間に逆噴射が指令されたとき、エンジン制御システムは逆噴射を有効にしなければならない）

原論文は、状態駆動の要件ではWhileの代わりにDuringを使ってもよく、意味はWhileと同じで読みやすさのための言い換えだと書いています。

### 「5つの型」と「6つの型」の数え方の違い

原論文は基本構文が「five types of requirement」（5つの型）に分かれると書き、Complexは型としてではなく「4.7 Complex requirement syntax」として、キーワードの組み合わせ方を説明しています。考案者サイトは型の総数を明示せず、Complexを含む6つの節で各パターンを説明しています。日本語の解説に「6つのパターン」と「5つのパターン」が混在しているのはこのためで、テンプレートの中身はどちらも同じです。本記事は原論文に合わせ、「5つの基本型と複合型」と数えます。

### 不要動作をIf-Thenで独立させた理由

原論文は、望ましくない動作（故障、外乱、利用者の誤操作、連携先システムの予期しない振る舞い）への対応が初期の要件で漏れやすく、後の高くつく手戻りの主な原因になると書いています。そのため、異常系の要件だけはIf-Thenという専用の型にし、ライフサイクル全体で見分けられるようにしました。正常系のWhenばかりが並ぶ仕様書は、異常系の抜けを疑う合図です。

## 日本語でEARSを書くテンプレートと「〜場合」の使い分け

日本語は述語が文末に来るので、「条件→主語→応答」というEARSの語順はもともと日本語に合っています。つまずくのは語順ではなく、条件の書き分けです。

| 型      | 日本語テンプレート                           |
| ------ | ----------------------------------- |
| 常時     | 〈システム〉は〈応答〉しなければならない。               |
| 状態駆動   | 〈状態〉の間、〈システム〉は〈応答〉しなければならない。        |
| イベント駆動 | 〈契機〉とき、〈システム〉は〈応答〉しなければならない。        |
| オプション  | 〈機能〉を備える構成では、〈システム〉は〈応答〉しなければならない。  |
| 不要動作   | もし〈異常〉ならば、〈システム〉は〈応答〉しなければならない。     |
| 複合     | 〈状態〉の間に〈契機〉とき、〈システム〉は〈応答〉しなければならない。 |

### 「〜場合」の4種類の条件への書き分け

日本語の仕様書では、状態も契機も異常も機能の有無も「〜場合」で書けてしまいます。「アカウントがロックされている場合」は状態（While）、「ログインボタンが押された場合」は契機（When）、「パスワードを5回続けて誤った場合」は異常（If-Then）です。「二要素認証を有効にしている場合」は、製品構成として二要素認証機能を備えるという意味なら機能の有無（Where）、利用者が実行中に切り替える設定を指すなら状態（While）になります。同じ「場合」でも、テストで確かめる内容が違います。レビューで「場合」と書かれた箇所を4つのどれかに言い換えさせるだけで、条件の曖昧さの多くは表に出ます。

### shallの訳語と語尾の統一

shallは「〜しなければならない」か「〜すること」のどちらかに決め、文書全体でそろえます。「〜できる」「〜が望ましい」「〜する」が混ざると、どれが必須要件なのかが読み手によって変わります。考案者サイトの規則では1つの要件に応答を複数書けますが、応答ごとに合否を判定したいなら、文を分けておくほうがテストケースとの対応が1対1になります。

## 曖昧な要件「ログインできること」のEARSでの書き直し例

既存の曖昧な要件文をEARSで書き直す例です。

```
利用者はログインできること。何度も間違えた場合はロックし、必要に応じて二要素認証も使えるようにする。
```

この要件文には、応答するシステムの名前が書かれていません。「何度も」が連続なのか累計なのか、何回なのか、ロック中に何をするのか、「必要に応じて」が製品の構成なのか利用者の設定なのかも決まっていません。EARSで書き直すときは、次の順に問いを立てます。

1. 応答するのは誰か：主語を「認証サービス」と決める。
2. 条件はどの型か：「間違えた場合」は異常（If-Then）、ロックしたあとは状態（While）、「必要に応じて」は製品構成（Where）に分ける。
3. 合否を決める数値は何か：「何度も」を「5回続けて」に置き換える。
4. ほかの要件とぶつからないか：並べた要件どうしで、同じ状況に別々の応答を求めていないかを確かめる。

書き直した結果は次の6件です。

- 常時：認証サービスは、パスワードをソルト付きのハッシュ値としてのみ保存しなければならない。
- イベント駆動：利用者が正しい認証情報を送信したとき、認証サービスは連続誤入力の回数を0に戻さなければならない。
- 不要動作：もしパスワードの誤入力が5回続いたならば、認証サービスはアカウントをロックしなければならない。
- 状態駆動：アカウントがロックされている間、認証サービスはすべてのログイン要求を拒否しなければならない。
- オプション：二要素認証を備える構成では、認証サービスは、正しいワンタイムコードを正しい認証情報の条件に含めなければならない。
- 複合：アカウントがロックされていない間に、利用者が正しい認証情報を送信したとき、認証サービスはセッショントークンを発行しなければならない。

最後の要件は、最初は「利用者が正しい認証情報を送信したとき、セッショントークンを発行しなければならない」というイベント駆動の形で書きがちです。しかしその形だと、ロック中に正しいパスワードが送られたときに、状態駆動の「すべて拒否」とぶつかります。EARSは要件どうしの優先順位を決めないので、「ロックされていない間に」という前提を足して複合型にしました。同じように、二要素認証の構成で何が揃えば「正しい」のかをオプションの要件で決めています。

なお、この6件には、回数（5回）・数え方（連続）・保存方式など、元の1文に書かれていなかった決定が入っています。型に当てはめることで決めるべき空欄は見えるようになりますが、空欄を埋める内容は書き手が勝手に決めず、依頼者と合意して決めるものです。

## EARSの型ごとのテストケース設計とpytestの実行例

EARSの1文は「どの条件で、誰が、何をするか」が決まっているので、型からテストで確かめることの見当が付きます。次の表は、上のログイン要件をテストにしたときの対応です。型ごとの普遍的な規則ではなく、この例での対応として見てください。

| 型      | 確かめること      | この例のケース                     |
| ------ | ----------- | --------------------------- |
| 常時     | 不変条件        | すべての利用者で成り立つ                |
| イベント駆動 | 契機の後の応答     | 3回誤ったあとに正しく送る               |
| 不要動作   | 異常の閾値       | 手前（4回）と到達（5回）               |
| 状態駆動   | 状態が続く間の応答   | 状態中に複数の入力を繰り返す              |
| オプション  | 構成による差      | 機能あり・なしの両構成と、コードの未入力・誤り・再利用 |
| 複合     | 前提と契機の組み合わせ | 前提を満たした状態で契機を起こす            |

複合型の要件のうち、前提を満たさない側（ロック中に正しく送る）は状態駆動のテストが受け持っています。テスト対象の最小実装を`auth.py`として保存します。パスワードの保存には標準ライブラリの`hashlib.pbkdf2_hmac`を使っています。反復回数は教材用の値です。ワンタイムコードも「1回使ったら無効にする」だけの簡略化で、実際の二要素認証は時間や回数による失効を伴います。実運用の方式と設定は別途選んでください。

```
import hashlib
import os
import secrets


class AuthService:
    """ログイン要件（EARS）を満たす最小の認証サービス（教材用）"""

    MAX_FAILURES = 5
    ITERATIONS = 100_000  # 教材用の値。実運用の推奨値ではない

    def __init__(self, two_factor=False):
        self.two_factor = two_factor  # オプション機能（製品構成で決まる）
        self.users = {}
        self.otp = {}
        self.failures = {}
        self.locked = set()

    def _hash(self, password, salt):
        return hashlib.pbkdf2_hmac("sha256", password.encode(), salt, self.ITERATIONS)

    def register(self, user, password, otp=None):
        salt = os.urandom(16)
        self.users[user] = (salt, self._hash(password, salt))
        self.otp[user] = otp

    def _valid(self, user, password, otp):
        salt, digest = self.users[user]
        if self._hash(password, salt) != digest:
            return False
        if not self.two_factor:
            return True
        return bool(otp) and otp == self.otp[user]  # 未登録・未入力・空文字は通さない

    def login(self, user, password, otp=None):
        valid = self._valid(user, password, otp)
        if valid:
            self.failures[user] = 0
        if user in self.locked:
            return {"ok": False, "reason": "locked"}
        if not valid:
            self.failures[user] = self.failures.get(user, 0) + 1
            if self.failures[user] >= self.MAX_FAILURES:
                self.locked.add(user)
            return {"ok": False, "reason": "invalid"}
        if self.two_factor:
            self.otp[user] = None  # 使ったコードは無効にする（教材用の簡略化）
        return {"ok": True, "token": secrets.token_urlsafe(16)}
```

同じディレクトリに`test_auth.py`として次のテストを保存します。テスト関数のコメントに元のEARS要件を英語で残しておくと、要件とテストの対応表を別に作らなくても追えます。要件からテストまでの対応づけ全般は[ITのトレーサビリティ](/tech/details/16816/)で扱っています。

```
import hashlib

import pytest

from auth import AuthService

PASSWORD = "correct horse"


@pytest.fixture
def svc():
    s = AuthService()
    s.register("alice", PASSWORD)
    return s


# 常時：The auth service shall store passwords only as salted hashes.
def test_ubiquitous_password_is_stored_as_salted_hash(svc):
    svc.register("bob", PASSWORD)
    for salt, digest in svc.users.values():
        expected = hashlib.pbkdf2_hmac("sha256", PASSWORD.encode(), salt, AuthService.ITERATIONS)
        assert digest == expected and digest != PASSWORD.encode()
    assert svc.users["alice"][1] != svc.users["bob"][1]  # ソルトが違えば同じパスワードでも別の値


# イベント駆動：When the user submits valid credentials, the auth service shall reset the consecutive failure count to zero.
def test_event_valid_credentials_reset_failure_count(svc):
    for _ in range(3):
        svc.login("alice", "wrong")
    svc.login("alice", PASSWORD)
    assert svc.failures["alice"] == 0


# 不要動作：If the password is wrong five times in a row, then the auth service shall lock the account.
@pytest.mark.parametrize("failures, locked", [(4, False), (5, True)])
def test_unwanted_lock_after_five_failures(svc, failures, locked):
    for _ in range(failures):
        svc.login("alice", "wrong")
    assert ("alice" in svc.locked) is locked


# 状態駆動：While the account is locked, the auth service shall reject all sign-in attempts.
@pytest.mark.parametrize("password", [PASSWORD, "wrong", ""])
def test_state_locked_account_rejects_every_attempt(svc, password):
    svc.locked.add("alice")
    for _ in range(3):
        assert svc.login("alice", password) == {"ok": False, "reason": "locked"}


# オプション：Where two-factor authentication is included, the auth service shall require a correct one-time code as part of valid credentials.
@pytest.mark.parametrize(
    "two_factor, otp, ok",
    [(True, None, False), (True, "", False), (True, "000000", False), (True, "123456", True), (False, None, True)],
)
def test_optional_two_factor_requires_otp(two_factor, otp, ok):
    s = AuthService(two_factor=two_factor)
    s.register("alice", PASSWORD, otp="123456")
    assert s.login("alice", PASSWORD, otp=otp)["ok"] is ok


def test_optional_unregistered_code_is_rejected():
    s = AuthService(two_factor=True)
    s.register("alice", PASSWORD)  # コード未登録
    assert s.login("alice", PASSWORD)["ok"] is False


def test_optional_one_time_code_cannot_be_reused():
    s = AuthService(two_factor=True)
    s.register("alice", PASSWORD, otp="123456")
    assert s.login("alice", PASSWORD, otp="123456")["ok"] is True
    assert s.login("alice", PASSWORD, otp="123456")["ok"] is False


# 複合：While the account is not locked, when the user submits valid credentials, the auth service shall issue a session token.
def test_complex_unlocked_valid_credentials_issue_token(svc):
    token = svc.login("alice", PASSWORD).get("token")
    assert isinstance(token, str) and token
```

pytestを入れて（`python3 -m pip install pytest`）、Python 3.9.6とpytest 8.4.2で実行した結果です。

```
$ python3 -m pytest -q test_auth.py
...........                                                              [100%]
15 passed in 8.55s
```

テストが要件を本当に確かめているかは、実装をわざと壊して流すと分かります。この方法は[ミューテーションテスト](/tech/details/16261/)と呼ばれます。`auth.py`を1か所ずつ壊して同じテストを流した結果です。

| 壊した箇所                    | 落ちたテスト          | 結果                  |
| ------------------------ | --------------- | ------------------- |
| ロック判定の`>=`を`>`に（6回目でロック） | 不要動作の\[5-True\] | 1 failed, 14 passed |
| 成功時にトークンを返さない            | 複合              | 1 failed, 14 passed |
| 成功時に誤入力の回数を戻さない          | イベント駆動          | 1 failed, 14 passed |
| 未入力のコードを拒否しない            | オプション（コード未登録）   | 1 failed, 14 passed |
| 使ったコードを無効にしない            | オプション（再利用）      | 1 failed, 14 passed |

不要動作のテストに手前の4回と到達の5回を並べているのは、片側だけでは見逃す実装があるからです。5回のケースだけでは「1回でロックする」ように早すぎる実装を、4回のケースだけでは「6回でロックする」ように遅すぎる実装を見逃します。状態駆動のテストで正しいパスワードを入力に含めているのも同じ考え方で、「ロック中は誤ったパスワードだけを拒否する」という取り違えを拾うためです。

## 原論文が測ったEARSの効果と限界

原論文は、自然言語の要件によく起きる問題を8つ挙げ、CS-E 50の規則文とEARSで書き直した要件とで、それぞれの件数を数えました。8つとは、曖昧さ（ambiguity）、漠然さ（vagueness）、複雑さ（complexity）、漏れ（omission）、重複（duplication）、冗長さ（wordiness）、実装方法の記述（inappropriate implementation）、検証不能（untestability）です。

| 項目         | 規則の原文 | EARSで書き直した要件 |
| ---------- | ----- | ------------ |
| 要件の件数      | 36件   | 47件          |
| 1件あたりの平均語数 | 36.9語 | 25.6語        |

件数が増えたのは、1つの条文に詰め込まれていた複合的な要件を、1件ずつに分けたためです。論文によると、複雑さ・漏れ・重複・実装方法の記述・検証不能の5つは書き直し後に見当たらなくなり、曖昧さ・漠然さ・冗長さの3つは減ったものの残りました。ただし漏れについては、異常系の要件をいくつか拾えただけで、ほかの抜けを見つけた証拠はないと著者自身が注意書きを付けています。

### 論文自身が挙げた3つの限界

- 標本が小さい：元の要件は36件だけ。
- 対象が偏っている：上位レベルの安全関連要件に限られ、他の種類や下位レベルの要件がEARSで書き切れるかは確かめていない。
- 判定が主観的：漠然さの分類は評価者の判断に左右される。

この数字は「EARSにすれば要件の質がこれだけ上がる」という一般的な保証ではなく、36件の事例での結果です。EARSが保証するのは文の形であって、内容が正しいかどうかではありません。「現行どおり動作しなければならない」は形としては常時型ですが、何が現行なのかが書かれていなければ検証できません。

### 後続論文で補われた点（2010年・2016年）

限界のうち「標本が小さい」は、翌年の続編で広げられています。Mavin氏とWilkinson氏の[Big Ears（RE’10）](https://doi.org/10.1109/RE.2010.39)は、CS-E全体、267件の要件文を持つ汎用サブシステム要件書、ある開発計画の3階層にまたがる418件の安全要件という3つの文書群にEARSを当て、要件の性質に合わせてテンプレートを手直ししました。この論文は、2つ以上の要件が絡み合うもの、前提条件が3つ以上あるもの、契機が2つ以上あるものを「複雑さ」の問題として数えています。多数の条件の組み合わせで動く機能については、真理値表で全組み合わせを洗い出してからEARSのテンプレートに流し込むことを勧めています。

それまでの産業界での適用経験をまとめた[Listens Learned（RE’16）](https://doi.org/10.1109/RE.2016.38)は、EARSに固有の教訓を8つの見出しで挙げています。

| 見出し（原文）                                        | 和訳                 |
| ---------------------------------------------- | ------------------ |
| Training should be short                       | 研修は短くてよい           |
| Use with or without a tool                     | ツールの有無を問わず使える      |
| Coaching to embed learning                     | 定着にはコーチングが要る       |
| Challenge the EARS Pattern                     | 選んだ型が要件に合っているかを見直す |
| Are the EARS clauses necessary and sufficient? | 節に過不足はないか          |
| Non-functional requirements                    | 非機能要件              |
| Safety and reliability requirements            | 安全性・信頼性の要件         |
| EARS helps authors of all abilities            | 書き手の力量を問わず役立つ      |

同論文も、下書きの要件に節や条件が多すぎるときは、真理値表など別の記法で表すべきだとしています。2010年論文の「前提条件3つ以上」は問題を数えるための集計基準で、何個から表にすべきかという規則ではありません。条件を重ねて1文が読みにくくなったら、EARSにこだわらず表に分けるのが考案者たちの勧め方です。

## EARSとGherkin・ユーザーストーリーの違い

EARSとよく比べられるのが、Cucumberなどで使うGherkin（Given-When-Then）です。どちらにもWhenが出てきますが、書く対象が違います。

| 観点       | EARS               | Gherkin             | ユーザーストーリー                 |
| -------- | ------------------ | ------------------- | ------------------------- |
| 書くもの     | システムが満たすべき要件       | 具体例のシナリオ            | 利用者にとっての価値                |
| 基本形      | the 〈システム〉 shall … | Given / When / Then | As a … I want … so that … |
| 1文の単位    | 要件1件               | 操作の1ステップ            | 機能の要望1件                   |
| テストとして実行 | しない                | ステップ定義と結び付けて実行      | しない                       |

EARSの1文は、指定した前提条件や契機が成立する範囲で、システムが満たすべき規則を表します。Gherkinのシナリオは、「残高1,000円の口座から500円を引き出す」のような1つの具体例です。両者は置き換える関係ではなく、EARSで書いた要件1件に、正常値・境界値・異常値のGherkinシナリオを数本ぶら下げる使い方ができます。上の不要動作の要件なら、「4回誤入力してもロックされない」「5回目でロックされる」の2本です。Gherkinのキーワードと.featureファイルの書き方は[Gherkinの構文と.featureファイルの書き方](/tech/details/11693/)、Javaで実行する手順は[CucumberによるJavaのテスト自動化](/tech/details/3639/)、シナリオを軸に開発を進める考え方は[BDD（振る舞い駆動開発）](/tech/details/16255/)で解説しています。

ユーザーストーリーは「誰が何のためにその機能を欲しいか」を短く示し、振る舞いの細部は対話や受け入れ基準で具体化します。Kiroのrequirements.mdも、ユーザーストーリーの下に受け入れ基準をEARSで並べる構成です。要件の粒度そのものの決め方は[要求定義と要件定義の違い](/column/details/16305/)と[機能要件と非機能要件の違い](/column/details/3715/)を参照してください。

## KiroやClaude CodeでEARSを書かせるときの注意点

[AWSのAI IDE「Kiro」](/tech/details/7963/)は、仕様（spec）を requirements.md・design.md・tasks.md の3ファイルに分けて作り、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
```

3つのファイルを1回で生成する[Quick Spec](https://kiro.dev/docs/specs/quick-spec/)でも、requirements.md は「user stories and acceptance criteria in EARS notation」と説明されています。Quick Specは段階ごとの承認を挟まずに進むので、生成された要件を人が読まないまま設計に進みやすい点に注意します。

### Kiroの書式と原典EARSの差

Kiroのドキュメントに定型として出てくるのは、イベント駆動型の「WHEN … THE SYSTEM SHALL …」です。原典のWhile・Where・If-Thenの型は定型に含まれていません。ロック中は拒否し続けるといった状態の制約や異常系が重要な機能では、生成された requirements.md をレビューするときに、原典の型で書くべき要件が抜けていないかを確かめます。ドキュメントの定型と例が主語を「THE SYSTEM」と書いている点も、具体的なシステム名を主語にする原典と違います。複数のサービスにまたがる機能では、応答する側のサービス名に書き換えたほうが設計に落としやすくなります。

バグ修正用の[Bugfix Spec](https://kiro.dev/docs/specs/bugfix-specs/)では、「WHEN 〈条件〉 THEN the system SHALL CONTINUE TO 〈既存の動作〉」という、直してはいけない動作を書く型が加わっています。回帰を防ぐためのKiro独自の書き方で、原論文にはありません。

### Analyze Requirementsとプロパティベーステスト

requirements.md を作ったあと、design に進む前に[Analyze Requirements](https://kiro.dev/docs/specs/analyze-requirements/)を実行すると、要件全体を横断して、論理的な矛盾、曖昧な表現（「大きなファイル」「速い応答」など）、両立しない制約、書かれていない前提、抜けている境界ケースを質問の形で返します。IDEでは Continue のメニューから、CLIでは `/spec analyze_requirements` で実行でき、Web版では現時点で使えません。ドキュメントは、要件を人が確認せずに自動生成したQuick Specのセッションを、特に実行すべき場面に挙げています。

この解析にEARSの文型が効いている理由は、Kiroの技術ブログ「[Requirements analysis: catching requirement bugs before they become code](https://kiro.dev/blog/deep-spec-analysis/)」（2026年5月12日）に書かれています。LLMで要件を形式論理（SMT-lib）に変換し、SMTソルバーで矛盾や抜けを探す仕組みで、EARSの各文は「WHERE/WHILE/WHEN/IF節が前件、THE … SHALL節が後件」という含意にそのまま対応すると説明されています。条件を文頭にそろえるというEARSの規則は、機械が論理式に変換するときの手がかりにもなっています。

もう1つは、EARSの受け入れ基準から[プロパティベーステスト](https://kiro.dev/docs/specs/correctness/)を作る機能です。ドキュメントは「任意の利用者と任意の車について、WHEN 利用者が車をお気に入りに追加する、THE System SHALL それを一覧に表示する」のような例を挙げており、対応しているのは現時点でIDEのみです。ランダムな入力で性質を確かめるテストの書き方そのものは[プロパティベーステストとは](/tech/details/16259/)で解説しています。

### Claude Code・Cursorに書かせるときの指示文

Claude CodeはプロジェクトのCLAUDE.mdを[セッションの開始時に読み込み](https://code.claude.com/docs/en/memory)、Cursorは[.cursor/rules](https://cursor.com/docs/context/rules)に置いた`.mdc`ファイルをプロジェクトのルールとして読み込みます。Cursorでは拡張子を`.mdc`にし、先頭の設定（frontmatter）で常に適用する（`alwaysApply: true`）か対象ファイルを指定します。拡張子が`.md`のままだと無視されるので、Markdownのまま置きたい場合はプロジェクト直下の`AGENTS.md`を使います。EARSで要件を書かせたいときは、型の一覧に加えて「使わない言葉」と「異常系の書き漏らし防止」まで書いておくと、生成結果のばらつきが減ります。CLAUDE.mdに置く例です。

```
## 要件の書き方（EARS）
- 要件は1文1件で書く。主語は応答するサービス名にする（例：認証サービス）
- 条件は文頭に置き、次のどれかの型で書く
  - 常時：〈サービス〉は〈応答〉しなければならない。
  - 状態：〈状態〉の間、〈サービス〉は〈応答〉しなければならない。
  - 契機：〈契機〉とき、〈サービス〉は〈応答〉しなければならない。
  - 異常：もし〈異常〉ならば、〈サービス〉は〈応答〉しなければならない。
  - 構成：〈機能〉を備える構成では、〈サービス〉は〈応答〉しなければならない。
- 「〜場合」「適切に」「速やかに」「必要に応じて」は使わない。回数・期限・表示文言は数値か逐語で書く
- 契機の要件ごとに異常系（誤入力・通信断・権限なし等）を検討する。動作が決まっていないものは要件にせず「未確定」として列挙する
- 各要件の下に、確かめるテストのケースを1行で書く（閾値は手前と到達の両方）
```

生成された要件は、そのまま採用せずに人がレビューします。上の「ログインできること」の例のように、ロック中の扱いなど元の要望に書かれていない論点を、AIが推測で埋めていることがあるためです。仕様駆動開発の考え方は[仕様駆動開発（SDD）とは](/tech/details/8740/)、Kiro以外のツールの違いは[仕様駆動開発ツール比較](/tech/details/8732/)、生成AIで要件定義をどこまで任せられるかは[要件定義はAIでどこまで自動化できるか](/tech/details/15349/)で扱っています。要件定義そのものを外部と一緒に進めたい場合は、弊社の[要件定義・RFP作成・PMO支援](/service/system/pmo/)でも支援しています。

## EARSの型に沿っているかを判定するPythonスクリプト

EARSは文頭のキーワードと節の順序が決まっているので、型に沿っていない文はある程度まで機械的に拾えます。次のスクリプトは、英語で書いた要件ファイルを1行ずつ読み、どの型に近いか、条件が応答の後ろに回っていないか、shallが2つ以上ないか、曖昧語が入っていないかを表示します。標準ライブラリだけで動きます。カンマで節を区切った英文を前提にした簡易チェックで、OKは「型の外形に合っている」という意味にとどまります。

```
import re
import sys

# EARSの5パターン＋複合形を、文頭のキーワードで判定する（カンマ区切りの英文が前提）
PRE = r"(While|During|Where)"
PATTERNS = [
    ("Complex(不要動作)", re.compile(rf"^({PRE}|When) .+, if .+, then the .+ shall .+", re.I)),
    ("Complex",           re.compile(rf"^{PRE} .+, (while|during|where|when) .+, the .+ shall .+", re.I)),
    ("Unwanted",          re.compile(r"^If .+, then the .+ shall .+", re.I)),
    ("State-driven",      re.compile(r"^(While|During) .+, the .+ shall .+", re.I)),
    ("Event-driven",      re.compile(r"^When .+, the .+ shall .+", re.I)),
    ("Optional",          re.compile(r"^Where .+, the .+ shall .+", re.I)),
    ("Ubiquitous",        re.compile(r"^The .+ shall .+", re.I)),
]
VAGUE = re.compile(r"\b(fast|quickly|user-friendly|appropriate|as soon as possible|etc)\b", re.I)

def check(line):
    kind = next((name for name, p in PATTERNS if p.match(line)), None)
    problems = []
    if kind is None:
        problems.append("EARSのどの型にも当てはまらない")
    if len(re.findall(r"\bshall\b", line, re.I)) > 1:
        problems.append("shallが2つ以上（要件の分割を検討）")
    if re.match(r"^If\b", line, re.I) and not re.search(r",\s*then\b", line, re.I):
        problems.append("Ifにthenが無い")
    response = re.split(r"\bshall\b", line, maxsplit=1, flags=re.I)[-1]
    if re.search(r"\b(when|while|during|where|if)\b", response, re.I):
        problems.append("条件が応答の後ろにある（節の順序）")
    for w in VAGUE.findall(line):
        problems.append(f"曖昧語「{w}」")
    return kind, problems

for n, line in enumerate(open(sys.argv[1], encoding="utf-8"), 1):
    line = line.strip()
    if not line or line.startswith("#"):
        continue
    kind, problems = check(line)
    print(f"{n:>2} {kind or '-':<16} {'OK' if not problems else ' / '.join(problems)}")
```

要件ファイル reqs.txt の例です。2〜7行目は上のログイン要件の英語版、8行目は状態駆動型をDuringで書いた形、9行目以降の5行はわざと崩した形です。

```
# 要件ファイル（1行1要件）
The auth service shall store passwords only as salted hashes.
When the user submits valid credentials, the auth service shall reset the consecutive failure count to zero.
While the account is locked, the auth service shall reject all sign-in attempts.
Where two-factor authentication is included, the auth service shall require a correct one-time code as part of valid credentials.
If the password is wrong five times in a row, then the auth service shall lock the account.
While the account is not locked, when the user submits valid credentials, the auth service shall issue a session token.
During maintenance, the auth service shall reject new sessions.
When the user logs in, the auth service shall respond fast.
If the token has expired the auth service shall redirect to the login page.
The auth service shall log each attempt and shall notify the administrator.
The auth service shall lock the account when the password is wrong five times.
Users can reset their password.
```

`python3 ears_lint.py reqs.txt` の実行結果です（Python 3.9.6で確認）。

```
 2 Ubiquitous       OK
 3 Event-driven     OK
 4 State-driven     OK
 5 Optional         OK
 6 Unwanted         OK
 7 Complex          OK
 8 State-driven     OK
 9 Event-driven     曖昧語「fast」
10 -                EARSのどの型にも当てはまらない / Ifにthenが無い
11 Ubiquitous       shallが2つ以上（要件の分割を検討）
12 Ubiquitous       条件が応答の後ろにある（節の順序）
13 -                EARSのどの型にも当てはまらない
```

10行目は「If」に対応する「then」を落としたため、どの型にも当たりません。11行目は記録と通知という2つの応答を1文に入れています。規則上は誤りではありませんが、テストと1対1にしたいなら分けます。12行目は条件を応答の後ろに置いたため、形の上では常時型に見えても節の順序が崩れています。13行目はシステム名とshallを明示していない自然文です。カンマを含む長い条件や、キーワードを3つ以上重ねた複合型は誤判定することがあり、内容の正しさも判定できないので、CIでは警告として出し、レビューで直す使い方が向いています。

## EARS記法に関するよくある質問

### EARS記法の読み方と正式名称は何ですか？

正式名称はEasy Approach to Requirements Syntaxで、英単語のears（耳）と同じ綴りです。考案者は公式のカタカナ表記を定めていませんが、日本語では「イヤーズ」と読むのが一般的です。

### EARS形式とEARS記法は違うものですか？

同じものです。考案者サイトはnotation（記法）とsyntax（構文）の両方の語を使っており、日本語では「EARS記法」「EARS形式」「EARS構文」と訳し分けられているだけです。Kiroのドキュメントは「EARS notation」「EARS format」の両方を使っています。

### EARS記法の型は5つですか、6つですか？

原論文（2009年）は5つの基本型（常時・イベント駆動・不要動作・状態駆動・オプション）とし、複合型はそれらの組み合わせ方として説明しています。複合型を数に含めると6つになります。テンプレートの中身は同じです。

### EARSとGherkin（Given-When-Then）はどう違いますか？

EARSは指定した条件のもとで満たすべき要件を1文で書き、Gherkinは1つの具体例をシナリオとして書いてテストとして実行します。EARSの要件1件に、境界値や異常値のGherkinシナリオを複数ひも付けて使えます。

### KiroではEARSをどう使いますか？

Kiroは仕様の requirements.md を「WHEN 〈条件〉 THE SYSTEM SHALL 〈振る舞い〉」の形で生成します。生成後に Analyze Requirements を実行すると、矛盾や曖昧さ、抜けている境界ケースを指摘します。IDE版では、EARSの受け入れ基準からプロパティベーステストを作ることもできます。

## 関連記事

- [Gherkinとは？構文の全キーワードと.featureファイルの書き方](/tech/details/11693/)
- [Kiroとは？AWS製の仕様駆動AI IDEの特徴・料金・使い方を解説【2026年版】](/tech/details/7963/)
- [仕様駆動開発（SDD）とは？従来手法との違いとSpec Kitで試す手順【2026年10月】](/tech/details/8740/)
- [プロパティベーステストとは？性質の書き方と縮小・再現の仕組みを実装者向けに解説](/tech/details/16259/)
- [機能要件とは？非機能要件・業務要件との違いと定義する5つの事項](/column/details/3715/)

---

出典: [EARS記法とは？読み方と5つの基本型の書き方を日本語例文で解説【Kiro対応】](<https://www.issoh.co.jp/tech/details/11489/>)（株式会社一創）
