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 :
- L’utilisateur pose une question
- Claude decide s’il a besoin d’un outil
- Si oui : on execute l’outil et on renvoie le resultat
- Claude formule sa reponse (ou demande un autre outil)
- On affiche la reponse
- 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
- La boucle d’outils : continuez a faire des requetes tant que
stop_reason == "tool_use" - Historique complet : gardez l’integralite de la conversation (messages + tool_use + tool_result)
- Outils multiples dans une reponse : Claude peut demander plusieurs outils simultanement
- Choix intelligent : Claude n’utilise les outils que quand c’est pertinent
- 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.