Qu'est-ce que l'utilisation d'outils ?
Vos workflows existants reposent sur de nombreuses technologies différentes — logiciels de gestion de projet, bases de données, fichiers. Claude ne peut pas simplement vérifier ces éléments lui-même. Il s'appuie plutôt sur des outils, qui donnent à Claude accès à des données et des actions externes.
Qu'est-ce qu'un outil
En termes simples, un outil est une fonction que vous définissez et exposez à Claude. Vous décrivez ce qu'elle fait et quelles entrées elle prend, et Claude décide quand l'appeler.
Voici l'élément clé à intégrer : Claude n'exécute pas l'outil — c'est votre code qui le fait. Le flux se présente ainsi :
- Claude demande un appel d'outil.
- Votre code exécute la fonction.
- Le résultat revient à Claude, qui poursuit.
Comment les outils sont définis
Les outils sont des schémas JSON comportant 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 doit appeler l'outil. Si vous rédigez une description vague, vous obtenez une mauvaise utilisation d'outils. C'est la raison numéro un pour laquelle les agents se trompent ou ne saisissent pas les outils qui sont à leur disposition. Soyez précis.
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 lorsque nous utilisons cela ? 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 :

Notre boucle appelle lookup_building_code avec le paramètre demandé par Claude, 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 :

Et Claude continue. À ce stade, nous pouvons continuer à appeler des outils et à renvoyer des résultats à Claude jusqu'à ce qu'il ait ce dont il a besoin.
Plusieurs outils : laisser Claude choisir
Un seul outil est utile, mais la partie intéressante consiste à donner à Claude plusieurs outils et à observer lequel il choisit d'utiliser, et 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 du jour et les prévisions pour les jours suivants. 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. Le seul élément nouveau est une fonction runTool qui se répartit selon 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-5",
max_tokens: 1024,
messages,
tools,
});
if (response.stop_reason !== "tool_use") {
// Claude a terminé — c'est la réponse finale
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 schéma. Vous voulez un troisième outil ? Ajoutez-le au tableau, ajoutez un cas au switch, et c'est terminé.
Exécutez ceci, et vous verrez Claude appeler get_weather puis get_forecast — parfois dans le même tour, parfois l'un après l'autre. Puis il répond : prévoyez des couches, attendez-vous à des averses de neige aujourd'hui, avec un réchauffement au cours de la semaine.
Remarquez maintenant comment Claude a choisi. Il a lu les descriptions, a associé votre prompt à « la météo du jour » et « les prochains jours », et a choisi le bon outil pour chacun. C'est pourquoi vos descriptions d'outils comptent vraiment.
L'exécuteur d'outils : évitez le code répétitif
Vous avez probablement déjà repéré deux signaux d'alerte dans ce que nous venons d'écrire :
- C'est beaucoup de code pour deux simples recherches.
- Dans une base de code réelle, 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à qu'intervient l'exécuteur d'outils (tool runner). Il est disponible en version bêta dans les SDK Claude : TypeScript, Python, Ruby, C#, Go, Java et PHP. Vous définissez chaque outil une seule fois, et l'exécuteur gère en interne toute la boucle d'utilisation d'outils / résultat d'outil.
En TypeScript, l'assistant recommandé de l'exécuteur, betaZodTool(), décrit chaque outil avec un court schéma écrit en Zod, une bibliothèque TypeScript pour déclarer et valider la forme des données. L'assistant nécessite Zod 3.25.0 ou une version ultérieure, ce qu'une installation récente vous procure :
npm install zodVotre 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 l'exécuteur d'outils :
import { betaZodTool } from "@anthropic-ai/sdk/helpers/beta/zod";
import { z } from "zod";
// Encapsule les deux mêmes recherches effectuées manuellement, chacune avec un court schéma Zod.
const weatherTool = betaZodTool({
name: "get_weather",
description: "Get today's current weather for a city.",
inputSchema: z.object({
city: z.string().describe("The city to check"),
}),
run: async ({ city }) => getWeather(city),
});
const forecastTool = betaZodTool({
name: "get_forecast",
description: "Get the weather forecast for the next few days for a city.",
inputSchema: z.object({
city: z.string().describe("The city to check"),
}),
run: async ({ city }) => getForecast(city),
});
const runner = client.beta.messages.toolRunner({
model: "claude-sonnet-5",
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: [weatherTool, forecastTool],
});
// Attend le runner pour obtenir le message final une fois que tous les échanges d'outils se sont stabilisés.
const finalMessage = await runner;Même scénario, une fraction du code :
- Pas de boucle while, pas d'instruction switch sur la raison d'arrêt, pas de renvoi manuel des résultats d'outils dans les messages — l'exécuteur gère tout cela.
- Pas de schémas JSON écrits à la main, juste un court schéma Zod par outil, qui valide également l'entrée envoyée par Claude.
- Chaque fonction
runenveloppe la même recherche que nous avons effectuée manuellement il y a un instant. - Attendre l'exécuteur renvoie le message final de l'assistant une fois que tout s'est stabilisé.
Exécutez-le, et vous obtenez la même réponse.
Les outils réels enveloppent votre code existant
Dans la vraie vie, vos outils ne seraient pas des données météo codées en dur. Ils envelopperaient des fonctions réelles que vous avez déjà dans votre application.
Prenez un agent de révision de conformité : ses outils sont de minces enveloppes autour des fonctions lookup_building_code et search_building_code qui existent déjà dans la base de code. Avec l'exécuteur d'outils, vous enveloppez chacune de ces fonctions dans une courte définition d'outil avec son propre schéma Zod, et l'agent cite des sections de code spécifiques dans chaque constat qu'il rédige :

Récapitulatif
- 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. - Rédigez des descriptions précises. Les descriptions vagues sont la raison numéro un pour laquelle les agents se trompent.
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, répartissez selon le nom de l'outil. Ajouter un outil signifie l'ajouter au tableau et ajouter un cas.
- L'exécuteur d'outils du SDK (disponible en bêta dans tous les SDK Claude) gère toute la boucle, et en TypeScript chaque outil est une courte définition avec un schéma Zod. 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.