Récapitulatif parlé — appuyez sur lecture pour suivre : la ligne lue reste en haut.
Vos workflows existants s'appuient sur de nombreuses technologies différentes — logiciels de gestion de projet, bases de données, fichiers. Claude ne peut pas simplement vérifier ces choses lui-même. À la place, il s'appuie sur des outils, qui donnent à Claude accès à des données externes et à des actions.
Ce qu'est un outil
En termes simples, un outil est une fonction que vous définissez et exposez à Claude. Vous décrivez ce qu'il fait et quelles entrées il prend, et Claude décide quand l'appeler.
Voici la chose clé à intérioriser : Claude n'exécute pas l'outil — votre code le fait. Le flux ressemble à ceci :
- Claude demande un appel d'outil.
- Votre code exécute la fonction.
- Le résultat revient à Claude, et il continue.
Comment les outils sont définis
Les outils sont des schémas JSON avec trois parties : un nom, une description et un schéma d'entrée. Vous les transmettez à Claude dans le corps de la requête sous forme de tableau tools.
La description est ce que Claude lit pour décider s'il faut appeler l'outil. Si vous écrivez une description vague, vous obtenez une mauvaise utilisation d'outil. C'est la première raison pour laquelle les agents dysfonctionnent ou ne saisissent pas les outils disponibles. Soyez spécifique.
Voici à quoi ressemble une définition d'outil :
{ "name": "lookup_building_code", "description": "Look up a specific building code section by its identifier. Returns the full text of that code section. ", "input_schema": { "type": "object", "properties": { "section": { "type": "string", "description": "The building code section to look up" } }, "required": ["section"] } }
Alors, que se passe-t-il quand nous l'utilisons ? Disons que nous envoyons à un agent un rapport de conformité. Au premier tour, Claude revient avec stop_reason: "tool_use" — c'est notre signal. Voici à quoi ressemble cette réponse :
An API response with stop_reason set to tool_use, containing a tool_use content block that names the tool and the input Claude wants to call it with
Notre boucle appelle lookup_building_code avec le paramètre que Claude a demandé, puis renvoie le résultat sous forme de résultat d'outil — un message utilisateur contenant un bloc tool_result lié à l'id de l'appel d'outil :
A user message containing a tool_result block with the tool_use_id and the looked-up building code text as its content
Et Claude continue. À ce stade, nous pouvons continuer à appeler des outils et renvoyer les résultats à Claude jusqu'à ce qu'il ait ce dont il a besoin.
Plusieurs outils : laisser Claude choisir
Un outil est utile, mais la partie intéressante est de donner à Claude plusieurs outils et de le regarder choisir lequel utiliser, dans quel ordre.
Imaginez ce scénario : vous préparez vos bagages pour un voyage de trois jours à Denver, et vous voulez à la fois la météo d'aujourd'hui et les prévisions pour les prochains jours. Nous déclarons donc deux outils au lieu d'un :
const tools = [ { name: "get_weather", description: "Get today's current weather for a city. ", input_schema: { type: "object", properties: { city: { type: "string", description: "The city to check" } }, required: ["city"] } }, { name: "get_forecast", description: "Get the weather forecast for the next few days for a city. ", input_schema: { type: "object", properties: { city: { type: "string", description: "The city to check" } }, required: ["city"] } } ];
La boucle est identique aux boucles d'agent que nous avons déjà vues. La seule nouvelle partie est une fonction runTool qui dispatche sur le nom de l'outil avec une instruction switch — ce bloc de code est simplement l'endroit où votre code s'exécute réellement :
function runTool(name, input) { switch (name) { case "get_weather": return getWeather(input. city); case "get_forecast": return getForecast(input. city); } }
while (true) { const response = await client. messages. create({ model: "claude-sonnet-4-6", max_tokens: 1024, messages, tools, });
if (response. stop_reason ! == "tool_use") { // Claude is done — this is the final answer break; }
messages. push({ role: "assistant", content: response. content });
const toolResults = response. content filter((block) => block. type === "tool_use") .map((block) => ({ type: "tool_result", tool_use_id: block. id, content: runTool(block. name, block. input), }));
messages. push({ role: "user", content: toolResults }); }
Et c'est tout le modèle. Vous voulez un troisième outil ? Ajoutez-le au tableau, ajoutez un cas au switch, et c'est fait.
Exécutez cela, et vous verrez Claude appeler get_weather puis get_forecast — parfois dans le même tour, parfois l'un après l'autre. Ensuite, il répond : emportez des couches, attendez-vous à des rafales de neige aujourd'hui, réchauffement au cours de la semaine.
Remarquez maintenant comment Claude a choisi. Il a lu les descriptions, mappé votre prompt à « la météo d'aujourd'hui » et « les prochains jours », et choisi le bon outil pour chacun. C'est pourquoi vos descriptions d'outil sont vraiment importantes.
Le lanceur d'outil : ignorer le code passe-partout
Vous avez probablement déjà repéré deux drapeaux rouges dans ce que nous venons d'écrire :
- C'est beaucoup de code pour deux simples recherches.
- Dans une véritable base de code, vous ne voulez pas écrire à la main des schémas JSON pour chaque fonction que vous avez. C'est comme écrire votre code deux fois.
C'est là que le lanceur d'outil intervient. Il est livré dans le SDK Claude pour TypeScript, Python et Ruby. Le lanceur prend vos fonctions réelles, lit les types et la documentation pour construire le schéma pour vous, et gère toute la boucle d'utilisation d'outil / résultat d'outil en interne.
Votre code se réduit à : décrire l'outil, envoyer le prompt, attendre le résultat. Voici la même démo météo à deux outils câblée via le lanceur d'outil :
// The same two lookups we ran by hand — just plain TypeScript functions function getWeather(city: string) { // ... existing lookup }
function getForecast(city: string) { // ... existing lookup }
const runner = client. beta. messages. toolRunner({ model: "claude-sonnet-4-6", max_tokens: 1024, messages: [ { role: "user", content: "I'm packing for a three-day trip to Denver. What's the weather today and over the next few days? ", }, ], tools: [getWeather, getForecast], });
// Returns the final assistant message after all the tool ping-pong has settled const finalMessage = await runner. untilDone();
Même scénario, une fraction du code :
- Pas de boucle while, pas de commutateur de raison d'arrêt, pas de poussée manuelle des résultats d'outil dans les messages — le lanceur gère tout cela.
- Pas de schémas JSON, donc vous n'écrivez pas les choses deux fois.
- Les deux fonctions sont les mêmes recherches que nous avons exécutées à la main il y a une minute, juste du TypeScript simple.
- runner. untilDone() retourne le message assistant final une fois que tout s'est stabilisé.
Exécutez-le, et vous obtenez la même réponse.
Les vrais outils enveloppent votre code existant
En réalité, vos outils ne seraient pas des données météorologiques codées en dur. Ils envelopperaient des fonctions réelles que vous avez déjà dans votre application.
Prenez un agent d'examen de conformité : ses outils sont des wrappers minces autour de fonctions lookup_building_code et search_building_code qui existent déjà dans la base de code. Avec le lanceur d'outil, vous transmettez ces fonctions directement, et l'agent cite des sections de code spécifiques dans chaque constatation qu'il rédige — aucune écriture de schéma requise :
A compliance review app showing a structural report alongside agent findings, each flagged item citing the specific building code section it checked
Résumé
- **Les outils donnent à Claude accès à vos systèmes. ** Un outil est une fonction que vous définissez et exposez ; Claude décide quand l'appeler, et votre code l'exécute.
- Les outils sont des schémas JSON avec un nom, une description et un schéma d'entrée, transmis dans la requête sous forme de tableau tools.
- **Écrivez des descriptions spécifiques. ** Les descriptions vagues sont la première raison pour laquelle les agents dysfonctionnent.
- stop_reason: "tool_use" est votre signal pour exécuter l'outil et renvoyer le résultat sous forme de résultat d'outil.
- Pour plusieurs outils, dispatchez sur le nom de l'outil. Ajouter un outil signifie ajouter au tableau et ajouter un cas.
- Le lanceur d'outil du SDK (TypeScript, Python, Ruby) construit des schémas à partir de vos fonctions réelles et gère toute la boucle — ou vous pouvez exécuter la boucle vous-même.
- Vous exécutez, ou vous déléguez la boucle. À l'extrémité de ce spectre, les agents gérés délèguent l'agent entier à Anthropic.