0:00 0:00
記事
Claude Codeの成功率を上げる制約条件と受け入れ条件の作り方:実装・UI・テスト別の書き方
Claude Codeに曖昧な依頼で失敗されないために、実装・UI・テスト・レビューの観点別に「制約条件」と「受け入れ条件」をどう書くかを整理します。コピペ可能な例を多めに紹介します。
結論:依頼文に「制約条件」と「受け入れ条件」を必ず両方書く
Claude Codeの成功率を一気に上げる方法は、難しい設定ではなく**「制約条件」と「受け入れ条件」を依頼文の中で明確に分けて書くこと**です。
- 制約条件(Constraints): 作業中に守るべきルール。「触ってはいけない」「使ってはいけない」「変えてはいけない」を扱います。
- 受け入れ条件(Acceptance Criteria): 完了判定の基準。「何が満たされたら終わりか」を、できる限りコマンドや観測可能な結果で表現します。
公式のベストプラクティスでは「Give Claude a way to verify its work(検証手段を与える)」が最も効果が高い1点と明言されています。受け入れ条件はこれを依頼文の中で強制するための仕組みです。
依頼文の基本構造(目的・背景・制約・完了条件などの7ブロック)はプロンプトの基本構造で扱っています。本記事はその中の「制約」と「完了条件」だけを掘り下げます。
「制約」と「受け入れ条件」を分けるとなぜ効くか
両者を混ぜると、Claude Codeはどこを守ればよいのかが曖昧になります。たとえば「テストが緑になればOK。ただしモック禁止」と1行に書くより、次のように分けると判断がブレません。
## 制約
- モックは使わない
- 既存の `__mocks__/` を増やさない
- 環境変数や秘密情報をテストに書かない
## 受け入れ条件
- `npm test -- src/services/order` が緑
- 追加テストが3件以上
- 公開関数のシグネチャは変更されていない
制約はプロセス、受け入れ条件は結果を扱います。レビューの観点も自然に分かれます。
制約条件の書き方(種類別)
制約は次の5カテゴリで考えると漏れにくいです。
1. スコープ制約(触ってよい / 触らない範囲)
- 触ってよい: src/services/order/ と test/services/order/
- 触ってはいけない: src/services/order/repository.ts(次回タスク)
- 他ディレクトリの便乗修正は禁止
範囲指定がないと、Claude Codeは関連ファイルまで「ついでに」直しがちです。これは公式ドキュメントの「Scope the task」項目で明示されています。
2. 依存制約(パッケージ・外部サービス)
- 新規 npm パッケージの追加は禁止
- 既存の lodash・date-fns を使ってよい
- 外部API呼び出しは追加しない
- DB スキーマやマイグレーションは変更しない
依存追加を黙認すると、package.json差分が紛れて事故になります。
3. 互換制約(後方互換・公開API)
- 公開関数のシグネチャは変更しない
- 戻り値の型・例外の種類・キー名は維持する
- 破壊的変更が必要なら、計画段階で明示してから承認を待つ
リファクタリング系では特に重要です。詳しくは既存コードを壊さずリファクタリングする依頼文を参照してください。
4. 品質制約(コーディング規約)
- 既存のコーディング規約(ESLint)に従う
- 新規ファイルは TypeScript の strict 設定で書く
- 一関数あたり50行以下、ネスト3段以下を目安にする
- console.log は本番コードに残さない(テストは可)
規約はチームごとに違うため、共通分はCLAUDE.mdに書いておけば毎回の依頼文が短くなります。CLAUDE.mdの整備は最初に作るべきCLAUDE.mdの書き方を参照してください。
5. セキュリティ制約
- 環境変数や秘密情報をコードに直書きしない
- ログに個人情報を出力しない
- ユーザー入力は必ずバリデーションを通す
- SQL は必ずパラメータ化クエリで書く
これは依頼ごとに書くより、CLAUDE.mdに共通制約として書く運用が現実的です。
受け入れ条件の書き方(種類別)
受け入れ条件は観測可能・自動検証可能であるほどよい依頼文になります。観点別に整理します。
A. 自動テストで検証できる条件
- `npm test -- src/services/order` が緑(追加テスト3件以上)
- `npx tsc --noEmit` でエラーなし
- `npm run lint` で新規警告なし
- 既存テストの期待値は書き換えない
検証コマンドを書くと、Claude Codeは実装後に自分で実行して結果を確認します。
B. UI・デザインで検証できる条件
- スクリーンショットを取り、添付した design.png と比較
- ブレークポイント 375px / 768px / 1280px の3種で崩れがない
- ダークモードでも文字色とのコントラストが WCAG AA 以上
- フォーカスリングが見える(キーボード操作可能)
公式ドキュメントのVerify UI changes visuallyにあるように、スクリーンショット比較を依頼文に組み込むと、UIタスクの精度が上がります。Chrome連携が利用できる環境ではClaude in Chromeも組み合わせられます。
C. 振る舞い・パフォーマンスで検証できる条件
- 1万件入力で 200ms 以内にレスポンスが返る(手元の Macbook で)
- メモリ使用量が処理前後で 100MB 以内に収まる
- 連続 100 リクエストでエラー率 0%
数値を入れると、Claude Codeは計測スクリプトを書いて自分で確認します。
D. ドキュメント・コメント条件
- 公開関数には JSDoc を1〜2行で付与
- README に新コマンドの使い方を3行追記
- BREAKING CHANGE がある場合は CHANGELOG に1行追記
書きすぎ注意です。「書く必要のないドキュメントを増やさない」ことも制約として書いておくと過剰生成を防げます。
E. レビュー前提条件
- 1コミット = 1意図
- 1PRあたり 300 行以下を目安(超える場合は分割案を出す)
- コミットメッセージは "feat(scope): summary" の形式
- PR 説明に 「変更点・テスト方法・スクリーンショット」を3節で書く
公開前のレビュー負荷を下げる効果があります。
タスク種類別:制約+受け入れ条件のセット例
例1: 入力バリデーションの追加
## 目的
@src/forms/signup.ts のメール入力に、空文字・@不在・ドメイン不正のバリデーションを追加する。
## 制約
- 触ってよい: src/forms/signup.ts と test/forms/signup.test.ts
- 触ってはいけない: 他フォーム(src/forms/login.ts など)
- 新規依存は不可(zod は既に入っているので利用可)
- 公開関数 validateSignup のシグネチャは変えない
## 受け入れ条件
- `npm test -- src/forms/signup` が緑、追加テスト3件以上
- `npx tsc --noEmit` でエラーなし
- 不正入力時のエラーメッセージが日本語で1文以内
例2: API のページング対応
## 目的
@src/api/users.ts の GET /users をカーソル方式ページングに対応させる。
## 制約
- 既存の offset 方式は維持(破壊的変更にしない)
- 新規依存は不可
- DBスキーマは変更しない
## 受け入れ条件
- 新パラメータ cursor / limit を受け付ける
- limit のデフォルトは 20、最大は 100
- カーソル無効時は 400 を返す
- `npm test -- src/api/users` が緑(cursor 系テスト4件以上)
- `curl 'http://localhost:3000/users?limit=20'` の結果に next_cursor が含まれる
例3: バグ修正
## 目的
セッションタイムアウト後に画面が真っ白になる問題を直す。
## 制約
- 触ってよい: src/auth/ と関連テスト
- 触ってはいけない: src/api/ 配下(次回タスク)
- 暫定対応(catch して隠す)はしない。根本原因を直す
## 受け入れ条件
- 失敗テスト(10分放置→画面遷移→真っ白を再現)を先に書き、緑になることを確認
- 実際の動作で再ログイン画面に遷移する
- `npm test -- src/auth` が緑
公式ドキュメントのAddress root causes, not symptomsに対応する書き方です。「暫定対応はしない」と明示するのが鍵になります。
例4: UI改善
## 目的
@src/components/Card.tsx の余白とフォントサイズを、design.png に合わせる。
## 制約
- 触ってよい: src/components/Card.tsx と関連 stories
- 既存のデザイントークン(src/styles/tokens.ts)を使う
- インラインスタイルではなく既存の className 体系で書く
## 受け入れ条件
- 修正後のスクリーンショットを取り、design.png と比較して差分が「余白とフォントサイズ」だけになる
- ブレークポイント 375px / 1280px で崩れない
- ダークモードでもコントラスト AA 以上
「受け入れ条件にできない」場合の代替
検証コマンドが用意できないときは、観測可能な状態で言語化します。
| 検証手段がないとき | 代わりに書くこと |
|---|---|
| 自動テストがない | 「手動テスト手順を3〜5ステップで報告して」 |
| UIスクショが取りにくい | 「変更前後の DOM スナップショットを diff として要約して」 |
| 計測ツールがない | 「処理時間を console.time で1回計測し、結果を要約して」 |
| 環境が立ち上がらない | 「動作確認はせず、計画と差分の説明だけ報告」 |
「検証できない=受け入れ条件を書かない」ではなく、人間が確認するための観測情報を必ず1つは書きます。
チェックリスト:依頼前の確認
依頼文を投げる前に、次のチェックを通します。
- スコープ制約を1個以上書いたか
- 依存制約(追加可否)を書いたか
- 互換制約(公開API・DB・キー名)を書いたか
- 受け入れ条件にコマンド(テスト・ビルド・型・lint)を1個以上書いたか
- UI・性能・観測可能な状態のいずれかを1個書いたか
- 「テストの期待値は書き換えない」を含めたか(リファクタ系のみ)
- 中断条件(テスト2回失敗で停止など)を書いたか
このチェックを通すと、依頼文は短くても「Claude Codeが自分で完了判定できる」状態になります。
検証用のCommandを直接渡すパターン
依頼の最後に、検証コマンドそのものを渡すと精度がさらに上がります。
## 受け入れ条件
- 下記コマンドが全て成功する:
npm test -- src/services/order npx tsc --noEmit npm run lint -- src/services/order 依頼文の中にコピーして実行できるコマンドを埋め込むと、Claude Codeはそのまま実行して結果を確認します。フラグや実行環境については基本コマンドを参照してください。
まとめ:制約と受け入れ条件は「分けて」「コマンドで」書く
依頼文の精度は、テクニックではなく型と検証手段で決まります。
- 制約条件は5カテゴリ(スコープ・依存・互換・品質・セキュリティ)で漏らさない
- 受け入れ条件はテスト・UI・性能・観測情報のいずれかで自動検証可能にする
- 「テスト期待値は書き換えない」は受け入れ条件と矛盾しないように制約側に書く
- 共通の制約は
CLAUDE.mdに集約し、依頼文を短く保つ
次のステップとしては、プロンプトの基本構造で7ブロック構成を整理し、計画してから実装させるプロンプト例で計画フェーズに制約・受け入れ条件を組み込み、最初の機能追加の手順で通しの実装フローに当てはめてみてください。