AIコーディングツールに「これ作って」と投げるだけでもそれなりに動くが、プロンプトの書き方を変えるだけで出力の精度と速度は大きく変わる。
この記事では、Claude CodeやChatGPTなどのAIツールを使った開発で実際に効果があったプロンプトの「型」を3つ紹介する。どれも特定のツールに依存しない汎用的なパターンなので、普段使っているツールですぐ試せるはずだ。
パターン1: 「ゴール / 制約 / 出力形式」の三段構成
全てのプロンプト設計の土台になるパターン。新しいコードを書いてもらうとき全般に使える。
悪い例
ユーザー登録APIを作って
これだと、AIが技術スタックを勝手に選んだり、ファイルの配置場所が期待と違ったりする。手戻りが発生しやすい。
良い例
ユーザー登録APIを作って。
【ゴール】
- POST /api/users でユーザーを新規登録
- バリデーション付き
【制約】
- Express + TypeScript
- パスワードはbcryptでハッシュ化
- 既存のsrc/routes/配下に追加
- 既存のUserモデル(src/models/user.ts)を使うこと
【出力形式】
- ルートファイル、バリデーション、テストの3ファイルを作成
- 各ファイルにはインラインで簡潔なコメント
なぜ効くのか: AIが「何を」「どう」「どんな形で」作ればいいか迷わなくなる。特に制約の部分が重要で、技術スタックや既存コードとの整合性を明示することで、自分のプロジェクトに合ったコードが出てくる。
制約を書かない場合と比べて、手戻り修正が体感で半分以下になる。
応用: 三段構成のテンプレート
[やりたいこと]を実装して。
【ゴール】
- [達成したい状態を箇条書き]
【制約】
- [使用技術/ライブラリ]
- [既存コードとの関係]
- [セキュリティ要件]
【出力形式】
- [ファイル構成]
- [コメントの有無]
- [その他の出力条件]
慣れてくると、毎回このテンプレを頭の中で組み立てるようになる。最初は面倒に感じるかもしれないが、手戻りの時間を考えれば明らかに得だ。
パターン2: 「既存コードを読んでから変更して」パターン
既存のコードベースに変更を加えるとき専用のパターン。新規作成ではなく、修正・拡張するケースで使う。
悪い例
payment.tsにタイムアウト処理を追加して
AIがファイルの中身を確認せずに推測で書き換えることがある。既存のエラーハンドリングパターンと異なるスタイルになったり、依存関係を見落としたりする。
良い例
src/services/payment.ts を読んで、以下の変更を加えて。
1. まず現在のコードを読んで構造を理解して
2. processPayment関数に、タイムアウト処理(30秒)を追加して
3. タイムアウト時はPaymentTimeoutErrorをthrowして
4. 既存のエラーハンドリングパターンに合わせて
5. 既存のテストファイルがあれば、そこにタイムアウトのテストも追加して
なぜ効くのか: 「まず読んで」を明示することで、AIが推測ではなく事実に基づいてコードを書く。「既存のパターンに合わせて」を入れることで、プロジェクト全体の一貫性が保たれる。
このパターンを使うと、生成されたコードが既存コードと自然に馴染む。try-catchの書き方、エラークラスの命名規則、ログの出し方などが統一されるので、レビューの手間も減る。
応用: 安全な変更のチェーンプロンプト
大きな変更を加える場合は、段階的に進めるとより安全だ。
Step 1: src/services/payment.ts を読んで、現在の構造を説明して(変更はしないで)
Step 2: [説明を確認した上で] この方針で変更して
Step 3: 変更後、関連テストを実行して結果を報告して
AIに一度に全部やらせるより、確認ポイントを挟むことで精度が上がる。
パターン3: 「テストを先に書いてから実装して」パターン
品質が重要な機能を実装するときに使うTDD(テスト駆動開発)パターン。
プロンプト例
カート機能の割引計算ロジックを実装したい。
手順:
1. まず以下の仕様に基づいてテストを書いて
- 通常価格: そのまま合計
- 10%割引クーポン: 合計から10%引き
- 数量割引: 3個以上で5%引き
- クーポン+数量割引: 両方適用(数量割引→クーポンの順)
- 0円以下にはならない
2. テストを実行して全部失敗することを確認
3. テストが通る実装を書いて
4. テストを再実行して全部通ることを確認
なぜ効くのか: テストを先に書かせることで、仕様が曖昧なまま実装されるのを防げる。AIは仕様の解釈を勝手に決めてしまうことがあるが、テストとして仕様を先に固めることで「この仕様で合ってるか」を実装前に確認できる。
もう一つのメリットはエッジケースの網羅だ。「0円以下にはならない」のような境界条件をテストで明示しておくと、実装側でもちゃんとハンドリングされる。
実行の流れ
- テストファイルが生成される(この時点で仕様を目視確認できる)
- テスト実行 → 全て失敗(Red)
- 実装コードが生成される
- テスト再実行 → 全て成功(Green)
Red → Green の流れを明示的に指示することがポイント。「テストが通る実装を書いて」だけだと、AIがテストと実装を同時に生成してしまい、テストの独立性が損なわれることがある。
3パターンの使い分け
| パターン | 使うとき | 主な効果 |
|---|---|---|
| 三段構成 | 新しいコードを書くとき | 手戻りの削減 |
| 既存コードを読んでから | 修正・拡張するとき | 既存コードとの一貫性 |
| テストファースト | 品質が重要な機能 | 仕様の明確化+品質担保 |
実務では、これらを組み合わせて使うことが多い。例えば「既存コードを読んでから」+「テストファースト」で、既存のテストパターンに合わせてTDDで新機能を追加する、というような使い方になる。
共通する原則
3つのパターンに共通しているのはAIに推測させないということだ。
- 技術スタックを明示する → 推測で別のライブラリを使われるのを防ぐ
- 既存コードを読ませる → 推測でスタイルが崩れるのを防ぐ
- テストで仕様を固める → 推測で仕様が変わるのを防ぐ
AIは推測が得意だが、推測が外れたときの手戻りコストは大きい。プロンプトで事前に情報を渡して推測の余地を減らすことが、結果的に最も効率がいい。
この記事で紹介した3パターンは基本的なものだが、実務ではさらに多くのパターンが役に立つ。バッチ処理、段階実行、差分確認、セキュリティレビュー、リファクタリング、マルチファイル操作、Git連携、デバッグ、ライブラリ移行など、全15パターンをコピペで使えるテンプレート付きでnoteにまとめている。
みょうが (@myougaTheAxo) ― ウーパールーパーのVTuber。AIを使った開発の実践知を発信中。