MENU

Claude CodeとCodexの単純作業をRTX 3080 Tiに下請けさせるMCPを自作|商品6,141件の照合を一晩で

RTX 3080 Tiに下請けさせる自作MCPサーバー、6,141件を一晩で

ProxmoxのVMでRTX 3080 TiのローカルLLMが動くようになったので、次にやりたくなったのがこれです。

「Claude CodeやCodexが長い作業をしているとき、量が多くて判断が軽い部分だけ、自宅のGPUに下請けさせたい」

そこで、Claude Code/Codexからlocal_llmというツールを呼ぶと、自宅のLANの3080 Tiが処理して返すMCPサーバーを自作しました。

3080 Tiでの構築と、HDDが遅かった話は前の記事に書いています。

関連記事
ProxmoxでRTX 3080 TiをGPUパススルー|Ubuntu・OllamaでローカルLLMを動かしてみたProxmoxでRTX 3080 TiをUbuntuへGPUパススルーし、OllamaでQwen3 8Bを動かした記録。PCIマッピングの設定、IOMMUエラーの復旧、日本語要約の実測時間と回答例を紹介します。
関連記事
ローカルLLMが遅い原因はHDDだった|プライムセールで買ったM.2にVMごと引っ越したら132秒→9秒、約15倍速にプライムセールで買ったSamsung 990 PROに、ProxmoxのVMをHDDからまるごと引っ越したら、LLMの待ち時間が132秒から9秒になった記録です。
目次

作ったものの全体像

自作したのは、MCPサーバーとゲートウェイの2つです。どちらもPythonの標準ライブラリだけで書いています(もちろん書いたのはAIです)。その先で、Ollamaが実際にLLMを動かします。

Claude Code / Codex
   │  MCPツール local_llm(このPCで動く小さなサーバー)
   │  HTTP+Bearerトークン
   ▼
GPUのVM:llm-gateway(窓口)
   │  GPUが別の用途のときは切り替えてから
   ▼
Ollama(VMの中だけに公開)
部品役割
MCPサーバー local_llmClaude CodeやCodexからのツール呼び出しを受けて、窓口へ送る
ゲートウェイ(窓口)トークンの確認、GPUの切り替え、Ollamaへの中継、使われなくなったら元に戻す
Ollama実際にLLMを動かす。VMの外には公開しない

いちばんのポイントはゲートウェイです。3080 TiはふだんLLM以外の用途に使っているので、依頼が来たときだけLLMに切り替えて、30分使われなければ自動で元に戻すようにしました。

切り替えの部分を簡略化すると、こうなっています。

def ensure_llm_mode():
    if ollama_active() and ollama_ready():
        return
    with wake_lock:  # 同時に依頼が来ても切り替えは1回だけ
        if not ollama_active():
            gpu_mode('llm')
        deadline = time.time() + 120
        while not ollama_ready():
            if time.time() > deadline:
                raise RuntimeError('ollama did not become ready')
            time.sleep(0.5)

トークンなしのアクセスは401で拒否することを確認しています。ゲートウェイの実行ユーザーにはsudoを全部渡さず、GPUのモードを切り替えるコマンド2つだけを許可しました。

つまずいたのは「停止に90秒かかる」問題

切り替えが妙に遅いと思ったら、元の用途のプログラムが停止の命令を無視していて、毎回systemdが90秒待ってから強制終了していました。すぐ止まるように設定を変えて解消です。

これで構築直後の計測では、別の用途で動いている状態から依頼して、返事まで約5秒(切り替え2秒+処理3秒)になりました。

使い方は「3080で要約して」と言うだけ

Claude Codeへの登録はコマンド1行です。

claude mcp add --scope user local-llm -- python local_llm_mcp.py

Codexは~/.codex/config.tomlに書きます。

[mcp_servers.local_llm]
command = "python"
args = ["local_llm_mcp.py"]
tool_timeout_sec = 900

[mcp_servers.local_llm.tools.local_llm]
approval_mode = "approve"

最後のapproval_modeが地味に大事でした。私の環境では、これがないとcodex execで動かしたときに承認待ちのまま拒否されました。

ツールの説明文に「要約、翻訳、分類、抽出のような量が多く判断が軽い作業向け」「ファイルは読めないので本文を全部プロンプトに入れること」と書いておくと、Claude Codeは「3080でこれを要約して」のひと言でツールを選んでくれます。GPUの一覧は設定ファイルにしてあるので、あとで4090を足すときもコードは変えていません。

モデルはqwen3.8:27b-iq3-text。12GBのVRAMに全部載るように、約10GBの量子化版を選びました。速度は毎秒約46トークンです。

どのくらい賢いのか:300字要約で3者比較

同じニュース記事を「300字で要約して」と3者に頼み、Codexにどれが誰のものか伏せて採点してもらいました。

RTX 3080 TiClaude CodeCodex
文字数263字337字306字
内容大筋は正確。結論の一部が抜け、1か所不正確正確ほぼ正確に網羅
点数(10点満点)6点8点9点

3080 Tiの要約は4.5秒で返ってきました。

採点したのがCodex自身なので、Codexの9点は少し割り引いて見ています。ただ、Claude Codeの評価でも順位は同じでした。

6点かぁ。でもタダで4.5秒なら、下書きには全然使えるんだよね。

別のテストでは、構成メモの要約で「毎秒46トークン」を「1秒で46文字」と書いたり、元の文にない推測を足したりもしました。要点はつかむけれど、数字と言い回しは間違える、というのが正直な印象です。

なので、Claude Codeの共通ルールにこう書きました。

  • 長い作業では、判断が軽く量の多い部分は3080に下請けに出してよい
  • 下請けの成果は、原文と照合して必ず自分で確認する
  • 「下請けの性能が低かったから」という説明はしない

最後の1行は私が言いたかっただけです。

実戦1:商品6,141件を楽天と照合して、同じものかを一晩で判定

いちばん効いたのがこれでした。別のサイトで、アフィリエイトの商品リンク(Rinker)の画像を楽天の正式な画像に替える作業です。

サイト全体の商品は約1万5千個。そのうち画像を替える対象が6,141個ありました。流れはこうです。

  1. スクリプトが商品名で楽天を検索する(無料だが数時間かかる)
  2. ブランド名が合わない候補は、LLMに聞く前にスクリプトで外す
  3. 「この商品と、検索で出た商品は同じものか?」を3080 Tiに判定させる
  4. 2回聞いて2回ともOKだったものだけ採用する
  5. Claude Codeが抜き取りで確認する

何千回もの判定をClaude Codeに直接やらせると、かなりの量を使います。3080 Tiなら追加の料金はかからず、PCをつけたまま寝るだけで終わりました。

項目件数
対象の商品6,141
楽天で候補が見つかった2,881
2回ともOKで採用1,826(約3割)
Claude Codeが抜き取り確認60
そのうち気になったもの1(型番のないイヤホンに最新の型番が当たっていた)

「2回聞いて2回ともOK」は簡単ですが、よく効きました。迷うものは無理に替えない、というルールと相性がいいです。

6,141件、寝てる間に終わってるの最高すぎる。

実戦2:旅行の写真を外に出さずに仕分け

もう1つは写真です。旅行の写真と動画、約1,620件をフォルダに分けました。

写真をクラウドのAIに送りたくないので、画像は自宅のLANの3080 Tiにしか送りません。Claude Codeが受け取るのは、「スクリーンショット・書類」「船内の客室」のような分類名と短い説明文だけです。

見積もりでは1枚10〜20秒、全体で4.5〜9時間でしたが、試運転では1枚2.4秒で、完了の見込みは1.5〜2時間に縮まりました。実際、始めてから1時間40分後には次の依頼に進んでいます。

続けて「2人がメインで写っている写真」も探させました。1,279枚をエラーなく判定して、ツーショット113枚、ワンショット34枚をコピーしています。ワンショットは「アップ」の判断が厳しめに出たようで、少なめでした。

4090でも試してみた

別のマシンの4090でも、同じスマホ画面のスクリーンショットを読ませて比べました。モデルは同じQwen3.8-27Bの別の量子化版です。

RTX 3080 TiRTX 4090
1回の問い合わせ(読み込み後)5〜13秒2〜3秒
使い始めの読み込み-約80秒
ボタンの座標のずれ1%以内1%以内

量子化版が違うので単純なGPUの比較ではありませんが、読み込んだあとの応答は4090がはっきり速く、位置の精度はどちらも1%以内でした。

実際の使われ方は「会話で1件ずつ」より「スクリプトでまとめて」

作ってみて分かったのは、会話の中でツールとして呼ぶ場面は意外と少ないことです。履歴で数えられた範囲では、local_llmの呼び出しは9回だけでした。

本命は、Claude Codeが書いたスクリプトでまとめて処理する使い方です。商品の判定では、スクリプトからlocal_llmの関数を直接呼んで、何千回も判定させました。全件の結果を会話に流さず、集計と抜き取り確認だけで済むので、Claude Code側の消費を抑えられます。

向いている向いていない
同じ形の判定を大量に繰り返す設計の判断、コードの修正
外に出したくないデータを扱う数字や固有名詞をそのまま使う文章
2回聞くなど、ルールで間違いを減らせる1回で正確さが求められる作業

まとめ:高いAIは「確認役」に回す

GPUを遊ばせずに、必要なときだけLLMとして使う仕組みは、窓口を1つ挟むだけで作れました。

いちばん大きかったのは、役割がはっきりしたことです。大量の判定はローカルのLLM、ルールを作って抜き取りで確認するのはClaude Code、レビューはCodex。賢いAIを全部の作業に使うより、確認に回したほうが、量も質も出せると感じています。

大量の作業を気軽に投げられるようになったのが、いちばん大きいかな。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

こんにちは、「雑記.com」運営者のTakaです。
実際に買った・使った・困った・直した・試した経験をもとに、IT・ガジェット・投資・教育などの実体験やトラブル解決をまとめています。
使ってわかったこと、試行錯誤した過程、解決までの具体的な手順を、日々の選択や困りごとの解決に役立つ形で紹介します。

目次