「強いモデルで段取りを組ませて、安いモデルに手を動かさせる」。エージェントコーディングのコスト削減レシピとして、ほぼ定石です。
私もそう信じて検証しました。Opus 4.7 にオーケストレータをやらせ、ローカルで動かしている Qwen 3.5-9B (トークン課金ゼロ) にコード編集を任せる。これで Opus 単独より安くなるはず。
結果は逆でした。
「タダ」のはずの構成 (Opus + Qwen) が、3つのコード修復タスク 全部で最高額 になりました。Opus 単独より高く、Opus + Haiku より高く、もちろん Haiku 単独より圧倒的に高い。「ローカルで動かしたから安いはず」を信じて GPU PC を組んだ私としては、けっこう困ります。
40試行ぶんの数字と原因を論文の形にまとめて、Zenodo に置きました。DOIはこちら: 10.5281/zenodo.20978074 / GitHub
この記事では、その40試行で何が起きたか、なぜ「タダ」が一番高くついたかを実測ベースで書きます。
TL;DR
40試行 × 4構成 × 3タスク、決定的判定器 (mypy + ruff + pytest の exit code のみ) で測りました。LLM-as-judge は一切使っていません。
- 「Opus が段取り + Qwen が手を動かす」構成は、3タスク全部でクラウド最高額。Opus 単独より高い。
- 原因は executor のトークン代ではなく、オーケストレータ側の prompt cache 再読み込みです。Opus が Qwen の返り値を毎ターン読み直す量が膨らみ、Opus 単独より入力ボリュームが 1.4〜5.3倍に育つ。
- Haiku 単独は最大タスクで Opus 単独の 5.5倍安い。ただし25%の確率で失敗する。クラウド全体で見ると Opus + Haiku が一番バランスが良い。
「executor のトークンが無料なんだから安いはず」という直感が、なぜ外れるのか。それを最後まで書きます。
何を測ったか
4つの構成
| arm | orchestrator | executor | 役割分担 |
|---|---|---|---|
| A | Opus 4.7 | (単独) | 1モデルで全部やる |
| B | Opus 4.7 | Qwen 3.5-9B (ローカル/Ollama) | Opus が段取り + 検証、Qwen が編集 |
| C | Opus 4.7 | Haiku 4.5 (Anthropic SDK サブループ) | Opus が段取り + 検証、Haiku が編集 |
| D | Haiku 4.5 | (単独) | 1モデルで全部やる (安い方) |
4 arms とも Anthropic SDK 経由で同じツール群を使えます。str_replace_editor (view/create/str_replace/insert) と bash (120秒タイムアウト)。オーケストレータ (B, C) には delegate_to_executor ツールが1つ追加されているだけ。
Anthropic prompt caching は全 arm で同じ設定: system / tools / 直近 user message に cache_control: ephemeral を付ける。temperature や seed は設定しないので、試行間ばらつきはサンプリングのランダム性そのものです。
3つのタスク
全部 typer リポジトリの commit b210c0e (v0.26.8) 上で動かしました。MIT license、各試行は git checkout -- . && git clean -fd でリセットしてから始まります。
- T1 — 故障修復: AST で 25 errors を注入 (mypy 10件 + ruff 10件 + pytest collection 失敗 5件)。fully green まで戻す。
-
T2 — リファクタ:
get_params_from_functionをtyper/utils.pyから新モジュールtyper/_param_extractor.pyに移動。全 import 元を更新。テストは全部 pass を維持。 -
T3 — 機能追加:
get_version_banner(prefix, uppercase) -> strを実装してtyper/__init__.pyから export。SHA-256 でフィンガープリントされたテストファイルを通す。
判定器
mypy + ruff check + pytest の exit code が 0 になったら成功、ならなかったら失敗。タスクごとに verify-T2.sh / verify-T3.sh で構造チェック (関数が新モジュールに移ってるか、フィンガープリントされたテストが改変されていないか等) も追加しています。
LLM に「これでOK?」とは一切聞いていません。判定は決定論的、再現可能。
結果 (success-only median、n=3/cell)
| arm | task | n_succ/total | wall (s) | iters | cost ($) | success rate |
|---|---|---|---|---|---|---|
| A Opus solo | T1 | 3/3 | 253 | 36 | 1.74 | 1.00 |
| A Opus solo | T2 | 3/4 | 233 | 26 | 1.11 | 0.75 |
| A Opus solo | T3 | 3/3 | 69 | 6 | 0.17 | 1.00 |
| B Opus+Qwen | T1 | 3/4 | 484 | 38 | 2.27 | 0.75 |
| B Opus+Qwen | T2 | 3/3 | 443 | 27 | 1.38 | 1.00 |
| B Opus+Qwen | T3 | 3/3 | 348 | 12 | 0.42 | 1.00 |
| C Opus+Haiku | T1 | 3/3 | 400 | 28 | 1.67 | 1.00 |
| C Opus+Haiku | T2 | 3/3 | 275 | 20 | 0.92 | 1.00 |
| C Opus+Haiku | T3 | 3/3 | 145 | 11 | 0.38 | 1.00 |
| D Haiku solo | T1 | 3/4 | 758 | 89 | 0.30 | 0.75 |
| D Haiku solo | T2 | 3/4 | 507 | 70 | 0.23 | 0.75 |
| D Haiku solo | T3 | 3/3 | 208 | 29 | 0.08 | 1.00 |
太字は列内ベスト。40試行で Anthropic への合計支払いは$35.98。論文化費用としては安かったほうです。
注目すべき行は arm B です。3タスクすべてで cost ($) がクラウド arm 最高 ($2.27 / $1.38 / $0.42)。Qwen のトークン代はゼロ円なのに、Opus 単独より高い。
なぜ「タダ」が一番高くついたか
Opus 側のトークン消費 (input + cache_read_input) を arm 別に比べると、こうなります。
| arm role | T1 (Opus 側 in+cache_r) | T2 | T3 |
|---|---|---|---|
| A (Opus solo) | 534,586 | 226,474 | 13,320 |
| B (Opus + Qwen) | 733,142 | 313,914 | 62,864 |
| C (Opus + Haiku) | 421,622 | 159,640 | 44,016 |
B/A 比 (Opus 側だけ): T1で 1.38倍、T2で 1.39倍、T3で 5.26倍。
executor (Qwen) のトークンは無料です。でも Opus 自身が読むトークン量が、単独で動かすより 1.4〜5.3倍に膨らんでいる。
なぜか。delegate_to_executor で Qwen に編集を任せると、Qwen は stdout サマリを返します (私の実装では最大4000 char で切り詰め)。そのサマリが Opus 側のコンテキストに毎ターン積まれていく。Anthropic の prompt cache は最新メッセージを cache_write し、次のターンで cache_read として読み戻します。30〜80 ターン回るうちに、Opus が「Qwen が何をやったかのサマリ」を何度も何度も読み直す形になる。
その読み直しに、cache_read 単価 ($1.50/M token = Opus input の 10%) が乗ります。executor が無料でも、orchestrator は無料ではない。当たり前に聞こえますが、「無料」と書いてある単語が文に入ると人間は判断停止しがちです。私です。
正しくは: orchestrator のコストは、executor の生 token 数ではなく、orchestrator が何度それを読み直すかに比例する。LLM じゃなくて中間管理職の話と勘違いしそうな結論ですが、本当にそうです。
T3 で 5.3倍に膨らんだ理由
最も極端なのが T3 (一番小さいタスク、6 iter 程度) です。
これも prompt cache の挙動で説明がつきます。base context (system + tools + 初期プロンプト) は最初の1ターンで cache_write され、以降は cache_read で安く読まれる。長いタスク (T1, T2) では、この base context は累積入力のうち小さな割合になります。
でも短いタスクでは違う。base context が累積入力に占める割合が大きい。だから「executor のサマリも返ってくるし、base も毎ターン読まれるし」のオーバーヘッドが効いてくる。T3 でだけ B/A 比 5.3倍という極端な数字が出るのは、これが理由です。
逆に C (Opus + Haiku) は T1 と T2 で cache_read footprint が A より小さくなる (T1で0.79倍、T2で0.70倍)。Haiku は実際に substantive な仕事をしてくれて、Opus が自分でやらなくて済んだ分が浮く。これは executor がちゃんと働く ケースで、サマリだけが膨らむ Qwen ケースとは反対側です。
オーケストレーションが勝つ条件 (自分の手で潰した範囲で)
「強いオーケストレータ + 安いエグゼキュータ」が反復ツールループで効きにくいのは、1ショットなら問題なくても、何十ターン回す iterative loop で orchestrator の cache_read が支配的になるからです。
今回の実験は、その意味で arm B が負けやすい条件で組まれています:
- executor の返り値が free-form (Qwen の stdout サマリ最大4000 char)。「構造化された diff 1個だけを返せ」と縛れば、Opus 側の累積コンテキストは小さくなる。
- タスクが順次的 (T1/T2/T3 はどれも 1試行内では並列化できない)。「同時に3箇所いじってOK」のタスクなら orchestration の元が取れる可能性が出てくる。
executor 返り値を tight に絞って arm B を再走するのは、次の実験で測ろうと思っています。たぶん T3 では逆転する。T1 では微妙。
実務へのテイクアウェイ
私が今回の数字を見て、自分のエージェントコーディング運用に持ち帰った判断はこれです:
- タスクが数イテレーションで終わるなら Opus solo が一番安い。T3 でクラウド arm 中 best ($0.17 / 69秒 / 6 iter)。「Opusは高い」は単発で見たときの話で、loop 全体で見ると per-iteration の効率が効く。
- タスクが数十イテレーション必要なら、per-iteration が安いモデルが効く。T1 で Haiku solo がドル建て 5.5倍安い。ただし 25% で失敗するので、retry コストを含めると 4.2倍に縮む。
- クラウドだけで完結したいなら Opus + Haiku が一番バランス良い。T1 で Opus solo と同等、T2 で最安、T3 でも僅差。Haiku 単独の失敗リスクを受け入れたくないなら、ここが安全側。
- ローカル Qwen で「タダ」を引きたい場合は、executor の返り値サイズを構造的に縛る。free-form な stdout を返させると、orchestrator 側が cache_read で食われる。
「強いモデル + 安いモデル」は、設計の自由度が思っているより狭いです。executor が何をどれくらい返すか まで含めて設計しないと、「orchestrator が高く付く」が再生産される。私はこの再生産を、計測ミスを疑って3回繰り返してから諦めました。
限界
正直に書く欄です:
- n=3/cell で母集団推定としては弱い。p値 (Mann-Whitney U) は normal approximation で 0.050 が小サンプル下限。effect size (Cliff's delta) は信用してOK、p値の細かい差は過大解釈しない。
- 3タスク全部が typer リポジトリ上。一般化するには別 codebase でも回す必要がある。harness 込みで MIT 公開、追試はしやすいはず。
- orchestrator のシステムプロンプトに「直接編集せず delegate しろ」と書いてある。現実的なデプロイ形ではあるが、結果に乗っている confounder。
再現
ベース環境は Ubuntu 22.04、Python 3.10+、uv 0.4+、anthropic Python SDK 0.83+。arm B は Ollama 0.4+ で qwen3.5:9b。arm A/C/D だけなら Ollama 不要。
git clone https://github.com/kenimo49/free-executor-paradox
cd free-executor-paradox
# arm A の T3 を 1 trial 走らせる
python scripts/runners/runner.py --arm A --task T3 --trial 1
詳細は repo の README と paper PDF を見てください。harness、breakage injection、runner、analysis 全部入っています。
おわりに
agentic coding のコスト議論は executor の値段に寄りがちですが、本当の支配項は orchestrator が何を何度読むかです。今回の Qwen は一例で、これから出てくるローカルモデル全部に同じ問題が付いて回ります (executor が free でも、orchestrator の cache_read は free にならない)。
数字で殴れる結論は強いので、論文の形にして Zenodo に置きました。「うちの codebase でも同じだったよ」「うちは逆だったよ」と追試してくれる人が出てくるのが、いちばん嬉しい結末です。
- 論文 (Zenodo): When Free Executors Cost More — DOI 10.5281/zenodo.20978074
- コード + データ + harness: https://github.com/kenimo49/free-executor-paradox
- GitHub Release: v1.0.0


