Chargement

Conversations multi-tours avec des outils

Leçon 279 min

La construction de conversations multi-tours avec utilisation d'outils nécessite de gérer différents types de réponses de Claude. Lorsque Claude répond, il peut avoir besoin d'utiliser un outil, ou il peut fournir une réponse directe. Votre code doit gérer les deux scénarios de manière élégante.

Le problème avec l'intégration simple d'outils

Si vous ajoutez simplement des résultats d'outils à chaque conversation, vous rencontrerez des problèmes. Lorsque Claude répond à une question simple comme « Combien font 1+1 ? », il n'a besoin d'aucun outil. Mais si votre code essaie toujours de traiter des résultats d'outils, vous finirez par ajouter des messages vides à votre historique de conversation.

La solution consiste à vérifier le stop_reason qui revient avec chaque réponse de Claude. Cela vous indique pourquoi Claude a arrêté de générer - qu'il ait terminé naturellement ou parce qu'il souhaite utiliser un outil.

Raisons d'arrêt

Claude peut s'arrêter pour plusieurs raisons :

  • "tool_use" - Le modèle souhaite appeler un outil
  • "end_turn" - Le modèle a terminé de générer sa réponse
  • "max_tokens" - La limite de sortie a été atteinte
  • "stop_sequence" - Une séquence d'arrêt que vous avez fournie a été rencontrée

Amélioration de la fonction de chat

Tout d'abord, mettez à jour votre fonction de chat pour qu'elle renvoie plus d'informations. Au lieu de simplement renvoyer le texte et les parties séparément, renvoyez un dictionnaire avec tout ce dont vous avez besoin :

python
def chat(messages, tools=None, system=None, **kwargs):
    # ... code existant ...
    
    return {
        "parts": parts,
        "stop_reason": response["stopReason"],
        "text": "\n".join([p["text"] for p in parts if "text" in p])
    }

Cette approche extrait tout le contenu textuel des parties de la réponse, ce qui est plus robuste que de supposer que la première partie est toujours du texte.

Construction d'une boucle de conversation

Créez une fonction qui gère le flux complet de la conversation :

python
def run_conversation(messages):
    while True:
        result = chat(messages, tools=[get_current_datetime_schema])
        
        add_assistant_message(messages, result["parts"])
        print(result["text"])
        
        if result["stop_reason"] != "tool_use":
            break
            
        tool_result_parts = run_tools(result["parts"])
        add_user_message(messages, tool_result_parts)
    
    return messages

Cette boucle continue jusqu'à ce que Claude s'arrête pour une raison autre que l'utilisation d'un outil. Chaque itération :

  1. Envoie les messages actuels à Claude
  2. Ajoute la réponse de Claude à l'historique des messages
  3. Vérifie si Claude souhaite utiliser un outil
  4. Si oui, exécute les outils et ajoute les résultats à la conversation
  5. Si non, quitte la boucle

Test de l'implémentation

Cette approche gère à la fois les questions nécessitant des outils et les questions simples :

python
# Question nécessitant un outil
messages = []
add_user_message(messages, "What time is it?")
run_conversation(messages)

# Question simple
messages = []
add_user_message(messages, "What is 1+1?")
run_conversation(messages)

Pour les questions liées à l'heure, Claude utilisera l'outil datetime. Pour les questions mathématiques, il répond directement sans aucun appel d'outil. La boucle de conversation s'adapte automatiquement en fonction de la raison d'arrêt de Claude.

Ce modèle s'adapte bien lorsque vous ajoutez davantage d'outils - la même boucle gère toute combinaison d'utilisation d'outils et de réponses directes, rendant votre IA conversationnelle plus robuste et naturelle.