デフォルトでは、Claudeは1つの応答で複数のツールを呼び出すことがあります。このページでは、それらの呼び出しの実行方法、並列処理が機能し続けるようにメッセージ履歴をフォーマットする方法、および必要に応じて並列ツール使用を無効にする方法について説明します。単一呼び出しのフローについては、ツール呼び出しの処理を参照してください。
Claudeがツールを呼び出すと、応答のstop_reasonはtool_useとなり、1つのアシスタントターンに複数のtool_useブロックが含まれることがあります。これらの呼び出しをどのように実行するかは、あなたの判断に委ねられます。APIは実行順序を規定していません。呼び出しを並行して(Promise.all、asyncio.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."
}ほとんどのアプリケーションではTool Runnerを使用してください: SDKのTool Runnerは、複数のツール呼び出しを含む応答を処理し、結果をフォーマットしてくれるため、この処理を自分で記述する必要はありません。カスタムバッチ処理、順序付け、エラー処理など、呼び出しの実行方法を直接制御する必要がある場合は、このページの手動パターンを使用してください。
次のスクリプトは、並列ツール呼び出しをトリガーするはずのリクエストを送信し、応答にそれらが含まれていることを確認し、並列処理が機能し続けるようにツール結果をフォーマットします。環境に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-4-8", 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-4-8", 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つのフォーマットルールを再確認しています。すべてのツール結果は1つのユーザーメッセージで返され、そのメッセージ内でツール結果の前にテキストコンテンツが表示されないことです。
Claude 4モデルは、リクエストが複数のツールから恩恵を受ける場合、デフォルトで並列ツール呼び出しを行います。すべてのモデルにおいて、的を絞ったプロンプトによって並列ツール呼び出しの可能性を高めることができます。
並列ツール使用はデフォルトで有効になっています。無効にするには、tool_choiceオブジェクト内でdisable_parallel_tool_use: trueを設定してください。これはトップレベルのリクエストパラメータではありません。効果はtool_choiceのタイプによって異なります。
tool_choiceのタイプがauto(デフォルト)の場合、disable_parallel_tool_use: trueを設定すると、Claudeは応答ごとに最大1つのツールを呼び出します。Claudeはツールを呼び出さずにプレーンテキストで回答することもできます。ハイライトされた行が、標準的なツール使用リクエストからの唯一の変更点です。
client = Anthropic()
response = client.messages.create(
model="claude-opus-4-8",
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)tool_choiceのタイプがanyまたはtoolの場合、disable_parallel_tool_use: trueを設定すると、Claudeは正確に1つのツールを呼び出します。次の例ではanyを使用しています。同じフィールドはtoolでも機能します。
client = Anthropic()
response = client.messages.create(
model="claude-opus-4-8",
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は次のターンでその呼び出しを再発行します。依存する呼び出しが一緒に出現するのを減らすには、システムプロンプトに次を追加してください:「互いに独立したツール呼び出しのみをバッチ処理してください。」
SDKのTool Runner抽象化を使用して、エージェントループ、エラーラッピング、型安全性を自動的に処理します。
tool_useブロックを解析し、tool_result応答をフォーマットし、is_errorでエラーを処理します。
ツールスキーマを指定し、効果的な説明を記述し、Claudeがツールを呼び出すタイミングを制御します。
Was this page helpful?