GitHub Copilot Code Review の誤検知が多い理由
今回の PR で起きたこと
- PR に対して Copilot から 26 件のレビューコメントが届いた
- 実際に修正が必要だったのは 2〜3 件程度
- 残りは誤検知・意図的設計・既対処済みに分類できた
- つまり適合率(precision)は 1 割未満
● 理由 1:ファイルをまたいだ実行フローを追えない
- 個々のファイルの内容は読めている
- ただし「どこから呼ばれるか」「呼ばれる前提条件は何か」を接続できない
- 例:auth-store.ts の sendEmailChangeVerification で auth.currentUser! を使っている → 「null になるかも」と指摘 → でも account.riot の onMounted() にログインガードがあり、未ログインなら画面自体が開けない → この 2 ファイルにまたがる因果関係を Copilot はつなげられていない
- 「コードを読んでいる」のではなく「コードのパターンを認識している」状態
● 理由 2:コードの見た目のパターンで判断している
- 実行時に何が起きるかではなく、コードの見た目の特徴だけで「危険に見える」と判断する
- 具体例
- href なしの に onclick がある → アクセシビリティ問題として検知(これは正しかった)
- auth.currentUser に ! がある → null リスクとして検知(呼び出し元でガード済みだった)
- 正規表現のパターンが特定の形をしている → 変換ロジックのバグとして検知(現在のキーには問題なかった)
- パターンが意図的かどうか・すでに対処済みかどうかを判断する手段がない
● 理由 3:見逃しを極端に嫌う設計になっている
- セキュリティ系のレビューツールとして「本物のバグを見逃す」ほうが「誤検知する」より悪い、という設計判断がある
- 結果として疑わしいものはとりあえず全部報告する方向に振れる
- 適合率を犠牲にして再現率を上げているトレードオフ
- ユーザー視点では「狼少年」になりがち
● 理由 4:学習データのカットオフ
- Gravatar が SHA-256 を正式サポートしたのは 2024 年
- Copilot の学習データにその情報が含まれていない可能性がある
- 「MD5 を使うべき」という古い常識で指摘してきた
- 最新の仕様変更・ライブラリアップデートへの追従が遅れる
● 誤検知を減らすためにやったこと
- ESLint の導入 → Copilot が見る前にツールが検知してコードを直す → Copilot に到達する頃には対処済みの状態になる
- TypeScript strict モードの対象を拡大(JS ユーティリティを TS に移行) → 型情報があれば Copilot も「ここは安全」と判断しやすくなる → 今回の pubDateObj バグのように型定義があればコンパイル時に気づけた
- 誤検知には根拠を示して反論・クローズする → 全部鵜呑みにしない運用が重要
● まとめ
- Copilot のコードレビューは「パターン認識」であり「理解」ではない
- 複数ファイルにまたがる設計意図・実行フローの把握が苦手
- 見逃しを嫌う設計なので誤検知は構造的に多くなる
- ツール(ESLint・TypeScript)で先に問題をつぶすと誤検知の絶対数は自然と減る
- 使い方は「全部信じる」でも「全部無視する」でもなく「トリアージして使う」