はじめに
「計画や設計はOpus、実装はSonnet」のように、Claude Codeでは作業工程によってモデルを使い分けたほうがいい、という話を最近よく聞きます。
言っていることはわかる。でも、ほんとに使い分けたほうがいいの?
そこで今回は、同じ要件のアプリを次の2パターンで作り、成果物とトークン消費を比べました。
- Opus+Sonnet:計画・設計はOpus、実装以降はSonnet
- 全部Opus:計画・設計・実装をすべてOpus
結論から言うと、今回の比較ではOpus+Sonnetのほうが推定コストが約3割少なく、成果物の品質で大きく差がある感じにもなりませんでした。見た目の作り込みは全部Opusがちょっと上。テストの量はOpus+Sonnetのほうが多い。「全部Opusの方が圧勝」にはなりませんでした。
同じプロンプトを各パターン1回ずつ流した比較です。同じモデルでも毎回出力は揺れるので、「モデルの優劣を決める検証」ではなく「実際のClaude Code運用を1回ずつ並べてみた結果」として読んでください。
きっかけは、みんなOpusばかり使っていたこと
社内には、AIエージェントのトークンの利用状況を確認できるWebシステムがあります。社内全体やメンバーごとの推定コストを、利用したモデル別に確認できるものです。
このシステムについては、以前書いたこちらの記事でも紹介しています。
丁寧すぎるClaude Codeを原始人にしたら、トークン使用量が3割減った
実際にメンバー別の利用状況を見てみると、体感では8割ほどの人が、ほぼOpusだけを使っていました。
計画ではFableを使い、その後の作業をOpusへ引き継いでいる人はちらほらいます。一方で、実装にSonnetを使うところまで細かくモデルを切り替えている人は、ほとんどいませんでした。
こちらは社内でトークン使用量がぶっちぎりで飛び抜けているMさん(@Shinn_Matsumoto)のトークン使用量です。
自分も似たような状態です。普段の業務では作業ごとにモデルを使い分けられておらず、ほとんどOpusです。
最近出たSonnet 5.5かなりいいってXでもよく見かけるし、、
使い分けたほうがいいとは聞くけど、実際どれくらい変わるんだろう、、
公式にも「計画はOpus、実装はSonnet」の設定がある
Claude Codeのモデル設定には、opus や sonnet のほかに opusplan というエイリアスがあります。公式ドキュメントによると、
- プランモードでは
opusを使い、複雑な推論や設計判断をする - 実行モードでは自動で
sonnetに切り替えて、コード生成と実装をする
という動きです。まさに今回試したい使い分けそのもの。
また、モデル選びの公式ガイド「Choosing the right model」でも、Opusは複雑なエージェント型コーディング、Sonnetは日常的なコード生成向けと整理されています。ただし同じページには「自分のユースケースで実際に試して比べよう」とも書かれていて、どっちが正解かは結局自分で試すしかないです。
なので検証してみました!
実験の条件
題材は「条件分岐付きフォームビルダー」
最初はゲームも考えたんですが、ゲームだと「面白さ」の比較が主観になります。モデルの差なのか、たまたま出たアイデアの差なのか判断しづらい。
そこで、Googleフォームを小さくしたような条件分岐付きフォームビルダーにしました。React+TypeScript+Viteで、バックエンドなし、データはlocalStorageに保存します。
- 質問の追加・複製・削除・ドラッグ&ドロップでの並べ替え
- 記述式・単一選択・複数選択の3形式
- 単一選択の回答に応じて次の質問へ分岐
- 循環する分岐や、削除された分岐先を検出
- 1問ずつ答えるプレビュー、回答結果のグラフ集計
- JSONのエクスポート・インポート、不正なJSONでも落ちない
- スマホでも横スクロールせずに操作できる
簡単すぎる題材だとどっちも完璧に作れてしまって差が出ないので、条件分岐・データの整合性・スマホ対応と、設計をサボると後で苦しくなる要素を詰めています。
(ちなみに題材もAIに考えてもらいました笑)
同じプロンプトを同じ回数だけ投げる
両パターンとも、まったく同じ5つのプロンプトを同じ順番で投げました。違うのはモデルだけです。
| 回 | 内容 | Opus+Sonnet | 全部Opus |
|---|---|---|---|
| 1 | 計画・設計(PLAN.mdを作るだけ) | Opus | Opus |
| 2 | PLAN.mdに沿って実装 | Sonnet | Opus |
| 3 | 14項目を実際に操作して確認・修正 | Sonnet | Opus |
| 4 | 新しい質問形式「日付」を追加 | Sonnet | Opus |
| 5 | 完成品としての最終確認・修正 | Sonnet | Opus |
4回目の「日付」追加は、最初の設計が拡張しやすいかを見るための追加改修です。
1回目:計画・設計のプロンプト全文
ブラウザで動作する「条件分岐付きフォームビルダー」を作ります。
今回は計画と設計だけを行ってください。まだソースコードを実装しないでください。
## 技術条件
- React
- TypeScript
- Vite
- バックエンドと外部APIは使用しない
- データはlocalStorageに保存する
- PCとスマートフォンの両方で操作できるようにする
- 必要なライブラリは追加してよい
- 現在のプロジェクト構成と既存ファイルを確認した上で設計する
- サブエージェントは使用しない
- 現在の作業ディレクトリの外にあるファイルや、もう一方の比較対象は参照しない
## 必須機能
### フォーム編集
- フォームのタイトルと説明を編集できる
- 質問を追加・編集・複製・削除できる
- 質問をドラッグ&ドロップで並べ替えられる
- 質問形式は「記述式」「単一選択」「複数選択」の3種類
- 各質問に必須・任意を設定できる
- 選択式の質問では選択肢を追加・編集・削除・並べ替えできる
### 条件分岐
- 単一選択の回答に応じて、次に表示する質問を指定できる
- 分岐を設定しない場合は次の質問へ進む
- 分岐先に指定された質問を削除した場合も、フォーム全体が壊れない
- 循環する分岐は保存できないか、実行前にエラーとして検出する
- 回答者が到達しない質問は表示しない
### プレビューと回答
- 編集中のフォームをプレビューできる
- 回答画面では1問ずつ質問を表示する
- 前の質問へ戻れる
- 必須項目が未入力の場合は次へ進めない
- 回答完了後に送信完了画面を表示する
- 複数件の回答を保存できる
### 回答結果
- 回答数を確認できる
- 質問ごとの回答を確認できる
- 単一選択と複数選択の回答はグラフで集計する
- 記述式の回答は一覧で表示する
### 保存と入出力
- 編集内容と回答内容をlocalStorageへ保存する
- ブラウザを再読み込みしても復元できる
- フォームをJSONファイルとしてエクスポートできる
- エクスポートしたJSONファイルをインポートできる
- 不正なJSONを読み込んでもアプリ全体が停止しない
- サンプルフォームを読み込める
### UI
- 編集、プレビュー、回答結果を迷わず切り替えられる
- 保存状態やエラーを画面上で確認できる
- 空の状態でも次に何をすればよいか分かる
- スマートフォンで横スクロールせずに操作できる
## 設計時に決めること
- ディレクトリとコンポーネントの構成
- フォーム、質問、選択肢、分岐、回答のデータ構造
- 状態管理の方法
- localStorageへの保存形式
- 条件分岐の実行方法
- 循環参照と削除済み分岐先の検出方法
- JSONインポート時の検証方法
- テスト方針
- 実装する順番
要件に曖昧な部分があれば、質問せずに妥当な仕様を決め、その判断を計画へ記載してください。
調査と設計が終わったら、実装担当者がそのまま作業を開始できる具体性で、プロジェクトのルートにPLAN.mdを作成してください。
この段階ではPLAN.md以外のファイルを変更しないでください。
2回目:実装のプロンプト全文
PLAN.mdを読み、記載されている設計と実装順序に従って、条件分岐付きフォームビルダーを完成させてください。
必須機能を省略せず、実際にブラウザで使用できる状態まで実装してください。見た目だけのモックや、ボタンを押しても動作しない未実装部分は残さないでください。
サブエージェントは使用しないでください。現在の作業ディレクトリの外にあるファイルや、もう一方の比較対象は参照しないでください。
実装中に問題が見つかった場合は、質問せずに原因を調査して修正してください。設計の変更が必要になった場合は、変更理由をPLAN.mdへ追記してから実装してください。
実装後は、型チェック、テスト、ビルドを実行してください。失敗した場合は修正して、すべて成功するところまで進めてください。
要件にない機能は増やさず、最後の報告は以下だけを簡潔にまとめてください。
- 実装した内容
- 実行した確認
- 残っている問題
3回目:動作確認・修正のプロンプト全文
現在の実装が、PLAN.mdと最初に提示した必須機能をすべて満たしているか確認してください。
サブエージェントは使用しないでください。現在の作業ディレクトリの外にあるファイルや、もう一方の比較対象は参照しないでください。
コードを読むだけで判断せず、可能な範囲でアプリを実際に操作し、次の流れを一通り検証してください。
1. 空の状態からフォームを作成する
2. 3種類の質問を追加する
3. 質問と選択肢を並べ替える
4. 単一選択の回答による条件分岐を設定する
5. プレビューで分岐を確認する
6. 必須入力の検証を確認する
7. 複数件の回答を送信する
8. 回答結果とグラフを確認する
9. 再読み込み後にデータが復元されることを確認する
10. JSONをエクスポートして再度インポートする
11. 不正なJSONをインポートする
12. 分岐先の質問を削除する
13. 循環する分岐を設定する
14. スマートフォン相当の画面幅で操作する
不具合、未実装、操作しにくい箇所を見つけた場合は、その場で修正してください。必須機能を追加で省略してはいけません。
修正後に型チェック、テスト、ビルドを実行し、すべて成功するところまで進めてください。
最後の報告は以下だけを簡潔にまとめてください。
- 見つけた問題
- 修正した内容
- 実行した確認
- 残っている問題
4回目:「日付」形式追加のプロンプト全文
既存のフォームビルダーへ、新しい質問形式「日付」を追加してください。
サブエージェントは使用しないでください。現在の作業ディレクトリの外にあるファイルや、もう一方の比較対象は参照しないでください。
## 要件
- フォーム編集画面で「日付」を選択できる
- 回答画面では日付入力用のUIを表示する
- 必須・任意を設定できる
- 任意で回答可能な最小日付と最大日付を設定できる
- 最小日付より前、または最大日付より後の回答は送信できない
- プレビューでも同じ検証が動作する
- 回答結果画面で入力された日付を一覧表示する
- localStorageへの保存と復元に対応する
- JSONのエクスポートとインポートに対応する
- 既存のフォームデータと回答データを壊さない
- 既存の3種類の質問形式の動作を変えない
現在の設計を確認し、必要な箇所だけを変更してください。実装後は日付形式のテストを追加し、既存テストを含めて型チェック、テスト、ビルドを実行してください。
失敗した場合は修正して、すべて成功するところまで進めてください。
最後の報告は以下だけを簡潔にまとめてください。
- 変更した内容
- 実行した確認
- 残っている問題
5回目:最終確認のプロンプト全文
これが最後の確認です。
サブエージェントは使用しないでください。現在の作業ディレクトリの外にあるファイルや、もう一方の比較対象は参照しないでください。
最初の必須機能と、追加した「日付」の質問形式を含め、アプリ全体を完成品として確認してください。
次の観点で問題を探してください。
- 操作しても動かない機能がないか
- データが消える操作がないか
- 条件分岐に矛盾や無限ループがないか
- 不正なデータによって画面全体が停止しないか
- ブラウザを再読み込みしても状態が復元されるか
- PCとスマートフォンの両方で操作できるか
- 初めて使う人が説明なしでフォームを作成できるか
- 同じ処理の重複や、責務が集中しすぎたファイルがないか
- 質問形式をさらに追加できる構造になっているか
- テストが実際の仕様を検証しているか
問題を見つけた場合は修正してください。ただし、新機能の追加や全面的なデザイン変更は行わないでください。
修正後に型チェック、すべてのテスト、ビルドを実行し、成功するところまで進めてください。
最後の報告は以下だけを簡潔にまとめてください。
- 最終的に修正した内容
- 実行した確認
- 残っている問題
実行方法
実行環境はClaude Code 2.1.288です。今回、opus と sonnet のエイリアスは、それぞれ claude-opus-5-5 と claude-sonnet-5-5 に解決されました。
opus と sonnet は固定されたモデル名ではなく、環境や時期によって解決先が変わります。詳しくはClaude Code公式のモデル設定を確認してください。
今回はCodexからClaude Code CLIを非対話で実行してもらいました。前回のyomiyasuの記事と同じやり方です。
1回目はこんな感じ。
claude -p \
--safe-mode \
--model opus \
--effort high \
--permission-mode auto \
--disallowedTools Agent \
--output-format json \
< 01-plan.txt
2回目以降は、1回目のセッションを --resume で引き継ぎながら、モデルだけ切り替えています。
# Opus+Sonnetは sonnet、全部Opusは opus
claude -p --resume <1回目のセッションID> \
--safe-mode \
--model sonnet \
--effort high \
--permission-mode auto \
--disallowedTools Agent \
--output-format json \
< 02-implementation.txt
同じセッションを引き継いでいるので、Sonnetも「Opusが計画を立てた会話」をそのまま見たうえで実装します。opusplan に近い使い方です。
公平にするために揃えたのはこのあたりです。
- 同じスターターを複製し、別々のGitリポジトリ・別ポートで動かす
- effortは両方
high -
--disallowedTools Agentでサブエージェントを禁止(別モデルの下位エージェントが混ざるのを防ぐ) - 片方の結果をもう片方に伝えない、人間も途中でヒントを出さない
- トークンと推定コストは
--output-format jsonの結果から工程ごとに記録
ちなみにClaude Maxプランのアカウントで実行しているので、以下に出てくるドル金額がそのまま請求されたわけではありません。Claude Codeが出したAPI換算の推定コストです。
結果:推定コストは約3割少なかった
| 項目 | Opus+Sonnet | 全部Opus |
|---|---|---|
| 推定コスト | $12.68 | $18.29 |
| トークン合計 | 約3,187万 | 約4,153万 |
| API処理時間 | 約44分 | 約53分 |
| ターン数 | 144 | 174 |
| 最終的なテスト数 | 263 | 178 |
| ソース行数 | 8,828行 | 8,791行 |
| 型チェック・lint・テスト・ビルド | すべて成功 | すべて成功 |
Opus+Sonnetのほうが、推定コストで約31%、トークンで約23%少なく済みました。処理時間も8分ほど短いです。
トークン合計の大半はキャッシュ読み込みです。Claude Codeはやりとりのたびに会話の履歴を読み直すので、ターン数が増えるほどここが膨らみます。
ソース行数はほぼ同じなので、「Sonnetが手を抜いて小さく作ったから安かった」わけではないです。
工程ごとに見ると、後半はOpusのほうがターン数が増えた
| 回 | Opus+Sonnet | 全部Opus |
|---|---|---|
| 1. 計画・設計(両方Opus) | $1.62 / 8分 | $1.54 / 8分 |
| 2. 実装 | $4.74 / 18分 | $6.76 / 22分 |
| 3. 動作確認・修正 | $1.69 / 6分 | $2.82 / 7分 |
| 4. 日付形式の追加 | $1.81 / 5分 | $3.20 / 8分 |
| 5. 最終確認 | $2.82 / 6分 | $3.96 / 9分 |
※時間はAPI処理時間
一番重い2回目の実装は、Sonnetのほうが出力トークンはむしろ多いのに、コストは約3割安いです。ここは単純にモデルの単価の差だと思います。
面白かったのは3〜5回目です。全部Opusのほうがターン数が多く(3回目は22回 vs 37回、4回目は18回 vs 30回)、確認や修正に時間をかけていました。慎重に確認していると言えば聞こえはいいですが、そのぶんトークンとコストが積み上がっています。
もっと複雑なものを作ると、コストの差はどんどん開きそうです。
成果物の違い
編集画面は設計の方向性から違った
ぱっと見でかなり違います。ただ、この差はSonnetかOpusかより、1回目にOpusが立てた計画(PLAN.md)の違いが大きそうです。計画は両方Opusですが、別々のセッションで作っているので中身は同じになりません。
- Opus+Sonnet:質問を折りたたんだ一覧で表示。開くと中身を編集する形式で、質問が多くても全体を見渡しやすい
- 全部Opus:Googleフォームのように、すべての質問をその場で編集できる形式。分岐の設定も選択肢のすぐ下に出るので、何がどこに飛ぶのかがひと目でわかる
全部Opus版はサンプルを読み込むと回答8件も一緒に入るので、結果画面のグラフをすぐ確認できます。「質問・選択肢の削除や形式の変更は、既存の回答の集計に反映されません」という注意書きまで出してくれる。このあたりの気配りは全部Opusが一枚上でした。
プレビュー画面
Opus+Sonnet版は「回答を開始」を押してから1問目に入る形式で、テスト回答を保存しないチェックボックスがあります。全部Opus版はいきなり1問目から始まり、進捗バーも出ます。
どっちも要件は満たしていて、好みの問題です。
スマホ幅
両方とも横スクロールなしで操作できました。細かいところでは、全部Opus版はタブの「プレビュー・回答」が2行に折り返しています。Opus+Sonnet版は折りたたみ一覧なので、スマホだとこっちのほうが操作しやすく感じました。
テストの量はOpus+Sonnetが多かった
テスト数の推移はこうなりました。
| 回 | Opus+Sonnet | 全部Opus |
|---|---|---|
| 2. 実装後 | 132 | 134 |
| 3. 動作確認後 | 134(3件修正) | 136(4件修正) |
| 4. 日付追加後 | 210(+76) | 170(+34) |
| 5. 最終確認後 | 263 | 178 |
実装直後はほぼ同じ。差がついたのは日付形式を追加したあたりからで、Sonnetは日付の境界値などをかなり細かくテストしていました。最終確認でも、データ消失の防止やインポート時の不正なID、モバイル表示などを幅広く直しています。
テストが多い=品質が高い、とは言い切れません。ただ少なくとも、「実装をSonnetにしたら雑になった」という感じはまったくなかったです。
まとめ:Claude Codeは作業工程によってモデルを使い分けるべき?
今回の結果だけで言うと、計画をOpusにしておけば、実装以降はSonnetでも十分でした。
- 推定コストは約3割、トークンは約2割少ない
- 型チェック・lint・テスト・ビルドの自動チェックはすべて通過
- 見た目の作り込みや気配りは全部Opusが少し上
- テストの量はOpus+Sonnetのほうが多い
みんながOpusに寄るのは「Opusのほうが品質がいいはず」という安心感だと思います。自分はそうです。笑
でも今回の題材くらいの規模なら、実装までOpusにした分の差はコストほど大きくなかったです。
正直、もっと差が出ると思ってました、、
今回は比較のために同じ回数で実行していますが、実際に使う場合は何回もラリーを続けると思うのでそれを踏まえると実装はSonnetの方がいいんじゃないかな、と私は思いました!
opusplan は /model opusplan で切り替えられるので、気になった人はまず普段の作業で試してみてください!
参考
- Model configuration(Claude Code公式ドキュメント)
- Choosing the right model(Anthropic公式ドキュメント)
- CLI reference(Claude Code公式ドキュメント)
関連記事
- 丁寧すぎるClaude Codeを原始人にしたら、トークン使用量が3割減った … 今回も使った社内のトークン確認システムで、出力スタイルを変えてトークンを減らした話
- Codexのモデル選びで迷わない。Astra・Sol・Terraの使い分け … Codex側のモデル使い分けを整理した話。Claude Codeと見比べると面白いです
- 新しい日本語推敲スキル「yomiyasu」がバズっていたので、Claudeで日本語推敲スキル3つを比べてみた … 今回と同じく、CodexからClaude Codeを動かして同じ条件で比べた話
告知
最後にお知らせとなりますが、イーディーエーでは一緒に働くエンジニアを
募集しております。詳しくは採用情報ページをご確認ください。
みなさまからのご応募をお待ちしております。




