GitHub CopilotやChatGPTなどのAIコーディングアシスタントは開発効率を大きく向上させますが、既存のコードベースに対して不用意に指示を出すと、意図しないデグレード(先祖返りや既存ロジックの破壊)を引き起こすリスクがあります。
この記事では、既存コードの振る舞いを維持しつつ、AIに安全かつ正確な修正を行わせるためのプロンプト設計、指示の出し方、および実務で使えるテンプレートとチェックリストを解説します。
読者が抱える課題
- AIにコード修正を依頼すると、既存の重要な処理や例外ハンドリングが勝手に省略されてしまう。
- 修正箇所以外の部分まで書き換えられ、マージ時にコンフリクトやバグが発生する。
- 既存のコーディング規約やアーキテクチャ方針を無視したコードが生成される。
この記事で分かること
- 既存コードを壊さないためのプロンプト構成要素
- AIへの指示における「良い例」と「悪い例」の比較
- 実務でそのまま使える「AI指示用プロンプトテンプレート」
- 差分適用時・レビュー時のチェックリスト
既存コードを保護するための3つの原則
AIにコードを修正させる際、以下の3つの原則を意識することでデグレードのリスクを下げることができます。
- コンテキストの局所化(Scope Limitation): 修正対象の関数やクラスのみにスコープを絞り、関係のないコードをAIに読み込ませたり出力させたりしない。
- 不変条件の明示(Invariants Specification): 「変更してはいけない挙動」や「維持すべき既存の仕様」を制約条件として明記する。
- 差分出力の強制(Diff-only Output): コード全体を再出力させるのではなく、変更箇所(差分)のみを出力させることで、見落としによる先祖返りを防ぐ。
良い指示と悪い指示の比較
ユーザー情報を更新する既存の関数に、新しく「メールアドレスの重複チェック」を追加する場合を例にします。
悪い指示の例
「以下のユーザー更新処理に、メールアドレスが重複していないかチェックする処理を追加してください。」
-
問題点: 既存のバリデーションルールや、エラーハンドリング(カスタム例外の送出など)が省略され、AIが一般的な
try-catchに書き換えてしまう可能性があります。また、コード全体が出力されるため、既存の細かい仕様が抜け落ちるリスクがあります。
良い指示の例
「以下の
updateUser関数に、メールアドレスの重複チェック処理を追加してください。制約条件:
- 既存の
UserValidationErrorを用いたエラーハンドリングフローを変更しないでください。- データベース接続のトランザクション処理(
db.transaction)の範囲を維持してください。- 変更箇所のみをUnified Diff形式、または該当箇所のみのコードブロックで出力してください。関係のない行は省略してください。」
- 改善点: 壊してはいけない既存の構造(例外クラス、トランザクション)を明示し、出力範囲を限定しています。
実務用プロンプトテンプレート
既存コードの修正・機能追加をAIに依頼する際に、コピー&ペーストしてカスタマイズできるテンプレートです。
# 目的
[例: 既存の決済処理に、クーポン適用時の割引ロジックを追加する]
# 対象コード
```[言語名]
[ここに修正対象のコードを貼り付ける]
変更内容
- [例: 引数に couponCode: string を追加する]
- [例: クーポンが有効な場合、合計金額から指定の割引率を適用する]
守るべき制約条件(既存コードの保護)
- 変更禁止: [例: 既存の外部決済API呼び出し(chargeGateway)のシグネチャおよび呼び出し順序は絶対に変更しないでください]
- 例外処理: [例: 既存の例外クラス(PaymentException)のハンドリングを維持してください]
-
型定義: [例: 既存のインターフェース
PaymentResultを変更せず、戻り値の型を維持してください]
出力フォーマット
- 修正が必要な関数/クラスのみを出力してください。変更のない関数は含めないでください。
- 変更前と変更後のコードの差分が明確に分かるように、該当箇所のみを出力してください。
---
## 実装・適用時の作業手順とチェックリスト
AIが生成したコードをローカル環境に適用し、安全にリリースするまでの手順とチェックリストです。
### 作業手順
1. **作業ブランチの作成**: 必ずクリーンな状態のGitブランチで作業を開始します。
2. **プロンプトの実行**: 上記テンプレートを用いてAIに指示を出します。
3. **差分適用**: 生成されたコードを適用します。エディタの差分表示機能(VS CodeのCompare機能など)を活用し、意図しない行が削除・変更されていないか確認します。
4. **ローカルテストの実行**: 既存のユニットテストを実行し、デグレードがないか確認します。
### 安全確認チェックリスト
| 確認項目 | チェック内容 | 確認方法 |
| :--- | :--- | :--- |
| **シグネチャの維持** | 関数の引数や戻り値の型が、既存の呼び出し元と整合しているか | コンパイル/型チェックの実行 |
| **例外ハンドリング** | 既存のカスタム例外やエラーログ出力処理が消去されていないか | コードレビューによる目視確認 |
| **不要なリファクタリング** | 指示していない変数名の変更や、ロジックの「最適化」が勝手に行われていないか | Gitの差分(`git diff`)確認 |
| **依存関係の追加** | AIが勝手に新しい外部ライブラリをインポートしていないか | インポート文の確認 |
| **テストの成否** | 既存のテストケースがすべてパスしているか | `npm test` や `pytest` 等の実行 |
---
## 注意点と失敗しやすいポイント
### 1. AIによる「親切なリファクタリング」に注意する
AIは指示された機能追加だけでなく、コードを「より綺麗に」しようとして、変数名をキャメルケースからスネークケースに変えたり、独自のユーティリティ関数に置き換えたりすることがあります。これは一見良いことに見えますが、他のファイルとの整合性を崩す原因になります。プロンプトで「指示のないリファクタリングは行わないこと」と明記することが有効です。
### 2. コンテキストウィンドウの限界とハルシネーション
一度に大量のソースコードをAIに読み込ませると、細かい制約条件を無視しやすくなります。修正したいファイルが複数にまたがる場合でも、1ファイルまたは1関数ずつ段階的に指示を出し、その都度動作確認を行うアプローチを推奨します。
## まとめ
AIコーディングで既存コードを壊さないためには、AIの自由度を適切に制限する「制約条件の明示」と「出力範囲の限定」が鍵となります。実務でAIを活用する際は、本記事のテンプレートとチェックリストを参考に、安全な開発プロセスを構築してください。
*※AIモデルのアップデートにより、プロンプトに対する応答の傾向が変化する場合があります。実際の開発環境に合わせて、プロンプトの制約表現を適宜微調整してください。*