この記事はヌーラボブログリレー2025冬 Techの19日目として投稿しています。

こんにちは。複数のAIによるコードレビューをサクッと行いたい時はありませんか?僕はあります。実際にこういったことをやろうと思えばAIにスクリプトを生成させてすぐに自分の手元で行うことができます。一件落着!としてしまうとブログが終わってしまいますので少しの間ですが、お付き合いください。

解決したい問題

さてここまでで大抵の場合は本当に一件落着なんですが、このように作られたスクリプトはChatGPTなどの従量課金であるAPIを叩いてしまうことが多いです。APIを叩くこと自体問題ないのですが、できればこういうタスクはサブスクリプションの金額で抑えたいと僕は感じていました。(サブスクリプションも回数上限があるので実質従量課金なんですが、自分の使い方では使い切ることは少ないので)

さてAIベンダーは各社独自のコーディングエージェントを提供しています。Codex, Claude-Code, Gemini-CLIなど。そのコーディングエージェント内でアカウントの認証をすることでサブスクリプションの契約の中でそれらのコーディングエージェントを使用することができます。GitHub Copilotは自社でAIの開発は行ってませんが、安価・定額でさまざまなモデルを試せることができると言うのが魅力的です。

なのでこれら定額のコーディングエージェントにコードレビューを移譲して、その結果を見比べるというのがよさそうです。そうすればAPIKeyを発行せずにいつも使っているコーディングエージェントを内部的に複数呼び出すだけで、コードレビューのセカンドオピニオンがすぐに手に入ります。

コードレビューのプロンプトについてもチームで統一されたものを使いたいというのもあるかもしれません。共通化までいかなくてもプロンプトを考えずにある程度整備されたチーム独自のものを使いたいと考えています。

じゃあCI上で各種CLIを動かせばいいのでは

おっしゃる通りです。とはいえCIで動かすとなると次はチームで使えるサブスクリプションをどうしようとか、もはや専用SaaSを導入した方がやすくて性能が良いのでは。。。など少し大きな話になってしまいます。

なので今回は手元でスクリプト的なレベルで動くものが欲しいと考えていました。ちゃんとやりたいなら前述の通りCIに寄せていくのがいいと思います。がその場合でも手元でのレビューについて複数確認をさっとしたい場合など便利かも?しれません

解決策

今回自作したai-utilsのおかげで自分の開発フローが少しだけ便利になりましたので紹介させてください。

実際の挙動

ではここで実際にai-utilsにCopilotCLIを追加する時に行ったレビューをみてみます。各AI毎に全文を載せると長くなるので実際のレビュー結果の一部になります。

こちらのコミットに関してのレビューをしています。実際にはstaged-check というコミット前のファイルに対してのAIによるチェックです。

リンク先のようなプロンプトによるチェックを行ってくれます。

結果から言うとここではCodexの指摘が一番正しく状況を捉えられてました。簡易的なチェックなので仕方ないですが、git diff の結果だけをプロンプトに渡しているせいもありLLM側でリポジトリの全体把握が難しい状況があるみたいでした。ここら辺はどこかで改善したいと考えています。 以下が実際のレビュー結果です。

  • ClaudeCode(4.5 Sonnet)
     コード品質は非常に良好です。新しいCopilotプロバイダーの実装は、既存のCodexプロバイダーと一貫した構造になっています。`stripFlagWithValue`ヘルパー関数は適切に再利用可能な形で実装されており、DRY原則に従っています。命名規則も明確で、Go言語の慣例に沿っています。
  • Gemini CLI(Gemini 2.5)
     * **コードの重複**:
         * **ファイル**: `internal/provider/copilot.go`
         * **問題**: `stripFlagWithValue` 関数が `copilot.go` で新たに定義されていますが、このロジックは `codex.go` でのモデルフラグ処理でも利用されています。現在、`codex.go` は `copilot.go` で定義されたこの関数にアクセスできないため、同様のロジックが `codex.go` にも(見えませんが、意図として)必要になります。このヘルパー関数はコード重複を避けるため、`provider` パッケージ内の共有ユーティリティファイル(例: `provider/utils.go`)に移動させるべきです。
  • Codex(GPT-5.2)
     - **致命的なタイムアウト単位バグ**: `internal/cli/root.go` の `initConfig()` で `config.ProviderConfig.Timeout` に `120` を代入していますが、型が `time.Duration` なので **120ns** になります(期待は `120*time.Second`)。今回 `copilot` 追加でも同じ値が入っており、デフォルト設定で実行すると即タイムアウト/不安定化します。少なくとも今回追加した `copilot` 分は修正必須、可能なら既存 `claude/gemini/codex` も同様に修正推奨です。

     - **ユーティリティ関数の置き場所**: `stripFlagWithValue()` が `internal/provider/copilot.go` に定義され、`internal/provider/codex.go` からも利用されています(同一 package なので動きますが)見通しが悪いです。`internal/provider/args.go` など共通ファイルへ移すと意図が明確になります。

     - **ハードコード文字列**: プロバイダ名 `"copilot"` やフラグ `"--model"` 等が散在(`internal/cli/root.go`, `internal/provider/*`)。小さくても定数化(少なくとも provider 名)で一貫性が上がります。
  • GitHub Copilot CLI(Claude Sonnet 4.5)
     **`internal/provider/copilot.go`**: `stripFlagWithValue` 関数が新たに実装されていますが、同じロジックが `codex.go` でも使用されています。DRYの原則に従い、この関数を `provider.go` などの共通ファイルに移動して両方のプロバイダーで共有すべきです。

     **`internal/provider/copilot_test.go`**: ファイル末尾に空行が欠けています(line 115)。Goのフォーマット規約では、ファイルは改行で終わるべきです。

     **`internal/provider/codex.go`**: `stripFlagWithValue` の実装が追加されていません。この変更により、codexプロバイダーがmodelフラグを処理する際に、この関数が未定義になる可能性があります。stagingが部分的である可能性があります。

プロンプトの不備もありながらでしたが、いろんなAIにレビューをお願いすることで一つのモデルの指摘に盲目的にならずにすみました。今回は実施しませんでしたがOpus4.5、Gemini3.0などの最先端のモデルを比べることもできます。どのモデルがいいのかわからないというケースも多い中コマンド一発で比較検証できるのは非常に便利です。

自作OSS

前述の通りai-utilsは自作のOSSです。規模的にも機能的にも簡単なわりに便利そうだったので自作をしました。 詳細はこちら

コンセプト

サブスクリプションの範囲内でローカルから簡単に複数のAIを実行したい

解決した課題

このようなOSSはありふれています。が私が今回解決したかったのは以下の3つでした

  • API Keyの発行をしたくない
  • プロンプトを自分流に書き換えたい
  • 複数AIからのレスポンスを比較したい

この3つを満たすOSSを探すことができずに今回は作ることを選択しました。AI時代自分が作りたいものを簡単に作れるので車輪の再発明をする工数を乗り越えることができました。

使い方

Macならbrewを使って以下の様に簡単にインストールできます。

brew tap trknhr/homebrew-tap

brew install aiu

Linuxならインストール用のシェルを実行してください。

curl -sSfL https://raw.githubusercontent.com/trknhr/ai-utils/main/install.sh | sh

ClaudeCodeやCodexなど対応するコーディングエージェントがインストールされて使える状態にしていないと使うことはできません。

###実際に使ってみる

commit-msgを使ってステージングされているファイルについてのコミットメッセージを出力することができます。

aiu commit-msg

-m を使えば複数AIを並列で実行できます。

また自分の用意したプロンプトを実行することもできます。プロンプトファイル内の{{$ }} はコマンドが実行されるため、コマンドの実行結果を動的にAIに渡すことができます。

Just say {{$ date }}.

とするとAI側に現在時刻がわたり現在時刻だけを返してくれます。これと同じ要領でレビュータスクではgit diffなどを渡しています。 このように例えばチームで独自のプロンプトを用意したいときは.aiu/prompts/にチーム独自のプロンプトを用意してレビューを統一的に行うことができます。

開発について

今回のアプリに求められるやっている実装は難しくはありませんでした。むしろよくあるCLIアプリケーションを実装するのにAIが得意すぎて私が独自でやることはあまりありませんでした。私のやったことは仕様の策定とテストくらいのものでこれがAI時代かーと何度も感心をしました。

まとめ

ただ各種プロバイダーから提供されているコーディングエージェントを呼び出すだけのツールですが、CLIとしてまとめてみると、意外と快適です。

このツールは機能が簡単なので実装もAIにおまかせをしやすいアプリケーションになりました。おそらく95%くらいはAIが書いています。

これを使うことで何かしらを大きく改善してくれるわけではないですが、日々のちょっとしたタスクを少しだけ楽に進めることを後押ししてくれます。

もしご興味ある方いらっしゃいましたら、こちらのGitHubのページを参考にインストールをお願いいたします。ご不満点などございましたら Issueにお願いいたします。


この記事は Zenn にも転載しています。