Aller au contenu principal

Envoyer les résultats d'outil

Mis à jour le 30 juillet 2026

Claude a demandé un appel d’outil, l’historique conserve sa demande : reste la moitié active du protocole — exécuter la fonction et renvoyer les résultats. C’est l’objet de cette leçon, et à sa fin, la boucle sera bouclée : l’utilisateur aura sa réponse, fondée sur la vraie sortie de notre fonction Python.

Exécuter la fonction

Première étape : transformer le bloc tool_use en appel de fonction réel.

tool_use_block = response.content[1]
input_params = tool_use_block.input
result = get_current_datetime(**input_params)

On récupère le bloc dans le contenu de la réponse — ici en position 1, après le bloc de texte — puis ses arguments dans input. Le double astérisque (**) décompresse le dictionnaire en arguments nommés : {"date_format": "%H:%M"} devient get_current_datetime(date_format="%H:%M"). Les arguments générés par le modèle épousent ainsi la signature de la fonction sans qu’on les recopie un à un.

Bloc de résultat d’outil

Le résultat repart vers Claude via un bloc d’un type nouveau, tool_result, avec trois champs :

  • tool_use_id : doit correspondre à l’ID du bloc tool_use original
  • content : la sortie de votre fonction, convertie en chaîne
  • is_error : true si une erreur s’est produite

Le tool_use_id est la pièce maîtresse : c’est lui qui apparie le résultat à la demande. Claude peut demander plusieurs outils en une seule réponse — chaque bloc a un ID unique, et vous devez les associer correctement dans vos résultats : un identifiant croisé, et le modèle raisonnera sur des données attribuées au mauvais outil. Quant à is_error, il officialise ce que nous préparions dès l’écriture des fonctions : une exception ne s’arrête pas dans votre code, elle se transmet — message d’erreur en content, is_error à true — et Claude pourra se corriger.

Envoyer la requête de suivi

Le bloc s’insère dans un message utilisateur — du point de vue de l’API, le résultat d’outil est une information que vous apportez à Claude :

messages.append({
    "role": "user",
    "content": [{
        "type": "tool_result",
        "tool_use_id": response.content[1].id,
        "content": result,
        "is_error": False
    }]
})

Un piège attend ici les implémentations pressées : incluez toujours le schéma d’outil dans la requête de suivi, même si Claude n’aura probablement plus besoin d’appeler d’outils. Le modèle en a besoin pour comprendre les références aux outils présentes dans l’historique — un historique qui mentionne get_current_datetime sans que le schéma soit fourni le laisse face à des blocs inintelligibles, et l’API peut rejeter la requête.

Flux complet

L’aller-retour intégral, du premier message à la réponse finale :

  1. L’utilisateur pose une question nécessitant un outil
  2. Claude répond avec un bloc tool_use
  3. Vous exécutez la fonction demandée
  4. Vous envoyez une requête de suivi avec le résultat
  5. Claude fournit la réponse finale intégrant les données de l’outil

Chaque maillon est désormais implémenté à la main — et c’est volontairement laborieux : deux appels API, des blocs à extraire, des identifiants à apparier. La prochaine étape s’impose d’elle-même : automatiser cet enchaînement dans une boucle de conversation qui détecte les demandes d’outils, les exécute et renvoie les résultats sans intervention manuelle.

Points clés à retenir

  • **input_params décompresse les arguments générés par Claude dans la signature de votre fonction
  • Le bloc tool_result répond au tool_use : l’appariement se fait par tool_use_id, à ne jamais croiser
  • Les erreurs voyagent dans le protocole : message en content, is_error: true — Claude peut se rattraper
  • Le résultat s’envoie dans un message de rôle user, schémas d’outils toujours inclus
  • Le flux manuel maîtrisé, la suite logique est de l’automatiser en boucle — objet des prochaines leçons