並列ツール呼び出しを増やすシステムプロンプトの書き方
Claudeが複数ツールを同時に呼ぶ確率を上げる、システムプロンプトの2段階の書き方と、平均ツール呼び出し数(average tools per message)で効果を測る方法をまとめます。
Claudeは既定で並列に複数ツールを呼ぶが、確実ではない
Claude 4以降のモデルは、独立した複数の操作が必要な場面では、追加の指示なしでも1回の応答に複数のtool_useブロックを含めます。2つの都市の天気を聞かれれば、天気取得ツールを2回、同じ応答の中で呼び出すのが基本挙動です。
ただし「基本的に起きる」ことと「毎回起きる」ことは別です。タスクが複雑になったり、ツールの数が増えたりすると、独立した操作のはずなのに1つずつ順番に呼び出してしまうことがあります。並列化が効けばレイテンシは大きく縮みますが、狙って安定的に起こすにはプロンプト側の設計が要ります。
レイテンシが縮む理由は単純です。3つの独立したツールを順番に呼ぶと、Claudeへの往復が3回発生し、それぞれのネットワーク遅延と生成時間が積み上がります。同じ3つを1回の応答にまとめて呼べれば、往復は実質1回で済み、こちらの実行環境側で3つを同時に走らせるだけで結果が揃います。呼び出し回数が多いワークフローほど、体感できるほどの差です。
並列化を狙う前に、そのツールが並列向きかを見る
システムプロンプトを調整する前に、対象のツールが並列実行に向いているかどうかを確認しておく価値があります。Messages APIはツールの実行順序を規定しないため、どちらの方式にするかはこちら側の判断です。
| ツールの性質 | 並列実行との相性 | 理由 |
|---|---|---|
| 読み取り専用の独立した操作(複数ファイルの読み込み、複数都市の天気取得など) | 並列実行との相性向く | 理由副作用がなく、実行順が結果に影響しない |
| 副作用のある操作(書き込み・送信・課金が発生するAPI呼び出し) | 並列実行との相性向かない場合が多い | 理由順序や排他制御が結果の正しさに関わる |
| 共有状態を読み書きする操作 | 並列実行との相性向かない場合が多い | 理由競合や中間状態の読み取りが起きうる |
| 順序に依存関係がある操作 | 並列実行との相性向かない | 理由前の結果を次の入力に使うなら並列にできない |
システムプロンプトで並列化を強く促す指示は、この判断をClaude側の解釈に委ねることになります。副作用のあるツールが混在する構成でプロンプトだけを強めると、本来直列にすべき呼び出しまで並列化しようとする恐れがあるため、読み取り専用のツール群に絞って促す設計のほうが安全です。
同じアプリケーションの中に読み取り専用ツールと副作用のあるツールが混在している場合、両方に同じ強さの並列化プロンプトを当てる必要はありません。ツールの説明文(description)に「このツールは他の呼び出しと独立して実行できる」「このツールは前の結果に依存する」といった実行特性を明記しておくと効果的です。システムプロンプト側の一律の指示よりも、ツールごとの判断材料としてClaudeに正確に伝わります。
システムプロンプトの一文と強い指定タグの効果差
もっとも手軽な対策は、システムプロンプトに1文を足すことです。公式が示す標準の一文は次の内容です。
For maximum efficiency, whenever you need to perform multiple independent operations, invoke all relevant tools simultaneously rather than sequentially.これでも並列化率が足りないと感じる場合に使うのが、より強い指定である<use_parallel_tool_calls>タグです。単なる依頼文ではなく、具体例と「独立した読み取り専用の複数コマンドは必ず並列で実行する」という踏み込んだ指示を含みます。
<use_parallel_tool_calls>
For maximum efficiency, whenever you perform multiple independent operations, invoke all relevant tools simultaneously rather than sequentially. Prioritize calling tools in parallel whenever possible. For example, when reading 3 files, run 3 tool calls in parallel to read all 3 files into context at the same time. When running multiple read-only commands like ls or list_dir, always run all of the commands in parallel. Err on the side of maximizing parallel tool calls rather than running too many tools sequentially.
</use_parallel_tool_calls>2つの違いは強度です。標準の一文は「推奨」程度のニュアンスに留まりますが、タグ付きの指示は具体例を示すことで並列化をほぼ既定の振る舞いとして扱わせます。まず標準の一文を足し、それでも並列化率が伸びないときにタグへ切り替える、という2段階で試すのが遠回りになりません。
ユーザーメッセージの書き方でも並列率は変わる
システムプロンプトに手を入れられない場面では、ユーザーメッセージ側の書き方も並列化に影響します。「パリの天気を教えて。ロンドンも」のように逐次列挙する代わりに、同時実行を明示する文に変えるだけで発生率が変わります。
Agent SDKでカスタムツールを定義している場合、ツール自体の実装を変えなくても、呼び出し元のプロンプト設計だけでこの挙動は変えられます。ツールのハンドラに手を入れる前に、まずプロンプト側の調整から試す方が変更のコストが低くて済みます。
平均ツール呼び出し数(average tools per message)で効果を測る
プロンプトを変えたら、実際に並列化が増えたかを主観でなく数値で確認します。公式が示す指標は「ツール呼び出しを含むメッセージ1件あたりの平均ツール呼び出し数」です。
tool_call_messages = [
msg for msg in messages if any(block.type == "tool_use" for block in msg.content)
]
total_tool_calls = sum(
len([block for block in msg.content if block.type == "tool_use"])
for msg in tool_call_messages
)
avg_tools_per_message = (
total_tool_calls / len(tool_call_messages) if tool_call_messages else 0.0
)この値が1.0を超えていれば、少なくとも一部のメッセージで並列呼び出しが起きています。プロンプト変更の前後でこの値を比較すれば、システムプロンプトを強めた効果は数値で判断可能です。1.0ちょうどに近い値が続く場合は、プロンプトではなく別の要因を疑う段階に移ります。
本番のログを集計する前に、狙って並列呼び出しを起こせるかを単発のリクエストで先に確認しておくと手戻りが減ります。「サンフランシスコとニューヨークの天気と時刻を教えて」のように、独立した複数の情報を同時に求める1文を送り、返ってきた応答のtool_useブロックが2件以上あるかを見るだけの簡単な確認です。この時点で複数呼び出しが起きないなら、プロンプトの強度が足りていないか、ツールの説明文があいまいで別のツールとして認識されている可能性を疑います。本番トラフィックのログを集計してから調整するより、こちらを先に済ませておくほうが調整のサイクルが速く回ります。
並列化が増えないときに疑う原因の順序
プロンプトを強めても効果が出ないときは、プロンプト以外の原因を先に疑います。もっとも多いのはtool_resultの返し方です。並列で呼ばれた複数のツールの結果を、呼び出しごとに別々のユーザーメッセージへ分けて送ってしまうと、会話履歴そのものが「逐次実行が普通」というパターンをClaudeに学習させてしまいます。
| 原因 | 症状 | 対処 |
|---|---|---|
| tool_resultの分割送信 | 症状複数呼び出しのはずが毎回1個ずつになる | 対処全結果を1つのuserメッセージにまとめて返す |
| プロンプトの弱さ | 症状既定のまま並列化率が変わらない | 対処標準の一文 →<use_parallel_tool_calls>の順で強化する |
| 長いエージェントループでの減少 | 症状Fable 5.1で、以前のモデルより並列数が少なくなる | 対処バッチ実行を促す一文を専用の追加指示で補う |
Claude Fable 5.1は、次に何を読むべきかが暗黙的にしか示されない長いエージェントループで、以前のモデルより並列ツール呼び出しの数が少なくなることがあります。対象は自作のコーディングエージェント、bashやtext editorを使うハーネス、computer useなどです。通常の関数呼び出し用途では、この影響は出ません。標準の関数呼び出しでプロンプトを見直しても効果が薄いと感じたら、まずtool_resultの返し方を疑い、それでも解決しなければ長いエージェントループ特有の現象である可能性を検討します。
長いエージェントループというのは、次に読むべきファイルや実行すべきコマンドを明示的な指示ではなく状況から推測して進めるタイプのタスクを指します。天気APIのように「何を呼ぶか」があらかじめ決まっている単発の関数呼び出しとは別物です。モデルが自律的に次の一手を判断し続ける分だけ、並列化の判断も揺れやすくなります。このケースに心当たりがあるなら、バッチ処理を促す指示をシステムプロンプトの独立した箇所に切り出し、通常の関数呼び出し用の指示と混在させないほうが効果を確認しやすくなります。
一部の呼び出しをあえて実行せずスキップする場合のtool_resultの書き方は、並列ツール呼び出しで一部だけ失敗したときの返し方で扱います。Claude Codeのサブエージェントを使った並列実行パターンは、Messages APIのtool_useレベルの並列化とは別のレイヤーの話になるので、混同しないよう区別しておくと設計がぶれません。
3つの経路をどの順番で試すか
アプリケーション全体のシステムプロンプトを自分で管理できるかどうかが、最初の分岐点です。管理できるなら、まずそこに標準の一文を足すのがもっとも影響範囲が広く、修正箇所も1か所で済みます。マルチテナントのプロダクトなどで機能ごとにシステムプロンプトの管理主体が違い、一律に変えづらい場合は、機能ごとのユーザーメッセージのテンプレートを見直すほうが現実的です。どちらの経路を選んでも、tool_resultの返し方が崩れていれば効果は相殺されてしまうため、最終的には両方の状態を確認することになります。
まとめ
並列ツール呼び出しを増やす経路は、システムプロンプトの強化・ユーザーメッセージの書き方・tool_resultの返し方という3つです。強いプロンプトを足しただけでは終わりません。average tools per messageで実測しながら、tool_resultの分割送信のような別要因が相殺していないかを確認するのが、遠回りをしない調整の順序です。読み取り専用の操作に絞って並列化を促し、副作用のある操作は直列のままにしておくことも、安定した挙動を保つうえで欠かせません。逆に並列呼び出しそのものを完全に止めたい場面では、プロンプトではなくリクエストのパラメータで制御することになります。