Aller au contenu principal
Leçon 39 sur 95 · Construire avec l'API Claude

Utiliser plusieurs outils

Leçon 39 sur 95 Mis à jour le 5 novembre 2026 Développeur
Sur cette page
  1. Pourquoi trois outils plutôt qu’un
  2. Ajouter une durée à une date
  3. Enregistrer un rappel
  4. Les deux définitions
  5. Déclarer les outils
  6. L’essai du cours officiel
  7. La recette pour ajouter un outil
  8. À vous de jouer
  9. Points clés à retenir

La boucle de la leçon 38 est en place. Ajouter un outil ne demande plus de toucher à la logique de conversation : on écrit la fonction et sa définition, puis on les déclare. Cette leçon complète l’assistant de rappels avec ses deux derniers outils.

Pourquoi trois outils plutôt qu’un

On pourrait écrire un seul outil « programmer un rappel dans N jours ». Il devrait alors savoir quel jour on est, additionner des durées et enregistrer le rappel : trois responsabilités dans une fonction, et un schéma plus difficile à remplir correctement. Découpé en trois outils au périmètre net, chaque morceau fait une chose vérifiable, et Claude orchestre l’enchaînement.

La documentation met aussi en garde contre l’excès inverse. Pour des opérations très proches, par exemple ouvrir, relire et fusionner une pull request, mieux vaut un seul outil avec un paramètre action qu’une série d’outils presque identiques. Le bon découpage suit les responsabilités, pas les verbes.

Ajouter une durée à une date

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()]})"

Trois choix méritent d’être relevés :

  • datetime.fromisoformat accepte 2050-01-01 comme 2050-01-01 09:30:00 : Claude peut passer telle quelle la sortie par défaut de get_current_datetime.
  • Pour les mois et les années, la fonction ramène le jour au dernier jour du mois si besoin : un mois après le 31 janvier 2026, on obtient le 28 février.
  • Le résultat porte le jour de la semaine, calculé par le code. Sinon, Claude devrait le déduire de la date, c’est-à-dire refaire le calcul de calendrier que l’outil doit justement lui épargner.

Enregistrer un rappel

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}"

Dans une vraie application, reminders serait une table de base de données ou un service de notifications. La validation resterait la même : un rappel vide ou dans le passé est refusé, avec un message que Claude peut comprendre.

Les deux définitions

add_duration_to_datetime_schema = ToolParam({
    "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. Utilisez cet outil pour tout calcul d'échéance, au lieu de compter "
        "les jours vous-même. Les mois et les années tiennent compte de la longueur réelle des mois. "
        "Pour reculer dans le temps, passez une durée négative."
    ),
    "input_schema": {
        "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"],
    },
})

set_reminder_schema = ToolParam({
    "name": "set_reminder",
    "description": (
        "Enregistre un rappel pour l'utilisateur à une date et une heure données, et renvoie une confirmation. "
        "Utilisez 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."
    ),
    "input_schema": {
        "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"],
    },
})

Déclarer les outils

Deux ajouts suffisent : la liste des définitions passée à la boucle, et le dictionnaire du routeur.

TOOLS = {
    "get_current_datetime": get_current_datetime,
    "add_duration_to_datetime": add_duration_to_datetime,
    "set_reminder": set_reminder,
}

tool_schemas = [
    get_current_datetime_schema,
    add_duration_to_datetime_schema,
    set_reminder_schema,
]

L’essai du cours officiel

messages = []
add_user_message(
    messages,
    "Programme un rappel pour mon rendez-vous chez le médecin. C'est 177 jours après le 1er janvier 2050.",
)
final = run_conversation(messages, tools=tool_schemas)
177 jours après le 1er janvier 2050 Quatre étapes : la question, le calcul par add_duration_to_datetime (2050-06-27, un lundi), l'enregistrement par set_reminder, la confirmation de Claude. PLUSIEURS OUTILS 177 jours après le 1er janvier 2050 1 Question un rappel 177 jours après le 1er janvier 2050 2 Calcul add_duration_to_datetime : 2050-06-27 (lundi) 3 Rappel set_reminder à cette date 4 Réponse Claude confirme le rappel Le second appel dépend du premier : deux tours successifs, sans besoin de l'heure actuelle.
D'après la leçon « Using multiple tools » (Claude Academy, Building with the Claude API).

Claude n’a pas besoin de l’heure actuelle : la date de départ est dans la question. Il demande add_duration_to_datetime avec 2050-01-01 et 177 jours, et reçoit 2050-06-27 00:00:00 (lundi). Il demande ensuite set_reminder à cette date, puis confirme à l’utilisateur. Les deux appels se suivent sur deux tours, parce que le second dépend du premier. Selon la formulation, Claude peut aussi demander l’heure du rendez-vous avant d’enregistrer le rappel.

La recette pour ajouter un outil

  1. Écrire la fonction, avec ses validations.
  2. Écrire sa définition : nom, description de trois ou quatre phrases, schéma.
  3. Ajouter la définition à la liste des outils.
  4. Ajouter la fonction au dictionnaire TOOLS.

La boucle, run_tools et la gestion des erreurs ne changent pas. Le routeur est le seul endroit qui grandit avec le nombre d’outils : gardez-le réduit à ce rôle, sans logique métier, pour que chaque outil se teste isolément.

À vous de jouer

Un quatrième outil. Ajoutez list_reminders, qui renvoie les rappels enregistrés entre deux dates. Écrivez la fonction, sa définition et l’entrée du routeur, puis demandez à l’assistant : « Qu’est-ce que j’ai de prévu la semaine prochaine ? ». Vérifiez dans l’historique quels outils Claude a appelés, et dans quel ordre.

Sources officielles : Using multiple tools (Claude Academy) · Define tools (documentation Claude : regrouper les opérations proches)

Points clés à retenir

  • Une fois la boucle en place, ajouter un outil ne touche plus à la logique de conversation.
  • On découpe par responsabilité : savoir quand on est, calculer, agir ; on regroupe les opérations presque identiques.
  • Le code renvoie aussi ce que Claude devrait sinon déduire, comme le jour de la semaine.
  • La recette : fonction, définition, liste des outils, entrée du routeur.
  • 177 jours après le 1er janvier 2050 : le lundi 27 juin 2050, calculé par l’outil.