Claude Platform Docs
Messagesツール

並列ツール使用

並列ツール呼び出しの有効化、フォーマット、無効化について、メッセージ履歴のガイダンスとトラブルシューティングとともに説明します。

デフォルトでは、Claudeは1回のレスポンスで複数のツールを呼び出すことがあります。このページでは、それらの呼び出しを実行する方法、並列性が機能し続けるようにメッセージ履歴をフォーマットする方法、そして必要に応じて「parallel tool use」(並列ツール使用)を無効化する方法について説明します。単一呼び出しのフローについては、ツール呼び出しの処理を参照してください。

実行セマンティクス

Claudeがツールを呼び出すと、レスポンスの stop_reasontool_use になり、1回のアシスタントターンに複数の tool_use ブロックが含まれることがあります。それらの呼び出しをどのように実行するかはあなた次第です。APIは実行順序を規定しません。呼び出しを並行して実行する(Promise.allasyncio.gather)ことも、出現順に逐次実行することも、ツールに適した任意の組み合わせで実行することもできます。

ツールが何を行うかに基づいて戦略を選択してください。独立した読み取り専用の操作は、通常、レイテンシを下げるために並列実行しても安全です。副作用、共有状態、または順序要件を持つツールは、逐次実行する方がよい場合があります。

どの戦略を使用する場合でも、各 tool_use ブロックに対して1つの tool_result を返し、それらをすべて次のユーザーメッセージにまとめてください。各結果を 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."
}

コンピュータ使用ツールブラウザ使用ツールはより厳格です。Claudeが1回のターンでそれらのメンバーツール呼び出しを複数返した場合(バッチアクション)、出現順に逐次実行し、最初の失敗で停止してください。スキップした呼び出しに対して返すべき正確なテキストは、各ツールで定義されています。

並列ツール呼び出しのテスト

次のスクリプトは、並列ツール呼び出しをトリガーするはずのリクエストを送信し、レスポンスにそれらが含まれていることを検証し、並列性が機能し続けるようにツール結果をフォーマットします。環境に ANTHROPIC_API_KEY を設定して実行してください:

client = Anthropic()

# ツールを定義
tools = [
    {
        "name": "get_weather",
        "description": "Get the current weather in a given location",
        "input_schema": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "The city and state, e.g. San Francisco, CA",
                }
            },
            "required": ["location"],
        },
    },
    {
        "name": "get_time",
        "description": "Get the current time in a given timezone",
        "input_schema": {
            "type": "object",
            "properties": {
                "timezone": {
                    "type": "string",
                    "description": "The timezone, e.g. America/New_York",
                }
            },
            "required": ["timezone"],
        },
    },
]

# 並列ツール呼び出しを含む会話をテスト
messages = [
    {
        "role": "user",
        "content": "What's the weather in SF and NYC, and what time is it there?",
    }
]

# 最初のリクエストを送信
print("Requesting parallel tool calls...")
response = client.messages.create(
    model="claude-opus-5", max_tokens=1024, messages=messages, tools=tools
)

# 並列ツール呼び出しを確認
tool_uses = [block for block in response.content if block.type == "tool_use"]
print(f"\n✓ Claude made {len(tool_uses)} tool calls")

if len(tool_uses) > 1:
    print("✓ Parallel tool calls detected!")
    for tool in tool_uses:
        print(f"  - {tool.name}: {tool.input}")
else:
    print("✗ No parallel tool calls detected")

# ツール実行をシミュレートし、結果を正しくフォーマット
tool_results = []
for tool_use in tool_uses:
    if tool_use.name == "get_weather":
        if "San Francisco" in str(tool_use.input):
            result = "San Francisco: 68°F, partly cloudy"
        else:
            result = "New York: 45°F, clear skies"
    else:  # get_time
        if "Los_Angeles" in str(tool_use.input):
            result = "2:30 PM PST"
        else:
            result = "5:30 PM EST"

    tool_results.append(
        {"type": "tool_result", "tool_use_id": tool_use.id, "content": result}
    )

# ツール結果を使って会話を継続
messages.extend(
    [
        {"role": "assistant", "content": response.content},
        {"role": "user", "content": tool_results},  # All results in one message!
    ]
)

# 最終レスポンスを取得
print("\nGetting final response...")
final_response = client.messages.create(
    model="claude-opus-5", max_tokens=1024, messages=messages, tools=tools
)

final_text = next(
    block.text for block in final_response.content if block.type == "text"
)
print(f"\nClaude's response:\n{final_text}")

# フォーマットを検証
print("\n--- Verification ---")
print(f"✓ Tool results sent in single user message: {len(tool_results)} results")
print("✓ No text before tool results in content array")
print("✓ Conversation formatted correctly for future parallel tool use")

末尾のサマリー行は、並列性を機能させ続けるための2つのフォーマットルールを再確認しています。すべてのツール結果は単一のユーザーメッセージで返すこと、そしてそのメッセージ内でツール結果より前にテキストコンテンツを置かないことです。

並列ツール使用の最大化

Claude 4以降のモデルは、リクエストが複数のツールから恩恵を受ける場合、デフォルトで並列ツール呼び出しを行います。すべてのモデルにおいて、的を絞ったプロンプトによって並列ツール呼び出しの可能性を高めることができます:

並列ツール使用の無効化

並列ツール使用はデフォルトで有効です。無効にするには、tool_choice オブジェクト内に disable_parallel_tool_use: true を設定します。これはトップレベルのリクエストパラメータではありません。効果は tool_choice のタイプによって異なります。

最大1回のツール呼び出し

tool_choice のタイプが auto(デフォルト)の場合、disable_parallel_tool_use: true を設定すると、Claudeは1回のレスポンスにつき最大1つのツールを呼び出します。Claudeはツールを呼び出さずにプレーンテキストで回答することもできます。ハイライトされた行が、標準的なツール使用リクエストからの唯一の変更点です:

client = Anthropic()

response = client.messages.create(
    model="claude-opus-5",
    max_tokens=1024,
    tools=[
        {
            "name": "get_weather",
            "description": "Get the current weather in a given location",
            "input_schema": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA",
                    }
                },
                "required": ["location"],
            },
        }
    ],
    tool_choice={"type": "auto", "disable_parallel_tool_use": True},
    messages=[
        {
            "role": "user",
            "content": "What is the weather in San Francisco and New York?",
        }
    ],
)
print(response.content)

ちょうど1回のツール呼び出し

tool_choice のタイプが any または tool の場合、disable_parallel_tool_use: true を設定すると、Claudeはちょうど1つのツールを呼び出します。Claude Fable 5.1とClaude Mythos 5.1はこれらの tool_choice タイプをサポートしていません(ツール使用の強制を参照)。次の例では any を使用しています。同じフィールドは tool でも機能します:

client = Anthropic()

response = client.messages.create(
    model="claude-opus-5",
    max_tokens=1024,
    tools=[
        {
            "name": "get_weather",
            "description": "Get the current weather in a given location",
            "input_schema": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA",
                    }
                },
                "required": ["location"],
            },
        }
    ],
    tool_choice={"type": "any", "disable_parallel_tool_use": True},
    messages=[
        {
            "role": "user",
            "content": "What is the weather in San Francisco and New York?",
        }
    ],
)
print(response.content)

トラブルシューティング

Claudeが期待どおりに並列ツール呼び出しを行わない場合は、以下のよくある問題を確認してください:

1. ツール結果のフォーマットが正しくない

最もよくある問題は、会話履歴内でツール結果を誤ってフォーマットしていることです。これはClaudeに並列呼び出しを避けるよう「教えて」しまいます。

特に並列ツール使用については:

  • 誤り: ツール結果ごとに別々のユーザーメッセージを使用する
  • 正しい: すべてのツール結果を単一のユーザーメッセージにまとめる
// Wrong: separate user messages reduce parallel tool use
[
  {"role": "assistant", "content": [tool_use_1, tool_use_2]},
  {"role": "user", "content": [tool_result_1]},
  {"role": "user", "content": [tool_result_2]}  // Separate message
]

// Correct: one user message with all results maintains parallel tool use
[
  {"role": "assistant", "content": [tool_use_1, tool_use_2]},
  {"role": "user", "content": [tool_result_1, tool_result_2]}  // Single message
]

その他のフォーマットルールについては、ツール呼び出しの処理を参照してください。

2. プロンプトが弱い

デフォルトのプロンプトでは不十分な場合があります。並列ツール使用の最大化にある、より強力なシステムプロンプトを使用してください。

3. 並列ツール使用の測定

並列ツール呼び出しが機能していることを検証するには:

messages = []  # Message objects returned by client.messages.create across your run

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
)
print(f"Average tools per message: {avg_tools_per_message}")
# 並列呼び出しが機能していれば1.0より大きくなるはずです

4. バッチ内の呼び出しが互いに依存しているように見える

実行順序はあなたが選択できます。ツールに順序の依存関係がある場合、バッチを逐次実行して最初の失敗で停止するのは有効な戦略です(コンピュータ使用ツールとブラウザ使用ツールでは必須の戦略です)。実行しなかった呼び出しには is_error: true を返してください。並列実行していて、前提条件が完了していなかったために呼び出しが失敗した場合は、自然なエラーメッセージとともに is_error: true を返してください。Claudeは次のターンでその呼び出しを再発行します。依存関係のある呼び出しが一緒に現れるのを減らすには、システムプロンプトに次を追加してください:「Only batch tool calls that are independent of each other.」(互いに独立したツール呼び出しのみをバッチ処理してください。)

次のステップ

SDKのTool Runner抽象化を使用して、エージェントループ、エラーのラップ、型安全性を自動的に処理します。

tool_useブロックの解析、tool_resultレスポンスのフォーマット、is_errorによるエラー処理を行います。

ツールスキーマを指定し、効果的な説明を記述し、Claudeがツールを呼び出すタイミングを制御します。

Was this page helpful?