7月16日、Towards Data Scienceが「Don't Let Claude Grade Its Own Homework」と題した記事を公開した。なお元記事のURLスラッグはdont-let-claude-gaslight-youとなっており、タイトルと一致しない点は元記事側の事情によるものだ。この記事では、ClaudeのPRを異なるAIプロバイダー(OpenAI Codex)のエージェントがGitHub Actions上でクロスレビューする仕組みの実装について詳しく紹介されている。
発端:Claudeがリンク先を「創作」していた
あるサイドプロジェクトのために、複数のClaudeエージェントに並行して戦略ドキュメントを書かせた。PRには10本のドキュメントが並び、相互リンクも整っており、一見して問題なく見えた。しかし自動レビュアーの指摘で実態が明らかになる。
95本の相対リンクのうち30本が、実在しないファイルを指していた。 ./market.mdの実体はmarket-analysis.md、./monetization.mdの実体はbusiness-model.md——しかも一部は最初から存在しないファイルへのリンクだった。人間がざっと見たら承認してしまう内容だ。ファイル名がそれらしく見えるだけで、リンクを実際に解決しようとは思わない。
Claudeに悪意はない。言語モデルは「最もありそうな続き」を生成するだけであり、時にその続きが自信満々な作り話になる。そして問題は、自信を持って間違っていることが、自信を持って正しいことと区別できない点にある。
なぜ「Claudeに自分のコードをレビューさせる」のが弱いのか
最初に思いつく解決策は、エージェント自身に自分の成果物をレビューさせることだ。だがこれが最も脆い。
ハルシネーション(幻覚生成)とは定義上「そのモデルにとって自然に見える出力」であり、同じモデルに同じセッション内で見つけさせようとしても、同じバイアスが再現されるだけだ。
この直感には研究の裏付けもある。NeurIPS 2024でのPanickssery et al.の研究では、LLMの評価者は自分自身の生成物を認識し、より高く評価することが示されている(論文)。続く研究では、このセルフ選好バイアスが「親しみやすさ」に起因することも示された——モデルは自分が書いたテキストほど予測しやすく感じ、高スコアをつける傾向がある(論文)。
異なるプロバイダーのモデルは、異なるデータ・異なる学習レシピ・異なるフィードバックループで訓練されている。どのプロバイダーも誤りをなくせてはいないが、誤りのパターンが違う。その「相関のなさ」こそがクロスレビューの価値だ。ClaudeのPRをCodexがレビューすると、Claudeが自己レビューで見逃した問題——発明されたファイル名、最初の要件と無関係なコードブロック、セキュリティ違反——を一貫して検出できる。
ただし「Codexの方が優秀」という結論は誤りだ。Codexも別の方向で誤る。重要なのはマルチモデル——異なるプロバイダーを同一ワークフロー内で組み合わせ、互いの盲点を補わせること——という考え方にある。
なお、ここで登場する「OpenAI Codex」は旧来のコード補完APIとは異なる。2025年以降にOpenAIがリリースしたエージェント型のコーディングサービスであり、Codex CLIやGitHub統合を通じてPRレビューなどのタスクをエージェントとして実行できる。本記事が対象とするのはこの新世代のCodexだ。
実装:GitHub Actions上の2ファイル構成
OpenAIとAnthropicはそれぞれ公式のPRレビュー統合(OpenAIのGitHub review integration、Anthropicのclaude-code-action)を提供している。ただし著者はプロンプト・レビューライフサイクル・マージゲーティング・モデルのバージョン固定を自分で管理したいため、独自のActionを実装している。
構成は2ファイルでシンプルだ。
.github/
├── workflows/
│ └── pr.yml # オーケストレーション: トリガー、コンテキスト、リトライ、投稿
└── actions/
└── codex-pr-review/
└── action.yml # レビュアー: バージョン固定したCodexの呼び出しとプロンプト
フローはこうだ。PRのオープン・プッシュのたびにpr.ymlがコードをチェックアウトし、PRの会話履歴全体を収集してcomposite actionに渡す。ActionはCodexでdiffをレビューし、結果をPRコメントとして更新し続ける。未解決のfindingがある間はコミットステータスが赤のまま残る——CI全体のgo/no-goシグナルになる。
実際にLLMを呼び出しているのはこの1ステップだけだ。
- uses: openai/codex-action@v1
with:
openai-api-key: ${{ inputs.openai-api-key }}
prompt: |
# レビュー契約: 何をレビューし、findingをどう追跡し、どう報告するか
実装上の工夫として特筆すべき点がいくつかある。
- 全処理を単一ジョブに集約する。 複数ジョブ構成にするとGitHubのジョブ出力サイズ制限(1MB)に引っかかりやすい。大きなdiffで実際にそのケースに当たった。
- PRの会話履歴を渡す。 issues comments・reviews・inline commentsの3種類をすべて取得し時系列でソートして渡す。これにより、著者が「このfindingは対応済み」とコメントすれば、次回レビュー時にCodexがそれを読んで解決済みとして扱える。レビューに記憶と説明責任を持たせる仕組みだ。
- 2回のリトライ構成にする。
uses:ステップはリトライラッパーで囲めないため手動で実装する。OpenAIへの一時的な接続エラーや新しいランナートークンの401エラーで全体が落ちるのを防ぐためだ。
コストと信頼性について
元記事では具体的なコスト数値は示されていないが、著者はCodexのレビューをあくまで「助言」として扱うべきだと明言している。レビュー自体にもハルシネーションは起きる。著者が誤りを指摘したら、Codexのレビューが間違っていたと書き返すこともある。最終的な品質の責任は——Claudeが書いたコードであれ、人間がPRを出した場合であれ——レビュープロセスに参加する人間が負う。
この仕組みが有効なのは、「findingの正誤を判定すること」ではなく、「見落としがちな盲点にフォーカスを当てること」にある。モデルが異なれば誤りのパターンも異なる——その非対称性を構造的に活かす点に、このアプローチの本質がある。
詳細はDon't Let Claude Grade Its Own Homeworkを参照していただきたい。