この記事の要点
- AI生成コードのレビューは、全行を同じ密度で読む必要はなく、「契約」と「テスト」で機械的に守れる部分と、人が読むべき部分に分けるのが現実的です。
- 契約(入力と出力の約束事)をテストで固定すると、人は実装の中身ではなく「契約そのものが正しいか」に集中できます。
- 認可・金銭・データ破壊など、契約で表しにくい領域は、AI生成であっても従来どおり人が精読する必要があります。
はじめに:AI生成コードのレビューで消耗していませんか
AI生成コードのレビューを、全行同じ密度で読み続けるのはつらい作業です。生成量が増えるほど、人の読む時間が先にあふれます。
この記事では、読む範囲を契約とテストで絞る設計を扱います。狙いは「手を抜く」ことではありません。「読む場所を選ぶ」ことです。
なお、この記事は次の記事の問題意識を参考にしています。内容の写しではなく、検索されやすい疑問に沿って再構成しました。
AI生成コードを全部同じ密度で読むべきか
結論から言うと、全部を同じ密度で読む必要はないと考えます。理由は2つです。
1つ目は、人の注意力に上限があることです。重要な1行と、定型の10行を同じ熱量で読めば、重要な1行を見落としやすくなります。
2つ目は、読まなくても守れる性質があることです。型、テスト、静的解析で検証できる部分は、機械に任せたほうが確実です。
ただし「読まない」と「検証済み」は別物です。検証の手段がない部分を読まないのは、ただの放置です。
契約(Design by Contract)とは何か
契約とは、関数やモジュールが守る約束事です。Design by Contract(契約による設計)では、主に3つを定義します。
- 事前条件(precondition): 呼び出し側が満たすべき入力の条件
- 事後条件(postcondition): 関数が返す結果が満たすべき条件
- 不変条件(invariant): 処理の前後で常に成り立つ条件
出典: https://en.wikipedia.org/wiki/Design_by_contract
AI に実装を任せるとき、この3つは「仕様書」として働きます。実装は毎回変わってもよく、契約だけが変わらなければ良い、という考え方です。
契約を書く側が人間である意味
契約は、人が書いて人がレビューします。実装は AI が書き、契約に照らして機械が検証します。
つまり、レビュー対象が「実装の数百行」から「契約の数行」に縮みます。これが絞り込みの核心です。
具体例:契約とテストでレビュー範囲を絞る
割引計算の関数を例にします。契約を先に人が書き、実装は AI に任せます。
from hypothesis import given, strategies as st
def apply_discount(price: int, rate_percent: int) -> int:
"""
事前条件: price >= 0, 0 <= rate_percent <= 100
事後条件: 0 <= 結果 <= price
事後条件: rate_percent == 0 なら結果 == price
"""
... # ここを AI に実装させる
@given(
price=st.integers(min_value=0, max_value=10**9),
rate=st.integers(min_value=0, max_value=100),
)
def test_contract(price, rate):
result = apply_discount(price, rate)
assert 0 <= result <= price
@given(price=st.integers(min_value=0, max_value=10**9))
def test_zero_rate_is_identity(price):
assert apply_discount(price, 0) == price
ここで使っている Hypothesis は、性質ベーステスト(property-based testing)のライブラリです。入力を自動生成して、契約が破れる例を探します。
- 公式ドキュメント: https://hypothesis.readthedocs.io/
こうしておくと、人が見る場所は3か所に減ります。
- 契約(docstring)は業務ルールと合っているか
- 性質テストは契約を漏れなく表しているか
- 契約の外側(丸め方、端数処理)は仕様で決まっているか
実装の中身は、テストが通る限り、読む優先度を下げられます。
書いてみて感じたこと
この例は、考え方を確かめるために書き下したものです。実プロジェクトでの計測はしていません。
書いてみて気づいたのは、契約を書く作業そのものが、仕様の曖昧さを洗い出す工程になることです。「端数は切り捨てか四捨五入か」は、実装を読んでも決まりません。契約を書く段階で初めて問いになります。
どこまで絞れるか:領域別の比較表
すべての領域で同じように絞れるわけではありません。目安を表にします。
| 領域 | 契約・テストで表せるか | レビューの密度 |
|---|---|---|
| 純粋関数(計算・変換) | 表しやすい | 契約とテストを中心に読む |
| データ整形・マッピング | 比較的表しやすい | 境界値と欠損の扱いを読む |
| 外部 API 連携 | 一部のみ | 失敗時の挙動とリトライを読む |
| 認可・認証 | 表しにくい | 全行を精読する |
| 金銭・決済 | 表しにくい | 全行を精読する |
| データ削除・マイグレーション | 表しにくい | 全行を精読し、実行手順も確認する |
認可の不備のような問題は、OWASP Top 10 でも主要なリスクとして挙げられています。
「テストが通った」ことは「認可が正しい」ことを意味しません。そもそも、そのテストが書かれていないことが多いからです。
テストの質を担保する:ミューテーションテスト
契約で絞る設計の弱点は、テストが弱いと全体が崩れることです。AI は「テストを通す実装」を作るのが得意です。弱いテストは、簡単にすり抜けられます。
そこで有効なのがミューテーションテストです。コードをわざと少し壊し(例:< を <= に変える)、テストが失敗するかを調べます。壊してもテストが通るなら、そのテストは弱いと判断できます。
実行時間はかかります。全体に回す必要はなく、契約で守ると決めた重要モジュールに限定するのが現実的です。
運用の手順:絞り込みレビューを始める5ステップ
- 変更を「契約で守れる層」と「守れない層」に分類する
- 守れる層は、先に人が契約とテストの雛形を書く
- AI に実装させ、テストと静的解析を CI で通す
- 人は契約・テスト・境界の扱いをレビューする
- 守れない層は、従来どおり全行を読む
分類の基準は、PR のテンプレートに書いておくと運用が安定します。たとえば「この PR は認可・金銭・削除に触れるか」というチェック欄です。
デメリット・向いていない人・うまくいかないケース
この設計には限界があります。導入前に確認してください。
うまくいかないケース
- 仕様が固まっていない開発: 契約が毎日変わると、書くコストが実装コストを上回ります。
- 副作用が中心のコード: 外部状態を変える処理は、契約で表すのが難しくなります。
- テスト基盤が未整備のチーム: CI でテストが回らないなら、絞り込みの前提が成り立ちません。
向いていない人
「レビューを楽にしたいだけ」の場合は、おすすめしません。契約を書く作業は、実装を読む作業とは別の負担です。総量は減らず、移動するだけの場合もあります。
残るリスク
契約そのものが間違っていれば、正しく間違った実装が量産されます。契約のレビューだけは、省略できません。
まとめ:次に取る行動
最初の一歩は小さくて構いません。次の PR で、純粋関数を1つ選び、契約を3行で書いてから AI に実装させてみてください。
残る問いは、「どの領域を、誰が、どの基準で『守れない層』と判定するか」です。この判定基準をチームで言語化できるかが、導入の成否を分けると考えています。
よくある質問
Q. AI生成コードは人間が書いたコードより厳しくレビューすべきですか?
一律に厳しくする必要はありません。重要なのは書き手ではなく、変更が触れる領域です。認可・金銭・削除に触れるなら、書き手に関係なく精読します。
Q. 契約とテストだけで AI生成コードのレビューは省略できますか?
省略はできません。契約とテストで機械的に検証できる範囲が広がり、人が読む対象を絞れる、というのが正確です。契約自体の妥当性は人が確認します。
Q. 性質ベーステスト(property-based testing)とは何ですか?
入力例を人が1つずつ書く代わりに、「どんな入力でも成り立つ性質」を書いて、入力を自動生成して検証する手法です。Python では Hypothesis が代表的なライブラリです。
Q. ミューテーションテストは毎回の CI で回すべきですか?
毎回全体に回す必要はありません。実行に時間がかかるため、重要モジュールに限定するか、夜間ジョブで実行する運用が現実的です。
Q. 契約はどこに書くのがよいですか?
docstring、型、テストの3か所に分けて置くのが扱いやすいです。型で表せるものは型に、表せない条件は性質テストにします。
Q. 小規模チームでも導入できますか?
導入できます。全体に適用せず、純粋関数など契約を書きやすい部分から始めるのが現実的です。CI でテストが回る状態であることが最低条件です。
Q. AI にテストも書かせてよいですか?
実装と同じ AI にテストも任せると、同じ誤解を両方に持ち込むおそれがあります。契約と性質テストの骨子は人が書き、細かいケースの補完を AI に任せる分担が安全です。