はじめに
「設計はクラウド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 つです。
-
無効: 名前か本文が(前後の空白を除くと)空なら、追加せず
invalidを数える。 -
重複: 名前(前後の空白を除く)と本文(1 文字も違わず、大文字小文字も区別)の組が、既存のコマンド、またはこの呼び出しですでに追加したコマンドと同じなら、追加せず
duplicatesを数える。 -
追加: それ以外は末尾に追加する。
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 は題材が違うため、料金を直接比べることはできません。
次は、規則が多く、複数の関数や状態、エラー処理が絡む題材で試すつもりです。