AIエージェントが作ったPRをレビューし、不要な変更を削る方法
AIコーディングエージェントが作成したPull Requestをマージ前に精査する実践手順です。受け入れ条件を固定し、完全なdiffを確認し、新しいコンテキストのレビュー役に根拠を求め、小さな単位で削減し、同じ検証を再実行して人間が承認します。
目次

AIコーディングエージェントは、バグ修正や機能実装を短時間で進められます。その一方で、依頼と無関係なファイルの整形、過剰な抽象化、設定変更、広範囲な書き換えまで含めることがあります。マージ前の目標は、単に行数を最小化することではありません。重要な変更が明確な要件に対応し、メンテナーが自分の言葉で説明でき、テストや別の証拠で確認できる状態にすることです。
ある開発者はXで、エージェントがPRを作った後、新しいコンテキストでもう一つのエージェントを起動し、削れる部分を探させる個人的な方法を紹介しました。本人も追加の作業とトークンが必要で、保証された最適解ではないと述べています。また別のユーザーは、Codexが多数のエラーを直した一方、コード全体を大きく変更し、自分で理解できなくなったと報告しました。これらは問題の存在を示す利用者報告であり、第二のエージェントが常にPRを改善するという証明ではありません。
以下では、第二のエージェントを「疑うレビュー役」として扱います。範囲、根拠、リスク、最終的なマージ判断の責任は人間に残します。
7ステップの全体像
- 受け入れ契約を書く。期待する動作、変えてはいけない動作、許可範囲、リスク、検証コマンドを固定する。
- Conversation、Commits、Checks、Files changedとローカルGitで変更の全体像を作る。
- 新しいコンテキストのエージェントには、最初はレビューだけをさせ、編集を禁止する。
- 指摘を「維持・簡略化・削除・別PRへ分離・人間判断」に分類し、根拠を要求する。
- 人間が承認した削減だけを、小さく元に戻せる単位で適用する。
- 削減前後で同じ関連テストとチェックを実行する。
- 最終diffを最初から読み直し、全変更を説明できる場合だけマージする。
1. 第二レビューの前に受け入れ契約を書く
「このPRをきれいにして」という指示は曖昧で、別の主観的な書き換えを誘発します。短い受け入れ契約に、最低でも次を含めます。
- 問題と観測可能な結果:ユーザーや呼び出し側が何を確認できるか。
- 維持する動作:既存インターフェース、失敗時の動作、互換性、データの意味。
- 許可する範囲:変更が予想されるモジュール、API、スキーマ、設定、テスト。
- 明示的な非目標:フレームワーク更新、全体整形、無関係な名称変更、将来用の抽象化、不要な移行を行わない。
- リスク制約:セキュリティ、権限、移行、性能、可観測性、ロールバック、後方互換性。
- 検証方法:リポジトリで実際に使うformat、lint、型検査、unit、integration、build、migration、E2Eコマンド。
正しい結果を説明できない状態では、不要なコードも判断できません。削る前に契約を明確にします。
2. エージェントの要約ではなく完全なdiffを確定する
GitHubではPRの証拠が複数の画面に分かれます。Conversationには説明と議論、Commitsには履歴、Checksには自動検証、Files changedには実際のdiffがあります。公式のレビュー機能では、行コメント、修正提案、ファイル単位のViewed、最後のComment・Approve・Request changesを使えます。
ローカルで実行または修正する場合、GitHubの手順は次です。
gh pr checkout <PR_NUMBER>
git fetch origin
origin/mainは実際のベースブランチに置き換え、共通祖先からHEADまでを確認します。
git diff --stat origin/main...HEAD
git diff --name-status origin/main...HEAD
git log --oneline origin/main..HEAD
Gitの定義では、git diff A...BはAとBのmerge baseからBまでの変更です。概要の後に完全なdiffと疑わしいパスを読みます。
git diff origin/main...HEAD
git diff origin/main...HEAD -- path/to/suspicious-file
この棚卸しではまだ削除しません。ファイルを次のように分けます。
| 分類 | 確認する質問 |
|---|---|
| 中核実装 | 受け入れ契約の項目を直接実装しているか |
| 必要な補助 | テスト、文書、移行、設定は中核変更に本当に必要か |
| 範囲拡大の疑い | 全体整形、大量名称変更、無関係な抽象化、依存更新が入っていないか |
| 生成物 | ソースと一緒にコミットすべきか、誤って入ったか |
| 不確実・高リスク | セキュリティ、データ、互換性、未知の領域に触れていないか |
複雑に見えるだけでは冗長とは言えません。防御処理、移行、互換性コードは長くても必要な場合があります。
3. 新しいコンテキストでは、最初のパスをレビュー専用にする
新しいコンテキストの利点は、第二のエージェントが本質的に正しいことではありません。実装を完成させるのではなく、範囲と根拠を疑う別の目的を与えられる点です。これは実務者の報告に基づくレビュー手法であり、GitHubの必須要件でも、効果が測定された保証でもありません。
受け入れ契約、完全なdiff、関連する呼び出し元、テスト、リポジトリ規則を渡し、次のように依頼します。
あなたはこのPull Requestの第二段階のメンテナーレビュー担当です。目的はコードを書き直すことではなく、受け入れ契約を満たす最小で説明可能な変更集合を見つけることです。
最初のパスはレビューのみ。ファイルを変更しないでください。
PRの目的、完全なdiff、関連する呼び出し元、テスト、リポジトリ制約を読んでください。
各指摘について出力するもの:
1. ファイルと正確なhunkまたはシンボル
2. その変更が満たす要件
3. 根拠:呼び出し元、テスト、インターフェース契約、文書、または根拠不足
4. 削除・簡略化のリスク
5. 推奨:KEEP / SIMPLIFY / REMOVE / SPLIT / HUMAN DECISION
6. 変更後に実行する正確な検証
規則:
- 長い、またはスタイルが違うという理由だけで削除を勧めない
- テスト成功だけを要件の正しさの唯一の証拠にしない
- 無関係な整形、重複抽象化、未使用helper、範囲外refactor、説明のない依存・設定変更を重点確認する
- 反証がなければ、セキュリティ、互換性、移行、エラー処理、可観測性を維持する
- 不確実性を明記し、業務ルールを推測しない
- 最後に低リスクから高リスクの削減計画を示す。まだコードを書かない
先に報告だけを出させれば、「削減」の名目で新しい大規模変更を作る危険を下げられます。各提案はファイル、hunk、根拠に結び付けます。
4. 人間が根拠を見て分類する
| 判断 | 適用条件 | 人間が確認する根拠 |
|---|---|---|
| 維持 | 契約、セキュリティ、互換性、移行、運用上必要 | 要件対応、呼び出し経路、テスト、インターフェース、文書化制約 |
| 簡略化 | 動作は必要だが分岐、wrapper、層が重複 | 前後の動作同等性と重要な境界の検証 |
| 削除 | 無関係、未使用、契約なし、偶発的な整形・改名 | リポジトリ検索、build、関連テストで依存がない |
| 分離 | 価値はあるが現在の契約外 | 独立して説明、テスト、レビュー、revertできる |
| エスカレーション | 未知領域、セキュリティ境界、移行、暗黙ルール | code owner、領域担当、characterization testが必要 |
次は疑うべきですが、自動削除の条件ではありません。1つの呼び出しに多層の汎用化、互換期間の説明がない新旧経路、無関係な整形・import・改名・移動、説明のない依存や設定、実装形状だけを検証するテスト、例外の握りつぶし、呼び出し元がないhelper、「将来使うかもしれない」コードです。
テストがないことも未使用の証明ではありません。カバレッジ不足かもしれません。不確実な動作を消す前にcharacterization testを追加するか、担当者に確認します。
5. 小さな単位で削り、復旧地点を残す
編集前にworking treeを確認し、ローカルのバックアップ参照を作ります。
git status --short
git branch backup/ai-pr-before-trim
ファイル全体をベース状態へ戻す場合:
BASE=$(git merge-base origin/main HEAD)
git restore --source="$BASE" -- path/to/unrelated-file
一部hunkだけなら:
git restore -p --source="$BASE" -- path/to/file
Gitの文書では、追跡対象パスがrestore sourceに存在しない場合、sourceに合わせるため削除されます。$BASEとパスを確認し、実行後すぐdiffを見てください。手動編集でも構いません。重要なのは、新たな範囲外refactorを混ぜないことです。
承認済みの1グループずつ処理します。
git diff
git add -p
git diff --cached
git commit -m "Remove unrelated changes from AI-generated PR"
小さいcommitなら、何を、なぜ削り、どの検証をしたか追跡できます。レビュー中に破壊的な履歴書き換えで過程を隠さないでください。
6. 削減前後で比較可能な検証を行う
テストの目的はdiffが短くなったことではなく、合意した動作が残ったことの確認です。可能なら元のPRの基準結果を記録し、各バッチ後に同じ関連コマンドを実行します。
<format-check-command>
<lint-command>
<typecheck-command>
<targeted-unit-test-command>
<relevant-integration-test-command>
<build-or-e2e-command>
コマンドはリポジトリ文書やCIから取り、エージェントに推測させません。通常経路、重要な境界、失敗、権限、空値、並行処理、timeout、retry、公開API、serialize形式、移行、build、型、lint、security、最新commitの必須Checksを確認します。
削減でテストが失敗したら、そのバッチを戻すかバックアップから復元して原因を調べます。受け入れ契約が古い期待を明確に否定し、人間が承認していない限り、緑にするためだけにテストと実装を同時変更しません。
緑のテストは重要ですが、完全とは限りません。メンテナーの理解も必須です。
7. 最終diffを再レビューし、明示的に判断する
削減後はFiles changedを開き、最初から全ファイルを見直します。GitHubではViewedにしたファイルが変更されるとViewedが解除されるため、再確認対象が分かります。CommitsとChecksも再度見て、最新revisionに対する結果か確認します。
最終diffだけを新しいコンテキストで再確認してもよいですが、停止条件を決めます。根拠のある問題だけを報告し、無限のスタイル改善を始めないことです。その後、人間が次を送信します。
- Approve:契約達成、全重要変更を説明可能、リスク対応済み、必須検証成功。
- Request changes:範囲外変更、不透明なロジック、失敗チェックが残る。実際にmergeを止めるかはrepository rulesとbranch protectionによる。
- Comment:有用なフィードバックだが、承認でも正式な変更要求でもない。
マージ前チェックリスト
- すべての変更ファイルが要件、必要テスト、明示的補助作業に対応している。
- メンテナーが重要なhunkをエージェント要約なしで説明できる。
- 説明のない依存、設定、権限、移行、生成物は削除、分離、または担当者へエスカレーションした。
- 元のPRと削減後で比較可能な検証を行った。
- ローカルテスト、build、最新commitのChecksがプロジェクト要件を満たす。
- セキュリティ、データ、互換性の不確実性を適切な担当者が確認した。
- diffがまだ広い場合、独立作業を別PRへ分けた。
- レビュー判断とfollow-upを記録した。
よくある失敗と復旧
第二エージェントがモジュールを書き直し始める
実行を止め、編集なしの報告へ戻します。対象ファイルを制限し、各提案にhunk、要件、検証を必須にします。根拠のない美的refactorは却下します。
エージェント同士の意見が割れる
多数決にしません。呼び出し元、インターフェース契約、失敗経路、テスト、過去の制約を比較します。根拠が弱ければ一時的に維持し、coverageを追加するか領域担当に確認します。
テストは通るがコードを説明できない
coverageと理解可能な設計は同じではありません。PRを分け、文書を追加し、重要経路の説明を求めます。CIが緑だけを理由に不透明なコードをマージしません。
信頼できるテストがない
維持する動作に対する最小characterization test、または再現可能な手動確認と記録を作ります。高リスク領域では、証拠不足は停止理由であり、推測の許可ではありません。
PRが大きすぎる
中核動作、refactor、依存更新、整形、移行を独立した変更に分けます。小さい単位ほど検証とrevertが容易です。
承認済み項目を実装するためのプロンプト
承認済みのfinding ID [LIST] だけを実装してください。
承認リスト外のファイルを変更せず、ついでのrefactorを行わないでください。
各論理グループごとに:
1. 実際のdiffを表示する
2. 指定された検証コマンドを実行する
3. コマンド、終了status、失敗要約を報告する
4. 残る不確実性を列挙する
受け入れ契約、公開interface、security、migrationの動作が変わる場合は停止し、人間の判断を求めてください。
重要なのは「エージェントを増やす」ことではありません。生成とレビューを分けます。第一のコンテキストが実装を提案し、第二のコンテキストが範囲と根拠を疑い、人間が決定と受け入れを所有します。正解は最短diffではなく、タスクを満たす最小で説明可能かつ検証済みの変更です。
情報源と適用範囲
- 実務者の個人報告:新しいコンテキストで削減レビューを行う Arnav GuptaのX投稿と返信。一般的な効果を示す統計ではありません。
- ユーザー報告:Codexの広範囲変更後にコードを理解できなくなったという 投稿。repository、diff、test dataは公開されていません。
- GitHub公式文書:PRの変更レビュー、PRをローカルにcheckout、Pull requests reference。
- Git公式文書:git diff、git restore。