はじめに
ChatGPT、Claude Code、Codex、GitHub Copilotなどを使えば、プログラミングを始めたばかりでも、短時間でコードを生成できるようになりました。
一方で、AIが生成したコードをそのまま利用すると、次のような問題が起こる可能性があります。
- 画面は動くが、実装方法が間違っている
- 指示していない仕様をAIが補っている
- エラーを解決した代わりに、別の機能が動かなくなっている
- セキュリティ上の問題が含まれている
- 必要以上に多くのファイルが変更されている
- 自分では説明できないコードが大量に増えている
- 修正を依頼するたびに、別のエラーが発生する
これは「AIは信用できない」という感覚的な話だけではありません。
GitHubはCopilotの公式ドキュメントで、生成されたコードは一見すると有効に見えても、構文や意味が正しくない場合や、開発者の意図を正確に反映していない場合があると説明しています。その対策として、生成コードを慎重にレビューし、テストすることを求めています。
NIST(米国国立標準技術研究所)も、生成AIに関するリスクの一つとして「Confabulation」を挙げています。これは、誤った内容を、正確であるかのように自信を持って生成する性質を指します。
NIST:Artificial Intelligence Risk Management Framework: Generative Artificial Intelligence Profile
AIが生成するコードは、変数名やインデントが整っており、説明も論理的に見えることがあります。
しかし、見た目が自然であること、説明に説得力があること、コードが正しいことは、それぞれ別の問題です。
セキュリティに関する研究でも、この点には注意が必要であることが示されています。
GitHub Copilotを対象とした2021年の研究では、セキュリティ上重要な89のシナリオから生成した1,689件のプログラムを分析した結果、約40%に脆弱性が含まれていました。
また、実際のGitHubプロジェクトに存在するAI生成コードを調査した別の研究では、分析対象となったコードのうち、Pythonでは29.5%、JavaScriptでは24.2%にセキュリティ上の弱点が確認されています。
ただし、これらは特定の時点のモデル、プログラミング言語、評価方法を対象とした研究です。「現在のすべてのAI生成コードの一定割合に脆弱性がある」と一般化できるものではありません。
それでも、AIが生成したコードにも、人間が書いたコードと同じようにレビューやセキュリティ確認が必要であることを示す根拠にはなります。
そのため、AIコーディングで大切なのは、便利なプロンプトを一つ覚えることだけではありません。
AIにどのような順序で作業してもらい、生成されたコードをどのように確認するかまで考える必要があります。
この記事では、AIにコードを丸投げするのではなく、初学者でも内容を理解しながら、安全かつ効率的に開発を進める方法を紹介します。
この記事で分かること
この記事では、主に次の内容を解説します。
- 初学者がAIコーディングでやりがちな失敗
- AIへいきなり実装させてはいけない理由
- 調査・計画・実装・確認の順番で開発する方法
- AIへ依頼する前に整理しておくこと
- AIへ要望を正確に伝えるプロンプトの書き方
- AIが生成したコードを確認する方法
- テスト結果をそのまま信用してはいけない理由
- Gitの差分を使って変更内容を確認する方法
- AIレビューや自動テストを活用する方法
- AIに任せてよいことと、人間が判断すべきこと
記事内では、考え方を説明するだけでなく、実際に利用できるプロンプト例も紹介します。
すべてを一度に実践する必要はありません。
まずは「AIにいきなり実装させない」「変更内容を自分でも確認する」といった基本から取り入れてみてください。
本記事で扱う範囲について
本記事では、AIコーディングを始めたばかりの方にも実践しやすいよう、AIへプロンプトを渡す際の考え方と、調査・計画・実装・確認を段階的に進める方法に焦点を当てています。
一方、AIコーディングツールでは、AGENTS.mdなどの指示ファイルにプロジェクト固有のルールを記録したり、Skillsで繰り返し使う手順を再利用したり、MCP(Model Context Protocol)で外部のツールやデータへ接続したりすることで、さらに効率よく活用できます。
これらはそれぞれ内容が広いため、本記事では詳しく扱いません。設定方法や具体的な活用例を知りたい方は、次の公式資料も参考にしてみてください。
なお、こうした仕組みを利用しても、仕様の整理、変更内容の確認、テスト、最終的な判断が不要になるわけではありません。本記事で紹介する基本的な考え方は、これらを導入した場合にも共通して必要になります。
この記事の対象読者
この記事は、次のような方を対象としています。
- プログラミングを学び始めた方
- ChatGPTなどでコードを生成している方
- Claude CodeやCodexなどのコーディングエージェントを使い始めた方
- AIを使うと開発は進むものの、コードの内容に自信がない方
- AIへ修正を依頼するたびに別のエラーが発生して困っている方
- AIが生成したコードを、どこまで信用してよいか分からない方
- 個人開発でAIを活用したい方
- AIを使いながらプログラミングも学びたい方
特定のプログラミング言語やフレームワークを前提にはしていません。
Webアプリ、スマートフォンアプリ、バックエンドなど、さまざまな開発へ応用できる考え方を扱います。
AIにコードを書かせるだけでは、うまくいかない
AIコーディングでは、次のような短い指示でもコードを生成してもらえます。
お気に入り登録機能を作ってください。
しかし、この指示だけでは、AIが正しく実装するための情報が不足しています。
例えば、お気に入り登録機能を作るだけでも、本来は次のような条件を考える必要があります。
- ログインしていないユーザーは利用できるのか
- 同じ商品を複数回登録できるのか
- 登録したデータをどこへ保存するのか
- 登録に失敗した場合は何を表示するのか
- 登録後に画面をどのように更新するのか
- お気に入りを解除する機能も必要なのか
- 既存プロジェクトではどのようにAPIを呼び出しているのか
- どのようなテストが必要なのか
これらが指定されていない場合、AIは周辺のコードや一般的な実装パターンを参考に、不足している情報を推測します。
その推測が正しければ期待どおりに動くかもしれません。しかし、こちらが想定していた仕様と異なる可能性もあります。
GitHub Copilotの公式ガイドでも、AIへ作業を依頼するときは、問題の明確な説明、完了条件、変更対象のファイルなどを含め、タスクを明確な範囲へ絞ることが推奨されています。
つまり、AIへコードを書かせること自体は簡単でも、期待どおりの機能を正しく作ってもらうことは別の問題です。
そこで、AIを使った開発では、最初からすべてを実装させるのではなく、次のように作業を分けます。
既存コードを調査する
↓
実装方法を考える
↓
人間が計画を確認する
↓
小さな単位で実装する
↓
テストする
↓
人間が変更内容を確認する
実際にClaude Codeには、コードを変更する前に関連ファイルを調査し、実装計画だけを作成させるPlan Modeが用意されています。
Codexの公式ガイドでも、コード変更だけで終わらせず、必要なテストの作成、関連する検証の実行、結果の確認、成果物のレビューまで行わせることが推奨されています。
これらの公式ガイドにも共通しているのは、AIへ一度依頼して終わりにするのではなく、作業範囲を明確にし、実装と検証を段階的に進めるという考え方です。
AIは単なるコード生成ツールではありません。
調査、計画、実装、検証を一緒に進める開発パートナーとして利用し、重要な判断と最終確認を人間が担うことで、失敗を減らしやすくなります。
初学者がAIコーディングでやりがちな失敗
ここからは、AIを使った開発で初学者が陥りやすい失敗を紹介します。
なお、「初学者が必ずこのような失敗をする」という意味ではありません。
AIコード生成ツールを使う初学者に関する研究では、AIの利用によってコード作成時の正答率が向上した例がある一方、その後にコードを修正する課題では成績が低くなるなど、過度な依存を示す兆候も報告されています。
また、32名のプログラミング初学者を対象にした2025年の実験では、LLMが生成したコードの正しさを理解・判断する課題の成功率が、1タスク当たり32.5%だったと報告されています。
この研究も対象人数や課題の範囲が限られているため、すべての初学者に結果を一般化することはできません。
それでも、コードを生成できることと、そのコードを理解して修正できることは別であり、初学者ほど意識して確認工程を設ける必要があることを示しています。
「〇〇を作って」だけで実装を始めさせる
最も起こりやすい失敗は、作りたいものだけを伝え、すぐに実装を始めさせることです。
ログイン機能を作ってください。
この指示だけでは、AIは次のような情報を判断できません。
- メールアドレスとパスワードでログインするのか
- Googleなどの外部サービスを利用するのか
- どこへユーザー情報を保存するのか
- ログイン後にどの画面へ移動するのか
- ログイン失敗時に何を表示するのか
- すでに導入されている認証機能を利用するのか
情報が不足していても、AIは一般的な方法や既存コードから条件を推測し、作業を進めることがあります。
その結果、画面上は動いていても、プロジェクトで利用している認証方法と異なっていたり、必要な認可処理が不足していたりする可能性があります。
GitHubも、Copilotへ作業を任せる際には、明確な問題説明、受け入れ条件、変更対象のファイルを含む、範囲の限定されたタスクが適していると説明しています。
実装を依頼する前に、まず次のように調査を依頼します。
ログイン機能を実装したいです。
まだコードは変更せず、現在の認証方法と関連するファイルを調査してください。
そのうえで、次の内容を整理してください。
- 現在の認証処理
- 関連するファイル
- 変更が必要なファイル
- 実装方針
- 仕様上の不明点
- 実装後に必要なテスト
最初に調査と計画を挟むことで、AIが誤った前提を置いていても、コードを書き換える前に修正できます。
AIが生成したコードをそのままコピペする
AIが出力したコードは、インデントや変数名が整っており、一見すると正しそうに見えます。
しかし、次のような問題が含まれている可能性があります。
- 存在しない関数やライブラリを使っている
- 古いバージョンの書き方を使っている
- プロジェクトの構成と合っていない
- エラー処理が不足している
- APIキーなどの秘密情報を直接書いている
- 入力値を安全に処理していない
- 必要以上に複雑な実装になっている
GitHubも、Copilotが生成するコードは有効に見えても、意味的・構文的に正しくない場合や、セキュリティ上の問題を含む場合があるため、人間によるレビューとテストが必要だと説明しています。
特に注意したいのは、AIが生成したコードを理解しないまま利用することです。
問題が発生したときに、どこを修正すればよいか判断できず、再びAIへ丸ごと修正を依頼することになります。
AIが生成したコードを利用する場合は、最低限、次の点を確認します。
- このコードは何をしているのか
- どのファイルへ追加するのか
- 入力と出力は何か
- エラーが発生した場合はどうなるのか
- 既存コードと何が変わるのか
- なぜこの実装方法を選んだのか
理解できない箇所があれば、そのまま使わず、AIへ説明を求めます。
このコードについて、プログラミング初学者にも分かるように説明してください。
特に、次の内容を教えてください。
- 各処理の役割
- 入力と出力
- エラーが起きる可能性
- 既存コードへ与える影響
- この実装方法を採用した理由
ただし、AIの説明が分かりやすいことも、コードが正しいことの証明にはなりません。
必要に応じて公式ドキュメントを確認し、実際にコードを実行して動作を確かめます。
エラーが消えたら完成だと思ってしまう
開発中にエラーが表示されなくなると、問題が解決したように見えます。
しかし、エラーが消えたことと、機能が正しく完成したことは同じではありません。
例えば、次のような変更でも、画面上のエラーだけを消すことはできます。
- 問題のある処理を削除する
- エラーを無視する
- 例外を握りつぶす
- 型を
anyに変更する - TypeScriptやLintのチェックを無効にする
- 失敗している処理を実行しないようにする
- エラーメッセージだけを非表示にする
AIが必ずこのような修正を行うという意味ではありません。
ただし、「エラーを消してください」という指示しか与えていない場合、AIにとっての完了条件が「エラーを表示しないこと」になり、本来の機能を維持することが十分に考慮されない可能性があります。
OpenAIのCodex公式ガイドでも、AIが良い成果を判断できるように、期待する挙動や検証方法をプロンプトまたはAGENTS.mdへ明記することが推奨されています。
エラーを修正してもらうときは、単に「エラーを消して」と依頼するのではなく、原因と修正内容を先に説明してもらいます。
このエラーの原因を調査してください。
まだコードは変更せず、次の内容を説明してください。
- エラーが発生している原因
- 影響を受けている処理
- 修正方法の候補
- 各修正方法のメリットと注意点
- 修正後に確認すべき既存機能
修正後は、エラーが消えたことだけでなく、本来の機能が動いていることや、別の機能が壊れていないことも確認します。
「テストに成功しました」をそのまま信用する
AIコーディングツールは、コードを変更したあとにテスト、型チェック、Lint、ビルドなどを実行し、「すべて成功しました」と報告することがあります。
便利な機能ですが、その報告だけで実装が正しいとは判断できません。
例えば、次のようなケースがあります。
- 一部のテストしか実行していない
- テストが1件も見つからないままコマンドが成功している
- 失敗するテストがスキップされている
- 重要な機能を確認するテストが存在しない
- AIが実装と同じ誤解に基づいてテストを書いている
- 外部サービスへ接続できず、必要なテストを実行していない
- テストを通すために期待値を変更している
GitHubの公式ドキュメントにも、Copilotが生成したテストはすべてのシナリオを網羅するとは限らないため、人間が内容をレビューし、必要なテストを追加するよう明記されています。
そのため、AIには結果だけでなく、実行内容も報告してもらいます。
検証結果について、次の内容を報告してください。
- 実行したコマンド
- 各コマンドの終了コード
- 成功・失敗・スキップしたテストの件数
- 実行できなかったテストと理由
- 警告の有無
- 手動で確認する必要がある項目
「成功したか」だけではなく、何を確認した結果として成功したのかを見ることが重要です。
分からないコードまで大量に生成させる
AIを使えば、短時間で大量のコードを生成できます。
しかし、生成速度に自分の理解が追いつかなくなると、次のような問題が起こります。
- どのファイルが何を担当しているか分からない
- 不要なコードを見分けられない
- エラーの原因を自分で追えない
- 同じ処理が複数の場所に作られる
- 修正による影響範囲が分からない
- AIが間違っていても気づけない
初学者とAIコード生成ツールの関係を調査した研究でも、一つのプロンプトで生成された回答へ強く依存したグループは、コードを作成する課題では高い成績を示した一方、その後にコードを修正する課題では低い成績を示しました。
この結果だけで「AIを使うとプログラミング能力が下がる」とはいえません。
しかし、AIによって完成したコードを得ることと、そのコードを理解し、あとから修正できることは別であると分かります。
特に初学者の場合は、機能全体を一度に生成させるより、小さな単位へ分けて進める方が、内容を確認しやすくなります。
例えば、ログイン機能であれば、次のように分割できます。
1. ログイン画面を作る
2. 入力値を検証する
3. ログインAPIを呼び出す
4. 成功時の処理を追加する
5. 失敗時のエラー表示を追加する
6. テストを追加する
一つの工程が終わるたびに、コードの内容と動作を確認します。
AIを使う目的は、できるだけ多くのコードを生成することではありません。
自分が確認できる範囲で、正しいコードを効率よく作ることです。
AIに修正を繰り返させて、変更内容を把握できなくなる
エラーが発生したとき、内容を確認せず、次のような依頼を繰り返してしまうことがあります。
直してください。
まだエラーが出ます。もう一度直してください。
別のエラーが出ました。全部直してください。
このような依頼を続けると、AIが複数のファイルを何度も変更し、最初の問題とは関係のない箇所まで書き換える可能性があります。
最終的にエラーが消えても、次のことが分からなくなります。
- 原因は何だったのか
- どの変更によって解決したのか
- 不要な変更が含まれていないか
- 既存機能が壊れていないか
- 元の状態へ戻せるのか
AnthropicのClaude Code公式ガイドでも、複雑な作業では実装前にPlan Modeを使い、AIがコードベースを調査して提案した方針を承認してから進める方法が紹介されています。また、AIが誤った方向へ進んだ場合は、早い段階で停止し、チェックポイントへ戻すことが推奨されています。
これを防ぐためには、一回の修正ごとに変更内容を確認します。
修正を行う前に、原因と変更予定のファイルを説明してください。
今回のエラーと関係のないファイルは変更しないでください。
修正後は、次の内容を報告してください。
- 変更したファイル
- 変更内容
- エラーが解消される理由
- 既存機能への影響
- 実行した確認
Gitを利用している場合は、作業前に現在の状態をコミットしておくことも有効です。
Gitで変更前の状態を残しておけば、問題が発生した場合も差分を確認し、必要に応じて元へ戻せます。
AIへ何度も修正を依頼すること自体が悪いわけではありません。
大切なのは、AIが何を変更したのかを確認しながら、一つずつ問題を解決することです。
AIの「直しました」という報告を完了の証明として扱うのではなく、人間が変更内容を確認するための合図として扱いましょう。
AI開発の基本は「調査→計画→実装→確認」
AIへ開発を任せるときは、最初からコードを書かせるのではなく、次の順序で進めることをおすすめします。
調査
↓
計画
↓
人間による確認
↓
小さな単位で実装
↓
テスト・動作確認
↓
コード差分の確認
これは単なる筆者個人の経験則ではありません。
GitHub Copilot CLIの公式ガイドでも、複雑な作業に対して、次の流れが紹介されています。
Explore
↓
Plan
↓
Review
↓
Implement
↓
Verify
↓
Commit
Claude Codeには、コードを変更する前に関連ファイルを調査し、実装計画を作成するPlan Modeがあります。Codexの公式ガイドでも、実装だけで終わらせず、テスト、検証、レビューまで依頼することが推奨されています。
ただし、これらの公式ガイドは「この手順を使えば、必ず不具合が減る」と証明する比較実験ではありません。
各ツールの開発元が、AIコーディングをより安全かつ効率的に利用するために推奨している運用方法です。
それでも、複数の主要なAIコーディングツールが共通して、調査、計画、検証、レビューを分けていることは、AIへいきなり実装を丸投げしない方がよいと考える一つの根拠になります。
ステップ1:まず既存コードを調査してもらう
最初のステップは、コードを書くことではなく、既存のコードを調査することです。
新しい機能を追加する場合でも、すでに存在するプロジェクトには、次のような決まりや実装パターンがあります。
- ディレクトリの構成
- コンポーネントの分け方
- APIの呼び出し方
- データの保存方法
- 認証情報の取得方法
- エラーの表示方法
- ログの出力方法
- テストの書き方
- 使用しているライブラリとバージョン
これらを確認せずに実装すると、機能単体では動いても、既存プロジェクトと異なる書き方が持ち込まれる可能性があります。
例えば、お気に入り機能を追加するときに、すでに共通のAPIクライアントが存在するにもかかわらず、AIがコンポーネント内へ直接fetchを書いてしまうかもしれません。
そのため、まずは次のように依頼します。
お気に入り登録・解除機能を実装したいです。
まだコードは変更せず、関連する既存コードを調査してください。
次の内容を整理してください。
- 現在の商品詳細画面の処理
- 認証情報の取得方法
- APIの呼び出し方法
- 状態管理とエラー表示の方法
- 関連するファイルと関数
- 類似機能があれば、その実装箇所
- 仕様または既存コードから判断できないこと
この段階では、AIが出した結論だけでなく、どのファイルや関数を根拠に判断したのかも確認します。
GitHub Copilot CLIの公式ガイドでも、コードベースへ参加した際の調査例として、認証フロー、ログ設定、APIエンドポイントの追加パターン、DBマイグレーションの場所などを質問する方法が紹介されています。
AIは多くのファイルを短時間で検索できますが、調査結果が必ず正しいとは限りません。
指定されたファイルだけを見て重要な処理を見落としたり、似た名前の関数を取り違えたりする可能性もあります。
そのため、調査結果にはファイル名や関数名を含めさせ、人間が根拠を追える状態にします。
ステップ2:実装方針を立ててもらう
調査が終わったら、すぐに実装させるのではなく、実装方針を作成してもらいます。
実装方針には、少なくとも次の内容を含めます。
- 変更するファイル
- 各ファイルを変更する理由
- 追加または変更する処理
- 既存機能への影響
- 必要なテスト
- 判断できていないこと
- 実装上のリスク
例えば、次のように依頼します。
調査結果をもとに、実装計画を作成してください。
まだコードは変更しないでください。
計画には、次の内容を含めてください。
- 変更対象のファイル
- ファイルごとの変更内容
- その変更が必要な理由
- 既存機能への影響
- 実装する正常系・異常系
- 追加または更新するテスト
- 仕様上の不明点
- 想定されるリスク
Claude CodeのPlan Modeでは、Claudeがファイルを読み取り、コードを変更せずに計画を提示し、利用者が承認するまで実装を開始しません。
GitHub Copilot CLIにもPlan Modeがあり、コードを作成する前にコードベースを分析し、不明点を質問し、構造化された実装計画を提示する流れが用意されています。
実装計画を先に確認する利点は、AIの認識が間違っていた場合に、コードを大量に修正する前に方向を変えられることです。
ただし、AIが作成した計画も正しいとは限りません。
計画は実装を保証するものではなく、AIがどのように実装しようとしているかを、人間が事前に確認するための材料です。
ステップ3:計画を人間が確認する
AIが作成した計画は、そのまま承認せず、人間が内容を確認します。
主に確認する項目は次のとおりです。
- 依頼した目的と合っているか
- 必要な要件がすべて含まれているか
- AIが勝手に仕様を追加していないか
- 変更対象のファイルは適切か
- 関係のないリファクタリングが含まれていないか
- 既存の設計方法と一致しているか
- 認証や認可が考慮されているか
- エラー時の挙動が含まれているか
- 必要なテストが計画されているか
- 不明点を推測で埋めていないか
例えば、お気に入り登録機能の計画へ「未ログインの場合は、自動的にログイン画面へ遷移する」と書かれていたとします。
一般的には自然な動作かもしれません。しかし、仕様に書かれていないのであれば、それが正しいとは限りません。
モーダルを表示するのか、ボタンを非表示にするのか、エラーメッセージを表示するのかは、サービスごとに異なります。
人間は、AIが提案した内容が一般的に妥当かだけでなく、今回のプロジェクトの仕様として正しいかを判断する必要があります。
NISTのGenerative AI Profileでは、人間とAIの構成における役割と責任を明確にし、必要に応じて独立した評価や監督を設けることが推奨されています。
NIST:Artificial Intelligence Risk Management Framework: Generative Artificial Intelligence Profile
この文書はAIコーディング専用のガイドラインではありません。
それでも、AIが出した提案をそのまま採用するのではなく、人間の責任と確認方法を明確にするという考え方は、AI開発にも応用できます。
計画に問題があれば、実装前に修正します。
計画を次のように修正してください。
- 未ログイン時の挙動は仕様から判断できないため、実装せず確認事項にする
- 今回と関係のない共通APIクライアントのリファクタリングは除外する
- API失敗時の画面表示とテストを追加する
- 既存のお気に入り一覧画面への影響も調査する
修正後の計画を提示し、まだ実装は開始しないでください。
ステップ4:小さな単位で実装してもらう
計画に問題がなければ、AIへ実装を依頼します。
ただし、機能全体を一度に変更させるのではなく、可能な範囲で小さな単位に分けます。
例えば、お気に入り機能であれば、次のように分割できます。
1. お気に入り情報を取得する処理
2. 登録・解除APIを呼び出す処理
3. ボタンと画面表示
4. API失敗時のエラー処理
5. テスト
小さく分けることで、各工程で次の内容を確認できます。
- どのファイルが変更されたか
- 何のための変更か
- 期待した動作になっているか
- 次の工程へ進んでも問題ないか
AnthropicのClaude Code公式ガイドでも、複雑な作業では、一つのファイルを変更してテストし、その後に次へ進む「段階的なテスト」が推奨されています。問題を早い段階で発見できれば、修正範囲も小さくできます。
GitHub Copilotの一般的なベストプラクティスでも、複雑なタスクを分割し、要件を具体的にすることが推奨されています。
また、AIに限らない一般的なコードレビューの考え方としても、GoogleのEngineering Practicesでは、小さな変更はレビューしやすく、不具合を持ち込む可能性を下げやすいと説明されています。
ただし、機械的に一ファイルずつ実装すればよいわけではありません。
ファイル単位ではなく、動作確認できる一つの責務や機能単位へ分けることが重要です。
例えば、API呼び出しと状態更新が密接に関係している場合、無理に別々に実装すると、途中の状態ではテストできないことがあります。
作業内容に応じて、確認可能な最小単位を考えます。
ステップ5:テストと動作確認を行う
実装が終わったら、AIへテスト、型チェック、Lint、ビルドなどを実行してもらいます。
例えば、次のように依頼します。
実装内容を検証してください。
プロジェクトで定義されている次の確認を実行してください。
- 関連する単体テスト
- 全体のテスト
- 型チェック
- Lint
- ビルド
完了後は、次の内容を報告してください。
- 実行したコマンド
- 各コマンドの結果
- 成功・失敗・スキップしたテスト件数
- 実行できなかった確認と理由
- 手動確認が必要な項目
OpenAIのCodex公式ガイドでは、コードの変更だけで終わらせず、必要なテストを作成し、関連する検証を実行し、結果を確認してから成果物をレビューすることが推奨されています。
GitHubも、Copilot cloud agentが変更を確実にビルド・テスト・検証できるよう、必要な依存関係やツールを開発環境へ準備することを推奨しています。
ただし、テストが成功しただけでは、仕様を満たしたことの証明にはなりません。
テストケースに必要な条件が含まれていなければ、不具合を含む実装でも成功します。
そのため、少なくとも次の3つを分けて考えます。
| 確認方法 | 確認できること |
|---|---|
| 自動テスト | あらかじめ定義した動作が維持されているか |
| 型チェック・Lint | 型や静的なルールに違反していないか |
| 手動確認 | 実際の画面や操作が期待どおりか |
GitHubの公式ドキュメントにも、Copilotが生成したテストはすべてのシナリオを網羅するとは限らないため、人間が内容をレビューし、必要なテストを追加するよう記載されています。
AIが「すべて成功しました」と報告しても、実行したコマンド、対象範囲、テスト内容、未実施の確認を確認します。
ステップ6:最後にコード差分を確認する
最後に、AIの完了報告ではなく、実際のコード差分を確認します。
AIの説明には、変更内容の漏れや誤解が含まれる可能性があります。
一方、Gitの差分には、実際に追加・削除・変更されたコードが表示されます。
最低限、次の内容を確認します。
- 変更されたファイルの一覧
- 各ファイルの追加・削除内容
- 今回の機能と関係のない変更がないか
- 依存パッケージが追加されていないか
- 設定ファイルが変更されていないか
- テストが削除または緩和されていないか
-
anyやエラー抑制が追加されていないか - 秘密情報が含まれていないか
Codexには、未コミットの変更、コミット、ベースブランチとの差分をレビューする機能があります。
Claude Codeのデスクトップアプリでも、コミット前の差分に対して、コンパイルエラー、明確なロジックエラー、脆弱性、不具合などをレビューする機能が提供されています。
AIによる差分レビューも補助として利用できますが、最終確認までAIだけで完結させるものではありません。
AIが生成したコードを別のAIがレビューしても、同じ誤解や見落としが残る可能性があります。
そのため、次の順番で確認すると分かりやすくなります。
1. 変更ファイルの一覧を見る
2. AIに差分を説明させる
3. 自分で実際の差分を読む
4. 不明な変更について質問する
5. 不要な変更を戻す
6. もう一度テストを実行する
AIの「実装が完了しました」という報告は、作業終了の証明ではありません。
人間が差分の確認を開始するための合図として扱います。
悪いプロンプトと良いプロンプトを比較する
AIから期待に近いコードを得るには、単にプロンプトを長くするのではなく、AIが作業するために必要な情報を整理して伝えることが重要です。
GitHub Copilotの公式ガイドでは、プロンプトを作成する際に、次の方法が推奨されています。
- 複雑なタスクを分割する
- 要件を具体的に伝える
- 入力、出力、実装などの例を示す
- 一般的なコーディングのベストプラクティスに従う
また、OpenAIのモデルガイドでも、AIへの依頼には、目的、関連するコンテキスト、制約、必要な根拠、成功条件、出力形式を含めることが推奨されています。
ここでは、同じ「お気に入り機能の実装」を例に、プロンプトを段階的に改善していきます。
悪い例:「お気に入り機能を実装してください」
最初に、情報が不足しているプロンプトを見てみます。
お気に入り機能を実装してください。
このプロンプトだけでは、AIは次のことを判断できません。
- どの画面へ追加するのか
- 誰が利用できるのか
- 登録だけでなく解除も必要なのか
- データをどこへ保存するのか
- APIはすでに存在しているのか
- 登録後に画面をどう更新するのか
- エラー時に何を表示するのか
- どのファイルを変更してよいのか
- どのようなテストが必要なのか
- 何をもって完成とするのか
情報が不足している場合、AIは一般的な実装方法や周辺コードから条件を推測します。
その結果、画面上は動いていても、こちらの想定とは異なる実装になる可能性があります。
GitHub Copilotの公式ガイドでも、AIへ作業を依頼するときは、解決すべき問題、受け入れ条件、変更対象のファイルを明確にすることが推奨されています。
GitHub:Best practices for using GitHub Copilot to work on tasks
短いプロンプトが必ず失敗するわけではありません。
しかし、仕様の解釈や複数ファイルの変更が必要なタスクでは、情報不足によるずれが生じやすくなります。
改善例:目的・仕様・制約を伝える
次に、目的、仕様、変更範囲、完了条件を追加します。
商品詳細画面へ、お気に入り登録・解除機能を実装してください。
## 目的
ログイン済みのユーザーが、気になった商品を保存し、
お気に入り一覧画面からあとで確認できるようにします。
## 仕様
- 未登録の商品でボタンを押すと、お気に入りへ登録する
- 登録済みの商品でボタンを押すと、お気に入りから解除する
- 処理に成功したら、画面を再読み込みせずボタン表示を更新する
- 未ログインの場合は操作できない
- APIに失敗した場合は、既存のエラー表示を使用する
- 処理中はボタンを無効にして、重複実行を防ぐ
## 参照するコード
- src/features/products/ProductDetail.tsx
- src/features/auth/useCurrentUser.ts
- src/lib/api/client.ts
- src/features/products/__tests__/ProductDetail.test.tsx
## 制約
- 既存の認証方法、APIクライアント、エラー表示に合わせる
- 関係のないリファクタリングは行わない
- 新しいライブラリは追加しない
- 既存テストを削除、スキップ、緩和しない
- TypeScriptやLintの設定を変更しない
## 完了条件
- 指定した正常系と異常系が実装されている
- 必要なテストが追加されている
- テスト、型チェック、Lint、ビルドに成功している
- 実行できなかった検証が報告されている
最初のプロンプトと比較すると、AIが判断できる情報が増えています。
| 項目 | 悪い例 | 改善例 |
|---|---|---|
| 目的 | 不明 | ユーザーが商品を保存する |
| 対象 | 不明 | ログイン済みユーザー |
| 正常系 | 不明 | 登録・解除・表示更新 |
| 異常系 | 不明 | 未ログイン・API失敗 |
| 変更範囲 | 不明 | 関連ファイルを指定 |
| 禁止事項 | 不明 | 無関係な変更や依存追加を禁止 |
| 完了条件 | 不明 | テスト・型・Lint・ビルドを指定 |
OpenAIのCodex公式ガイドでは、大規模なコードベースやリスクの高い作業ほど、明確なプロンプトによって結果の信頼性を高めやすいと説明されています。
ただし、詳細なプロンプトを書いたからといって、必ず正しいコードが生成されるわけではありません。
AIが仕様を誤解したり、指定したファイル以外に重要な処理が存在したりする可能性があります。
そのため、さらに安全に進めるには、調査と計画を実装から分けます。
さらに改善:調査と計画を先に依頼する
複数ファイルへまたがる変更では、最初の依頼で実装まで行わせず、まず調査と計画だけを依頼します。
商品詳細画面へ、お気に入り登録・解除機能を追加したいです。
まだコードは変更しないでください。
最初に、次のファイルと関連コードを調査してください。
- src/features/products/ProductDetail.tsx
- src/features/auth/useCurrentUser.ts
- src/lib/api/client.ts
- src/features/products/__tests__/ProductDetail.test.tsx
次の内容を整理してください。
1. 現在の商品詳細画面の処理
2. 認証情報の取得方法
3. API呼び出しとエラー表示の既存パターン
4. 変更が必要なファイル
5. ファイルごとの変更内容
6. 既存機能への影響
7. 必要な正常系・異常系テスト
8. 仕様またはコードから判断できないこと
重要な不明点がある場合は、推測で補わず質問してください。
調査結果と実装計画を提示し、私が確認するまで実装を開始しないでください。
この方法では、コードが変更される前に次の点を確認できます。
- AIが正しいファイルを調査しているか
- 既存の設計を理解しているか
- 必要な変更を見落としていないか
- 関係のない変更を計画していないか
- AIが勝手に仕様を補っていないか
- 必要なテストが含まれているか
計画を作らせれば正しさが保証されるわけではありませんが、AIの認識がずれていた場合に、実装前に修正しやすくなります。
一度にすべて書かず、作業を段階的に進める
プロンプトへ多くの情報を詰め込んで、一度に調査、実装、テスト、修正まで行わせると、人間が途中経過を確認しにくくなります。
そのため、作業を次のように分割します。
第1段階:既存コードの調査
第2段階:実装計画の作成
第3段階:人間による計画の確認
第4段階:小さな機能単位での実装
第5段階:テストと動作確認
第6段階:コード差分の確認
ただし、どのような作業でも一ファイルずつ進めればよいわけではありません。
API呼び出しと状態更新など、まとめて実装しなければ動作確認できない処理もあります。
ファイル数ではなく、人間が内容と動作を確認できる機能単位へ分けることが重要です。
そのまま使えるAIコーディング用プロンプト
ここからは、AIを使った開発で利用できるプロンプトを目的別に紹介します。
プロジェクトによって仕様、ファイル構成、実行コマンドは異なるため、[]で囲んだ部分を書き換えて使用してください。
また、これらのプロンプトを使用しても、AIの出力が正しいと保証されるわけではありません。
AIが行った調査、変更、テストを人間が確認することを前提としたテンプレートです。
既存コードを調査してもらうプロンプト
[実装したい機能または解決したい問題]について調査してください。
この段階ではコードを変更しないでください。
## 目的
[何を実現したいのか]
## 最初に確認してほしい資料・ファイル
- [要件・設計書]
- [関連する画面またはコンポーネント]
- [関連するAPI・データアクセス処理]
- [認証・認可処理]
- [既存テスト]
上記以外にも関連するコードがあれば調査してください。
## 調査してほしいこと
1. 現在の処理フロー
2. 関連するファイル・関数・型
3. 既存プロジェクトで採用されている実装パターン
4. 類似機能の実装箇所
5. 変更が必要になりそうなファイル
6. 既存機能への影響範囲
7. 仕様と既存コードの矛盾
8. 仕様またはコードから判断できないこと
## 出力形式
- 調査結果
- 判断の根拠となったファイルと関数
- 想定される変更箇所
- 不明点・確認事項
まだ実装は開始しないでください。
調査結果には、ファイル名と関数名を含めてもらいます。
AIの説明だけでなく、その説明がどのコードを根拠としているかを追跡できるようにするためです。
実装計画を立ててもらうプロンプト
先ほどの調査結果をもとに、実装計画を作成してください。
まだコードは変更しないでください。
## 計画に含める内容
1. 実装方針の概要
2. 変更対象のファイル
3. ファイルごとの変更内容
4. その変更が必要な理由
5. 既存機能への影響
6. 正常系・異常系・境界値
7. 追加または変更するテスト
8. 実装後に実行する検証
9. 手動確認が必要な項目
10. 残っている不明点とリスク
## ルール
- 仕様にない動作を勝手に追加しないでください
- 重要な不明点は推測で補わず、質問してください
- 複数の実装方法がある場合は、メリットと注意点を比較してください
- 関係のないリファクタリングは計画に含めないでください
私が計画を確認するまで、実装は開始しないでください。
機能を実装してもらうプロンプト
確認済みの実装計画に従って、[対象機能]を実装してください。
## 仕様
- [要件1]
- [要件2]
- [要件3]
- [異常時の挙動]
- [対象外とする内容]
## 制約
- 確認済みの計画に含まれる範囲だけを変更してください
- 関係のないリファクタリングは行わないでください
- 新しい依存パッケージが必要な場合は、追加前に確認してください
- 既存APIのインターフェースを変更しないでください
- 既存テストを削除、スキップ、緩和しないでください
- TypeScript、Lint、ビルドの設定を変更しないでください
- エラーを握りつぶさないでください
- 既存の未コミット変更を保持してください
## 進め方
- 動作確認できる小さな単位で実装してください
- 各工程の終了後に、変更内容を簡潔に報告してください
- 仕様から判断できない重要事項が見つかった場合は、実装を止めて質問してください
エラーの原因を調査してもらうプロンプト
次のエラーについて原因を調査してください。
この段階ではコードを変更しないでください。
## エラー内容
[エラーメッセージを省略せず貼り付ける]
## 発生条件
- 実行した操作:[操作内容]
- 期待する動作:[期待する結果]
- 実際の動作:[実際の結果]
- 直前に行った変更:[変更内容]
- 実行環境:[OS・ランタイム・ブラウザなど]
## 調査してほしいこと
1. エラーが発生している直接的な原因
2. 原因を作っている元の処理
3. 影響を受ける機能
4. 修正方法の候補
5. 各修正方法のメリットと注意点
6. 修正後に確認すべき既存機能
7. 原因を判断した根拠となるコード・ログ・公式仕様
エラーメッセージを非表示にするだけの変更や、
型チェック・Lint・テストを無効化する変更は提案しないでください。
原因と修正方針を確認するまで、コードは変更しないでください。
AIへ「直して」とだけ依頼するのではなく、原因、影響範囲、修正候補を先に調査させます。
テストを作成してもらうプロンプト
[対象機能]のテストケースを整理し、既存のテスト方法に合わせて実装してください。
## 参照するもの
- [要件・受け入れ条件]
- [対象コード]
- [既存テスト]
- [テストに関するプロジェクトルール]
## 必ず検討する観点
- 正常系
- 異常系
- 境界値
- 未認証・権限不足
- 空データ
- 不正な入力
- API・ネットワーク失敗
- 重複実行・連続操作
- 既存機能への回帰
## 制約
- 実装の内部構造ではなく、要件と利用者から見た動作を確認してください
- 重要な処理を過度にモックしないでください
- 既存テストを削除、スキップ、緩和しないでください
- テストを通すために本来の期待値を変更しないでください
- テストしにくい要件がある場合は、その理由と代替確認方法を報告してください
実装前に、要件とテストケースの対応表を提示してください。
GitHubの公式ドキュメントにも、Copilotが生成したテストはすべてのシナリオを網羅するとは限らないため、人間がレビューし、必要なテストを追加するよう記載されています。
したがって、テストコードを作成させる前に、要件とテストケースの対応関係を確認します。
実装後の確認を依頼するプロンプト
今回の実装内容を検証してください。
## 実行する確認
- 関連する単体テスト
- 全体のテスト
- 型チェック
- Lint
- ビルド
- プロジェクトで定義されているその他の検証
## 追加で確認すること
- 要件をすべて満たしているか
- 仕様にない動作を追加していないか
- 関係のないファイルを変更していないか
- 既存テストを削除、スキップ、緩和していないか
- セキュリティ上の問題がないか
- 手動確認が必要な項目は何か
## 完了報告に含める内容
1. 変更したファイル
2. ファイルごとの変更概要
3. 対応した要件
4. 実行したコマンド
5. 各コマンドの終了コードと結果
6. 成功・失敗・スキップしたテスト件数
7. 実行できなかった確認と理由
8. 手動確認項目
9. 残っているリスク・不明点
「問題ありません」とだけ回答せず、
判断の根拠となるコード差分と検証結果を示してください。
OpenAIのCodex公式ガイドでも、変更だけで終わらせず、テストの作成、関連する検証、結果の確認、成果物のレビューまで行わせることが推奨されています。
AIが生成したコードで確認すべき8つのこと
AIが生成したコードも、人間が書いたコードと同じようにレビューが必要です。
GitHubはCopilotの責任ある利用に関する公式ドキュメントで、生成されたコードが有効に見えても、意味的・構文的に正しくない場合や、開発者の意図を反映していない場合があるため、慎重なレビューとテストが必要だと説明しています。
ここでは、初学者でも確認しやすいように、レビューの観点を8つに分けます。
1. お願いした機能がすべて実装されているか
最初に、依頼した要件がすべて実装されているか確認します。
「お気に入り機能が動く」とまとめて判断するのではなく、要件を一つずつコードやテストと対応させます。
| 要件 | 実装箇所 | 確認方法 |
|---|---|---|
| 未登録の商品を登録できる | 登録API・状態更新 | 正常系テスト |
| 登録済みの商品を解除できる | 解除API・状態更新 | 正常系テスト |
| 未ログインでは操作できない | 認証判定 | 未認証テスト |
| API失敗時にエラーを表示する | 例外処理・UI | 異常系テスト |
| 連続操作を防ぐ | 処理中の制御 | UIテスト・手動確認 |
受け入れ条件とコードを対応させることで、実装漏れやテストされていない要件を見つけやすくなります。
2. AIが勝手に仕様を追加していないか
次に、仕様へ書かれていない動作をAIが追加していないか確認します。
例えば、次のような内容です。
- API失敗時に自動で再試行する
- 未ログイン時にログイン画面へ移動する
- お気に入り数へ上限を設ける
- 成功時に通知を表示する
- 楽観的更新を行う
- 一定時間後にエラー表示を消す
これらは一般的に妥当な実装かもしれません。
しかし、一般的に妥当であることと、今回の仕様として正しいことは別です。
NISTは生成AIのリスクとして、誤った内容を確信があるように提示する「Confabulation」を挙げています。
NIST:Artificial Intelligence Risk Management Framework: Generative Artificial Intelligence Profile
AIが自然に説明しているから正しいと判断せず、仕様書、受け入れ条件、既存コードと照合します。
3. 既存コードと同じ書き方になっているか
新しいコードが、既存プロジェクトの実装方法と一致しているか確認します。
主な確認項目は次のとおりです。
- APIの呼び出し方
- 認証情報の取得方法
- 状態管理の方法
- エラーの分類と表示
- コンポーネントの責務
- 型の定義場所
- ログの出力方法
- テストの書き方
ただし、既存コードが常に正しいわけではありません。
既存の方法に問題がある場合は、今回の変更で直すのか、別タスクに分けるのかを人間が判断します。
4. 関係のないファイルまで変更していないか
Gitの差分を開き、変更されたファイルを一覧で確認します。
特に注意したい変更は次のとおりです。
- 関係のないリファクタリング
- 依存パッケージやロックファイルの更新
- 共通関数のインターフェース変更
- TypeScriptやLintの設定変更
- 既存テストの削除・スキップ・緩和
-
.gitignoreへの追加 - エラー抑制コメントの追加
- 生成ファイルや一時ファイルの追加
変更理由を説明できないファイルが含まれている場合は、本当に必要か確認します。
AIの変更要約だけで終わらせず、実際の差分を確認します。
5. エラーや想定外の操作を考慮しているか
正常に操作した場合だけでなく、失敗や想定外の条件も確認します。
例えば、次のような条件です。
- 未認証・権限不足
- 空の入力
- 不正な入力
- APIの失敗・タイムアウト
- ネットワーク切断
- ボタンの連続クリック
- 同じ処理の重複実行
- 対象データがすでに削除されている
- 複数画面から同時に更新された
- 処理の一部だけ成功した
すべての機能で、すべての異常系を確認する必要はありません。
発生しやすさ、ユーザーへの影響、データ不整合の可能性から優先順位を決めます。
6. セキュリティ上の問題がないか
機能が正しく動作していても、安全であるとは限りません。
最低限、次の項目を確認します。
- ログイン確認だけでなく、操作権限も確認しているか
- 他人のデータを閲覧・更新できないか
- 入力値を無条件に信用していないか
- APIキーやパスワードを直接書いていないか
- 秘密情報をログへ出力していないか
- SQLインジェクションやXSSなどの問題がないか
- 外部URLやファイルを無条件に処理していないか
- エラーメッセージから内部情報が漏れないか
- 追加した依存パッケージに既知の脆弱性がないか
GitHub Copilotを対象とした研究では、セキュリティ関連の89シナリオから生成された1,689件のプログラムのうち、約40%に脆弱性が含まれていました。
また、実際のGitHubプロジェクト内のAI生成コードを分析した研究でも、複数のセキュリティ上の弱点が確認されています。
これらは特定のモデル、時点、課題、言語を対象とした研究であり、現在のすべてのAI生成コードへ数値を一般化することはできません。
それでも、AI生成コードに対してもセキュリティレビューが必要であることを示す根拠になります。
7. テストの内容は本当に正しいか
AIが生成したテストコードもレビューします。
主な確認項目は次のとおりです。
- 要件に基づいたテストになっているか
- 関数が呼ばれたことだけで終わっていないか
- 出力や画面表示まで確認しているか
- 失敗すべき条件で本当に失敗するか
- アサーションが弱すぎないか
- 重要な処理を過度にモックしていないか
- 正常系だけでなく異常系や境界値があるか
- 既存の不具合に合わせて期待値を変えていないか
AIが仕様を誤解した場合、その誤解に基づいて実装とテストの両方を作る可能性があります。
その場合、すべてのテストが成功していても、本来の仕様とは異なるコードが完成します。
確認すべきなのは、テストの成功件数だけではありません。
そのテストが、何を正しい動作として定義しているかを確認します。
8. 本番環境で問題が起きないか
最後に、手元の開発環境で動くことだけでなく、本番環境へ反映した場合の影響を確認します。
例えば、次のような項目です。
- 不要なAPI呼び出しが増えていないか
- 大量データで処理が遅くならないか
- DBマイグレーションを安全に適用できるか
- 古いアプリやAPIとの互換性を壊していないか
- ログやメトリクスから障害を確認できるか
- エラー発生時に原因を追跡できるか
- 段階的にリリースできるか
- 問題が起きた場合に元へ戻せるか
- 個人情報や秘密情報をログへ出していないか
NISTのSecure Software Development Frameworkでは、ソフトウェアをリリースする前に、コードレビュー、コード分析、テストなどを組み合わせ、脆弱性や不具合を確認することが推奨されています。
NIST:Secure Software Development Framework Version 1.1
AIは、依頼された機能を完成させることへ集中します。
監視、デプロイ、切り戻しなどが指示に含まれていなければ、自動的にすべて考慮されるとは限りません。
そのため、本番運用に必要な条件も、プロンプトとレビュー項目へ含めます。
AIの「実装できました」という報告は、正しさの証明ではありません。
仕様、コード差分、テスト結果、セキュリティ、本番への影響を人間が確認して、初めてリリース可否を判断できます。
「テスト成功」をそのまま信用してはいけない理由
ここまで、AIが生成したテストコードも確認する必要があると説明してきました。
ここではAIが報告した「テスト成功」という言葉を、どのように確認すればよいのかに焦点を当てます。
重要なのは、結果を次の3つに分けて考えることです。
1. テストコマンドを実行した
2. 実行対象のテストに成功した
3. 実装が仕様を満たしている
これらは同じ意味ではありません。
コマンドが正常終了しても、必要なテストが実行されていない可能性があります。また、すべての既存テストに成功しても、今回の要件を確認するテストが存在しなければ、実装の正しさまでは証明できません。
本当にテストを実行したか確認する
最初に、AIが実行したコマンドと出力を確認します。
AIの完了報告に「テストに成功しました」と書かれているだけでは、次の内容が分かりません。
- 実際にコマンドを実行したのか
- どのディレクトリで実行したのか
- 終了コードはいくつだったのか
- 途中でタイムアウトしていないか
- 警告やエラーが出ていないか
- 実行できないテストを省略していないか
そこで、次のように報告させます。
検証結果について、要約だけでなく次の情報を示してください。
- 実行したコマンド
- 実行したディレクトリ
- 終了コード
- 成功・失敗・スキップしたテスト件数
- 主要な出力
- 実行できなかった確認と理由
Codexは、ターミナルログやテスト結果を作業の証跡として提示し、利用者が実行内容を確認できる仕組みを提供しています。
ただし、ログが存在することと、必要な検証が十分に行われたことは別です。
ログは「AIが正しい」という証明ではなく、人間が作業内容を追跡するための証跡として使います。
どのテストを実行したか確認する
次に、テストの実行範囲を確認します。
例えば、Jestでは、コマンドによって実行対象が変わります。
# 原則として全テストを実行する
jest
# 指定したパターンに一致するテストだけを実行する
jest favorite
# 変更されたファイルに関連するテストだけを実行する
jest --onlyChanged
# 指定したファイルに関連するテストを実行する
jest --findRelatedTests src/features/FavoriteButton.tsx
AIが一部の関連テストだけを実行して成功した場合、それは無意味ではありません。実装直後に素早く問題を発見する方法としては有効です。
ただし、関連テストの成功を「すべてのテストに成功した」と表現するのは正確ではありません。
次のように区別して報告してもらいます。
- 今回変更した機能に関連するテスト
- プロジェクト全体のテスト
- 型チェック
- Lint
- ビルド
- E2Eテスト
どのテストを実行したか分からない場合は、AIへテストファイルの一覧と実行件数を提示させます。
AIがテストを通すために期待値を変えることがある
テストが失敗したあとに、AIがどのファイルを変更したか確認します。
本来、実装が仕様に反しているのであれば、実装側を修正する必要があります。しかし、AIが既存の実装結果に合わせて、テストの期待値を変更する可能性もあります。
例えば、本来の期待値が次の内容だったとします。
expect(response.status).toBe(401);
AIが現在の実装に合わせて、次のように変更すればテストは成功します。
expect(response.status).toBe(200);
しかし、仕様が「未認証の場合は401を返す」であれば、これは修正ではありません。
同様に、次の変更にも注意が必要です。
- 失敗するテストを削除する
-
skipを追加する - アサーションを減らす
- スナップショットを無条件に更新する
- 重要な処理をモックへ置き換える
- テスト対象からファイルを除外する
- タイムアウトを過度に延長する
テストファイルが変更されている場合は、その理由を必ず確認します。
テスト失敗後に変更したファイルを一覧で示してください。
テストコードを変更した場合は、次の内容を説明してください。
- 変更前と変更後の期待値
- 期待値を変更した根拠となる仕様
- 実装ではなくテストを変更した理由
仕様変更に伴ってテストの期待値を変更すること自体は、問題ではありません。
問題なのは、仕様ではなく、現在の実装に合わせるためだけに期待値を変えることです。
実行できなかった確認項目を報告してもらう
AIの実行環境では、必要なすべての検証を行えるとは限りません。
例えば、次の理由でテストできない場合があります。
- 必要な環境変数がない
- データベースへ接続できない
- 外部APIを利用できない
- ブラウザを起動できない
- テスト用アカウントがない
- OSやランタイムが異なる
- 実行時間の制限を超える
- 必要な依存パッケージがない
この場合、確認できなかったことを失敗として責めるのではなく、未検証の内容を正確に報告させることが重要です。
実行できなかった確認について、次の形式で報告してください。
- 確認できなかった項目
- 実行しようとしたコマンド
- 実行できなかった理由
- 代わりに確認できた範囲
- ローカル環境またはCIで実行すべき手順
「実行できなかった」ことが分かれば、人間が別の環境で引き継げます。
最も危険なのは、未実施の確認が完了報告から抜け落ち、人間が検証済みだと誤解することです。
最後は自分でも動作を確認する
自動テストが成功したあとも、ユーザーが実際に行う操作を確認します。
例えば、お気に入り機能であれば、次のような操作です。
1. 未登録の商品をお気に入りへ登録する
2. ボタンの表示が登録済みに変わる
3. 画面を再読み込みしても登録状態が残る
4. 登録済みの商品を解除する
5. API失敗時にエラーが表示される
6. 連続クリックで処理が重複しない
7. 未ログイン状態では操作できない
手動確認は自動テストの代わりではありません。
毎回同じ操作を人間だけで確認していると、確認漏れが起きやすく、変更のたびに時間もかかります。繰り返し確認する重要な操作は、後からE2Eテストなどへ移していきます。
自動テストと手動確認を、次のように使い分けます。
| 方法 | 主な役割 |
|---|---|
| 単体テスト | 関数や小さな処理を高速に確認する |
| 結合テスト | 複数の処理や外部境界の連携を確認する |
| E2Eテスト | ユーザー操作を通した一連の挙動を確認する |
| 手動確認 | 見た目、操作感、仕様上の判断を確認する |
Gitの差分を確認する習慣をつける
AIコーディングで変更内容を把握するには、Gitの差分を確認する習慣が重要です。
まずは、次の3点を見ることから始めます。
1. どのファイルが変更されたか
2. 何が追加・削除されたか
3. その変更が今回の依頼に必要か
AIの説明ではなく、実際の変更を見る
AIは作業終了時に、変更内容を自然な文章で要約してくれます。
しかし、要約に書かれていない変更が含まれている可能性もあります。
例えば、AIが次のように報告したとします。
お気に入り登録・解除機能とテストを追加しました。
実際の差分には、次の変更も含まれているかもしれません。
-
package.jsonへ依存関係を追加 -
tsconfig.jsonのチェックを緩和 - 共通APIクライアントを変更
- 既存テストへ
skipを追加
そのため、AIの報告を確認したあとに、実際の差分を見ます。
変更されたファイルを一覧で確認する
最初からすべてのコードを読むのが難しい場合は、変更ファイルの一覧から確認します。
例えば、次のような結果が表示されたとします。
src/features/products/FavoriteButton.tsx
src/lib/api/favorites.ts
src/features/products/FavoriteButton.test.tsx
package.json
package-lock.json
tsconfig.json
お気に入り機能に関連する3ファイルは自然に見えます。
一方、package.json、ロックファイル、tsconfig.jsonは、なぜ変更されたのか確認が必要です。
変更されたファイルを次のように分類すると、確認しやすくなります。
| 分類 | 確認内容 |
|---|---|
| 予定どおり | 計画に含まれていた変更 |
| 理由を確認 | 関係はありそうだが計画外 |
| 不要な可能性 | 今回の機能との関係を説明できない |
身に覚えのない変更がないか確認する
身に覚えのない変更を見つけた場合は、すぐに削除するのではなく、まず理由を確認します。
次のファイルが実装計画に含まれていませんでしたが、変更されています。
- package.json
- package-lock.json
- tsconfig.json
それぞれについて、変更内容、変更した理由、今回の要件に必要な根拠を説明してください。
まだ追加の変更は行わないでください。
注意して確認したいのは、次のような変更です。
- 依存パッケージの追加・更新
- コンパイラ設定の変更
- Lintルールの無効化
- 既存テストの削除・スキップ
-
.gitignoreへの追加 - APIキーやパスワードの追加
- DBスキーマやマイグレーションの変更
- 共通処理のインターフェース変更
説明を聞いても必要性を確認できない場合は、その変更を今回の作業から外します。
大きな変更は小さな単位に分ける
変更が大きすぎて確認できない場合は、実装単位そのものを見直します。
例えば、次の変更を一度に行うと、差分が大きくなります。
- DBスキーマを追加
- APIを追加
- UIを追加
- 状態管理を変更
- テストを追加
- 共通処理をリファクタリング
次のように、確認可能な単位へ分けます。
1. データ構造とAPI
2. UIと状態更新
3. エラー処理
4. テスト
5. 必要なら別タスクでリファクタリング
AIに限らない一般的なコードレビューの考え方として、GoogleのEngineering Practicesでも、小さな変更は素早く正確にレビューしやすいと説明されています。
Google Engineering Practices:Small CLs
ただし、一ファイルずつ機械的に分けるのではなく、動作や責務として確認できる単位へ分けます。
AIへ差分を説明させてから自分でも確認する
差分の内容が難しい場合は、最初にAIへ説明させる方法も有効です。
現在のGit差分を、変更ファイルごとに説明してください。
各ファイルについて、次の内容を整理してください。
- 何を変更したか
- なぜ変更したか
- どの要件に対応するか
- 既存機能への影響
- 注意して確認すべき行
説明を読んだあと、実際の差分と照合します。
AIへセルフレビューを依頼することもできます。
現在の差分をレビューしてください。
特に次の点を確認してください。
- 要件の実装漏れ
- 仕様にない変更
- 関係のないファイル変更
- エラー処理
- セキュリティ
- テスト不足
まだコードは修正せず、指摘だけを提示してください。
ただし、実装したAI自身が同じ前提でレビューするため、同じ誤解を見落とす可能性があります。
AIの説明とレビューは、自分で確認する場所を絞り込むために使います。
AIを使ってレビューを効率化する
AIが生成するコード量が増えると、人間が確認する差分も増えます。
そこで、コード生成だけでなく、レビュー前の整理にもAIを利用します。
AIレビューの目的は、人間による確認をなくすことではありません。
変更の全体像を整理し、注意すべき箇所へ人間の時間を集中させることです。
AIにセルフレビューを依頼する
実装終了直後に、AIへ自分の変更をレビューさせます。
今回の差分をセルフレビューしてください。
次の観点で問題候補を洗い出してください。
- 要件の実装漏れ
- 仕様にない変更
- ロジック上の不具合
- エラー処理
- セキュリティ
- 既存機能への影響
- 不足しているテスト
まだ修正は行わず、次の形式で報告してください。
- 対象ファイルと行
- 問題の内容
- 問題になる条件
- 重要度
- 修正案
実装直後のAIは、調査したファイルや採用した方針を把握しているため、変更内容の整理には向いています。
一方、実装時と同じ誤解を引き継いでいる可能性があります。
そのため、セルフレビューは最終的な品質保証ではなく、見直すための第一段階として利用します。
別のAIにセカンドレビューを依頼する
必要に応じて、実装に使ったAIとは別のAIへレビューを依頼します。
例えば、Claude Codeで実装した差分をCodexへ確認させたり、その逆を行ったりします。
次のコード差分をレビューしてください。
実装者の説明を前提にせず、差分と要件から独立して確認してください。
特に次の点を確認してください。
- 要件との不一致
- ロジック上の不具合
- 認証・認可
- 異常系
- 既存機能への回帰
- テストの不足
確信度が低い指摘は、その旨を明記してください。
別のAIを使えば、異なる観点の指摘を得られる可能性があります。
ただし、別のAIによるレビューも正しさの証明にはなりません。複数のAIが同じ一般的な実装パターンに基づき、同じ問題を見落とす可能性もあります。
別AIの指摘はそのまま採用せず、コードと仕様を確認して対応の要否を判断します。
Issueの要件と実装を照合する
レビューでは、コードの品質だけでなく、Issueに書かれた要件がすべて実装されているか確認する必要があります。
AIへ次のように依頼できます。
Issueの要件と現在のコード差分を照合してください。
各要件を次のいずれかに分類してください。
- 実装済み
- 未実装
- 実装されたか判断できない
それぞれについて、根拠となるファイル、コード、テストを示してください。
Issueに書かれていない変更も一覧にしてください。
この方法を利用するには、Issue側へ確認可能な要件を書く必要があります。
## 受け入れ条件
- 未登録の商品をお気に入りへ登録できる
- 登録済みの商品を解除できる
- 未ログイン状態では操作できない
- API失敗時にエラーが表示される
- 登録・解除に対応するテストがある
Issueが「お気に入り機能を作る」だけでは、AIも実装済みか正確に照合できません。
CodeRabbitでプルリクエストをレビューする
CodeRabbitは、GitHubやGitLabのプルリクエストを分析するAIコードレビューサービスです。
プルリクエストの変更内容を要約し、変更ファイルを処理のまとまりごとに整理し、レビューコメントを提示できます。
CodeRabbitのPR Walkthroughでは、変更ファイルの要約に加えて、プルリクエストへ関連付けられたIssueとの照合も行えます。
例えば、プルリクエストの説明へ次のように記載します。
Closes #123
CodeRabbitはリンクされたIssueを読み取り、Issueの要求とプルリクエストの変更内容の間に不足がないかを評価します。
また、Change Stackでは、プルリクエストの変更を、関連する処理と依存関係に沿った順序へ整理できます。
例えば、次のような順番です。
型・データ構造
↓
API・ドメイン処理
↓
画面・コンポーネント
↓
テスト
変更ファイルが多い場合も、どこから差分を読めばよいか把握しやすくなります。
ただし、CodeRabbitのレビューにも誤検知や見落としは起こり得ます。Issueが曖昧であれば、要件との正確な照合もできません。
最終判断ではなく、レビュー対象を整理する補助として利用します。
TODOやFIXMEを洗い出してIssue候補にする
コード内のTODOやFIXMEは、コメントとして残しただけでは忘れられる可能性があります。
GitHub Copilot CLIの公式ガイドでは、リポジトリ内のTODOやFIXMEを検索し、周辺コードから優先度を判断して、GitHub Issueを作成する例が紹介されています。
GitHub:Filing issues without breaking your flow
このリポジトリからTODOとFIXMEを検索してください。
各項目について次の内容を整理してください。
- コメントの内容
- ファイルと行番号
- 周辺コード
- 放置した場合の影響
- 推奨する対応
- 優先度
- 推奨ラベル
重複、対応済み、生成ファイル、外部ライブラリのコメントを除外し、
Issue候補を提示してください。
まだIssueは作成しないでください。
見つかったコメントをすべて自動的にIssue化する必要はありません。
次のようなものが混ざっている可能性があります。
- すでに対応済みのコメント
- 現在の仕様では不要な作業
- 同じ問題を指す重複コメント
- 文脈が不足しているコメント
- テストやサンプルコード内のコメント
まずAIに候補を整理させ、人間がIssue化する対象を確認します。
画面の崩れをVisual Regression Testで検出する
フロントエンドでは、ロジック上のテストに成功していても、画面が意図せず変わることがあります。
例えば、次のような変化です。
- ボタンの位置がずれる
- テキストが折り返される
- モーダルが画面外へはみ出す
- 共通CSSの変更が別画面へ影響する
- 特定の画面幅だけ崩れる
- ローディングやエラー表示が消える
このような変化は、Visual Regression Testで検出できます。
Playwrightには、現在の画面と基準画像を比較するtoHaveScreenshot()があります。
import { test, expect } from "@playwright/test";
test("お気に入り登録後の表示", async ({ page }) => {
await page.goto("/products/1");
await page
.getByRole("button", { name: "お気に入りに追加" })
.click();
await expect(page).toHaveScreenshot(
"favorite-registered.png"
);
});
最初の実行で基準画像を作成し、次回以降は現在の画面と比較します。
AIには、変更差分から確認すべき画面を洗い出したり、既存のPlaywrightテストに合わせてテストコードを作成したりしてもらえます。
今回のUI変更によって、見た目が変わる可能性がある画面を洗い出してください。
各画面について、次の内容を整理してください。
- 影響を受ける理由
- 確認する画面幅
- 必要な画面状態
- Visual Regression Testの候補
ただし、画像差分が検出されたからといって、必ず不具合とは限りません。
意図したデザイン変更の場合もあるため、差分を承認するかは人間が判断します。
また、OS、ブラウザ、フォントなどの実行環境が異なると、問題のない差まで検出される可能性があります。CIなどで比較環境をできるだけ統一することも重要です。
AIレビュー、テスト、Visual Regression Testは、それぞれ異なる問題を発見するための手段です。
どれか一つへ置き換えるのではなく、変更内容に応じて組み合わせます。
AI・人間の役割を分ける
AIを使った開発では、すべての確認を一つの手段へ任せないことが重要です。
AI、自動テスト、Lint、人間では、それぞれ確認できることが異なります。
| 担当 | 主な役割 |
|---|---|
| AI | 調査、実装案、影響範囲、問題候補を整理する |
| 自動テスト | 事前に定義した動作が維持されているか確認する |
| 型チェック・Lint | 型や決められたルールへの違反を検出する |
| 人間 | 仕様、設計、リスク、ユーザーへの影響を判断する |
重要なのは、どれか一つを万能な方法として扱わないことです。
AIへレビューを依頼しても、自動テストに成功しても、人間が一度コードを確認しても、それだけですべての問題を見つけられるわけではありません。
それぞれが得意な確認を組み合わせることで、見落としを減らしていきます。
AIが得意なこと
AIは、大量の情報から関連する内容を探し、確認すべき論点を整理する作業に向いています。
例えば、次のような作業です。
- 関連するコードやテストを検索する
- 現在の処理フローを説明する
- 複数ファイルの変更内容を要約する
- 実装方法の候補を比較する
- 影響を受ける可能性がある機能を洗い出す
- 正常系、異常系、境界値の候補を出す
- コード差分から問題候補を探す
- Issueと実装内容を対応づける
- 不足しているテストケースを提案する
- エラーやログから原因の候補を整理する
人間がコードベースを一ファイルずつ確認する前に、AIへ全体像を整理させることで、調査やレビューを始めやすくなります。
一方、AIが提示した関連箇所や影響範囲が、必ず完全であるとは限りません。
AIには、答えを確定してもらうのではなく、人間が確認するための候補と根拠を整理してもらうと考えると使いやすくなります。
人間が判断しなければならないこと
人間が担うのは、正解がコードや設定だけでは決まらない判断です。
例えば、次のような内容です。
- ユーザーが本当に必要としている機能は何か
- 曖昧な要望をどのような仕様にするか
- 複数の実装方法から、どれを採用するか
- 既存設計を維持するか、改善するか
- どこまでを今回の変更範囲に含めるか
- どの不具合やリスクを許容できるか
- テスト内容は十分か
- 本番環境へ反映してよいか
- 問題発生時にどのように対応するか
例えば、AIは「楽観的更新を使えば、画面を素早く見せられる」と提案できます。
しかし、更新に失敗した場合の分かりにくさや、データの重要性を踏まえて、その方法を採用してよいか判断するのは人間です。
AIは選択肢や注意点を提示できますが、ユーザーや事業への影響を引き受けることはできません。
NISTのAI Risk Management Frameworkでも、人間とAIの構成における役割、責任、監督方法を明確にすることが示されています。
NIST:Artificial Intelligence Risk Management Framework 1.0
AIを利用しても、仕様の承認や本番反映の責任までAIへ移るわけではありません。
重要な機能ほど人間の確認を増やす
すべての変更へ、同じ量の確認を行う必要はありません。
例えば、管理画面の文言修正と、決済金額を計算する処理では、不具合が発生した場合の影響が大きく異なります。
次のような機能では、特に慎重な確認が必要です。
- ログインや権限管理
- 決済や請求
- 個人情報
- データの削除
- ファイルの公開範囲
- 医療や健康に関する情報
- 法令や契約に関係する処理
- DBマイグレーション
- 外部公開するAPI
- 大量データの一括更新
変更によるリスクが高い場合は、確認方法を増やします。
低リスクな変更
AIによる調査
→ 関連テスト
→ 差分確認
→ 手動確認
高リスクな変更
AIによる調査・計画
→ 人間による設計確認
→ 小さな単位で実装
→ 単体・結合・E2Eテスト
→ 静的解析・脆弱性検査
→ 複数人によるコードレビュー
→ ステージング環境で確認
→ 切り戻し手順の確認
→ 本番反映
NISTのGenerative AI Profileでも、AIに対する評価や監督の強度を、特定されたリスクに応じて調整する考え方が示されています。
NIST:Artificial Intelligence Risk Management Framework: Generative Artificial Intelligence Profile
AIへ任せる範囲は、「AIが実行できるか」だけで決めるものではありません。
失敗した場合の影響、元へ戻せるか、十分なテストがあるかを踏まえて決めます。
まとめ
ここまで、AIを使って効率的かつ安全に開発する方法を、初学者向けに順序立てて紹介してきました。
AIコーディングで大切なのは、長くて複雑なプロンプトを一つ用意することではありません。
作業を次のような工程へ分け、それぞれの段階で内容を確認することです。
調査
↓
計画
↓
人間による確認
↓
小さな単位で実装
↓
テスト・動作確認
↓
コード差分の確認
AIを使うことで、これまでなら時間がかかっていた調査や実装を、短時間で進められるようになりました。
一方で、コードが速く生成されるほど、人間が内容を理解しないまま変更を積み重ねる危険性も高まります。
AIを利用する目的は、自分で考えなくてもよい状態を作ることではありません。
AIには、調査、生成、整理、機械的な確認を手伝ってもらい、人間は、何を作るか、何を正しいとするか、どのリスクを受け入れるかを判断します。
AIにコードを書かせる方法だけでなく、AIが書いたコードを確かめる方法まで身につける。
それが、AIを便利なコード生成ツールで終わらせず、継続的な開発へ活用するための第一歩だと考えています。
この記事が、AIを使った開発に興味がある方や、生成されたコードをどこまで信用してよいか悩んでいる方の参考になれば嬉しいです。