← 返回列表

AIシリーズ面接16:良いSpec Codingとはどのようなものか?

良い Spec Coding(仕様駆動プログラミング)の核心は、「曖昧なアイデア」を「正確で、検証可能で、実行可能な契約」に変えることです。単なるドキュメント作成ではなく、人とAI(または人と人)の間の曖昧さのないコミュニケーション言語を確立することです。以下では、仕様の内容構成、記述原則、AIとの協働フロー、品質検証の4つの観点から、良いSpecのあり方を示します。


一、仕様ドキュメントの標準構造(機能モジュールを例に)

セクション 必須項目
1. 目的と範囲 何をするかを一文で記述し、何をしないかを明確にする 「ユーザー登録APIを実装するが、メール検証は含まない」
2. 入出力契約 データ構造、型、必須/オプションフィールド、サンプル値 POST /register リクエストボディ {email: string, password: string}、レスポンス 201 または 400(エラーコード含む)
3. 振る舞いとロジック ビジネスルール、境界条件、状態遷移 「パスワード長は8〜20文字で、少なくとも1つの数字を含むこと。メールアドレスが既に存在する場合は 409 を返す」
4. エラーハンドリング 全ての異常シナリオと対応するエラーコード/メッセージ 「データベース接続失敗 → 503 を返し、スタックトレースを公開しない」
5. 非機能要件 パフォーマンス(応答時間 < 200ms)、セキュリティ(パラメータ化クエリ)、ログ、可観測性 「全てのSQLはプリコンパイルを使用すること。email はログに記録するが password は記録しない」
6. テストケース(重要) 少なくとも3つの代表的な入力 + 2つの境界/異常入力、期待出力を明記 下記表参照
7. 依存関係と制約 使用するライブラリ、バージョン、環境変数 「Python 3.10+、FastAPI、環境変数 DB_URL

テストケースの例(specに内包)

シナリオ 入力 期待出力
正常登録 email: a@b.com, pwd: Pass1234 201user_id を返す
パスワード短すぎ pwd: Ab1 400、エラーコード WEAK_PASSWORD
メールアドレス既存 同上 email 409、エラーコード EMAIL_EXISTS

良いSpecはまずテストケースを書くべきです。なぜなら、AIがそれらから直接ユニットテストを生成し、完了後に自動検証できるからです。


二、Spec記述の核心原則(SMART変種)

原則 説明 悪い例
正確(Precise) 具体的な数値、型、ブール条件を使用し、「できるだけ」「通常」を避ける ❌ 「パスワードは十分に安全であること」→ ✅ 「パスワードは最低8文字で、大文字、小文字、数字を含むこと」
検証可能(Verifiable) 各要件が自動テストまたは手動チェックで合格/不合格を判定できること ❌ 「コードはエレガントであること」→ ✅ 「関数の循環的複雑度 ≤ 10、重複コードブロックなし」
曖昧さなし(Unambiguous) 同じ用語をドキュメント全体で一貫して使用し、必要に応じて用語集を提供する ❌ 「ユーザーが存在しない場合、エラーを返す」→ ✅ 「ユーザーが存在しない → 404{code: 'USER_NOT_FOUND'} を返す」
完全(Complete) ハッピーパス、全ての異常パス、非機能要件をカバーする ❌ 成功シナリオのみ記述 → ✅ データベースタイムアウト、権限不足などを含める
アトミック(Atomic) 1つのspecは、独立してデリバリー可能な1つの機能を記述する(AIが一度で完了しやすいように) ❌ 1つのspecで「決済システム全体」を書く → ✅ 「支払いオーダー生成」「コールバック署名検証」「返金」に分割

三、AIとの協働におけるSpec Codingフロー

  1. 人間がspecを書く(上記の構造、特にテストケースと関数シグネチャをしっかり書く)。
  2. specを一度にAIに与える(対話的な要件追加は避け、ゆらぎ汚染を防ぐ)。
  3. AIがコード+ユニットテストを出力する(AIはspec中のテストケースに従って実行可能なテストを生成する必要がある)。
  4. テストを実行する:全て合格なら次のステップへ。不合格ならspecを修正するか、直接コードを修正する(この場合、小さなループに入るが、変更は記録する)。
  5. 人間によるレビュー:spec外の機能が導入されていないか(スコープクリープ)、セキュリティ/パフォーマンスを確認する。
  6. 固定化:specドキュメントと最終コードを一緒にリポジトリにコミットし、永続的なドキュメントとする。

重要な実践:Specのコード化——spec.md + test_spec.py を使用し、テストファイルはspecのサンプルから直接生成する。これにより、後でコードを変更する際にテストを実行するだけでspecが破壊されていないか検証できる。


四、良いSpecがもたらす効果(受け入れ基準として)

  • 決定性:同じspecを異なるAI(または異なる人)に与えても、類似した実装が得られる。
  • テスト容易性:コードを書き終えたらすぐに90%の正当性を自動検証できる。
  • 保守性:半年後に誰がspecを見ても、当初の設計意図を理解できる。
  • 低コミュニケーションコスト:チームの議論はspecについてのみ行い、具体的なコード行については議論しない。
  • セキュリティ/品質の組み込み:セキュリティ要件(例:パラメータ化クエリ)や境界条件がspecに明記され、AIが遵守しなければならない。

五、良いSpecの例(最小版)

# Spec: ユーザー登録API

## 範囲
- email, password を受け付ける
- 確認メールは送信せず、メールアドレスの実在性は確認しない

## 契約
POST /register
Content-Type: application/json
Request: { "email": string, "password": string }
Response 201: { "user_id": string }
Response 400: { "code": "INVALID_PASSWORD" | "INVALID_EMAIL" }
Response 409: { "code": "EMAIL_ALREADY_EXISTS" }

## 振る舞い
- email はRFC 5322基本フォーマット(a@b.c)に準拠すること
- password: 長さ8〜20文字、少なくとも1つの数字と1つの大文字を含む
- bcryptを使用してハッシュ化保存、ソルトコスト10
- データベース保存前にemailの重複を確認 → 重複していれば409

## テストケース(入力 -> 期待ステータスコード+レスポンスフィールド)
| 入力 email | password | 期待 |
|------------|----------|------|
| test@x.com | Pass1234  | 201, user_id が存在 |
| test@x.com | pass      | 400, INVALID_PASSWORD |
| bad        | Pass1234  | 400, INVALID_EMAIL |
| (既存のメール) | Pass1234 | 409, EMAIL_ALREADY_EXISTS |

## 非機能
- SQLはパラメータ化クエリを使用すること(インジェクション対策)
- ログに登録元IPを記録し、パスワードは記録しない
- 応答時間 95%リクエスト < 100ms (bcrypt除く)

## 依存関係
- Python 3.10+, FastAPI, bcrypt, asyncpg

良いSpec Coding = 人間の「設計判断」を、機械の「テストケース+型シグネチャ+振る舞い制約」として書き下し、AIには実装の充填だけを任せ、人間が常に品質と方向性をコントロールすることです。

评论

暂无已展示的评论。

发表评论(匿名)