Standardmäßig kann Claude mehrere Tools in einer einzigen Antwort aufrufen. Diese Seite behandelt, wie du diese Aufrufe ausführst, wie du den Nachrichtenverlauf formatierst, damit die Parallelität weiterhin funktioniert, und wie du die parallele Tool-Nutzung deaktivierst, wenn du das brauchst. Für den Ablauf mit einem einzelnen Aufruf siehe Tool-Aufrufe verarbeiten.
Wenn Claude Tools aufruft, hat die Antwort einen stop_reason von tool_use und kann mehrere tool_use-Blöcke in einem einzigen Assistant-Turn enthalten. Wie du diese Aufrufe ausführst, ist deine Entscheidung. Die API schreibt keine Ausführungsreihenfolge vor: Du kannst die Aufrufe gleichzeitig ausführen (Promise.all, asyncio.gather), sequenziell in der Reihenfolge, in der sie erscheinen, oder in jeder Kombination, die zu deinen Tools passt.
Wähle die Strategie danach, was deine Tools tun. Unabhängige, schreibgeschützte Operationen können in der Regel sicher parallel ausgeführt werden, um die „latency" (Latenz) zu verringern. Tools mit Seiteneffekten, gemeinsamem Zustand oder Anforderungen an die Reihenfolge werden besser sequenziell ausgeführt.
Welche Strategie du auch verwendest, gib für jeden tool_use-Block ein tool_result zurück, alle zusammen in der nächsten User-Nachricht. Ordne jedes Ergebnis mit tool_use_id seinem Aufruf zu und platziere jeden tool_result-Block vor jeglichem Textinhalt in dieser Nachricht. Siehe Tool-Aufrufe verarbeiten für die vollständigen Formatierungsregeln. Wenn du dich entscheidest, einen bestimmten Aufruf nicht auszuführen (zum Beispiel, weil du den Batch sequenziell ausgeführt hast und ein früherer Aufruf fehlgeschlagen ist), gib trotzdem ein tool_result dafür zurück, mit is_error: true und einer kurzen Erklärung.
{
"type": "tool_result",
"tool_use_id": "toolu_02",
"is_error": true,
"content": "Not executed: the preceding write_file call failed."
}Das folgende Skript sendet eine Anfrage, die parallele Tool-Aufrufe auslösen sollte, überprüft, ob die Antwort sie enthält, und formatiert die Tool-Ergebnisse so, dass die Parallelität weiterhin funktioniert. Führe es mit gesetztem ANTHROPIC_API_KEY in deiner Umgebung aus:
client = Anthropic()
# Tools definieren
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"],
},
},
]
# Konversation mit parallelen Tool-Aufrufen testen
messages = [
{
"role": "user",
"content": "What's the weather in SF and NYC, and what time is it there?",
}
]
# Erste Anfrage stellen
print("Requesting parallel tool calls...")
response = client.messages.create(
model="claude-opus-5", max_tokens=1024, messages=messages, tools=tools
)
# Auf parallele Tool-Aufrufe prüfen
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-Ausführung simulieren und Ergebnisse korrekt formatieren
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}
)
# Konversation mit Tool-Ergebnissen fortsetzen
messages.extend(
[
{"role": "assistant", "content": response.content},
{"role": "user", "content": tool_results}, # All results in one message!
]
)
# Finale Antwort abrufen
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}")
# Formatierung überprüfen
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")Die Zusammenfassungszeilen am Ende wiederholen die beiden Formatierungsregeln, die die Parallelität aufrechterhalten: Jedes Tool-Ergebnis wird in einer einzigen User-Nachricht zurückgegeben, und in dieser Nachricht erscheint kein Textinhalt vor den Tool-Ergebnissen.
Claude 4 und spätere Modelle führen standardmäßig parallele Tool-Aufrufe aus, wenn eine Anfrage von mehreren Tools profitiert. Bei allen Modellen kannst du die Wahrscheinlichkeit paralleler Tool-Aufrufe durch gezieltes Prompting erhöhen:
Parallele Tool-Nutzung ist standardmäßig aktiviert. Um sie auszuschalten, setze disable_parallel_tool_use: true innerhalb des tool_choice-Objekts. Es ist kein Request-Parameter auf oberster Ebene. Die Wirkung hängt vom tool_choice-Typ ab.
Wenn der tool_choice-Typ auto ist (der Standard), bedeutet das Setzen von disable_parallel_tool_use: true, dass Claude höchstens ein Tool pro Antwort aufruft. Claude kann weiterhin in reinem Text antworten, ohne ein Tool aufzurufen. Die hervorgehobenen Zeilen sind die einzige Änderung gegenüber einer Standard-Tool-Nutzungs-Anfrage:
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)Wenn der tool_choice-Typ any oder tool ist, bedeutet das Setzen von disable_parallel_tool_use: true, dass Claude genau ein Tool aufruft. Das folgende Beispiel verwendet any. Dasselbe Feld funktioniert mit 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)Wenn Claude keine parallelen Tool-Aufrufe macht, obwohl du sie erwartest, überprüfe diese häufigen Probleme:
1. Falsche Formatierung der Tool-Ergebnisse
Das häufigste Problem ist die falsche Formatierung von Tool-Ergebnissen im Gesprächsverlauf. Das „lehrt" Claude, parallele Aufrufe zu vermeiden.
Speziell für parallele Tool-Nutzung:
// 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
]Siehe Tool-Aufrufe verarbeiten für weitere Formatierungsregeln.
2. Schwaches Prompting
Das Standard-Prompting reicht möglicherweise nicht aus. Verwende den stärkeren System-Prompt aus Parallele Tool-Nutzung maximieren.
3. Parallele Tool-Nutzung messen
Um zu überprüfen, ob parallele Tool-Aufrufe funktionieren:
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}")
# Sollte > 1.0 sein, wenn parallele Aufrufe funktionieren4. Aufrufe in einem Batch scheinen voneinander abzuhängen
Die Ausführungsreihenfolge ist deine Entscheidung. Wenn deine Tools Abhängigkeiten in der Reihenfolge haben, ist es eine gültige Strategie, den Batch sequenziell auszuführen und beim ersten Fehler zu stoppen: Gib is_error: true für jeden Aufruf zurück, den du nicht ausgeführt hast. Wenn du parallel ausführst und ein Aufruf fehlschlägt, weil seine Voraussetzung noch nicht abgeschlossen war, gib is_error: true mit der natürlichen Fehlermeldung zurück. Claude wird den Aufruf im nächsten Turn erneut ausgeben. Um zu reduzieren, dass abhängige Aufrufe zusammen erscheinen, füge dies zu deinem System-Prompt hinzu: "Only batch tool calls that are independent of each other."
Verwende die Tool-Runner-Abstraktion des SDK, um die agentische Schleife, das Einpacken von Fehlern und die Typsicherheit automatisch zu handhaben.
Parse tool_use-Blöcke, formatiere tool_result-Antworten und behandle Fehler mit is_error.
Spezifiziere Tool-Schemas, schreibe effektive Beschreibungen und steuere, wann Claude deine Tools aufruft.
Was this page helpful?