powered by TechFeed
表示モード
ハウツー

ClaudeのPRをOpenAIにレビューさせる — 「自分の答案を自分で採点させるな」を実装した結果

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上でクロスレビューする仕組みの実装について詳しく紹介されている。

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 CLIGitHub統合を通じて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を参照していただきたい。