Appel d'outils programmatique
Permettez à Claude d'appeler vos outils depuis du code dans le conteneur d'exécution de code, afin de réduire les allers-retours avec le modèle et la consommation de tokens dans les workflows multi-outils.
Le « programmatic tool calling » (appel d'outils programmatique) permet à Claude d'écrire du code qui appelle vos outils de manière programmatique au sein d'un conteneur d'exécution de code, plutôt que de nécessiter des allers-retours via le modèle pour chaque invocation d'outil. Cela réduit la « latency » (latence) pour les flux de travail multi-outils et diminue la consommation de tokens en permettant à Claude de filtrer ou de traiter les données avant qu'elles n'atteignent la « context window » (fenêtre de contexte) du modèle. Sur des benchmarks de recherche agentique comme BrowseComp et DeepSearchQA, qui testent la recherche web en plusieurs étapes et la récupération d'informations complexes, l'ajout de l'appel d'outils programmatique par-dessus des outils de recherche de base a amélioré les performances de 11 % en moyenne tout en utilisant 24 % de tokens d'entrée en moins (voir Improved web search with dynamic filtering).
Prenons l'exemple de la vérification de la conformité budgétaire de 20 employés : l'approche traditionnelle nécessite 20 allers-retours distincts avec le modèle, en injectant au passage des milliers de lignes de dépenses dans le contexte. Avec l'appel d'outils programmatique, un seul script exécute les 20 recherches, filtre les résultats et ne renvoie que les employés ayant dépassé leurs limites, réduisant ce sur quoi Claude doit raisonner de centaines de kilo-octets à une poignée de lignes.
L'appel d'outils programmatique nécessite l'outil d'exécution de code avec la version d'outil code_execution_20260120 ou ultérieure. Pour vérifier si un modèle prend en charge l'appel d'outils programmatique avant d'envoyer une requête, lisez sa valeur capabilities.code_execution.supported depuis l'API Models. La section Utiliser l'API Models décrit ce champ.
Démarrage rapide
Voici un exemple dans lequel Claude interroge une base de données plusieurs fois de manière programmatique et agrège les résultats. L'ajout de allowed_callers: ["code_execution_20260120"] à une définition d'outil est ce qui rend cet outil appelable depuis l'exécution de code (voir Le champ allowed_callers) :
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=4096,
messages=[
{
"role": "user",
"content": "Query sales data for the West, East, and Central regions, then tell me which region had the highest revenue",
}
],
tools=[
{"type": "code_execution_20260120", "name": "code_execution"},
{
"name": "query_database",
"description": "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.",
"input_schema": {
"type": "object",
"properties": {
"sql": {"type": "string", "description": "SQL query to execute"}
},
"required": ["sql"],
},
"allowed_callers": ["code_execution_20260120"],
},
],
)
print(response)La réponse s'arrête avec stop_reason: "tool_use", un ID de container et un bloc tool_use pour query_database dont le champ caller identifie l'exécution de code qui l'a appelé. Renvoyez le résultat comme indiqué à l'étape 3 de l'exemple de flux de travail afin que le code puisse se terminer.
Fonctionnement de l'appel d'outils programmatique
Lorsque vous configurez un outil pour qu'il soit appelable depuis l'exécution de code et que Claude détermine que cet outil est nécessaire :
- Claude écrit du code Python qui invoque l'outil comme une fonction, incluant potentiellement plusieurs appels d'outils et une logique de pré/post-traitement
- Claude exécute ce code dans un conteneur isolé (sandbox) via l'exécution de code
- Lorsqu'une fonction d'outil est appelée, l'exécution de code se met en pause et l'API renvoie un bloc
tool_use - Vous fournissez le résultat de l'outil, et l'exécution de code se poursuit (les résultats intermédiaires ne sont pas chargés dans la fenêtre de contexte de Claude)
- Une fois toute l'exécution de code terminée, Claude reçoit la sortie finale et continue à travailler sur la tâche
Cette approche est particulièrement utile pour :
- Le traitement de grands volumes de données : filtrer ou agréger les résultats d'outils avant qu'ils n'atteignent le contexte de Claude
- Les flux de travail en plusieurs étapes : économiser des tokens et de la latence en appelant des outils en série ou en boucle sans échantillonner Claude entre les appels d'outils
- La logique conditionnelle : prendre des décisions en fonction des résultats intermédiaires des outils
Concepts fondamentaux
Le champ allowed_callers
Le champ allowed_callers spécifie quels contextes peuvent invoquer un outil :
{
"name": "query_database",
"description": "Execute a SQL query against the database",
"input_schema": {
// ...
},
"allowed_callers": ["code_execution_20260120"]
}Valeurs possibles :
["direct"]- Claude est guidé pour appeler cet outil directement (valeur par défaut si omis)["code_execution_20260120"]- Claude est guidé pour appeler cet outil uniquement depuis l'exécution de code["direct", "code_execution_20260120"]- Claude peut appeler cet outil directement ou depuis l'exécution de code
"code_execution_20260120" et "code_execution_20260521" sont tous deux acceptés dans allowed_callers et sont interchangeables : une requête utilisant l'une ou l'autre version de l'outil d'exécution de code satisfait les outils qui listent l'un ou l'autre appelant. Les blocs de réponse étiquettent toujours l'appelant comme code_execution_20260120, quelle que soit la version déclarée dans la requête.
Le champ caller dans les réponses
Chaque bloc d'utilisation d'outil inclut un champ caller indiquant comment il a été invoqué :
Invocation directe (utilisation d'outils traditionnelle) :
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "query_database",
"input": { "sql": "<sql>" },
"caller": { "type": "direct" }
}Invocation programmatique :
{
"type": "tool_use",
"id": "toolu_xyz789",
"name": "query_database",
"input": { "sql": "<sql>" },
"caller": {
"type": "code_execution_20260120",
"tool_id": "srvtoolu_abc123"
}
}Le tool_id est l'id du bloc server_tool_use d'exécution de code qui a effectué l'appel, ce qui vous permet d'associer chaque tool_use programmatique à l'exécution de code qui l'a produit.
Cycle de vie du conteneur
L'appel d'outils programmatique utilise les mêmes conteneurs que l'exécution de code :
- Création du conteneur : un nouveau conteneur est créé pour chaque requête, sauf si vous en réutilisez un existant
- ID du conteneur : renvoyé dans les réponses dans le champ
container, accompagné d'un horodatageexpires_at - Réutilisation : transmettez l'ID du conteneur lors de la requête suivante pour conserver l'état. Pendant qu'un appel d'outil programmatique attend votre résultat, l'ID du conteneur est obligatoire sur cette requête, et non facultatif : l'API rejette la requête s'il est absent.
- Expiration :
expires_atvous indique combien de temps il reste au conteneur. Les conteneurs inactifs sont actuellement récupérés après environ 5 minutes, et aucun conteneur ne peut être réutilisé plus de 30 jours après sa création.
Exemple de flux de travail
Voici comment fonctionne un flux complet d'appel d'outils programmatique :
Étape 1 : requête initiale
Envoyez une requête avec l'exécution de code et un outil qui autorise l'appel programmatique. Pour activer l'appel programmatique, ajoutez le champ allowed_callers à votre définition d'outil.
La forme de la requête est identique à celle de l'exemple de Démarrage rapide : incluez code_execution dans votre liste d'outils, ajoutez allowed_callers: ["code_execution_20260120"] à tout outil que vous souhaitez que Claude invoque depuis le code, et envoyez votre message utilisateur. Les étapes restantes de ce flux de travail utilisent le message utilisateur "Query customer purchase history from the last quarter and identify our top 5 customers by revenue".
Étape 2 : réponse de l'API avec appel d'outil
Claude écrit du code qui appelle votre outil. L'API se met en pause et renvoie :
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll query the purchase history and analyze the results."
},
{
"type": "server_tool_use",
"id": "srvtoolu_abc123",
"name": "code_execution",
"input": {
"code": "import json\n\nrows = json.loads(await query_database({'sql': '<sql>'}))\ntop_customers = sorted(rows, key=lambda x: x['revenue'], reverse=True)[:5]\nprint(f'Top 5 customers: {top_customers}')"
}
},
{
"type": "tool_use",
"id": "toolu_def456",
"name": "query_database",
"input": { "sql": "<sql>" },
"caller": {
"type": "code_execution_20260120",
"tool_id": "srvtoolu_abc123"
}
}
],
"container": {
"id": "container_xyz789",
"expires_at": "2026-01-20T14:30:00Z"
},
"stop_reason": "tool_use"
}Étape 3 : fournir le résultat de l'outil
Envoyez l'historique complet de la conversation ainsi que votre résultat d'outil. Trois détails importent pour cette requête :
- Le message utilisateur qui transporte votre résultat ne peut contenir que des blocs
tool_result. Consultez Restrictions de formatage des messages. - Transmettez l'ID de
containerde la réponse en pause. L'API rejette une continuation qui comporte des appels d'outils programmatiques en attente mais aucun ID de conteneur. - Envoyez le même tableau
toolsque dans la requête d'origine. L'outil d'exécution de code doit toujours être présent pour que le code en pause reprenne, et les outils que vous envoyez dans cette requête sont les définitions que Claude et le code en cours d'exécution peuvent utiliser pour le reste du tour.
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=4096,
container="container_xyz789", # Reuse the container
messages=[
{
"role": "user",
"content": "Query customer purchase history from the last quarter and identify our top 5 customers by revenue",
},
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll query the purchase history and analyze the results.",
},
{
"type": "server_tool_use",
"id": "srvtoolu_abc123",
"name": "code_execution",
"input": {"code": "..."},
},
{
"type": "tool_use",
"id": "toolu_def456",
"name": "query_database",
"input": {"sql": "<sql>"},
"caller": {
"type": "code_execution_20260120",
"tool_id": "srvtoolu_abc123",
},
},
],
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_def456",
"content": '[{"customer_id": "C1", "revenue": 45000}, {"customer_id": "C2", "revenue": 38000}, ...]',
}
],
},
],
# Même tableau d'outils que dans la requête d'origine.
tools=[
{"type": "code_execution_20260120", "name": "code_execution"},
{
"name": "query_database",
"description": "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.",
"input_schema": {
"type": "object",
"properties": {
"sql": {"type": "string", "description": "SQL query to execute"}
},
"required": ["sql"],
},
"allowed_callers": ["code_execution_20260120"],
},
],
)
print(response)Étape 4 : appel d'outil suivant ou achèvement
Le code reprend là où il s'était mis en pause et traite votre résultat. Chaque réponse de continuation soit se met à nouveau en pause avec d'autres blocs tool_use programmatiques, soit termine l'exécution de code et laisse Claude poursuivre le tour (étape 5). Vérifiez stop_reason et le caller de chaque bloc tool_use pour distinguer les deux cas : une réponse qui se met en pause pour vous a stop_reason: "tool_use" et un bloc tool_use dont le caller désigne une version d'exécution de code, et vous répétez l'étape 3 avec un tool_result pour chaque appel programmatique en attente dans un seul message utilisateur.
Étape 5 : réponse finale
Une fois l'exécution de code terminée, Claude fournit la réponse finale :
{
"content": [
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "code_execution_result",
"stdout": "Top 5 customers: [{'customer_id': 'C1', 'revenue': 45000}, {'customer_id': 'C2', 'revenue': 38000}, {'customer_id': 'C5', 'revenue': 32000}, {'customer_id': 'C8', 'revenue': 28500}, {'customer_id': 'C3', 'revenue': 24000}]",
"stderr": "",
"return_code": 0,
"content": []
}
},
{
"type": "text",
"text": "I've analyzed the purchase history from last quarter. Your top 5 customers generated $167,500 in total revenue, with Customer C1 leading at $45,000."
}
],
"stop_reason": "end_turn"
}Modèles avancés
Traitement par lots avec des boucles
Claude peut écrire du code qui traite efficacement plusieurs éléments :
regions = ["West", "East", "Central", "North", "South"]
results = {}
for region in regions:
rows = json.loads(await query_database({"sql": f"<sql for {region}>"}))
results[region] = sum(row["revenue"] for row in rows)
# Traiter les résultats par programmation
top_region = max(results.items(), key=lambda x: x[1])
print(f"Top region: {top_region[0]} with ${top_region[1]:,} in revenue")Ce modèle :
- Réduit les allers-retours avec le modèle de N (un par région) à 1
- Traite de grands ensembles de résultats de manière programmatique avant de revenir à Claude
- Économise des tokens en ne renvoyant que des conclusions agrégées au lieu de données brutes
Arrêt anticipé
Claude peut arrêter le traitement dès que les critères de réussite sont remplis :
endpoints = ["us-east", "eu-west", "apac"]
for endpoint in endpoints:
status = await check_health({"endpoint": endpoint})
if status == "healthy":
print(f"Found healthy endpoint: {endpoint}")
break # Stop early, don't check remainingSélection conditionnelle d'outils
path = "/tmp/example.txt"
file_info = json.loads(await get_file_info({"path": path}))
if file_info["size"] < 10000:
content = await read_full_file({"path": path})
else:
content = await read_file_summary({"path": path})
print(content)Filtrage des données
server_id = "srv-01"
log_text = await fetch_logs({"server_id": server_id})
errors = [line for line in log_text.splitlines() if "ERROR" in line]
print(f"Found {len(errors)} errors")
for error in errors[-10:]: # Only return last 10 errors
print(error)Format de réponse
Appel d'outil programmatique
Lorsque l'exécution de code appelle un outil :
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "query_database",
"input": { "sql": "<sql>" },
"caller": {
"type": "code_execution_20260120",
"tool_id": "srvtoolu_xyz789"
}
}Gestion du résultat de l'outil
Votre résultat d'outil est retransmis au code en cours d'exécution :
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_abc123",
"content": "[{\"customer_id\": \"C1\", \"revenue\": 45000, \"orders\": 23}, {\"customer_id\": \"C2\", \"revenue\": 38000, \"orders\": 18}, ...]"
}
]
}Achèvement de l'exécution de code
Lorsque tous les appels d'outils sont satisfaits et que le code se termine :
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_xyz789",
"content": {
"type": "code_execution_result",
"stdout": "Analysis complete. Top 5 customers identified from 847 total records.",
"stderr": "",
"return_code": 0,
"content": []
}
}Gestion des erreurs
Erreurs courantes
| Erreur | Où elle apparaît | Description | Solution |
|---|---|---|---|
invalid_tool_input | error_code sur le bloc d'erreur code_execution_tool_result dans la réponse | Des paramètres invalides ont été transmis à l'outil d'exécution de code | Consultez les erreurs de l'outil d'exécution de code |
invalid_request_error (sur tool_choice) | Réponse d'erreur HTTP 400 | tool_choice désigne un outil dont allowed_callers n'inclut pas "direct" | Ajoutez "direct" aux allowed_callers de cet outil, ou retirez l'outil de tool_choice et laissez Claude l'invoquer depuis le code |
Expiration du conteneur pendant un appel d'outil
Si votre résultat d'outil n'arrive pas dans un délai d'environ 4 minutes, l'appel en attente lève une TimeoutError dans le code en cours d'exécution de Claude. Claude voit l'erreur dans stderr et réessaie généralement l'appel :
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "code_execution_result",
"stdout": "",
"stderr": "TimeoutError: Calling tool ['query_database'] timed out (no response after 270s).",
"return_code": 0,
"content": []
}
}Pour éviter les expirations :
- Surveillez le champ
expires_atdans les réponses - Implémentez des délais d'expiration pour l'exécution de vos outils
- Envisagez de découper les opérations longues en morceaux plus petits
Erreurs d'exécution des outils
Si votre outil renvoie une erreur :
{
"type": "tool_result",
"tool_use_id": "toolu_abc123",
"content": "Error: Query timeout - table lock exceeded 30 seconds"
}Le code de Claude reçoit cette erreur et peut la gérer de manière appropriée.
Contraintes et limitations
Incompatibilités de fonctionnalités
- Sorties structurées : les outils avec
strict: truene sont pas pris en charge avec l'appel programmatique - Choix d'outil : vous ne pouvez pas forcer l'appel programmatique d'un outil spécifique via
tool_choice - Utilisation d'outils en parallèle :
disable_parallel_tool_use: truen'est pas pris en charge avec l'appel programmatique
Limitations du schéma d'entrée
Les outils personnalisés dont l'input_schema contient un $ref récursif (un cycle de références, comme un schéma qui se référence lui-même) ne peuvent pas être activés pour l'appel programmatique. Inclure une version de l'outil d'exécution de code dans allowed_callers pour un tel outil fait échouer la requête avec une erreur 400 invalid_request_error dont le message contient Circular $ref detected. Le même schéma est accepté pour l'appel d'outil direct.
Pour contourner ce problème, effectuez l'une des actions suivantes :
- Conservez l'outil en mode direct uniquement en omettant
allowed_callers(ou en le définissant sur["direct"]). Les autres outils de la même requête peuvent toujours utiliser l'appel programmatique. - Supprimez le cycle du schéma. Par exemple, déroulez la récursion jusqu'à une profondeur fixe et décrivez toute imbrication plus profonde dans la
descriptiondu niveau le plus interne, ou remplacez la propriété récursive par un simple{"type": "object"}dont ladescriptionexplique la forme attendue.
Restrictions sur les outils
Les outils suivants ne peuvent pas être appelés de manière programmatique :
- Les outils fournis par un connecteur MCP
- Les ensembles d'outils computer use et browser use (
computer_toolset_20260801etbrowser_toolset_20260801), dont le champallowed_callersn'accepte que"direct"
Restrictions de formatage des messages
Lorsque vous répondez à des appels d'outils programmatiques, des exigences de formatage strictes s'appliquent :
Réponses contenant uniquement des résultats d'outils : s'il existe des appels d'outils programmatiques en attente de résultats, votre message de réponse doit contenir uniquement des blocs tool_result. Vous ne pouvez inclure aucun contenu textuel, même après les résultats d'outils.
Invalide - Impossible d'inclure du texte lors de la réponse à des appels d'outils programmatiques :
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01",
"content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}]"
},
{ "type": "text", "text": "What should I do next?" }
]
}Valide - Uniquement des résultats d'outils lors de la réponse à des appels d'outils programmatiques :
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01",
"content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}]"
}
]
}Cette restriction ne s'applique que lors de la réponse à des appels d'outils programmatiques (exécution de code). Pour les appels d'outils classiques côté client, vous pouvez inclure du contenu textuel après les résultats d'outils.
Contenu de résultat d'outil textuel uniquement : le content de chaque tool_result qui répond à un appel programmatique doit être une chaîne ou des blocs text. Les images, documents et autres types de blocs de contenu sont rejetés.
Limites de débit
Les appels d'outils programmatiques sont soumis aux mêmes « rate limits » (limites de débit) que les appels d'outils classiques. Chaque appel d'outil depuis l'exécution de code compte comme une invocation distincte.
Valider les résultats d'outils avant utilisation
Lors de l'implémentation d'outils définis par l'utilisateur qui seront appelés de manière programmatique :
- Les résultats d'outils sont renvoyés sous forme de chaînes : ils peuvent contenir n'importe quel contenu, y compris des extraits de code ou des commandes exécutables susceptibles d'être traités par l'environnement d'exécution.
- Validez les résultats d'outils externes : si votre outil renvoie des données provenant de sources externes ou accepte des entrées utilisateur, soyez conscient des risques d'injection de code si la sortie est interprétée ou exécutée comme du code.
Efficacité en tokens
L'appel d'outils programmatique réduit la consommation de tokens de trois manières :
- Les résultats d'outils issus d'appels programmatiques ne sont pas ajoutés au contexte de Claude - seule la sortie finale du code l'est
- Le traitement intermédiaire se fait dans le code - le filtrage, l'agrégation et les autres transformations ne consomment pas de tokens du modèle
- Plusieurs appels d'outils dans une seule exécution de code - réduit la surcharge par rapport à des tours de modèle distincts
Par exemple, appeler 10 outils directement utilise environ 10 fois plus de tokens que de les appeler de manière programmatique et de renvoyer un résumé.
Dans les évaluations internes d'Anthropic sur un modèle Claude de production :
- Sur un benchmark d'agent de gestion de projet à 75 outils, l'activation de l'appel d'outils programmatique a réduit les tokens d'entrée facturés d'environ 38 % sans changement de la précision des tâches.
- Sur τ²-bench (domaines du transport aérien, du commerce de détail et des télécommunications), où chaque tour effectue un ou deux appels d'outils séquentiels, l'appel d'outils programmatique a laissé les scores inchangés et a coûté environ 8 % de plus. Les flux de travail séquentiels à appel unique n'en bénéficient pas.
- Sur l'ensemble du trafic API de production, les requêtes dont le tableau
toolscontient de 10 à 49 définitions d'outils constatent des économies de tokens typiques de 20 % à 40 % avec l'appel d'outils programmatique activé.
Les économies réelles varient selon la forme de la charge de travail. Consultez Quand utiliser l'appel programmatique.
Utilisation et tarification
L'appel d'outils programmatique utilise la même tarification que l'exécution de code. Consultez la tarification de l'exécution de code pour plus de détails.
Bonnes pratiques
Conception des outils
- Fournissez des descriptions de sortie détaillées : comme Claude désérialise les résultats d'outils dans le code, documentez le format (structure JSON et types de champs)
- Renvoyez des données structurées : le JSON ou d'autres formats lisibles par machine fonctionnent le mieux pour le traitement programmatique
- Gardez les réponses concises : ne renvoyez que les données nécessaires pour minimiser la surcharge de traitement
Quand utiliser l'appel programmatique
L'appel d'outils programmatique échange une petite surcharge fixe (démarrage du conteneur, génération du script) contre d'importantes économies sur les tokens de résultats d'outils et les allers-retours avec le modèle. La rentabilité de cet échange dépend de la forme de la charge de travail.
Bonne adéquation :
- Opérations de distribution ou parallèles sur de nombreux éléments (par exemple, vérifier 50 points de terminaison ou rechercher 20 enregistrements)
- Résultats d'outils volumineux pouvant être filtrés, agrégés ou résumés avant d'atteindre le contexte de Claude
- Recherche et récupération agentiques, où l'interrogation itérative et le filtrage des résultats dominent le flux de travail
Faible adéquation :
- Flux de travail strictement séquentiels où chaque appel dépend du raisonnement de Claude sur le résultat précédent, car le script ne peut pas éviter l'aller-retour avec le modèle dans ce cas
- Un petit nombre d'appels d'outils avec de petites réponses, en particulier au premier tour d'une conversation, où la surcharge du conteneur et du script peut dépasser les économies
- Outils nécessitant un retour immédiat de l'utilisateur entre les appels
En cas de doute, mesurez les tokens d'entrée facturés avec et sans allowed_callers sur un échantillon représentatif de votre trafic avant de l'activer largement.
Optimisation des performances
- Réutilisez les conteneurs lorsque vous effectuez plusieurs requêtes liées afin de conserver l'état
- Regroupez les opérations similaires dans une seule exécution de code lorsque c'est possible
Dépannage
Problèmes courants
invalid_request_error lors de la définition de tool_choice
tool_choicene peut pas désigner un outil dontallowed_callersomet"direct". Ajoutez"direct"auxallowed_callersde cet outil, ou retirez l'outil detool_choiceet laissez Claude l'invoquer depuis le code.
Expiration du conteneur
- Répondez à chaque appel d'outil programmatique bien avant l'horodatage
expires_atde la réponse en pause. Le code de Claude cesse d'attendre un résultat après environ 4 minutes, et les conteneurs inactifs sont actuellement récupérés après environ 5 minutes. - Envisagez d'implémenter une exécution d'outils plus rapide
Résultat d'outil mal analysé
- Assurez-vous que votre outil renvoie des données sous forme de chaîne que Claude peut désérialiser
- Fournissez une documentation claire du format de sortie dans la description de votre outil
Conseils de débogage
- Journalisez tous les appels d'outils et leurs résultats pour suivre le flux
- Vérifiez le champ
callerpour confirmer l'invocation programmatique - Surveillez les ID de conteneur pour garantir une réutilisation correcte
- Testez les outils indépendamment avant d'activer l'appel programmatique
Pourquoi l'appel d'outils programmatique fonctionne
Claude est entraîné sur de grandes quantités de code, donc présenter les outils comme des fonctions Python appelables lui permet d'exploiter cette force :
- Composition d'outils : les appels enchaînés, les boucles et les conditions sont du flux de contrôle Python ordinaire au lieu d'une série d'allers-retours avec le modèle
- Traitement des résultats : le code de Claude filtre et agrège les sorties d'outils volumineuses, ou les écrit dans des fichiers, et seule la sortie finale entre dans la fenêtre de contexte
- Latence : le modèle n'est pas rééchantillonné entre les appels d'outils au sein d'une même exécution de code
Implémentations alternatives
L'appel d'outils programmatique est un modèle généralisable qui peut également être implémenté sur votre propre infrastructure. Voici comment les approches se comparent :
Exécution directe côté client
Fournissez à Claude un outil d'exécution de code et décrivez les fonctions disponibles dans cet environnement. Lorsque Claude invoque l'outil avec du code, votre application l'exécute localement là où ces fonctions sont définies.
Avantages :
- Réarchitecture minimale de votre application
- Contrôle total sur l'environnement et les instructions
Inconvénients :
- Exécute du code non fiable en dehors d'une sandbox
- Les invocations d'outils peuvent être des vecteurs d'injection de code
À utiliser lorsque : votre application peut exécuter du code arbitraire en toute sécurité, vous souhaitez l'implémentation la plus légère, et l'offre gérée d'Anthropic ne correspond pas à vos besoins.
Exécution en sandbox autogérée
Même approche du point de vue de Claude, mais le code s'exécute dans un conteneur isolé avec des restrictions de sécurité (par exemple, aucune sortie réseau). Si vos outils nécessitent des ressources externes, vous aurez besoin d'un protocole pour exécuter les appels d'outils en dehors de la sandbox.
Avantages :
- Appel d'outils programmatique sûr sur votre propre infrastructure
- Contrôle total sur l'environnement d'exécution
Inconvénients :
- Complexe à construire et à maintenir
- Nécessite de gérer à la fois l'infrastructure et la communication inter-processus
À utiliser lorsque : la sécurité est critique et la solution gérée d'Anthropic ne correspond pas à vos exigences.
Exécution gérée par Anthropic
L'appel d'outils programmatique d'Anthropic est une version gérée de l'exécution en sandbox avec un environnement Python aux choix affirmés, optimisé pour Claude. Anthropic prend en charge la gestion des conteneurs, l'exécution du code et la communication sécurisée des invocations d'outils.
Avantages :
- Sûr et sécurisé par défaut
- Activé par une définition d'outil, sans infrastructure à exploiter
- Environnement et instructions optimisés pour Claude
Envisagez d'utiliser la solution gérée d'Anthropic si vous utilisez l'API Claude, Claude Platform sur AWS ou Microsoft Foundry. Sur Microsoft Foundry, l'appel d'outils programmatique nécessite un déploiement Hosted on Anthropic.
Conservation des données
L'appel d'outils programmatique repose sur l'infrastructure d'exécution de code et utilise les mêmes conteneurs sandbox. Les données des conteneurs, y compris les artefacts d'exécution et les sorties, sont conservées jusqu'à 30 jours.
Pour l'éligibilité ZDR de toutes les fonctionnalités, consultez API et conservation des données.
Étapes suivantes
Diffusez les entrées d'outils en streaming sans mise en mémoire tampon JSON côté serveur pour les applications sensibles à la latence.
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.
Connectez Claude à des outils et API externes. Découvrez où les outils s'exécutent, quand Claude les appelle et quel outil convient à votre tâche.
Spécifiez les schémas d'outils, rédigez des descriptions efficaces et contrôlez quand Claude appelle vos outils.
Compatibility
- Supported models
- Fable 5 and 5.1
- Mythos 5 and 5.1
- Opus 4.5, 4.6, 4.7, 4.8, 5, and 5.5
- Sonnet 4.5, 4.6, 5, and 5.5
- Haiku 5.5
- Supported platforms
- Claude API
- Claude Platform on AWS
- Microsoft Foundry1
- Sur Microsoft Foundry, l'appel d'outils programmatique nécessite un déploiement Hosted on Anthropic. ↩
- L'appel d'outils programmatique nécessite l'outil d'exécution de code avec la version d'outil
code_execution_20260120ou ultérieure. - Claude Haiku 4.5 accepte les versions d'outil
code_execution_20260120et ultérieures, mais ne prend pas en charge l'appel d'outils programmatique.
Was this page helpful?