並列ツール実行をClaude APIで使う

Claude.ai エンジニアリング 6分で読めます

Claude は既定で、1回の応答の中に複数の tool_use ブロックを返すことがあります。これを並列ツール実行と呼びます。公式ドキュメント Parallel tool use をもとに、実行の決め方、結果の返し方、無効化の方法、そして「並列にならない」ときの切り分けを整理します。

概要:1回の応答で複数のツールが返る

ツールが呼ばれた応答は stop_reasontool_use になり、1つのアシスタントターンの中に複数の tool_use ブロックが入ることがあります。ここで重要なのは、API は実行の順序を決めていないという点です。同時に走らせる(Promise.allasyncio.gather)のも、書かれた順に1つずつ実行するのも、混ぜるのも、すべて呼び出し側の判断に委ねられています。

判断の基準はツールの性質です。副作用のない読み取り専用の処理は、並列に走らせて待ち時間を縮めるのが自然です。逆に、書き込みを伴うもの、共有状態を触るもの、順序が意味を持つものは、順番に実行したほうが安全です。

なお、computer use ツールと browser use ツールは例外で、より厳しい規則があります。これらのメンバーツールが1ターンにまとめて返ってきた場合(バッチアクション)は、書かれた順に1つずつ実行し、最初の失敗で止めることが求められます。飛ばした呼び出しに何を返すかは、それぞれのツールが定義しています。

tool_resultは1つのユーザーメッセージにまとめる

実行の仕方は自由ですが、結果の返し方には決まりがあります。各 tool_use ブロックに対して tool_result を1つずつ用意し、すべてを次の1つのユーザーメッセージにまとめて返します。対応づけは tool_use_id で行い、そのメッセージの中では tool_result ブロックをテキストより前に置きます。

実行しなかった呼び出しがあっても、黙って省いてはいけません。たとえば順番に実行していて途中で失敗した場合でも、残りの呼び出しに対して is_error: true を付けた tool_result を返します。

{
  "type": "tool_result",
  "tool_use_id": "toolu_02",
  "is_error": true,
  "content": "Not executed: the preceding write_file call failed."
}

多くのアプリケーションでは、この整形を自分で書く必要はありません。SDK の Tool Runner が複数ツール呼び出しの応答を受け取り、結果の整形まで行ってくれます。手作業のパターンが要るのは、バッチの切り方・順序・エラー処理を自分で制御したいときです。

並列を起きやすくするシステムプロンプト

Claude 4 以降のモデルは、複数のツールを使ったほうがよい要求に対して既定で並列に呼び出します。それでも確率を上げたいときは、システムプロンプトで明示します。公式が示している最小の一文はこれです。

For maximum efficiency, whenever you need to perform multiple independent operations, invoke all relevant tools simultaneously rather than sequentially.

より強く効かせたい場合は、公式が示すタグ付きの長い版があります。「3つのファイルを読むなら3つの呼び出しを並列で走らせる」「ls のような読み取り専用コマンドは必ず全部並列にする」といった具体例を含む形です。抽象的な指示より、こうした具体例つきの指示のほうが効きます

ユーザー側の書き方も影響します。「パリの天気は? ロンドンも見て」のように2文に分けるより、「パリとロンドンの天気を調べて」と1文で並べたほうが、並列呼び出しになりやすくなります。

並列を無効にする disable_parallel_tool_use

並列ツール実行は既定で有効です。止めたいときは tool_choice オブジェクトの中に disable_parallel_tool_use: true を入れます。リクエスト直下のパラメータではありません。ここを取り違えると、指定したつもりで効いていない状態になります。

効き方は tool_choice の type によって変わります。

"tool_choice": {"type": "auto", "disable_parallel_tool_use": true}

ただし anytool は全モデルで使えるわけではありません。公式は Claude Fable 5.1 と Claude Mythos 5.1 がこの2つの type に対応しないと記載しています。

並列にならないときの切り分け

並列になるはずの場面で1つずつしか呼ばれないときは、次の順に見ます。

1. 会話履歴の整形が間違っている。これが最も多い原因です。ツール結果ごとに別々のユーザーメッセージを作っていると、Claude に「並列にしない」ことを教えてしまいます。正しいのは、すべての tool_result を1つのユーザーメッセージにまとめる形です。

2. プロンプトが弱い。既定の書き方では足りないことがあります。前節の強いシステムプロンプトに差し替えて再測定します。

3. そもそも測っていない。効いたかどうかは、応答の中の tool_use ブロック数を数えれば分かります。取得済みの応答をクライアント側で集計するだけの話なので、まず「1応答あたり平均何個か」を出してから対策を評価してください。