blog.garicchi.me

【GitHub Copilot】Sonnet 4.5とGPT-5.2-CodexとGemini 3で話し合ってもらう

GitHub Copilotにはサブエージェントという機能があります。 サブエージェントを使うと、エージェントから別のエージェントを呼び出すことができます。

サブエージェントを呼び出すことで、メインエージェントのコンテキストウインドウの肥大化を抑えることができます。 例えば、サブエージェントに複雑な調査を依頼し、結果の要約だけをメインエージェントが受け取るなどです。

さらにGitHub Copilotは、サブエージェントごとに異なるベンダーのAIモデルを使用することができます。 これを使うと、異なるAIモデル同士で議論をさせ、より深い思考をさせることができる可能性があります。

複数のAIモデルにコードレビューをしてもらう

単一のコーディングエージェントにコードレビューをしてもらうと、 間違った指摘になってしまうことがあります。 その原因としては、AIモデルの能力であったり、 読み込むファイルがたまたま悪く、コンテキスト不足であったり、様々な要因があります。 一方、ベンダーの異なるAIモデルを使うと、全く異なるレビュー結果になったりもします。

人間も1人でレビューするより、複数人でレビューしたほうがより良いレビューになるように、 AIモデルも複数モデルでレビューしたほうが良いレビューになる可能性があります。

そこで今回は、GitHub Copilotのサブエージェント機能を使い、 複数のAIモデルに議論してもらいながらコードレビューをしてもらうことにします。

議論のテーマ - C#14の新記法

まず、お題のコードがないと議論できないので、お題を用意します。

LLMにコードレビューしてもらっていると気づくのですが、 LLMはプログラミング言語がバージョンアップして新しい記法が書けるようになった時、 間違った指摘やコード生成をすることがあります。

2026/02/03時点ですが、Sonnet 4.5はC#14の拡張メンバーという新しい記法の知識がなさそうです。 よって、拡張メンバーを使ったコードをレビューしてもらうと、文法が間違っているという指摘をすることがあります。

例えば、下記のようなコードを用意します。 .NET 10であれば、コンパイルが通るはずです。

public class User
{
    public string? Name { get; set; }
}

public static class UserExtensions
{
    extension(User user)
    {
        public bool IsValid()
            => user.Name != null;
    }
}

これをSonnet 4.5単体にレビューしてもらいます。 すると、C#14の知識が無いため、構文エラーとして指摘されてしまいます。

🔴 重大な問題 C# 13の拡張メンバー構文の誤り 拡張メンバー(extension)の構文が正しくありません

今回は.NET 10の環境を用意しているので、Sonnet 4.5の指摘は間違っているということになります。

本来ならば、MCPなり、AGENTS.mdなり、Skillsなりで知識を与えて解決するのが良いですが、 今回はこれを題材にAIモデルの三者会議をし、問題ないという結論に達することができるかを試します。

議論の流れ

議論の流れとしては、以下のようにします。

まず、レビュー対象を確認するためにgit差分を取得します。 その後、3つの異なるAIモデルに順番にレビューをしてもらいます。

3者の意見が対立しているのであれば、claudeのレビューに戻り、再度議論をします。 3者の意見が対立していないなら、結果をまとめてユーザーに返します。

  graph TD;
   gitdiff["git差分取得"]
   claude-review["sonnet 4.5によるレビュー"]
   codex-review["GPT-5.2-Codexによるレビュー"]
   gemini-review["Gemini 3によるレビュー"]
   decision@{ shape: diamond, label: "終了判断" }
   result["結果のまとめ"]

   gitdiff -- "取得した差分" --> claude-review
   claude-review -- "差分と前回までのレビュー結果" --> codex-review
   codex-review -- "差分と前回までのレビュー結果" --> gemini-review
   gemini-review -- "三者のレビュー結果" --> decision
   decision -- "意見が対立している" --> claude-review
   decision -- "意見が対立していない" --> result

これを自動で行うエージェントを作ります。

カスタムエージェントの作成

サブエージェントを呼び出すには、 カスタムエージェントを作る必要があります。 今回は4つのカスタムエージェントを作成します。

1. claude-reviewer

claude-reviewerという名前のカスタムエージェントで、 モデルはSonnet 4.5を使うこととします。

claude-reviewer.md

---
description: 'Claude系のモデルを使ってレビューします'
tools: ['read', 'search', 'execute']
model: Claude Sonnet 4.5 (copilot)
---

厳密なコードレビューを行い、バグを指摘する

結果は、会議を行うように発言として結果を返す

2. codex-reviewer

codex-reviewerという名前のカスタムエージェントで、 モデルはGPT-5.2-Codexを使うこととします。

codex-reviewer.md

---
description: 'Codex系のモデルを使ってレビューを行います'
tools: ['read', 'search', 'execute']
model: GPT-5.2-Codex (copilot)
---

厳密なコードレビューを行い、バグを指摘する

結果は、会議を行うように発言として結果を返す

C#14の拡張メンバーは使用できます。

namespace CustomExtensionMembers;

public static class MyExtensions
{
    extension(string str)
    {
        public bool Length10() =>
            str.Length == 10;
    }
}

3. gemini-reviewer

gemini-reviewerという名前のカスタムエージェントで、 モデルはGemini 3 (Preview)を使うこととします。

gemini-reviewer.md

---
description: 'Gemini系のモデルを使ってレビューします'
tools: ['read', 'search', 'execute']
model: Gemini 3 Pro (Preview) (copilot)
---

厳密なコードレビューを行い、バグを指摘する

結果は、会議を行うように発言として結果を返す

C#14の拡張メンバーは使用できます。

namespace CustomExtensionMembers;

public static class MyExtensions
{
    extension(string str)
    {
        public bool Length10() =>
            str.Length == 10;
    }
}

実験してみたところ、CodexもGeminiも拡張メンバーを知らないという立場を取ることがよくありました。 議論ができるように、CodexとGeminiだけ、C#14の拡張メンバーの知識を与えておきます。1

4. review-commander

議論の司令塔としてreview-commanderというカスタムエージェントを用意します。

#tool:agent/runSubagent を使うことで、サブエージェントを呼び出すことができます。

review-commanderはコードレビューは行わないので、 性能は低くてもよいはずですが、GPT4.1などでは議論の進行がうまくできませんでした。 今回はreview-commanderにもSonnet 4.5を使用します。

review-commander.md

---
description: '会議のコーディネーターとして各サブエージェントを呼び出します'
tools: ['execute', 'read', 'agent', 'search', 'todo']
model: Claude Sonnet 4.5 (copilot)
---

会議のコーディネーターとなり、各サブエージェントを呼び出して会議を進行する。

各サブエージェントでレビューを行う際は、取得した差分及び、前回までのレビュー結果を渡す

各サブエージェントに指示を出す時は、他のサブエージェントの意見を信頼せずに
独立した意見を提示することを指示

計画は #tool:todo に最初に記載し、進捗を都度記録する

各ステップでサブエージェントから結果が返ってきたあとは、
サブエージェントの発言、レビュー結果を3行以内で状況として実況する

## 手順

### 1. 差分確認

下記コマンドを実行し、差分を確認する
git diff {branch}

branchはユーザーから与えられれば、それを使う。
与えられなければ、 `origin/main` を使う

### 2. claudeレビュー

#tool:agent/runSubagent を使用し、
`claude-reviewer` を呼び出し、レビューを行う

### 3. codexレビュー

#tool:agent/runSubagent を使用し、
`codex-reviewer` を呼び出し、レビューを行う

### 4. geminiレビュー

#tool:agent/runSubagent を使用し、
`gemini-reviewer` を呼び出し、レビューを行う


### 5. 終了判断

各サブエージェントの意見が1つでも対立している場合は、
[2. claudeレビュー](#2-claudeレビュー)へ戻り、
各サブエージェントが納得するまで再度議論をする

議論が平行線になるか、各サブエージェントの意見が対立していないなら、
[6. 結果のまとめ](#6-結果のまとめ)に移動する

### 6. 結果のまとめ

結果をまとめてユーザーに返す

コードレビュー実行

実際にreview-commanderに、C#14の新しい記法を使用したコードのレビューを行ってもらいました。

議論の過程を以下に示します。

# コードレビュー会議

## レビュー第1ラウンド

### Claude Reviewer
- **判定**: ❌ 採用不可
- **指摘**: Extensions構文の誤用。C# 13の正しい構文への修正が必要
- **懸念**: 後方互換性の破損

### Codex Reviewer
- **判定**: ⚠️ 条件付き採用
- **指摘**: C# 14プレビュー機能のため、LangVersion設定確認が必要
- **評価**: `IsValid()`のロジック自体は問題なし

### Gemini Reviewer
- **判定**: ✅ 採用可能
- **評価**: 構文の使用は適切で、仕様ガイドラインに合致している

---

## プロジェクト設定確認

`Directory.Build.props`を確認した結果:
- LangVersion 14.0が設定済み
- .NET 10.0を使用中

---

## レビュー第2ラウンド(設定確認後)

### Claude Reviewer(再レビュー)
- **判定**: ❌ 採用不可
- **指摘**: `static class`内に`extension`ブロックを入れる方式は誤り
- **主張**: 正しい構文は `public extension UserExtensions for User` の形式

### Codex Reviewer(再レビュー)
- **判定**: ✅ 採用可能
- **評価**: extension member構文として妥当。LangVersion 14.0前提なら問題なし

### Gemini Reviewer(再レビュー)
- **判定**: ✅ 採用可能
- **評価**: 現在の仕様では`static class`内への配置は有効なショートハンド宣言

**投票結果**: 2対1でClaude Reviewerと意見対立

---

## 実際のビルド検証

**結果**:
- ✅ ビルド成功
- ✅ コンパイルエラー: 0件
- ✅ 構文エラー: なし

---

## レビュー最終ラウンド

### Claude Reviewer(最終判断)
- **判定**: ✅ 採用可能
- **理由**:
  - ビルド成功の事実を重視
  - プロジェクト内の既存コードで同様のパターンを確認
  - C# 14.0のextension member構文として妥当
- **指摘事項**:
  - ドメインモデルとしての設計が貧血モデル
  - テストコードの不在

---

## 最終結論

### ✅ **採用可能(全レビュアー合意)**

#### 構文の正当性
- C# 14.0 extension member構文として正しい
- 実際のビルドで検証済み
- プロジェクト設定に適合

---

## レビュー会議の特徴

- **議論回数**: 3ラウンド
- **参加レビュアー**: 3名(Claude、Codex、Gemini)
- **意見の収束**: 実際のビルド検証により全員が合意
- **重視した要素**: 実証的な検証(ビルド成功)を理論的な議論より優先

第1ラウンドでは、Claudeが否定的意見、Codexが中間の意見、Geminiが肯定的意見でした。

第2ラウンドでは、ランタイムのバージョンを確認後、Codexが肯定派に意見を変えました。

第3ラウンドでは、最終的にClaudeも変更を肯定する結果となりました。

結果、無事にC#14の新記法を使用したコードが問題ないという結論に達することができました。

おわりに

今回は、GitHub Copilotのサブエージェント機能を使い、 3モデルによるコードレビュー議論を試してみました。

各モデルによって、主張する内容が違う状況をシミュレーションし、 三者間で議論をさせ、最終的に合意に達するまで繰り返し議論をさせることができました。

実際に動かしてみると、まるでSFの世界のようなものを体験でき、 LLMのすごさを実感しました。

注意点としては、サブエージェント呼び出しには、 それなりのプレミアムリクエストが必要になるため、あまり多用はできなさそうです。

また、何度か試した結果、新しい記法を採用するべきではない みたいな 結論に3モデルともなることが結構あったり、 1つのモデルの間違った意見に流されたりすることもありました。 もう少しプロンプトの工夫が必要だったりするかもしれません。

とはいえ、1モデルだけを使用するより深い思考ができると思われるので、 ここぞという時に使ってみてはいかがでしょうか。


  1. C#14の知識があるか無いかは本質ではなく、複数のAIモデル間で意見が異なるという状況をシミュレーションすることを目的としています。 ↩︎