Aller au contenu principal

Chatbot avec plusieurs outils

Objectifs

  • Construire un chatbot complet avec plusieurs outils
  • Gerer une conversation multi-tours avec des appels d’outils
  • Implementer un agent conversationnel autonome

Architecture du chatbot

Nous allons construire un chatbot capable d’utiliser plusieurs outils dans une conversation continue. L’architecture suit une boucle :

  1. L’utilisateur pose une question
  2. Claude decide s’il a besoin d’un outil
  3. Si oui : on execute l’outil et on renvoie le resultat
  4. Claude formule sa reponse (ou demande un autre outil)
  5. On affiche la reponse
  6. Retour a l’etape 1

Definir plusieurs outils

Creons un assistant personnel avec trois outils :

import json
from datetime import datetime

# Fonctions des outils
def get_weather(city):
    """Simule une API meteo."""
    weather_data = {
        "Paris": {"temp": 18, "condition": "Nuageux"},
        "Lyon": {"temp": 22, "condition": "Ensoleille"},
        "Marseille": {"temp": 25, "condition": "Ensoleille"},
    }
    data = weather_data.get(city, {"temp": 15, "condition": "Inconnu"})
    return json.dumps(data, ensure_ascii=False)

def get_time(timezone="Europe/Paris"):
    """Retourne l'heure actuelle."""
    return datetime.now().strftime("%H:%M:%S")

def calculate(expression):
    """Evalue une expression mathematique."""
    try:
        result = eval(expression)  # Attention : eval est dangereux en production
        return str(result)
    except Exception as e:
        return f"Erreur : {e}"

# Definitions des outils
tools = [
    {
        "name": "get_weather",
        "description": "Recupere la meteo actuelle d'une ville francaise.",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {
                    "type": "string",
                    "description": "Le nom de la ville"
                }
            },
            "required": ["city"]
        }
    },
    {
        "name": "get_time",
        "description": "Retourne l'heure actuelle.",
        "input_schema": {
            "type": "object",
            "properties": {
                "timezone": {
                    "type": "string",
                    "description": "Le fuseau horaire (defaut: Europe/Paris)"
                }
            },
            "required": []
        }
    },
    {
        "name": "calculate",
        "description": "Evalue une expression mathematique.",
        "input_schema": {
            "type": "object",
            "properties": {
                "expression": {
                    "type": "string",
                    "description": "L'expression mathematique a evaluer (ex: '2 + 3 * 4')"
                }
            },
            "required": ["expression"]
        }
    }
]

# Mapping nom -> fonction
tool_functions = {
    "get_weather": lambda **kwargs: get_weather(kwargs["city"]),
    "get_time": lambda **kwargs: get_time(kwargs.get("timezone", "Europe/Paris")),
    "calculate": lambda **kwargs: calculate(kwargs["expression"]),
}

La boucle du chatbot

from anthropic import Anthropic

client = Anthropic()

def chatbot():
    """Chatbot interactif avec outils."""
    conversation = []
    system_prompt = """Vous etes un assistant personnel utile.
Vous avez acces a des outils pour la meteo, l'heure et les calculs.
Utilisez-les quand c'est pertinent, sinon repondez directement.
Repondez en francais."""

    print("Chatbot demarre ! Tapez 'quit' pour quitter.\n")

    while True:
        user_input = input("Vous : ")
        if user_input.lower() == "quit":
            print("Au revoir !")
            break

        # Ajouter le message utilisateur
        conversation.append({"role": "user", "content": user_input})

        # Envoyer a Claude
        response = client.messages.create(
            model="claude-sonnet-4-20250514",
            max_tokens=4096,
            system=system_prompt,
            tools=tools,
            messages=conversation
        )

        # Boucle d'outils : tant que Claude veut utiliser un outil
        while response.stop_reason == "tool_use":
            # Ajouter la reponse de Claude
            conversation.append({
                "role": "assistant",
                "content": response.content
            })

            # Executer chaque outil demande
            tool_results = []
            for block in response.content:
                if block.type == "tool_use":
                    print(f"  [Outil : {block.name}({block.input})]")
                    func = tool_functions[block.name]
                    result = func(**block.input)
                    tool_results.append({
                        "type": "tool_result",
                        "tool_use_id": block.id,
                        "content": result
                    })

            # Renvoyer les resultats
            conversation.append({
                "role": "user",
                "content": tool_results
            })

            # Nouvelle requete
            response = client.messages.create(
                model="claude-sonnet-4-20250514",
                max_tokens=4096,
                system=system_prompt,
                tools=tools,
                messages=conversation
            )

        # Afficher la reponse finale
        assistant_text = ""
        for block in response.content:
            if hasattr(block, "text"):
                assistant_text += block.text

        print(f"Claude : {assistant_text}\n")
        conversation.append({
            "role": "assistant",
            "content": response.content
        })

# Lancer le chatbot
chatbot()

Exemple de conversation

Vous : Quelle est la meteo a Paris et combien font 15% de 2500 ?
  [Outil : get_weather({"city": "Paris"})]
  [Outil : calculate({"expression": "2500 * 0.15"})]
Claude : Il fait actuellement 18 degres a Paris avec un ciel nuageux.
         Et 15% de 2500 font 375.

Vous : Merci ! Quelle heure est-il ?
  [Outil : get_time({})]
Claude : Il est actuellement 14:32:45.

Vous : Qui a ecrit Les Miserables ?
Claude : Les Miserables a ete ecrit par Victor Hugo, publie en 1862.

Notez que pour la derniere question, Claude repond directement sans utiliser d’outil, car aucun n’est necessaire.

Points cles a retenir

  1. La boucle d’outils : continuez a faire des requetes tant que stop_reason == "tool_use"
  2. Historique complet : gardez l’integralite de la conversation (messages + tool_use + tool_result)
  3. Outils multiples dans une reponse : Claude peut demander plusieurs outils simultanement
  4. Choix intelligent : Claude n’utilise les outils que quand c’est pertinent
  5. Reponse finale : quand Claude a toutes les infos, il formule une reponse textuelle naturelle

Exercice

Enrichissez le chatbot avec un quatrieme outil search_product qui recherche des produits dans un catalogue fictif. Le chatbot doit pouvoir repondre a des questions comme “Est-ce que vous avez des ecouteurs Bluetooth a moins de 50 euros ?”.

Voir un indice

Definissez un outil avec deux parametres : query (string) et max_price (number, optionnel). La fonction peut retourner une liste de produits fictifs filtres par prix.