この記事は「AIエージェントを工程に入れる」シリーズの第2回です。
第1回では、AIエージェントに渡す仕様書の書き方を扱いました。
今回は、その後に必ず来る問題、つまり「出てきた成果物をどう検品するか」を扱います。
AIエージェントを使い始めると、最初に速くなるのは実装です。
Claude Code や Codex に頼めば、既存コードを読み、差分を作り、テストを追加し、失敗ログを読んで直す。これまで人間が一つずつやっていた作業を、かなりの速度で進められます。
ただ、その次に別のボトルネックが出ます。
レビューです。
AIが1本のPRを作るだけなら、人間が見ればいい。
10本なら、まだ何とかなる。
でも、50本、100本、700本になったらどうするか。
生成だけなら700本出せる。けれど検品の仕組みがなければ、同じ700本が今度は700件分のレビュー負債になります。
ここで必要なのは、「AIにもう一度レビューさせる」だけではありません。
どの変更を人間が見るべきか。
どの変更は機械的に落とせるか。
どの失敗を eval に回すか。
どの trace を残すか。
CI に入る前にどこで止めるか。
レビュー結果を次の仕様書や AGENTS.md に戻すか。
この層を作らないと、AIエージェントは速い作業者ではなく、速いレビュー負債生成器になります。
Reviewは「読む」だけでは足りない
人間が書いたコードのレビューなら、PRを開いて diff を読む、コメントする、直してもらう、で回ります。
AIエージェントの出力でも、最初は同じように見えます。
でも量が変わると、性質が変わります。
AIは疲れません。並列に動きます。小さな修正も大量に作れます。ログを読んで何度も直せます。つまり、出力の上限が人間の手より高い。
そのぶん、レビュー側が詰まります。
ここで review を「人間が読む作業」とだけ考えていると破綻します。
AIエージェント時代の review は、次の4つに分けた方がいいです。
1. Trace 何が起きたかを残す
2. Triage どれを見るべきか分ける
3. Eval 機械的に判定できるものを判定する
4. Human 人間が最終判断する
人間レビューは最後に残ります。
ただし、人間に上げる前に、かなりのものを整理できます。
Trace:まず「何をしたか」を残す
AIエージェントの作業で困るのは、あとから追いにくいことです。
どのプロンプトで始まったのか。
どのファイルを読んだのか。
どのコマンドを実行したのか。
どのテストが落ちたのか。
どのログを見て、どう修正したのか。
どの判断を人間が承認したのか。
これが残っていないと、レビューは diff から推理するしかありません。
人間が書いたPRでも、背景がない diff は読みづらい。AIが作った diff なら、なおさらです。
だから、まず trace が必要になります。
trace は、きれいなダッシュボードである必要はありません。最初は作業ログで十分です。
agent に、最後にこう出させるだけでも変わります。
最後に作業ログをまとめてください。
- 最初の目的
- 読んだ主なファイル
- 変更したファイル
- 実行したコマンド
- 失敗したテスト
- 修正した理由
- 未確認のこと
- 人間に見てほしい点
これがあると、reviewer は diff の前に文脈を読めます。
Traceで見るもの
Trace で見たいのは、長い会話ログそのものではありません。
見るべきなのは、判断に必要な点です。
| 見るもの | なぜ必要か |
|---|---|
| 目的 | 最初の依頼から外れていないか見る |
| 読んだファイル | 必要な文脈を見たか確認する |
| 変更ファイル | 変更範囲が広がっていないか見る |
| 実行コマンド | テストやビルドを本当に走らせたか見る |
| 失敗ログ | 場当たり的に直していないか見る |
| 未確認事項 | 人間が判断すべき点を残す |
PromptLayer のような trace 系ツールは、この位置に入ります。
「プロンプト管理ツール」として見るより、review の材料を残す部品として見る方が分かりやすいです。どの依頼から、どの出力が生まれ、どこでコストや失敗が発生したかを追えると、後から改善できます。
trace がない eval は作りにくい。trace がない review は属人的になります。
Triage:全部を読まないために分ける
次に必要なのは triage です。
すべての AI 生成 diff を同じ重さで見る必要はありません。
たとえば、次の変更は軽い。
- typo 修正
- README の小さな補足
- テスト名の修正
- 明らかに局所的な型修正
一方で、次は重い。
- 認証まわり
- 課金まわり
- DB migration
- 権限チェック
- 外部API呼び出し
- セキュリティ境界
- 大きなリファクタ
- テスト削除
同じ review queue に入れると、人間は疲れます。
だから、まず分けます。
このdiffを triage してください。
分類:
- trivial: 文言、コメント、局所的な型修正
- normal: 通常の機能修正、テスト追加
- risky: 認証、権限、DB、外部API、セキュリティ境界、広範囲変更
出力:
- 分類
- 理由
- 人間レビューで見るべき点
- 機械的に確認できる点
この triage は、人間がやってもいいし、別の agent にやらせてもいいです。
重要なのは、reviewer がいきなり全 diff に向き合わないことです。
PRは「差分」だけでは足りない
GitHub の diff view は、人間が書いた中小PRを読むにはよくできています。
でも AIエージェント時代には、PRに含まれるものが増えます。
- 実装差分
- テスト差分
- 生成された補助ファイル
- スナップショット更新
- ログ
- agent の作業メモ
- 複数回の修正履歴
diff だけを見ると、文脈が足りません。
Linear Diffs のような PR review workflow は、この文脈で見ます。単に diff を見やすくする道具ではなく、人間が見るべき変更をどう並べるか、どの変更を先に見るか、どこを畳むか、という triage の部品です。
AI生成コードが増えるほど、review UI は「全部を表示する場所」から「見るべきものを絞る場所」に変わります。
Eval:毎回見るものを機械に落とす
review で毎回同じことを見ているなら、それは eval にできます。
eval で大事なのは、評価を雰囲気でやらないことです。自分のプロダクトに合わせた評価項目を作り、実データと失敗例を見て、改善ループを回す。
coding agent でも同じです。
最初から立派な eval 基盤を作る必要はありません。
最初は checklist でいいです。
AI生成diffの最低チェック:
- 変更対象外のファイルを触っていないか
- 既存テストを削っていないか
- API / DB schema を勝手に変えていないか
- 認証・権限まわりに触っていないか
- テストが実装の都合に寄りすぎていないか
- 失敗したテストをスキップしていないか
これを人間が毎回見る。
次に、機械化できるものをスクリプトにします。
- テスト削除を検出する
- migration 変更を検出する
- auth ディレクトリ変更を risky に分類する
- snapshot 大量更新を検出する
- TODO / FIXME の増加を検出する
- テストスキップの追加を検出する
さらに、AIによる一次判定が向いているものだけを自動判定に回します。
- 仕様から外れていないか
- エラー状態の説明が足りているか
- review summary が正しいか
- user-facing text が既存トーンに合っているか
全部を LLM judge にする必要はありません。
ルールで落とせるものはルールで落とす。
テストで落とせるものはテストで落とす。
LLM judge は、言語的・文脈的な判断が必要なところに使う。
この分け方が大事です。
小さいevalと大きいevalを分ける
eval は、細かいチェックだけでは足りません。
小さい eval は、1つの出力を見るものです。
- テストを消していないか
- migration が増えていないか
- secret らしき文字列がないか
- 仕様にないファイルを触っていないか
- PR説明にテスト結果があるか
これは機械化しやすいです。
一方で、大きい eval は、作業全体を見るものです。
- 調査から実装までの流れが妥当か
- 最初の仮説は外れていなかったか
- failing test は本当にバグを表していたか
- 修正後に同じ種類の失敗を防げるか
- review の指摘が次回のルールに戻ったか
これは単純な lint では見られません。
作業ログ、diff、テスト、review、Compound note をまとめて見ます。
AIエージェントの eval は、単発の回答採点だけでは弱いです。
実務では、1つの出力より、1つの作業の終わり方を見る必要があります。
良い作業:
- 目的が明確
- 変更範囲が小さい
- 再現テストがある
- 関連テストを実行している
- review しやすい diff
- 次回に戻す学びがある
悪い作業:
- 速いが差分が広い
- テストがない
- 失敗理由が曖昧
- 仕様外の改善が混ざる
- 次回に何も残らない
この見方を入れると、eval は「採点」ではなく、作業品質を見る仕組みになります。
Pre-CI Review:CIに入る前に止める
AIエージェントの出力は、CIまで行く前に止めたいものがあります。
たとえば、次のような差分です。
- 関係ないファイルを大量に変更している
- テストを削っている
- テストを skip している
- lockfile だけ大きく変わっている
- migration があるのに rollback がない
- 認証・権限まわりに触っているのに説明がない
- secrets らしき文字列が混ざっている
これらは、CI の前に検出できます。
Chunk sidecars のような、CI に入る前の検証系の仕組みは、この位置に入ります。
目的は「AIレビューを賢くする」ことではありません。
CIに入れる前に、明らかに危ない差分を止めることです。
たとえば、CI に入る前にこういう分類をします。
safe:
- docs-only
- test-only
- 型注釈の局所修正
needs-review:
- 通常の機能変更
- UI変更
- テスト追加を伴うロジック変更
blocked:
- テスト削除
- migration 変更
- 認証・権限まわり
- secrets らしき文字列
- 変更ファイル数がしきい値超え
blocked は人間承認なしに進めない。
needs-review は review queue に入れる。
safe は軽い review に回す。
このように分けると、人間の目を使う場所が絞れます。
Human Review:人間が見るべきものを残す
ここまで trace、triage、eval、CI に入る前の検証を書きました。
それでも、人間レビューは残ります。
むしろ、ここが残るように前段を作ります。
人間が見るべきなのは、次のような判断です。
- この仕様は本当に必要か
- 今回のPRでやるべきか
- リスクを受け入れるか
- 既存設計と違うが、変える価値があるか
- ユーザー体験として自然か
- 運用チームが扱えるか
- セキュリティ上、この境界でよいか
これは agent に任せきれません。
agent は材料を整理できます。候補を出せます。危ない点を指摘できます。でも、プロダクト上の優先順位や組織としてのリスク許容は、人間が持つべきです。
だから、良い review flow は人間を消しません。
人間が見るべきものだけを残します。
具体例:検索機能PRをreviewする
第1回の仕様書で作った商品検索機能を例にします。
agent が実装して、PR を作ったとします。
まず trace を出させます。
このPRの作業ログをまとめてください。
- 最初の目的
- 読んだファイル
- 変更したファイル
- 実行したテスト
- 失敗したテストと修正内容
- 未確認のこと
- 人間に見てほしい点
次に triage します。
このPRを risky / normal / trivial に分類してください。
観点:
- API変更
- DB変更
- 認証・権限
- 変更ファイル数
- テスト削除
- 既存仕様への影響
分類理由も書いてください。
次に eval/checklist を通します。
以下を確認してください。
- 商品名検索だけに収まっているか
- SKU検索を追加していないか
- API と DB schema を変更していないか
- カテゴリフィルタと同時に使えるテストがあるか
- 空文字なら全件表示されるテストがあるか
- 既存のソート順が壊れていないか
最後に人間が見ます。
人間が見るのは、全部ではありません。
- 仕様から外れていないか
- UIとして自然か
- テスト観点が十分か
- 今回やらないと決めたことを守っているか
この順番なら、reviewer はいきなり diff の海に入らずに済みます。
Review結果を次に戻す
review は、その場で終わらせると弱いです。
毎回同じ指摘をしているなら、それは次の仕様書、AGENTS.md、checklist、eval に戻します。
たとえば、今回こういう指摘が出たとします。
カテゴリフィルタと検索条件を同時に使うテストが抜けていた。
その場で直すだけなら、次回また抜けます。
次のように戻します。
AGENTS.md:
一覧画面に検索・フィルタを追加する場合、
既存フィルタとの組み合わせテストを必ず検討する。
仕様書テンプレート:
既存フィルタ、ソート、ページネーションとの組み合わせを確認する。
eval/checklist:
filter / search / sort のいずれかを変更したPRでは、
組み合わせテストの有無を確認する。
こうして、review の学びを次の Plan に戻します。
これがないと、review はただの消耗になります。
ツールが自然に出てくる場所
この回でも、ツールは主役ではありません。
詰まった場所で出てきます。
trace が残らないなら PromptLayer
どのプロンプトで、どの出力が出て、どこでコストが増え、どこで失敗したかを追いたいなら、PromptLayer のような trace 系ツールが出てきます。
見るべき点は、UIのきれいさではありません。
- 作業単位で trace を追えるか
- review に必要な情報だけ抜けるか
- コストと失敗を紐づけられるか
- 後から eval dataset に回せるか
CI前に止めたいなら Chunk sidecars
AIが作った差分を CI に入れる前に検証したいなら、Chunk sidecars のような仕組みが出てきます。
見るべき点は、どれだけ多く検出できるかだけではありません。
- 誤検知で開発を止めすぎないか
- blocked / needs-review / safe を分けられるか
- 人間承認をどこに入れるか
- 既存CIとどうつなぐか
PRが読みにくいなら Linear Diffs
AIエージェントのPRが増え、diff が読みにくくなるなら、Linear Diffs のような review workflow が出てきます。
見るべき点は、diff の見た目だけではありません。
- 変更の意図が追えるか
- 関連ファイルをまとめて見られるか
- 人間が見るべき箇所を上げられるか
- agent の作業ログと diff をつなげられるか
ツールは、review工程の詰まりに対して出てきます。
まとめ
AIエージェントを使うと、実装は速くなります。
でも、review がそのままだと、速くなった分だけレビュー負債が増えます。
必要なのは、もう一人のAI reviewer ではありません。
Trace。
Triage。
Eval。
Pre-CI Review。
Human Review。
そして、review結果を次の Plan に戻す仕組み。
この流れがあると、AIエージェントの出力は扱いやすくなります。
逆に、この流れがないと、agent が作った量を人間が全部受け止めることになります。
AI時代の review は、「読む力」だけでは足りません。
どこを機械に落とすか。
どこを人間に残すか。
どこで止めるか。
何を次回のルールに戻すか。
ここを設計することが、review の仕事になります。
次回は、review で見つかった失敗をどう次回に戻すかを扱います。
AGENTS.md、memory、skill、compound engineering の話です。