AIにプログラムを書かせると、こちらが頼んでいないのに「整理しました!」「最適化しました!」と、既存コードを大胆に置き換えられることがあります。
結果、互換性が壊れたり、既存メソッドが消えたり、レビューが地獄になったり……。
そこで私は、“壊さない改修” を引き出すための指示を毎回ほぼ同じ型で入れるようにしています。
このメモでは、特に効いた3つのポイントをまとめます。
まず前提:AIは「善意で整理」して壊しがち
AIは、指示が曖昧だと「読みやすい形に整える」方向へ寄りがちです。
でも現実の開発では、読みやすさよりも先に大事なことが多いですよね。
- 既存の公開APIを壊さない
- 差分を小さくしてレビュー可能にする
- 周辺影響を最小化する
この前提を踏まえて、以下の3点を“最初に”固めます。
「削除禁止・互換性維持」を明示する
毎回これを最初に付けるのが効きます。
ポイントは「雰囲気」ではなく、禁止事項を明文化することです。
禁止事項を箇条書きで固定する
例えばこんな感じで、最初に釘を刺します。
- 既存のメソッド名/シグネチャは削除・変更禁止
- 必要なら deprecated 扱いで残す
- 既存ロジックは差分最小(置換ではなく追記・局所修正)
ここまで言うと、AIの“全体最適化欲”をだいぶ抑えられます。
deprecated で残す発想が効く
「消さない」の代わりに「deprecatedで残す」を許可すると、AIは逃げ道を得ます。
逃げ道がないと、勝手に置換したり、別案を出すために削ったりしがちです。
- 残す(互換維持)
- ただし将来の削除予定としてマークする(設計意図も守る)
この折衷案が、現場ではかなり実用的です。
出力形式を「diff」か「編集指示」に固定する
次に大事なのが、全文貼り替えをさせないことです。
これができるだけで、事故率が一気に下がります。
全文貼り替えを防ぐのが最重要
AIは気を抜くと、ファイル全体を「完成版」として出してきます。
それをコピペ運用すると、意図しない変更が混ざりやすいです。
そこで出力形式を固定します。
- 「unified diff で返して」
- もしくは「変更箇所と追加コードだけ。全文は出さない」
レビューや差分確認の導線ができるので、こちらの精神衛生も守れます。
diff指定が難しい場合の代替
diffが苦手なケース(複数ファイル、口頭ベースの改修など)では、こう言うと安定します。
- 「変更点の一覧(ファイル名/行/理由)→追加コード→置換対象の最小ブロック、の順で」
- 「新規関数は丸ごとOK、既存関数は“追記だけ”」
要は、AIに“全文出力の許可”を与えないのがコツです。
“契約(インターフェース)” を先に固定する
互換性を壊す最大の原因は、AIが「どこが外部契約か」を知らないことです。
移行ライブラリや共通モジュールほど、ここが命取りになります。
公開API・例外・ログ・整合性方針を渡す
最低限、これを明文化して渡すと削除が起きにくいです。
- 公開API一覧(関数/メソッド名、引数、戻り値)
- 例外仕様(何を投げるか)
- ログ仕様
- リトライ/整合性方針(アップロード再開、ETag確認など)
AIは「仕様が書かれていない部分」を勝手に簡略化しやすいので、契約部分だけは先に固定します。
移行・互換系タスクほど先に決める
移行・互換対応は、実装よりも“守るべき約束”が重要です。
この契約を先に渡すと、AIが「触ってはいけない領域」を理解しやすくなります。
そのまま使えるプロンプト雛形(コピペ用)
最後に、上の3点をまとめたコピペ用です。必要に応じて調整して使えます。
- 前提/制約
- 既存のメソッド名/シグネチャは削除・変更禁止
- 変更が必要なら deprecated 扱いで残す
- 既存ロジックは差分最小(置換ではなく追記・局所修正)
- 出力形式
- unified diff で返して(全文貼り替えは禁止)
- 変更箇所と追加コードだけを提示すること
- 契約(インターフェース)
- 公開API:{ここに一覧}
- 例外仕様:{ここに仕様}
- ログ仕様:{ここに仕様}
- リトライ/整合性方針:{ここに方針}
- 依頼内容
- {やりたい改修内容を1〜3行で}
- {受け入れ条件(テスト、互換、パフォーマンスなど)}
まとめ
- 削除禁止・互換性維持を最初に明示すると事故が減る
- 出力をdiffか編集指示に固定して全文貼り替えを防ぐ
- “契約(インターフェース)” を先に固定すると互換が守られやすい
- 最後はコピペ雛形にして毎回同じ型で投げるのがラク
壊さない改修は、AIの能力というより「こちらの指示の型」で決まることが多いです。
この3点だけでも、かなり安定するはずです。
