Les outils exécutés côté serveur partagent ces mécanismes : le bloc server_tool_use, la continuation pause_turn, les tours qui mélangent outils serveur et outils client, l'éligibilité à la « Zero Data Retention » (rétention zéro des données), ou ZDR, et le filtrage de domaines. Pour les outils individuels, consultez la référence des outils.
Le bloc server_tool_use apparaît dans la réponse de Claude lorsqu'un outil exécuté côté serveur s'exécute. Son champ id utilise le préfixe srvtoolu_ pour le distinguer des appels d'outils client :
{
"type": "server_tool_use",
"id": "srvtoolu_01A2B3C4D5E6F7G8H9",
"name": "web_search",
"input": { "query": "latest quantum computing breakthroughs" }
}L'API exécute l'outil en interne. Vous voyez l'appel et son résultat dans la réponse, mais vous ne gérez pas l'exécution. Contrairement aux blocs tool_use client, vous n'avez pas besoin de répondre avec un tool_result. Le bloc de résultat de l'outil (par exemple, web_search_tool_result pour la recherche web) suit le bloc server_tool_use dans le même tour de l'assistant, apparié par tool_use_id. Si Claude appelle l'un de vos outils client en même temps, le bloc server_tool_use apparaît sans son résultat, et la réponse se termine par stop_reason: "tool_use". L'API exécute l'outil lorsque vous renvoyez les blocs tool_result client dans votre requête suivante.
Lors de l'utilisation d'outils serveur tels que la recherche web, l'API exécute les appels d'outils dans une boucle agentique côté serveur. Sur un tour de longue durée, l'API peut mettre cette boucle en pause et renvoyer un stop_reason pause_turn.
Voici comment gérer le stop_reason pause_turn :
client = anthropic.Anthropic()
# Requête initiale avec recherche web
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}],
)
# Vérifier si la réponse a un stop_reason pause_turn
if response.stop_reason == "pause_turn":
# Poursuivre la conversation avec le contenu mis en pause
messages = [
{
"role": "user",
"content": "Search for comprehensive information about quantum computing breakthroughs in 2025",
},
{"role": "assistant", "content": response.content},
]
# Envoyer la requête de continuation
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)Lors de la gestion de pause_turn :
server_tool_use dont l'outil n'a pas encore été exécuté, et l'API renvoie une erreur de validation si cet outil est absent de la continuation.stop_reason sur chaque réponse et continuez jusqu'à obtenir un stop_reason différent, en plafonnant le nombre de continuations comme vous le feriez pour toute boucle de nouvelle tentative.Pour les autres valeurs de stop_reason et les modèles de gestion généraux, consultez Stop reasons et solutions de repli.
Claude peut appeler un outil serveur et un outil client dans le même groupe d'appels d'outils parallèles, par exemple web_fetch avec un outil défini par l'utilisateur. Un outil client est tout outil que votre code exécute et qui produit un bloc tool_use, qu'il soit défini par l'utilisateur ou qu'il s'agisse d'un outil client à schéma Anthropic tel que l'outil Bash. Lorsque cela se produit, l'API n'exécute pas l'outil serveur. Elle renvoie immédiatement afin que vous puissiez d'abord exécuter l'outil client :
stop_reason est "tool_use", et non "pause_turn".content contient le bloc server_tool_use et le bloc tool_use client, mais aucun bloc de résultat pour l'outil serveur : cet appel n'est pas terminé.server_tool_use dont l'id n'a pas de bloc de résultat correspondant dans la réponse. Un bloc mcp_tool_use provenant du connecteur MCP se comporte de la même manière. Les appels d'outils serveur qui ont déjà leur bloc de résultat dans la même réponse sont terminés et ne nécessitent rien de votre part.Avec l'appel d'outils programmatique, la même forme de réponse signifie quelque chose de différent. Le bloc tool_use client provient du code qui s'exécute dans l'outil code_execution plutôt que de Claude directement, et son champ caller nomme le bloc code_execution qui l'a appelé. Ce code a déjà démarré : il est en pause en attente de vos blocs tool_result, et les envoyer reprend l'exécution au lieu de démarrer un outil différé. Le propre bloc de résultat du bloc code_execution arrive une fois que le code se termine, ce qui peut nécessiter plus d'un aller-retour de résultats d'outils. Le message utilisateur de suivi lui-même est identique dans les deux cas ; avec l'appel d'outils programmatique, renvoyez également l'id du champ container de la réponse, comme le montre cette page.
{
"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" }
}
]
}Pour continuer le tour, exécutez les outils client et envoyez un message utilisateur dont le contenu est uniquement constitué des blocs tool_result, un pour chaque bloc tool_use de cette réponse. Conservez le même tableau tools : une requête de reprise qui ne définit plus l'outil serveur en attente échoue avec une erreur 400 dont le message se termine par but no `web_fetch` tool was provided.
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01PjgRJLbXrXEMZwDNYLnBqk",
"content": "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux"
}
]
}L'API attache vos résultats au tour de l'assistant toujours ouvert, exécute l'outil serveur différé (pour une exécution de code mise en pause, la reprend), puis laisse Claude continuer. Pour un outil serveur que Claude a appelé directement, la réponse suivante commence par le bloc de résultat qui répond à l'id du server_tool_use de la réponse précédente, suivi du contenu nouvellement généré et d'un nouveau 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..."
}
]
}Un bloc server_tool_use et son bloc de résultat sont appariés par tool_use_id, et non par position : dans ce flux, ils arrivent dans deux réponses différentes, et le bloc server_tool_use n'est pas répété dans la seconde. Lors des requêtes ultérieures, conservez l'ensemble de l'échange dans votre tableau messages dans l'ordre : la première réponse en tant que message assistant, le message utilisateur tool_result, puis la réponse suivante en tant qu'autre message assistant, de la même manière que vous accumulez tout autre échange d'utilisation d'outils.
Le message utilisateur de suivi ne doit contenir rien d'autre que des blocs tool_result. Un bloc ajouté après les résultats, tel que du texte, indique à l'API que le tour de l'assistant est terminé. Pour un outil serveur que Claude a appelé directement, cela laisse le tour avec un appel d'outil serveur non résolu, et la requête échoue avec une erreur 400 invalid_request_error :
`web_fetch` tool use with id `srvtoolu_01HxbWnMRmbWyMfUtJKC45rA` was found without a corresponding `web_fetch_tool_result` blockUn suivi qui place du contenu avant les résultats, ne répond qu'à certains des ID tool_use client, ou ne contient aucun bloc tool_result échoue plus tôt, avec l'erreur d'outil client décrite dans Gérer les appels d'outils :
`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.Pour fournir plus d'entrées à Claude, envoyez-les dans un message utilisateur distinct une fois le tour terminé.
En quoi cela diffère de pause_turn : Une réponse pause_turn peut également se terminer par un bloc server_tool_use qui n'a pas été exécuté, mais elle ne laisse jamais un bloc tool_use client en attente de votre part, donc vous la continuez en renvoyant le contenu de l'assistant tel quel. Une réponse qui laisse un bloc tool_use client en attente de votre part n'a jamais un stop_reason de pause_turn : lorsque Claude s'arrête pour appeler vos outils, stop_reason est tool_use, et vous la continuez en envoyant les blocs tool_result client plutôt qu'en renvoyant la réponse. Dans les deux cas, l'API exécute l'outil serveur en attente au début de la requête suivante.
L'exemple suivant active web fetch avec un outil run_command défini par l'utilisateur et gère la réponse mixte :
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,
# Exécutez votre outil ici. Cet exemple renvoie une chaîne fixe.
"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:
# Un bloc server_tool_use sans bloc de résultat dans cette réponse n'est pas terminé ; son résultat arrive dans une réponse ultérieure.
# Renvoyez uniquement les blocs tool_result client, avec les mêmes outils.
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},
],
)
# Si un web_fetch a été différé, il s'exécute lors de cette requête et son
# web_fetch_tool_result est le premier bloc de continuation.content.
print(continuation)
else:
print(response)Ce code est également correct lorsque Claude ne mélange pas les deux types d'appels. Un tour avec uniquement des blocs tool_use client emprunte le même chemin de continuation, et un tour avec uniquement des appels d'outils serveur ne nécessite aucun bloc tool_result client de votre part : ses blocs de résultat sont normalement déjà présents, et un tour qui revient suspendu, tel qu'une réponse pause_turn, est renvoyé tel quel à la place.
Les versions de base de la recherche web (web_search_20250305) et de web fetch (web_fetch_20250910) sont éligibles à la Zero Data Retention (ZDR).
Les versions _20260209 et ultérieures avec filtrage dynamique ne sont pas éligibles à la ZDR par défaut, car le filtrage dynamique repose en interne sur l'exécution de code.
Pour utiliser un outil serveur _20260209 ou ultérieur avec la ZDR, désactivez le filtrage dynamique en définissant "allowed_callers": ["direct"] sur l'outil :
{
"type": "web_search_20260209",
"name": "web_search",
"allowed_callers": ["direct"]
}Cela restreint l'outil à l'invocation directe uniquement, contournant l'étape interne d'exécution de code.
allowed_callers contrôle la manière dont un outil peut être invoqué : directement par Claude ("direct"), depuis l'intérieur d'un conteneur d'exécution de code (par exemple, "code_execution_20260120"), ou les deux. Les versions _20260209 des outils web utilisent par défaut uniquement l'appelant d'exécution de code ; les versions antérieures utilisent par défaut ["direct"]. Sur les modèles qui ne prennent pas en charge l'appel d'outils programmatique, ces versions nécessitent allowed_callers: ["direct"] ; sans cela, l'API renvoie une erreur de validation indiquant de le définir.
Même lorsque web fetch est utilisé dans une configuration éligible à la ZDR, les éditeurs de sites web peuvent conserver tous les paramètres passés à l'URL si Claude récupère du contenu depuis leur site.
Les outils serveur qui accèdent au web acceptent les paramètres allowed_domains et blocked_domains pour contrôler les domaines auxquels Claude peut accéder. Les deux sont des champs de l'objet outil :
{
"type": "web_search_20250305",
"name": "web_search",
"allowed_domains": ["example.com", "docs.python.org"]
}Lors de l'utilisation des filtres de domaines :
example.com au lieu de https://example.com).example.com couvre docs.example.com).docs.example.com renvoie uniquement les résultats de ce sous-domaine, et non de example.com ou api.example.com).example.com/blog correspond à example.com/blog/post-1).allowed_domains, soit blocked_domains, mais pas les deux dans la même requête.Prise en charge des caractères génériques :
*) ne sont pas autorisés dans le domaine lui-même, uniquement dans le chemin qui le suit.example.com/*, example.com/*/articles*.example.com, ex*.comLes formats de domaine invalides sont rejetés au moment de la requête avec une erreur 400 invalid_request_error.
Les restrictions de domaines au niveau de la requête fonctionnent conjointement avec toutes les restrictions de domaines au niveau de l'organisation configurées dans Claude Console. Les allowed_domains au niveau de la requête doivent être un sous-ensemble de la liste autorisée au niveau de l'organisation ; les entrées en dehors de celle-ci amènent l'API à renvoyer une erreur de validation. Les domaines que votre organisation bloque sont retirés d'une liste autorisée au niveau de la requête plutôt que de renvoyer une erreur.
Les caractères Unicode dans les noms de domaine peuvent contourner les filtres de domaines par des attaques homographes : аmazon.com (avec un а cyrillique) semble identique à amazon.com mais est un domaine différent. Utilisez des noms de domaine uniquement ASCII dans les listes d'autorisation et de blocage, et auditez les entrées existantes pour détecter les caractères non ASCII.
Les versions _20260209 et ultérieures de la recherche web et de web fetch utilisent l'exécution de code en interne pour appliquer des filtres dynamiques aux résultats de recherche.
Vous n'avez pas besoin d'ajouter un outil code_execution pour ces versions : lorsque le filtrage dynamique s'exécute, l'API provisionne automatiquement l'exécution de code pour la requête, et les deux outils partagent un seul conteneur d'exécution. Si vous en incluez un, utilisez code_execution_20260120 ou une version ultérieure ; l'API rejette les versions d'exécution de code plus anciennes aux côtés de ces versions d'outils web.
Les événements d'outils serveur sont diffusés dans le cadre du flux normal de « server-sent events » (événements envoyés par le serveur), ou SSE. Un bloc server_tool_use que Claude appelle directement est diffusé comme un bloc tool_use client : un événement content_block_start suivi d'événements input_json_delta. Le bloc de résultat arrive complet dans un seul événement content_block_start, sans deltas.
Consultez Streaming pour la référence complète des événements. Les pages des outils individuels documentent les noms d'événements spécifiques aux outils lorsqu'ils diffèrent.
Tous les outils serveur prennent en charge le traitement par lots. Dans un lot, la boucle agentique s'exécute exactement comme pour les requêtes synchrones, avec une limite d'itérations par tour plus élevée. Si la boucle atteint cette limite, la réponse se termine par stop_reason: "pause_turn" ; vous pouvez la continuer en soumettant une requête de suivi avec le contenu renvoyé. Consultez Outils serveur et boucle agentique pour plus de détails.
Les charges de travail par lots courantes incluent l'enrichissement d'un jeu de données avec des informations provenant du web, la vérification d'un grand ensemble de documents par rapport à des sources actuelles, et l'exécution de code d'analyse sur de nombreux fichiers.
Corrigez les erreurs d'utilisation d'outils les plus courantes grâce à des tableaux de diagnostic symptôme-solution.
Recherchez sur le web et citez les résultats.
Récupérez et lisez du contenu à partir d'URL spécifiques pour enrichir le contexte de Claude avec du contenu web en direct.
Exécutez du code Python et bash dans un conteneur isolé pour analyser des données, générer des fichiers et itérer sur des solutions.
Découvrez et chargez des outils à la demande.
Was this page helpful?