AI が書いたコードはそれらしく動きます。
だからこそ、レビューで見る場所を決めておく必要があります。
実際に問題が見つかりやすい順に整理します。
1. 認可のチェックが抜けていないか(最頻出)
指示に含めないと、ログインチェックだけで認可が入らないことがよくあります。
# 生成されがちなコード
@login_required
def order_detail(request, pk):
order = Order.objects.get(pk=pk) # ← 他人の注文も取れる
「ユーザー自身のデータのみ」という条件は、
明示的に指示しないと入りません。最優先で確認します。
2. エラー処理が握りつぶされていないか
try:
result = external_api_call()
except Exception:
pass # ← 失敗が無かったことになる
except Exception: pass は特に危険です。
何が起きても表面上は成功するため、問題の発見が遅れます。
3. 存在しないものを使っていないか
実在しない引数やメソッドが混ざることがあります。
User.objects.filter(email=email).get_or_none() # そんなメソッドは無い
テストを実行するのが最も確実な確認方法です。
読むだけでは見落とします。
4. 効率が悪くないか
動きますが、件数が増えると破綻する書き方が生成されることがあります。
# N+1
for order in Order.objects.all():
print(order.customer.name)
# 全件をメモリに載せる
all_orders = list(Order.objects.all())
小さなデータでテストすると気づけません。
件数が増えたときの挙動を想像して読みます。
5. 既存のコードと合っているか
プロジェクト内に同じ機能の関数があるのに、
新しく似たものが作られることがあります。
# 既に utils.py にある
def format_price(amount): ...
# 生成されたコード内に
def price_to_string(amount): ... # 同じことをしている
重複は保守の負担になります。
既存の共通処理を使うよう指示するのが有効です。
レビューを楽にする指示の出し方
生成時点で条件を伝えると、レビューの負担が減ります。
・認可は「ログインユーザー自身のデータのみ」を必ず含める
・例外は握りつぶさず、ログに残して呼び出し元へ伝える
・既存の utils.py にある関数を使う
・N+1 を避けるため select_related を使う
・テストも一緒に書く
プロジェクトの規約をファイルにまとめておくと、毎回指示せずに済みます。
テストは自分で確認する
AI が書いたテストが通ることを確認するだけでは不十分です。
テスト自体が甘い可能性があります。
def test_cannot_access_others_order(self):
res = self.client.get(f"/orders/{other_order.pk}/")
self.assertNotEqual(res.status_code, 500) # ← これでは意味がない
「何を検証しているか」を必ず読みます。
責任は書いた人にある
AI が生成したかどうかに関わらず、
コミットした時点で自分の書いたコードです。
「AIが書いたので」は説明になりません。
理解できないコードはコミットしない、という原則は変わりません。
まとめ
優先順に確認します。
- 認可のチェックが入っているか
- 例外が握りつぶされていないか
- 実在しないメソッドを使っていないか(テスト実行で確認)
- N+1・全件読み込みがないか
- 既存の共通処理と重複していないか
生成時に条件を渡しておくと、この負担は大きく下がります。