機密コードをクラウドに出さずにAIでレビューする(ローカルLLM × dev-orchestra) 機密コードをクラウドに出さずにAIでレビューする(ローカルLLM × dev-orchestra)
はじめに
AI にコードレビューをさせると、自分では気づけないバグが見つかります。 3 つの AI にレビューさせた回では、自分で書いた 1,418 行から実バグが 11 件出ました。
ただ、クラウドの AI にコードを送れない場面があります。
- 業務のコードで、社外のサービスに送ることが契約や規程で禁じられている
- 個人情報や認証情報に近い処理が含まれている
- まだ公開していない製品のコード
そういうコードでも、手元の PC の中だけでAI にレビューさせる方法をまとめます。 使うのは、ミニPCで動かしているローカル LLM(Qwen3.6-35B-A3B)と、 複数の AI にレビューを分担させるツール dev-orchestra です。
方針: 2 つの使い方を分ける
| A. ローカルで完結 | B. クラウドと併用 | |
|---|---|---|
| 向いているコード | 社外に出せないもの | 公開してよいもの |
| レビュアー | ローカル LLM だけ | クラウドの AI + ローカル LLM |
| コードの行き先 | PC の中だけ | クラウドにも送られる |
| 見つかる量 | 少なめ | 多い |
機密のものは A、それ以外は B。 1 つの仕組みで、この 2 つを切り替えられるようにします。
構成
dev-orchestra の「プロバイダ」は、CLI をラップする設計です。API を直接叩く口がありません。 そこで、プロンプトを標準入力で受けて答えを標準出力に返すだけの薄い CLI を挟みます。
dev-orchestra
└─ プロバイダ localllm(ユーザープロバイダとして登録)
└─ local-llm.cmd → local-llm.py(stdin → API → stdout)
└─ llama-server(127.0.0.1:8080、この PC の中)
dev-orchestra 0.9.0 から、プラグイン本体に手を入れずに独自のプロバイダを足せる仕組み(ユーザープロバイダ)が入りました。 アダプタは dev-orchestra の設定フォルダに置くので、プラグインを更新しても消えません。 作り方の詳細はレビュアーに追加した回に書いています。
手順
1. アダプタを入れて、レビュアーとして登録する
アダプタ(localllm.py)と、プロンプトを中継する薄い CLI の中身は、
レビュアーに追加した回で説明しています。
ここでは、それを dev-orchestra の設定フォルダ(providers)に置いた前提で進めます。
# アダプタを dev-orchestra の設定フォルダに入れる(私の環境ではインストーラを Python で書いた)
python integrations\dev-orchestra\install.py
# プラグインの場所(バージョン番号として比べて、いちばん新しいもの)
$P = (Get-ChildItem "$env:USERPROFILE\.claude\plugins\cache\dev-orchestra\dev-orchestra" -Directory |
Sort-Object { [version]$_.Name } -Descending | Select-Object -First 1).FullName
# レビュアーとして追加し、名前とモデルを付ける
python "$P\scripts\dev_orchestra.py" reviewer add --provider localllm --role general
python "$P\scripts\dev_orchestra.py" reviewer list # 追加された番号を確かめる
python "$P\scripts\dev_orchestra.py" reviewer set 3 --model qwen3.6-35b-a3b --id localllm-qwen
reviewer set の番号は、reviewer list で確かめたものに置き換えてください。
インストーラは Python で書いてあります。 dev-orchestra が Microsoft Store 版の Python で動いている場合、
Store 版は %APPDATA% を別の場所に振り替えるので、PowerShell でコピーしたファイルは dev-orchestra から見えません。
読む側と同じ Python で書き込めば、振り替えの有無に関係なく一致します。
2. 機密のコードは、ターミナルから直接、ローカルだけでレビューする
python "$P\scripts\dev_orchestra.py" review snapshot
python "$P\scripts\dev_orchestra.py" state record test ok
python "$P\scripts\dev_orchestra.py" review run --only localllm-qwen
--only でレビュアーを絞るのが肝です。付け忘れると、登録してある全レビュアー(クラウドの AI を含む)に差分が送られます。
結果は dev-orchestra の統合ファイルに書き出されるので、それを自分で読んで採否を決めます。
3. 公開してよいコードは、全員でレビューする
python "$P\scripts\dev_orchestra.py" review run
クラウドの AI 2 つとローカル LLM の、3 つの意見が揃います。
最大の落とし穴: 呼び出し元の AI がコードを読む
dev-orchestra は、Claude Code などの AI のエージェントから呼び出して使うこともできます。 その場合、呼び出した AI 自身が、レビューの対象のコードを読みます。
レビュアーをローカル LLM だけに絞っても、呼び出し元がクラウドの AI なら、コードはクラウドに出ていきます。
機密のコードを扱うときは、AI のエージェントを通さず、ターミナルから dev-orchestra のコマンドを直接実行してください。 上の図の A が成り立つのは、この条件のときだけです。
ローカル LLM のレビューの実力
では、ローカル LLM だけでどこまで見つけられるのか。2 つの計測があります。
わざと入れたバグは見つけた
関数に 2 つの欠陥を仕込んで、レビューさせました。
| 仕込んだ欠陥 | 結果 |
|---|---|
| ガードを消して ZeroDivisionError が起きる | 検出(critical) |
[:n+1] のオフバイワン | 検出(high) |
所要時間は 29 秒。要求した出力の形式も守れていました。
実際のコードでは、6 件中 1 件だった
自分で書いた 1,418 行を、クラウドの AI 2 つとローカル LLM にレビューさせたときの結果です。
| レビュアー | 指摘 | 採用 | 却下 | 重複 |
|---|---|---|---|---|
| Claude | 6 | 6 | 0 | 0 |
| Codex | 6 | 4 | 0 | 2 |
| ローカル LLM | 6 | 1 | 5 | 0 |
ローカル LLM の却下 5 件は、「〜の可能性がある」で終わる推測の指摘が多く、 中には自分の指摘と矛盾しているものもありました。 採用した 1 件(エラー応答の本文を握り潰している件)は、まっとうな指摘です。
見つかる量と正確さは、クラウドの AI に及びません。 これは正直に書いておきます。
なぜ差が出るのか
いちばん大きいのは、見えている範囲の違いです。
| クラウドの AI(エージェント型) | ローカル LLM | |
|---|---|---|
| 見えるもの | 差分に加えて、関連ファイルを自分で読みに行ける | 渡された差分だけ |
| できる指摘 | 「この関数の呼び出し元で壊れる」 | 差分の中で閉じた指摘 |
ローカル LLM の役割は、あくまでレビュアーです。 ファイルを読み書きできないので、設計や実装を任せる用途には向きません(アダプタでも実装の役割は断るようにしています)。
それでもローカルで回す価値
| 観点 | ローカル LLM だけのレビュー |
|---|---|
| コードの行き先 | PC の外に出ない |
| 費用 | 電気代だけ。何回回しても課金されない |
| 見つかる量 | クラウドより少ない |
| 手間 | 推測の指摘を読んで却下する手間が増える |
「クラウドに出せないから、AI のレビューを諦める」よりは、ずっと良いと考えています。 わざと入れた典型的なバグは見つけられたので、見落としやすい単純なミスの網としては働きます。
長い差分を扱うときの注意
- コンテキスト長: 1,400 行・62 KB の差分で 19,303 トークンになり、16K の設定では断られた。
-c 65536にしてある - 読み込み時間: 3 万トークンの差分なら 2〜3 分。レビューを回すたびにかかる
- 2 回目は速いとは限らない: 同じ文書への質問なら読み直しは末尾だけで済むが、差分が変われば読み直しになる
まとめ
- 機密のコードはローカル LLM だけ、公開してよいものはクラウドと併用、と使い分ける
- dev-orchestra のユーザープロバイダでローカル LLM を登録し、
--onlyでレビュアーを絞る - AI のエージェントから呼ぶと、その AI がコードを読む。 機密のものはターミナルから直接実行する
- ローカル LLM は、仕込んだバグ 2 件は見つけたが、実コードでは 6 件中 1 件。網としては働くが、クラウドの代わりにはならない
- それでも、コードを外に出さずに AI の目を通せるのは大きい
関連記事 Related Posts
自分が書いた1418行を3つのAIにレビューさせたら、実バグが11件出た 自分が書いた1418行を3つのAIにレビューさせたら、実バグが11件出た
Claude・Codex・ローカルQwenの3枚に、自分で書いて自分で動かしていたスクリプトをレビューさせました。3件は自力では気づけないもので、1件は「レビュー結果を集計するスクリプト自体」のバグでした。一方で、3枚とも見逃した欠陥もあります。 Claude・Codex・ローカルQwenの3枚に、自分で書いて自分で動かしていたスクリプトをレビューさせました。3件は自力では気づけないもので、1件は「レビュー結果を集計するスクリプト自体」のバグでした。一方で、3枚とも見逃した欠陥もあります。
ローカルLLMをdev-orchestraのコードレビュアーに追加してみた ローカルLLMをdev-orchestraのコードレビュアーに追加してみた
自宅PCで動かしているQwenを、複数モデルで独立レビューするdev-orchestraの3枚目のレビュアーとして組み込みました。プロバイダがAPIではなくCLIをラップする設計だったので、薄いCLIを1枚挟んで繋いだ話です。翌日の公式対応と、Store版Pythonのパス罠についても追記しました。 自宅PCで動かしているQwenを、複数モデルで独立レビューするdev-orchestraの3枚目のレビュアーとして組み込みました。プロバイダがAPIではなくCLIをラップする設計だったので、薄いCLIを1枚挟んで繋いだ話です。翌日の公式対応と、Store版Pythonのパス罠についても追記しました。
WSLからホストのローカルLLMを使う方法を調べて、やめた WSLからホストのローカルLLMを使う方法を調べて、やめた
WSL上の開発でWindowsホストのローカルLLMをレビュアーとして使いたい。経路は2つあり、どちらも実現はできます。ただし片方は安全性を、もう片方は信頼性を差し出す必要があったので見送りました。その判断の記録です。 WSL上の開発でWindowsホストのローカルLLMをレビュアーとして使いたい。経路は2つあり、どちらも実現はできます。ただし片方は安全性を、もう片方は信頼性を差し出す必要があったので見送りました。その判断の記録です。