2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ローカルAIに実装を任せればClaudeのトークンは減る? 実測したら逆だった(と、そこから分かったこと)

2
Posted at

はじめに

「設計はクラウドAI(Claude)、実装はローカルAI(Qwen)」と分担すれば、クラウドAIのトークン消費を減らせるのではないか。そう考えて、実際に測ってみました。

先に結論を書きます。

  • テスト1(クイック検索)では、Claude の料金は減るどころか約 2.1 倍になり、時間も大幅に増えました。
  • 原因は、Claude が仕様書を書くだけでなく、Qwen が正しく実装できるように**大量の補助(骨組み、受け入れテスト、タスクカードなど)**を用意していたことです。補助の準備だけで、Claude が直接実装するより多く書いていました。
  • そこで補助を全部やめ、仕様 1 ページだけで任せるテスト2(コマンドの取り込み)をしました。すると 8 回すべてで満点でした。ただし、時間は 1 回あたり 30〜90 分かかりました。

つまり「補助を減らせば成立する。ただし小さい題材の話で、時間はかかる」というのが、現時点での結論です。

実験の設定

  • 題材はデスクトップアプリ(Tauri v2 の、コマンドを保存するメニューバー常駐ツール)の機能実装です。
  • PC: MacBook Pro(Apple M5 Pro、18 コア、メモリ 64GB)です。
  • ローカルAI: mlx-community/Qwen3.8-27B-4bit(27B パラメータを 4bit 量子化したモデル)を、MLX ベースのローカルサーバー(omlx)で動かしました。エージェントとしての実行は Hermes 経由です。
  • Qwen の出力速度: 平均で約 28 トークン/秒でした(範囲は 19〜39)。同じマシンで、この実験用ハーネスを使って実装を任せた 20 回の実行記録(出力 31.7 万トークン、実行時間の合計 3 時間 10 分)から、出力トークン数 ÷ 実行時間で求めた値です。ツールの実行待ちや入力の読み込みの時間も含むため、純粋な生成速度より低めに出ています。
  • Claude は Sonnet を使い、消費は claude -p --output-format json で計測しました。
  • Qwen に実装を任せるための仕組み(ハーネス)を自作し、その上で比較しました。

何を実装させたか

この記事では、2 つのテストをしました。題材は、テストごとに違います。どちらも、自作の「コマンド保存ツール」(保存したシェルコマンドをコピーして使うアプリ)に足す機能です。技術は Tauri v2(Rust のバックエンドと、TypeScript の画面)です。

テスト1: クイック検索ウィンドウ(Rust + TypeScript、複数ファイルにまたがる)

どのアプリを使っていても、Alt+Space(macOS では ⌥Space)で小さな検索ウィンドウを開き、コマンドを絞り込んで、キーボードだけでコピーできる機能です。仕様書は、細かい動作まで書いたものです。

  • グローバルショートカット: 公式の tauri-plugin-global-shortcut で登録します。登録に失敗してもアプリは起動を続けます。押したときだけ反応し、離したときは何もしません。
  • ウィンドウと画面: 560×380 程度の最前面ウィンドウに、検索欄と候補の一覧(最大 50 件)を出します。選択中の候補は 1 つで、aria-selected で示します。
  • キー操作: ↑ ↓ で選択を動かし(端で止まる)、Enter で使い、Escape で閉じます。候補のクリックでも使えます。
  • 「使う」の分岐: 固定コマンドはコピーしてトレイに ✓ を出し、プレースホルダー付きのコマンドは入力ウィンドウを開きます。失敗したら閉じずにエラーを出します。実行中の二重実行も防ぎます。
  • Rust 側: Tauri コマンドを 2 つ(copy_command と open_fill_for)足します。

実際には、Rust(ショートカット登録、Tauri コマンド、ウィンドウ生成)、HTML/TypeScript(画面とキー操作)、権限の設定、README が絡みます。受け入れ条件は cargo fmt / clippy / cargo test、tsc、vitest、ビルドがすべて通ることです。

テスト2: コマンドの取り込み(Rust の純粋な関数 1 つ)

エクスポートしたコマンド一覧を取り込むとき、すでにあるコマンドと重複するものを除いて足す関数 merge_commands です。ファイルも画面も関係しません。規則は 3 つです。

  1. 無効: 名前か本文が(前後の空白を除くと)空なら、追加せず invalid を数える。
  2. 重複: 名前(前後の空白を除く)と本文(1 文字も違わず、大文字小文字も区別)の組が、既存のコマンド、またはこの呼び出しですでに追加したコマンドと同じなら、追加せず duplicates を数える。
  3. 追加: それ以外は末尾に追加する。id は取り込み側の値を無視して新しい UUID にし、名前とフォルダ名は前後の空白を除き、本文はそのままにする。

さらに「added + duplicates + invalid は入力の件数と等しい」「既存の要素は変更も並べ替えもしない」といった条件があります。小さく見えますが、空白の扱い、取り込み内の重複、既存側の空白といった境界の判断が入っています。

テスト1(クイック検索): Qwen に任せたら、Claude の料金は 2.1 倍になった

上のクイック検索を 2 通りで実装しました。

  • 方式 A: Qwen に任せる。Claude は準備と、最後の取り込みレビューをする。
  • 方式 B: Claude が直接実装する。
方式 A: Qwen に任せる 方式 B: Claude が直接実装
Claude の料金 1.07 ドル(準備 0.83 + 取り込み 0.24) 0.50 ドル
Claude の出力トークン 27,015 12,067
Claude の手番 33 16
Qwen 約 275 万トークン、約 53 分(ローカル) なし
結果 全検査が通る 全検査が通る
かかった時間 1 時間強 数分

Qwen の品質に問題はありませんでした。Qwen のコードは、取り込みのレビューで修正なしでした。それでも Claude の料金は約 2.1 倍です。

なぜ増えたのか

Claude にとっての費用の大部分は、「書く」ことではなく「読んで理解し、決める」ことでした。

  • 方式 A の準備(骨組み、受け入れテスト、タスクカード、API の確認、配線)だけで、方式 B の実装全体より多く書いていました(出力 24,469 対 12,067 トークン)。
  • 受け入れテストを先に書くには、実装と同じだけ仕様を詰める必要があります。テストは本体より長くなりがちです。
  • 取り込みのレビューが、さらに追加でかかります。

つまり、Qwen に実装を任せるために Claude がやった補助が、実装そのものより重かったのです。(この数字には、実験を指揮した会話の費用は含めていません。含めれば差はさらに開きます。)

テスト2(コマンドの取り込み): 補助を全部やめたら、どうなったか

テスト1 の結果から、疑問が出ました。その補助は、本当に必要だったのでしょうか。

そこでテスト2 では、Claude が書くのを仕様 1 ページ(約 1,300 文字)だけにしました。テストも骨組みも実装も、Qwen がすべて行います。題材は、上で説明した「コマンドの取り込み」(merge_commands)です。

Qwen の仕事は 3 段階です。T(テストと骨組み)、I(実装)、H(テストの強化。テストが弱いときだけ動く)。

評価は、Claude が別に書いた物差しで行いました。隠しテスト 12 件、正しい参考実装、参考実装をわざと壊した 20 個の版です。Qwen にはこれらを見せていません。

結果

スキル(superpowers)の有無でも比べ、各 4 回、計 8 回試しました。

指標 スキルあり (n=4) スキルなし (n=4)
隠しテスト 12 件 12/12 を 4 回 12/12 を 4 回
壊した 20 版の検出 20/20 を 4 回 20/20 を 4 回
実装の試行回数 1 回(4 回とも) 1 回(4 回とも)
所要時間(平均 / 範囲) 46 分 / 19〜89 分 33 分 / 29〜40 分
  • 8 回すべてで満点でした。Qwen は仕様だけで、正しいテストと正しい実装を書きました。この題材では、テスト1 で用意した補助は不要でした。
  • 強化の段階(H)は、1 度も動きませんでした。
  • スキルの効果は、この題材では測れませんでした。どちらも満点で、差が出る余地がなかったためです(天井効果)。

時間はかかった

ここは正直に書いておきます。**1 回あたり 30〜90 分かかりました。**同じ種類の機能を Claude が直接書けば数分です。ローカルで動かすぶん料金はかかりませんが、待ち時間は確実に増えます。

Claude 側の費用は、仕様と最後のレビューだけです。テスト1 ではレビューが 0.24 ドルで、直接実装の 0.50 ドルより小さくなる見込みです。ただしこれは、テスト1 の数字からの見積もりで、テスト2 で直接測ったものではありません。

ハーネスの欠陥も見つかった

最初の 4 回の試行で、仕組みの側の問題が見つかりました。スキルの有無とは無関係で、すべて直しました。

  • 実装担当の Qwen が、凍結されたテストの lint 警告を #[expect(...)] で抑止して押し切って通過していました(4 回中 2 回)。ゲートが #[expect] を知らなかったためです。
  • テストの lint(clippy)を、テスト作成の段階で確かめていませんでした。
  • 骨組みの段階で通るテストの扱いが、段階 T と I で食い違っていました。

ローカルAIに任せるときは、AIがルールの抜け穴を見つけて通ることを前提に、ゲートを作る必要があります。

結論と注意

  • 「補助を厚くして任せる」やり方では、Claude の料金も時間も増えました。
  • 「仕様だけで任せる」やり方は、小さい題材(純粋な関数 1 つ)では成立しました。ただし時間はかかります。
  • ローカルAIが向くのは、仕様が短いのに出力が大量になる仕事(一括の書き換え、テストデータの大量生成、翻訳など)や、社外に出せないコード、オフライン、料金を気にせず何度も試したい場面です。

注意点もあります。

  • 題材は 1 つで、n=4 ずつです。
  • 題材が単純で、Qwen の能力の限界は測れていません。
  • テスト1 とテスト2 は題材が違うため、料金を直接比べることはできません。

次は、規則が多く、複数の関数や状態、エラー処理が絡む題材で試すつもりです。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?