Outils et APIs (function calling)
Comment un agent LLM déclenche des actions réelles via des schémas d'outils typés, et comment sécuriser ces appels avec authentification et idempotence.
Table des matières
Pourquoi le function calling change la donne
Un modèle de langagegrand modèle de langageIAModèle entraîné à prédire le token suivant d'une séquence de texte. Toutes ses capacités apparentes — résumer, traduire, coder — découlent de cette unique tâche.Voir dans le glossaire seul ne fait que prédire du texte. Il ne peut ni consulter une base de donnéesdonnéesIAEnsemble d'informations structurées ou non utilisées pour entraîner, évaluer ou alimenter un modèle. La qualité, la quantité et la représentativité des données sont les facteurs décisifs pour les performances en apprentissage automatique.Voir dans le glossaire, ni envoyer un e-mail, ni vérifier un stock, ni déclencher un remboursement. Le function callingtool callingIACapacité d'un agent ou d'un LLM à invoquer des outils externes (API, calcul, recherche) pendant le raisonnement.Voir dans le glossaire (ou tool use) est le mécanisme qui comble cet écart : il permet au modèle de produire, au lieu d'une réponse en prose, un appel structuré — nom de fonction et arguments — que votre application intercepte, exécute contre un système réel, puis renvoie au modèle sous forme de résultat.
Ce déplacement change la nature du risque. Tant que le modèle ne fait que parler, l'erreur reste une phrase malheureuse. Dès qu'il déclenche des outils, une hallucinationhallucinationIAProduction par un modèle d'un énoncé faux formulé avec la même assurance qu'un fait établi. Le phénomène est structurel : le modèle optimise la vraisemblance, pas la vérité.Voir dans le glossaire peut devenir une commande passée par erreur, un fichier supprimé, ou une requête envoyée avec de mauvais paramètres. Ce chapitre traite le function callingappel d'outilsIAMécanisme par lequel un modèle produit un appel de fonction structuré que le code environnant décide d'exécuter. Le modèle n'a jamais d'accès direct : il propose, le code dispose.Voir dans le glossaire comme une interface entre un système probabiliste et un système transactionnel, avec toute la rigueur que cette frontière exige.
Le LLMLLMIAGrand modèle de langage (Large Language Model) entraîné sur d'énormes corpus pour prédire et générer du texte.Voir dans le glossaire ne se connecte à aucune API. Il produit une intention structurée (un objet JSON conforme au schéma déclaré). C'est votre code — la couche d'exécution — qui valide cet objet, l'authentifie, l'exécute et renvoie le résultat. Toute la sécurité du système repose sur cette couche intermédiaire, jamais sur la sagesse supposée du modèle.
Le mécanisme : du texte à l'appel structuré
Concrètement, vous déclarez au modèle un catalogue d'outils disponibles, chacun décrit par un schéma proche de JSON Schema : un nom, une description en langage naturel, et une liste de paramètres typés. Le modèle choisit alors, à chaque tour de génération, s'il répond directement ou s'il invoque un ou plusieurs outils pour obtenir l'information ou provoquer l'effet nécessaire.
Le point essentiel : le modèle ne produit pas du code exécutable, il produit un objet conforme à un contrat. C'est cette contrainte de format qui rend l'appel exploitable de façon fiable par un système classique, sans avoir à parser du texte libre.
Anatomie d'un cycle complet
Un appel d'outil traverse toujours les mêmes étapes, quelle que soit la plateforme (API Anthropic, OpenAI, frameworks d'agentsagentIASystème qui enchaîne des appels d'outils de façon autonome pour atteindre un objectif : il planifie, agit, observe, recommence. Sa fiabilité décroît exponentiellement avec le nombre d'étapes.Voir dans le glossaire type LangChain ou équivalents maison) :
- Déclaration — votre application envoie, avec le promptpromptIAConsigne ou contexte fourni à un modèle de langage pour orienter sa réponse. La qualité du prompt conditionne souvent la qualité du résultat.Voir dans le glossaire, la liste des outils disponibles et leurs schémas.
- Décision — le modèle décide s'il répond directement ou s'il invoque un outil ; il peut en invoquer plusieurs en parallèle.
- Émission — le modèle produit un bloc structuré : nom de l'outil + arguments au format JSON.
- Validation — votre code vérifie la conformité au schéma, l'autorisation de l'appelant, et la cohérence métier (un identifiant existe-t-il, une date est-elle plausible).
- Exécution — l'appel réel est effectué contre l'API ou le système cible, avec ses propres identifiants et scopes.
- Retour — le résultat (ou l'erreur) est réinjecté dans le contextefenêtre de contexteIAQuantité de texte qu'un modèle peut prendre en compte simultanément : question, documents fournis et historique. Au-delà, les éléments les plus anciens sortent du champ.Voir dans le glossaire de conversation comme un message de type résultat d'outil.
- Reprise — le modèle reprend la génération en tenant compte du résultat, et peut enchaîner un nouvel appel ou formuler la réponse finale.
Cette boucle peut se répéter plusieurs fois dans un même échange. C'est elle qui constitue la boucle agentique de base, avant même toute logique de planification plus élaborée.
Concevoir des schémas robustes
La qualité d'un schéma détermine directement la fiabilité des appels. Un schéma vague produit des arguments incohérents ; un schéma trop rigide bloque des cas légitimes. Quelques règles éprouvées :
- Types stricts plutôt que chaînes libres. Préférez un
enumà une chaîne libre dès que l'ensemble des valeurs possibles est fini (statut, devise, unité). Une chaîne libre invite le modèle à improviser une valeur plausible mais invalide. - Descriptions précises, pas décoratives. La description d'un paramètre n'est pas un commentaire de confort : c'est l'unique information dont dispose le modèle pour deviner le bon format.
date_debutaccompagné de « Date de début au format ISO 8601, ex. 2026-03-01 » réduit fortement les erreurs de format par rapport à un simpledate_debut: string. - Champs requis minimaux. Chaque champ marqué requis est un point de rejet potentiel. Si un paramètre peut raisonnablement avoir une valeur par défaut côté serveur, ne l'exposez pas comme requis.
- Un outil, une responsabilité. Un outil
gerer_commandequi accepte un modecreate|update|delete|canceldans un champ texte est plus fragile que quatre outils distincts, chacun avec son propre schéma restreint. La granularité fine facilite aussi les contrôles d'autorisation par outil. - Bornes explicites. Longueurs maximales, plages numériques (
minimum,maximum), formats (pattern) : tout ce que JSON Schema permet d'exprimer doit l'être, plutôt que délégué à une vérification a posteriori dans le code métier.
| Mauvaise pratique | Conséquence | Alternative |
|---|---|---|
Paramètre params: string en JSON libre |
Parsing fragile, erreurs silencieuses | Champs typés explicites dans le schéma |
| Pas de description sur les champs | Arguments plausibles mais faux | Description + exemple pour chaque champ |
| Un outil générique à tout faire | Impossible de restreindre les permissions finement | Un outil par action métier |
| Aucune limite de valeur | Injection de valeurs aberrantes (quantité négative, date absurde) | minimum, maximum, enum, pattern |
Un schéma d'outil doit être conçu avec le même soin qu'un endpoint REST public : versionné, documenté, testé avec des cas limites. Les équipes qui le traitent comme un détail d'implémentation interne accumulent une dette qui se paie en incidents de production.
Authentification et sécurité des appels
Une confusion fréquente consiste à donner au modèle, via le prompt ou un paramètre d'outil, un jeton d'authentification qu'il devrait transmettre lui-même. C'est une erreur de conception : le modèle ne doit jamais manipuler de secret.
Le bon découpageChunkingIADécoupage d'un document en segments de taille fixe ou sémantique avant indexation vectorielle, pour optimiser la récupération RAG.Voir dans le glossaire :
- L'identité de l'appelant (utilisateur final, agent de service) est résolue par votre application, en amont de l'appel au LLM, à partir de la session ou du jeton de la requête entrante.
- Les identifiants vers l'API cible (clé API, jeton OAuth) vivent exclusivement dans la couche d'exécution des outils, jamais dans le contexte envoyé au modèle, jamais comme argument de schéma.
- Le scope d'autorisation est appliqué avant l'exécution : même si le modèle demande une action, votre code vérifie que l'identité résolue a le droit de la réaliser sur la ressource visée.
Un modèle peut être manipulé par une injection de promptInjection de promptCybersécuritéAttaque visant à détourner un LLM en insérant des instructions malveillantes dans le contexte (entrée utilisateur, document RAG, etc.).Voir dans le glossaire pour tenter d'invoquer un outil hors de son périmètre légitime. Si l'unique barrière est « le modèle ne devrait pas faire ça », l'attaque réussit dès qu'un contenu malveillant (document, page web, e-mail) atteint le contexte. L'autorisation doit être vérifiée côté code, à chaque appel, indépendamment de ce que le modèle a « décidé ».
En pratique, cela signifie : un jeton dédié par outil ou par domaine fonctionnel, des scopes minimaux (principe du moindre privilège), et une liste blanche explicite d'outils autorisés par contexte d'exécution plutôt qu'une liste noire.
Idempotence et effets de bord
Un agent peut relancer un appel après une erreur réseau, un timeout, ou une reprise de session. Si l'outil déclenche un effet de bord (créer une commande, débiter un compte, envoyer une notification), rejouer l'appel sans précaution produit une duplication : deux commandes au lieu d'une, deux e-mails envoyés.
L'idempotence est la propriété qui garantit qu'un même appel, exécuté plusieurs fois avec les mêmes paramètres, produit le même état final sans effet cumulatif. Le mécanisme standard est la clé d'idempotence : un identifiant unique généré pour chaque intention d'action (pas pour chaque tentative réseau), transmis à l'API cible, qui l'utilise pour reconnaître et court-circuiter une exécution déjà traitée.
Un outil
creer_remboursementreçoitmontant,commande_id, et une cléidempotency_keygénérée une seule fois par la couche d'exécution au moment de la décision de rembourser — pas régénérée à chaque retry. Si le réseau coupe après l'envoi mais avant la réception de la réponse, le retry renvoie la même clé. L'API détecte le doublon et renvoie le résultat déjà produit, sans créer un second remboursement.
Tous les outils ne sont pas concernés de la même façon :
- Opérations de lecture (consulter un stock, chercher un client) sont naturellement idempotentes : les rejouer ne change rien à l'état du système.
- Opérations d'écriture non idempotentes par nature (créer, incrémenter, envoyer) doivent recevoir une clé d'idempotence explicite, gérée par votre couche d'exécution, jamais laissée à l'initiative du modèle.
- Opérations irréversibles (suppression définitive, virement bancaire) méritent en plus une confirmation explicite hors du seul jugement du modèle — validation humaine, double appel, ou fenêtre d'annulation.
Une clé d'idempotence évite la duplication d'un même appel. Elle ne vérifie pas que l'appel initial était légitime. Les deux contrôles sont complémentaires et doivent coexister.
Gestion des erreurs et stratégie de retry
Une API externe peut échouer pour des raisons très différentes, qui appellent des réponses différentes :
- Erreur de validation (400) — l'appel ne doit pas être rejoué tel quel ; le résultat doit être renvoyé au modèle pour qu'il corrige les arguments.
- Erreur d'autorisation (401/403) — ne jamais renvoyer au modèle un message suggérant de « réessayer avec d'autres identifiants » ; c'est un échec définitif à traiter côté application.
- Indisponibilité temporaire (429/5xx) — candidate légitime à un retry avec backoff exponentiel, à condition que l'appel soit idempotent ou protégé par une clé d'idempotence.
- Timeout réseau — état ambigu : l'action a peut-être été exécutée côté serveur sans que la réponse soit arrivée. C'est exactement le scénario que la clé d'idempotence est censée couvrir.
La règle générale : ne jamais rejouer automatiquement un appel à effet de bord sans garantie d'idempotence, et toujours limiter le nombre de tentatives (typiquement trois, avec backoff) pour éviter qu'un agent ne s'enferme dans une boucle de retry silencieuse.
Orchestration multi-outils
Un agent réel enchaîne rarement un seul appel. Une demande comme « annule ma dernière commande et rembourse-moi » suppose une recherche (retrouver la commande), une vérification (statut annulable), puis deux actions distinctes (annulation, remboursement). Deux modes d'enchaînement coexistent :
- Séquentiel — chaque résultat conditionne l'appel suivant ; nécessaire dès qu'une dépendance de données existe (il faut l'identifiant de commande avant de pouvoir la rembourser).
- Parallèle — plusieurs outils indépendants sont invoqués dans le même tour (consulter le stock et consulter le taux de change simultanément), ce que les API modernes autorisent en renvoyant plusieurs blocs d'appel dans une seule réponse.
La complexité augmente avec le nombre d'outils exposés simultanément : au-delà d'une quinzaine d'outils dans un même catalogue, la précisionprécisionIAProportion des alertes émises par un modèle qui sont justifiées. Elle s'oppose au rappel : améliorer l'une dégrade l'autre.Voir dans le glossaire de sélection du bon outil se dégrade sensiblement. Regrouper les outils par domaine, ou les exposer dynamiquement selon le contexte de la conversation, atténue ce problème.
Observabilité : tout appel doit être traçable
Chaque invocation d'outil devrait être journalisée avec, au minimum : l'identité de l'appelant, le nom de l'outil, les arguments reçus, le résultat ou l'erreur, la latence, et la clé d'idempotence utilisée le cas échéant. Cette trace sert à la fois d'audit de sécurité et d'outil de diagnostic quand un agent produit un comportement inattendu.
Les journaux d'appels d'outils doivent rester consultables indépendamment de l'historique de conversation, qui peut être tronqué, résumé ou expiré. Un incident découvert trois semaines après les faits doit pouvoir être reconstitué à partir des seuls logs d'exécution, jamais à partir du seul fil de discussion visible par l'utilisateur.
Checklist avant déploiement
Avant d'exposer un catalogue d'outils à un agent en production :
- Chaque outil a un schéma strict, avec types, enums et bornes explicites.
- Aucun secret ne transite par le prompt ou les arguments d'outil.
- L'autorisation est vérifiée côté code à chaque appel, pas déduite de l'intention du modèle.
- Toute opération d'écriture dispose d'une clé d'idempotence gérée par la couche d'exécution.
- Les opérations irréversibles exigent une confirmation hors du seul jugement du modèle.
- Les erreurs 4xx et 5xx sont traitées différemment, avec un nombre de retries borné.
- Chaque appel est journalisé indépendamment de l'historique de conversation.
- Le catalogue d'outils exposé à un instant donné reste restreint au strict nécessaire du contexte.
Ce qu'il faut retenir
Le function calling déplace la responsabilité : ce n'est plus le modèle qui doit être fiable à 100 %, c'est la couche d'exécution qui doit être conçue pour rester sûre même quand le modèle se trompe. Un schéma strict limite les arguments invalides, une authentification découplée du prompt empêche la fuite de secrets, une clé d'idempotence absorbe les retries inévitables. Aucun de ces mécanismes n'est optionnel dès qu'un outil produit un effet réel — ce sont eux, et non la qualité du prompt, qui déterminent si un système d'agents est déployable en production.
L'essentiel à retenir
Ce chapitre détaille le mécanisme du function calling : comment un modèle transforme une intention en langage naturel en un appel structuré, validé par un schéma JSON, puis exécuté contre une API réelle. Il couvre la conception de schémas robustes, la gestion de l'authentification côté outil plutôt que côté prompt, et l'idempotence comme garde-fou contre les doubles exécutions. Une attention particulière est portée aux stratégies de retry, à l'orchestration multi-outils et à la journalisation, avec une checklist actionnable avant tout déploiement en production.
Questions fréquentes
Le function calling est-il la même chose que les agents ?
Faut-il valider les arguments d'un appel d'outil même s'ils respectent déjà le schéma JSON ?
Comment gérer un outil qui déclenche une action irréversible, comme un virement bancaire ?
Peut-on laisser le modèle choisir lui-même quels outils sont autorisés selon le contexte ?
Que se passe-t-il si deux appels d'outils parallèles modifient la même ressource ?
Un outil de lecture seule a-t-il besoin d'une clé d'idempotence ?
Comment tester un catalogue d'outils avant de le mettre en production ?
Progression sauvegardée dans votre navigateur.
Quiz de validation
Quiz Player
Quiz de validation
Plusieurs réponses possibles — validez ensuite.
Vrai ou faux.
Quiz indisponible (données invalides).