Serverseitig ausgeführte Tools teilen sich diese Mechanismen: den server_tool_use-Block, die pause_turn-Fortsetzung, Turns, die Server- und Client-Tools mischen, die Eignung für „Zero Data Retention" (ZDR) und die Domain-Filterung. Für einzelne Tools siehe die Tool-Referenz.
Der server_tool_use-Block erscheint in Claudes Antwort, wenn ein serverseitig ausgeführtes Tool läuft. Sein id-Feld verwendet das Präfix srvtoolu_, um ihn von Client-Tool-Aufrufen zu unterscheiden:
{
"type": "server_tool_use",
"id": "srvtoolu_01A2B3C4D5E6F7G8H9",
"name": "web_search",
"input": { "query": "latest quantum computing breakthroughs" }
}Die API führt das Tool intern aus. Du siehst den Aufruf und sein Ergebnis in der Antwort, aber du kümmerst dich nicht um die Ausführung. Anders als bei Client-tool_use-Blöcken musst du nicht mit einem tool_result antworten. Der Ergebnisblock des Tools (zum Beispiel web_search_tool_result für die Websuche) folgt dem server_tool_use-Block im selben Assistant-Turn, verknüpft über tool_use_id. Wenn Claude gleichzeitig eines deiner Client-Tools aufruft, erscheint der server_tool_use-Block ohne sein Ergebnis, und die Antwort endet mit stop_reason: "tool_use". Die API führt das Tool aus, wenn du die Client-tool_result-Blöcke in deiner nächsten Anfrage zurückgibst.
Bei der Verwendung von Server-Tools wie der Websuche führt die API Tool-Aufrufe in einer serverseitigen agentischen Schleife aus. Bei einem lang laufenden Turn kann die API diese Schleife pausieren und einen pause_turn-Stop-Reason zurückgeben.
So handhabst du den pause_turn-Stop-Reason:
client = anthropic.Anthropic()
# Erste Anfrage mit Websuche
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
messages=[
{
"role": "user",
"content": "Search for comprehensive information about quantum computing breakthroughs in 2025",
}
],
tools=[{"type": "web_search_20250305", "name": "web_search", "max_uses": 10}],
)
# Prüfe, ob die Antwort den stop_reason pause_turn hat
if response.stop_reason == "pause_turn":
# Setze die Konversation mit dem pausierten Inhalt fort
messages = [
{
"role": "user",
"content": "Search for comprehensive information about quantum computing breakthroughs in 2025",
},
{"role": "assistant", "content": response.content},
]
# Sende die Fortsetzungsanfrage
continuation = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
messages=messages,
tools=[{"type": "web_search_20250305", "name": "web_search", "max_uses": 10}],
)
print(continuation)
else:
print(response)Beim Umgang mit pause_turn:
server_tool_use-Block enden, dessen Tool noch nicht ausgeführt wurde, und die API gibt einen Validierungsfehler zurück, wenn dieses Tool in der Fortsetzung fehlt.stop_reason bei jeder Antwort und fahre fort, bis du einen anderen Stop-Reason erhältst, wobei du die Anzahl der Fortsetzungen begrenzt, wie du es bei jeder Retry-Schleife tun würdest.Für die anderen stop_reason-Werte und allgemeine Handhabungsmuster siehe Stop-Reasons und Fallback.
Claude kann ein Server-Tool und ein Client-Tool in derselben Gruppe paralleler Tool-Aufrufe aufrufen, zum Beispiel web_fetch zusammen mit einem benutzerdefinierten Tool. Ein Client-Tool ist jedes Tool, das dein Code ausführt und das einen tool_use-Block erzeugt, unabhängig davon, ob es benutzerdefiniert ist oder ein Anthropic-Schema-Client-Tool wie das Bash-Tool. Wenn das passiert, führt die API das Server-Tool nicht aus. Sie kehrt sofort zurück, damit du zuerst das Client-Tool ausführen kannst:
stop_reason ist "tool_use", nicht "pause_turn".content enthält den server_tool_use-Block und den Client-tool_use-Block, aber keinen Ergebnisblock für das Server-Tool: dieser Aufruf ist nicht abgeschlossen.server_tool_use-Block suchst, dessen id keinen passenden Ergebnisblock in der Antwort hat. Ein mcp_tool_use-Block vom MCP-Connector verhält sich genauso. Server-Tool-Aufrufe, die ihren Ergebnisblock bereits in derselben Antwort haben, sind abgeschlossen und benötigen nichts von dir.Bei programmatischem Tool-Aufruf bedeutet dieselbe Antwortform etwas anderes. Der Client-tool_use-Block stammt von Code, der im code_execution-Tool läuft, und nicht direkt von Claude, und sein caller-Feld benennt den code_execution-Block, der ihn aufgerufen hat. Dieser Code hat bereits gestartet: Er ist pausiert und wartet auf deine tool_result-Blöcke, und das Senden dieser Blöcke setzt die Ausführung fort, anstatt ein aufgeschobenes Tool zu starten. Der eigene Ergebnisblock des code_execution-Blocks kommt an, sobald der Code fertig ist, was mehr als eine Runde von Tool-Ergebnissen dauern kann. Die nachfolgende User-Nachricht selbst ist in beiden Fällen dieselbe; bei programmatischem Tool-Aufruf übergib zusätzlich die id aus dem container-Feld der Antwort, wie auf jener Seite gezeigt.
{
"stop_reason": "tool_use",
"content": [
{
"type": "text",
"text": "I'll fetch the article and check your system at the same time."
},
{
"type": "server_tool_use",
"id": "srvtoolu_01HxbWnMRmbWyMfUtJKC45rA",
"name": "web_fetch",
"input": { "url": "https://example.com/article" }
},
{
"type": "tool_use",
"id": "toolu_01PjgRJLbXrXEMZwDNYLnBqk",
"name": "run_command",
"input": { "command": "uname -a" }
}
]
}Um den Turn fortzusetzen, führe die Client-Tools aus und sende eine User-Nachricht, deren Inhalt nur aus den tool_result-Blöcken besteht, einer für jeden tool_use-Block in dieser Antwort. Behalte dasselbe tools-Array bei: Eine Fortsetzungsanfrage, die das wartende Server-Tool nicht mehr definiert, schlägt mit einem 400-Fehler fehl, dessen Meldung mit but no `web_fetch` tool was provided endet.
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01PjgRJLbXrXEMZwDNYLnBqk",
"content": "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux"
}
]
}Die API hängt deine Ergebnisse an den noch offenen Assistant-Turn an, führt das aufgeschobene Server-Tool aus (bei pausierter Code-Ausführung setzt sie diese fort) und lässt Claude dann fortfahren. Für ein Server-Tool, das Claude direkt aufgerufen hat, beginnt die nächste Antwort mit dem Ergebnisblock, der die server_tool_use-id der vorherigen Antwort beantwortet, gefolgt vom neu generierten Inhalt und einem neuen stop_reason:
{
"stop_reason": "end_turn",
"content": [
{
"type": "web_fetch_tool_result",
"tool_use_id": "srvtoolu_01HxbWnMRmbWyMfUtJKC45rA",
"content": {
"type": "web_fetch_result",
"url": "https://example.com/article",
"content": {
"type": "document",
"source": {
"type": "text",
"media_type": "text/plain",
"data": "Full text content of the article..."
}
}
}
},
{
"type": "text",
"text": "The article argues that... and your machine is running Linux..."
}
]
}Ein server_tool_use-Block und sein Ergebnisblock werden über tool_use_id verknüpft, nicht über die Position: In diesem Ablauf kommen sie in zwei verschiedenen Antworten an, und der server_tool_use-Block wird in der zweiten nicht wiederholt. Behalte bei späteren Anfragen den gesamten Austausch in deinem messages-Array in der richtigen Reihenfolge: die erste Antwort als assistant-Nachricht, die tool_result-User-Nachricht und dann die nächste Antwort als weitere assistant-Nachricht, genauso wie du jeden anderen Tool-Nutzungs-Austausch akkumulierst.
Die nachfolgende User-Nachricht darf nichts außer tool_result-Blöcken enthalten. Ein Block, der nach den Ergebnissen hinzugefügt wird, wie etwa Text, teilt der API mit, dass der Assistant-Turn vorbei ist. Für ein Server-Tool, das Claude direkt aufgerufen hat, hinterlässt das den Turn mit einem ungelösten Server-Tool-Aufruf, und die Anfrage schlägt mit einem 400 invalid_request_error fehl:
`web_fetch` tool use with id `srvtoolu_01HxbWnMRmbWyMfUtJKC45rA` was found without a corresponding `web_fetch_tool_result` blockEine Folgeanfrage, die Inhalt vor die Ergebnisse setzt, nur einige der Client-tool_use-IDs beantwortet oder überhaupt keine tool_result-Blöcke enthält, schlägt früher fehl, mit dem Client-Tool-Fehler, der in Tool-Aufrufe handhaben beschrieben ist:
`tool_use` ids were found without `tool_result` blocks immediately after: toolu_01PjgRJLbXrXEMZwDNYLnBqk. Each `tool_use` block must have a corresponding `tool_result` block in the next message.Um Claude weitere Eingaben zu geben, sende sie als separate User-Nachricht, nachdem der Turn abgeschlossen ist.
Wie sich das von pause_turn unterscheidet: Eine pause_turn-Antwort kann ebenfalls mit einem server_tool_use-Block enden, der noch nicht ausgeführt wurde, aber sie hinterlässt nie einen Client-tool_use-Block, der auf dich wartet, also setzt du sie fort, indem du den Assistant-Inhalt unverändert erneut sendest. Eine Antwort, die einen Client-tool_use-Block hinterlässt, der auf dich wartet, hat nie einen stop_reason von pause_turn: Wenn Claude anhält, um deine Tools aufzurufen, ist stop_reason tool_use, und du setzt sie fort, indem du die Client-tool_result-Blöcke sendest, anstatt die Antwort erneut zu senden. In beiden Fällen führt die API das ausstehende Server-Tool zu Beginn der nächsten Anfrage aus.
Das folgende Beispiel aktiviert Web-Fetch zusammen mit einem benutzerdefinierten run_command-Tool und handhabt die gemischte Antwort:
client = anthropic.Anthropic()
tools = [
{"type": "web_fetch_20250910", "name": "web_fetch", "max_uses": 5},
{
"name": "run_command",
"description": "Run a shell command on this computer and return its output.",
"input_schema": {
"type": "object",
"properties": {
"command": {"type": "string", "description": "The command to run"}
},
"required": ["command"],
},
},
]
messages = [
{
"role": "user",
"content": "Summarize https://example.com/article and run uname -a to tell me what system this is on.",
}
]
response = client.messages.create(
model="claude-opus-4-8", max_tokens=1024, tools=tools, messages=messages
)
tool_results = [
{
"type": "tool_result",
"tool_use_id": block.id,
# Führe dein Tool hier aus. Dieses Beispiel gibt einen festen String zurück.
"content": "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux",
}
for block in response.content
if block.type == "tool_use"
]
if response.stop_reason == "tool_use" and tool_results:
# Ein server_tool_use-Block ohne Ergebnisblock in dieser Antwort ist nicht abgeschlossen; sein Ergebnis kommt in einer späteren Antwort.
# Sende nur die Client-tool_result-Blöcke zurück, mit denselben Tools.
continuation = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
tools=tools,
messages=[
*messages,
{"role": "assistant", "content": response.content},
{"role": "user", "content": tool_results},
],
)
# Wenn ein web_fetch zurückgestellt wurde, läuft er bei dieser Anfrage und sein
# web_fetch_tool_result ist der erste Block von continuation.content.
print(continuation)
else:
print(response)Dieser Code ist auch korrekt, wenn Claude die beiden Arten von Aufrufen nicht mischt. Ein Turn mit nur Client-tool_use-Blöcken nimmt denselben Fortsetzungspfad, und ein Turn mit nur Server-Tool-Aufrufen benötigt keine Client-tool_result-Blöcke von dir: Seine Ergebnisblöcke sind normalerweise bereits vorhanden, und einer, der ausgesetzt zurückkommt, wie eine pause_turn-Antwort, wird stattdessen unverändert erneut gesendet.
Die Basisversionen von Websuche (web_search_20250305) und Web-Fetch (web_fetch_20250910) sind für Zero Data Retention (ZDR) geeignet.
Die Versionen _20260209 und später mit dynamischer Filterung sind standardmäßig nicht ZDR-geeignet, da die dynamische Filterung intern auf Code-Ausführung basiert.
Um ein Server-Tool der Version _20260209 oder später mit ZDR zu verwenden, deaktiviere die dynamische Filterung, indem du "allowed_callers": ["direct"] für das Tool setzt:
{
"type": "web_search_20260209",
"name": "web_search",
"allowed_callers": ["direct"]
}Dies beschränkt das Tool auf direkten Aufruf und umgeht den internen Code-Ausführungsschritt.
allowed_callers steuert, wie ein Tool aufgerufen werden kann: direkt von Claude ("direct"), aus einem Code-Ausführungs-Container heraus (zum Beispiel "code_execution_20260120") oder beides. Die _20260209-Versionen der Web-Tools verwenden standardmäßig nur den Code-Ausführungs-Caller; frühere Versionen verwenden standardmäßig ["direct"]. Bei Modellen, die keinen programmatischen Tool-Aufruf unterstützen, erfordern diese Versionen allowed_callers: ["direct"]; ohne diese Angabe gibt die API einen Validierungsfehler zurück, der besagt, dass du sie setzen sollst.
Selbst wenn Web-Fetch in einer ZDR-geeigneten Konfiguration verwendet wird, können Website-Betreiber alle an die URL übergebenen Parameter speichern, wenn Claude Inhalte von ihrer Website abruft.
Server-Tools, die auf das Web zugreifen, akzeptieren die Parameter allowed_domains und blocked_domains, um zu steuern, welche Domains Claude erreichen kann. Beide sind Felder im Tool-Objekt:
{
"type": "web_search_20250305",
"name": "web_search",
"allowed_domains": ["example.com", "docs.python.org"]
}Bei der Verwendung von Domain-Filtern:
example.com statt https://example.com).example.com deckt docs.example.com ab).docs.example.com liefert nur Ergebnisse von dieser Subdomain, nicht von example.com oder api.example.com).example.com/blog matcht example.com/blog/post-1).allowed_domains oder blocked_domains verwenden, aber nicht beide in derselben Anfrage.Wildcard-Unterstützung:
*) sind in der Domain selbst nicht erlaubt, nur im Pfad danach.example.com/*, example.com/*/articles*.example.com, ex*.comUngültige Domain-Formate werden zur Anfragezeit mit einem 400 invalid_request_error abgelehnt.
Domain-Einschränkungen auf Anfrageebene arbeiten mit allen Domain-Einschränkungen auf Organisationsebene zusammen, die in der Claude Console konfiguriert sind. allowed_domains auf Anfrageebene müssen eine Teilmenge der auf Organisationsebene erlaubten Liste sein; Einträge außerhalb davon führen dazu, dass die API einen Validierungsfehler zurückgibt. Domains, die deine Organisation blockiert, werden aus einer auf Anfrageebene erlaubten Liste entfernt, anstatt einen Fehler zurückzugeben.
Unicode-Zeichen in Domain-Namen können Domain-Filter durch Homograph-Angriffe umgehen: аmazon.com (mit einem kyrillischen а) sieht identisch aus wie amazon.com, ist aber eine andere Domain. Verwende ausschließlich ASCII-Domain-Namen in Allow- und Block-Listen und überprüfe bestehende Einträge auf Nicht-ASCII-Zeichen.
Die Versionen _20260209 und später von Websuche und Web-Fetch verwenden intern Code-Ausführung, um dynamische Filter auf Suchergebnisse anzuwenden.
Du musst für diese Versionen kein code_execution-Tool hinzufügen: Wenn die dynamische Filterung läuft, stellt die API die Code-Ausführung für die Anfrage automatisch bereit, und beide Tools teilen sich einen einzigen Ausführungs-Container. Wenn du doch eines einfügst, verwende code_execution_20260120 oder später; die API lehnt ältere Code-Ausführungs-Versionen neben diesen Web-Tool-Versionen ab.
Server-Tool-Events werden als Teil des normalen „server-sent events" (SSE)-Ablaufs gestreamt. Ein server_tool_use-Block, den Claude direkt aufruft, wird wie ein Client-tool_use-Block gestreamt: ein content_block_start-Event gefolgt von input_json_delta-Events. Der Ergebnisblock kommt vollständig in einem einzigen content_block_start-Event an, ohne Deltas.
Siehe Streaming für die vollständige Event-Referenz. Einzelne Tool-Seiten dokumentieren tool-spezifische Event-Namen, wo sie abweichen.
Alle Server-Tools unterstützen Batch-Verarbeitung. In einem Batch läuft die agentische Schleife genauso wie bei synchronen Anfragen, mit einem höheren Iterationslimit pro Turn. Wenn die Schleife dieses Limit erreicht, endet die Antwort mit stop_reason: "pause_turn"; du kannst sie fortsetzen, indem du eine Folgeanfrage mit dem zurückgegebenen Inhalt sendest. Siehe Server-Tools und die agentische Schleife für Details.
Häufige Batch-Workloads umfassen das Anreichern eines Datensatzes mit Informationen aus dem Web, das Abgleichen einer großen Menge von Dokumenten mit aktuellen Quellen und das Ausführen von Analyse-Code über viele Dateien.
Behebe die häufigsten Tool-Nutzungs-Fehler mit Symptom-zu-Lösung-Diagnosetabellen.
Durchsuche das Web und zitiere Ergebnisse.
Rufe Inhalte von bestimmten URLs ab und lies sie, um Claudes Kontext mit Live-Webinhalten zu erweitern.
Führe Python- und Bash-Code in einem Sandbox-Container aus, um Daten zu analysieren, Dateien zu generieren und an Lösungen zu iterieren.
Entdecke und lade Tools bei Bedarf.
Was this page helpful?