Ajouter plusieurs outils
Sur cette page
Un outil fonctionne ; ajoutons les deux autres pour terminer l’assistant de rappels : add_duration_to_datetime et set_reminder. Une fois la boucle en place, ajouter un outil se fait en deux gestes : une fonction et son schéma.
Les deux fonctions
Le cours officiel fournit ces fonctions dans son notebook. En voici une version complète, avec les validations de la leçon 23 :
import calendar
from datetime import datetime, timedelta
JOURS = ["lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"]
def add_duration_to_datetime(datetime_str, duration, unit="days"):
if not datetime_str:
raise ValueError("datetime_str ne peut pas être vide (format AAAA-MM-JJ ou AAAA-MM-JJ HH:MM:SS)")
start = datetime.fromisoformat(datetime_str)
if unit in ("seconds", "minutes", "hours", "days", "weeks"):
result = start + timedelta(**{unit: duration})
elif unit in ("months", "years"):
months = duration if unit == "months" else 12 * duration
index = start.month - 1 + months
year, month = start.year + index // 12, index % 12 + 1
day = min(start.day, calendar.monthrange(year, month)[1])
result = start.replace(year=year, month=month, day=day)
else:
raise ValueError(f"unité inconnue : {unit} (seconds, minutes, hours, days, weeks, months ou years)")
return f"{result:%Y-%m-%d %H:%M:%S} ({JOURS[result.weekday()]})"
reminders = []
def set_reminder(content, timestamp):
if not content:
raise ValueError("content ne peut pas être vide")
when = datetime.fromisoformat(timestamp)
if when <= datetime.now():
raise ValueError(f"la date du rappel est passée : {timestamp}")
reminders.append({"content": content, "timestamp": when})
return f"Rappel enregistré pour le {when:%Y-%m-%d à %H:%M} : {content}"
add_duration_to_datetime traite les mois et les années à part, car leur longueur varie : un mois après le 31 janvier tombe le 28 ou le 29 février. Elle renvoie aussi le jour de la semaine, qu’un modèle calcule mal de tête. set_reminder se contente ici de garder le rappel en mémoire ; dans une vraie application, elle écrirait dans un agenda ou une base.
Les deux schémas
add_duration_to_datetime_schema = {
"toolSpec": {
"name": "add_duration_to_datetime",
"description": (
"Ajoute une durée à une date et renvoie la date obtenue au format AAAA-MM-JJ HH:MM:SS, "
"suivie du jour de la semaine. Utilise cet outil pour tout calcul d'échéance, au lieu de compter "
"les jours toi-même. Les mois et les années tiennent compte de la longueur réelle des mois. "
"Pour reculer dans le temps, passe une durée négative."
),
"inputSchema": {
"json": {
"type": "object",
"properties": {
"datetime_str": {
"type": "string",
"description": "Date de départ au format ISO, par exemple 2050-01-01 ou 2050-01-01 09:30:00.",
},
"duration": {
"type": "integer",
"description": "Nombre d'unités à ajouter ; négatif pour reculer.",
},
"unit": {
"type": "string",
"enum": ["seconds", "minutes", "hours", "days", "weeks", "months", "years"],
"description": "Unité de la durée.",
},
},
"required": ["datetime_str", "duration", "unit"],
"additionalProperties": False,
}
},
}
}
set_reminder_schema = {
"toolSpec": {
"name": "set_reminder",
"description": (
"Enregistre un rappel pour l'utilisateur à une date et une heure données, et renvoie une confirmation. "
"Utilise cet outil quand l'utilisateur demande explicitement qu'on lui rappelle quelque chose, "
"après avoir calculé la date exacte avec les autres outils. "
"La date doit être dans le futur ; l'outil ne modifie ni ne supprime un rappel existant."
),
"inputSchema": {
"json": {
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "Texte du rappel, tel qu'il sera présenté à l'utilisateur.",
},
"timestamp": {
"type": "string",
"description": "Date et heure du rappel au format ISO, par exemple 2050-06-27 09:00:00.",
},
},
"required": ["content", "timestamp"],
"additionalProperties": False,
}
},
}
}
L’enum de unit ferme la liste des unités : Claude ne peut pas inventer « quinzaines ». Les descriptions disent quand utiliser chaque outil, y compris l’ordre attendu : calculer la date d’abord, poser le rappel ensuite.
Brancher les outils
Deux gestes : déclarer les fonctions dans l’aiguillage, et les schémas dans la liste d’outils.
TOOLS.update({
"add_duration_to_datetime": add_duration_to_datetime,
"set_reminder": set_reminder,
})
tools = [get_current_datetime_schema, add_duration_to_datetime_schema, set_reminder_schema]
messages = []
add_user_message(messages, "Rappelle-moi d'aller chez le médecin dans 100 jours.")
run_conversation(messages, tools)
Claude décompose seul la demande : il demande la date du jour, puis ajoute 100 jours, puis pose le rappel, en expliquant souvent son plan au passage. Chaque étape dépend de la précédente : ce sont trois tours de la boucle de la leçon 28.
À vous de jouer
Un rappel exigeant. Demandez : « Rappelle-moi de renouveler mon passeport trois mois avant le 31 mai 2027. » Suivez les outils appelés et vérifiez la date du rappel. Puis demandez un rappel dans le passé : comment Claude réagit-il à l’erreur de set_reminder ?
Sources officielles : Adding multiple tools (Claude Academy) · Use a tool to complete an Amazon Bedrock model response (documentation AWS)
Points clés à retenir
- Ajouter un outil : une fonction dans l’aiguillage, un schéma dans la liste d’outils.
- Les cas délicats (mois de longueur variable, jour de la semaine, date passée) se règlent dans le code de l’outil.
- Un
enumferme la liste des valeurs possibles d’un argument. - Claude enchaîne seul les outils dépendants, un tour de boucle par étape.