Aller au contenu principal

Gérer les blocs de messages

Mis à jour le 30 juillet 2026

Fonction prête, schéma prêt : il est temps d’envoyer notre premier outil à l’API et de regarder ce qui revient. Car avec les outils activés, les réponses de Claude changent de nature : au lieu d’un simple bloc de texte, le modèle peut retourner des messages multi-blocs, mêlant texte et demandes d’utilisation d’outil. Savoir lire — et surtout conserver — ces structures est le prérequis de toute la suite.

Activer les outils dans l’appel API

L’activation tient en un paramètre :

response = client.messages.create(
    model=model,
    max_tokens=1000,
    messages=messages,
    tools=[get_current_datetime_schema],
)

Le paramètre tools prend une liste de schémas JSON — ici un seul, notre schéma datetime. À partir de cet appel, Claude sait que l’outil existe, ce qu’il fait, et comment le remplir ; libre à lui de s’en servir si la conversation le justifie.

Messages multi-blocs

Posez maintenant une question qui exige l’outil — « quelle heure est-il ? » — et inspectez response.content. Au lieu de l’unique bloc habituel, la liste contient deux éléments :

  • Bloc TextBlock : texte explicatif (« Je vais chercher l’heure pour vous »)
  • Bloc ToolUse : instructions pour votre code avec l’ID de l’appel, le nom de la fonction, les paramètres, et le type "tool_use"

Les deux blocs jouent des rôles complémentaires. Le texte est destiné à l’humain — Claude annonce ce qu’il fait, et votre interface peut l’afficher pendant que l’outil s’exécute. Le bloc tool_use est destiné à votre code : c’est une demande structurée, avec un identifiant unique qui servira à apparier la réponse. Notez aussi le stop_reason du message, qui vaut "tool_use" : Claude s’est arrêté non parce qu’il avait fini, mais parce qu’il attend le résultat d’un outil pour continuer.

Préserver l’historique complet

Vient alors le point critique de cette leçon, celui qui cause le plus d’erreurs en pratique : il faut conserver la structure complète du contenu dans l’historique, tous blocs confondus.

messages.append({
    "role": "assistant",
    "content": response.content
})

On ajoute response.content tel quel — le bloc texte et le bloc tool use. La tentation existe d’extraire le texte et de ne garder que lui, comme dans les conversations simples ; elle casse tout. Le prochain message de la conversation contiendra le résultat de l’outil, qui référence l’identifiant du bloc tool_use — si ce bloc a disparu de l’historique, l’API rejette la requête : un résultat d’outil doit répondre à une demande d’outil présente dans le contexte. Conserver la structure intégrale n’est pas une précaution, c’est une exigence du protocole.

Flux complet

Cette mécanique s’insère dans un aller-retour dont voici le squelette :

  1. Envoyer le message utilisateur avec le schéma d’outil
  2. Recevoir un message assistant multi-blocs (texte + tool use)
  3. Extraire les informations d’appel d’outil et exécuter la fonction
  4. Renvoyer le résultat à Claude avec l’historique complet
  5. Recevoir la réponse finale

Les étapes 3 et 4 sont encore à construire — extraire les paramètres du bloc, appeler notre fonction Python, formater le résultat dans le message de retour. C’est exactement le programme des prochaines leçons, qui aboutira à la boucle de conversation automatisant l’ensemble.

Points clés à retenir

  • tools=[...] active les outils ; Claude décide ensuite seul de s’en servir
  • Une réponse à outil est multi-blocs : TextBlock pour l’humain, ToolUse pour votre code
  • stop_reason: "tool_use" signifie « j’attends un résultat d’outil pour continuer »
  • Ajoutez response.content entier à l’historique — supprimer le bloc tool_use fait rejeter la suite par l’API
  • Reste à implémenter l’exécution et le retour du résultat : objet des prochaines leçons