Les outils typés éliminent les angles morts de vos API
Les outils typés imposent aux agents des contrats API, une validation aux frontières et des approbations avant toute écriture risquée.

Un agent doit choisir ce qu'il faut faire. Il ne doit jamais inventer la forme attendue par votre API. Cette séparation paraît évidente jusqu'au jour où un modèle envoie customer_id alors que le point d'accès attend accountId, transforme un aperçu en mise à jour ou remplit une valeur enum inconnue avec un mot plausible. La requête peut sembler correcte dans la transcription tout en étant invalide, ambiguë ou dangereuse.
Les outils typés déplacent cette ambiguïté du prompt vers un contrat applicable. Le modèle reçoit un ensemble limité d'opérations, chacune assortie d'une forme d'entrée vérifiable par une machine. Votre application valide l'appel avant qu'il ne touche la logique métier, puis demande à une personne d'approuver toute opération qui modifie un état. Le modèle continue de raisonner sur l'intention. Le code contrôle la syntaxe, les droits et l'exécution.
J'ai vu des équipes traiter un long prompt système comme une définition d'interface. Ce n'en est pas une. Un texte peut expliquer une règle, mais il ne peut pas refuser un champ supplémentaire, imposer une union discriminée, comparer un numéro de version ou empêcher une nouvelle tentative de facturer deux fois. Si un agent peut atteindre une API de production, ces contrôles doivent vivre dans le code.
Un prompt décrit l'intention, un contrat d'outil définit le droit
Un prompt peut demander à un agent de ne mettre à jour un client qu'après confirmation. Un contrat d'outil définit précisément la mise à jour disponible, les champs qu'elle accepte et le sens de cette confirmation. Ces fonctions se recoupent dans la conversation, mais elles échouent différemment. Le texte échoue par interprétation. Le contrat échoue de façon visible lors de la validation, ce qui donne un échec testable et exploitable.
Imaginons qu'une API interne expose un grand point d'accès appelé execute_action. Ses arguments action, resource et payload sont tous des chaînes. Le prompt énumère les actions permises et fournit des exemples. Cette conception semble souple, car une nouvelle action ne demande aucun changement de schéma. Elle contourne aussi toutes les contraintes que l'API a déjà appris à appliquer. Le modèle peut mal orthographier une action, envoyer du JSON sérialisé dans payload ou associer une ressource à une action qui ne lui a jamais été destinée.
Une surface typée doit exposer des opérations étroites comme get_customer, preview_address_change et commit_address_change. Chaque nom porte une seule capacité. Chaque schéma d'entrée limite le modèle aux champs utilisables par cette opération. Si le modèle demande une action non prise en charge, l'appel doit échouer comme tel. Un appel refusé est plus sûr qu'un appel deviné, et il montre où compléter le catalogue d'outils.
C'est aussi ici que certaines équipes confondent sûreté des types et formatage du prompt. Demander au modèle de répondre en JSON facilite l'analyse. Cela ne rend pas le JSON valide pour votre activité. La syntaxe dit que les accolades correspondent. Un contrat d'outil dit que country utilise un code autorisé, que customer_id désigne le bon type d'enregistrement et qu'une écriture exige une proposition approuvée. Les deux couches sont nécessaires.
Conservez les descriptions, mais réduisez leur rôle. Une description explique quand utiliser un outil et ce que signifient ses termes. Le schéma décide ce qui peut franchir la frontière. Lorsqu'une contrainte reste importante après la génération du texte, encodez-la là où l'exécuteur peut la vérifier.
Un bon schéma rend les états interdits difficiles à exprimer
Un schéma utile ne se contente pas de déclarer des champs comme chaînes. Il encode les choix qui changent le comportement et refuse les combinaisons absurdes. Si une API accepte soit une adresse de livraison existante, soit une nouvelle adresse, modélisez deux cas distincts. N'acceptez pas douze champs facultatifs en espérant que le prompt explique quels sont les six qui vont ensemble.
Cet extrait de JSON Schema donne au modèle un choix explicite et ferme l'objet aux champs inventés :
{
"type": "object",
"additionalProperties": false,
"required": ["customer_id", "destination"],
"properties": {
"customer_id": {"type": "string", "minLength": 1},
"destination": {
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"required": ["kind", "address_id"],
"properties": {
"kind": {"const": "saved"},
"address_id": {"type": "string"}
}
},
{
"type": "object",
"additionalProperties": false,
"required": ["kind", "line1", "city", "country"],
"properties": {
"kind": {"const": "new"},
"line1": {"type": "string"},
"city": {"type": "string"},
"country": {"type": "string", "pattern": "^[A-Z]{2}$"}
}
}
]
}
}
}
Le champ kind est un discriminant. Il empêche l'identifiant d'une adresse enregistrée de glisser dans le cas d'une nouvelle adresse et donne un emplacement utile aux erreurs de validation. additionalProperties: false compte, car les modèles produisent souvent des ajouts qui paraissent utiles. Ignorer silencieusement ces champs habitue tout le monde à accepter un écart entre la transcription et l'action réellement exécutée. Refusez-les.
N'encodez pas sous forme d'enums statiques les faits qui dépendent de données vivantes. Une liste d'identifiants d'entrepôts, d'utilisateurs ou de forfaits actuels vieillit. Placez le vocabulaire stable comme draft, approved et cancelled dans le schéma. Résolvez les identifiants changeants avec un outil de lecture, puis validez-les contre le système de référence au moment de l'exécution.
Les dates, l'argent et les quantités méritent des représentations explicites. Utilisez une chaîne de date ISO si l'API parle d'une date civile, pas un horodatage accompagné d'un fuseau implicite. Représentez l'argent par un entier dans la plus petite unité prise en charge et un code de devise, sauf si le modèle métier existant impose une autre représentation exacte. Ajoutez minimums, maximums, longueurs et motifs lorsque le domaine les possède. Toute limite omise devient une valeur que l'agent peut raisonnablement essayer.
La gestion des versions du schéma doit rester ennuyeuse. Attribuez une version à chaque outil dans le registre, gardez les anciennes versions disponibles tant que des exécutions actives peuvent encore les appeler et placez les changements incompatibles dans une nouvelle version. Rendre obligatoire sur place un champ autrefois facultatif peut transformer une nouvelle tentative ordinaire de l'agent en mystérieuse erreur de validation.
Valider avant et après la logique métier
La validation à la frontière demande deux passages. Validez d'abord les arguments du modèle contre le schéma publié de l'outil. Validez ensuite les faits métier dans le service qui en est propriétaire. Le premier passage intercepte les appels mal formés. Le second intercepte les appels bien formés dont les hypothèses ne sont plus vraies.
Une requête contenant customer_id: "C-1842" peut respecter toutes les règles JSON tout en désignant un enregistrement supprimé ou un client extérieur au tenant de l'opérateur. Une quantity positive peut dépasser le stock disponible. Une proposition approved peut avoir expiré. L'adaptateur d'outil ne doit prendre une validation de schéma ni pour une autorisation, ni pour une validation métier.
Renvoyez les erreurs sous forme de résultats typés, pas de paragraphes que le modèle doit réinterpréter. Une enveloppe d'erreur stable donne au planificateur assez d'informations pour reprendre sans exposer de traces de pile :
{
"ok": false,
"error": {
"code": "VERSION_CONFLICT",
"message": "Customer changed after the proposal was created",
"retryable": false,
"field": "expected_version"
}
}
Le code sert au flux de contrôle. Le message sert à la transcription et à l'opérateur. L'indicateur de nouvelle tentative dit au moteur si répéter exactement le même appel peut un jour aider. Gardez ces sens stables d'un outil à l'autre. Si chaque adaptateur invente son propre texte d'erreur, le modèle devient par accident votre analyseur d'erreurs.
Validez aussi les sorties. Les auteurs d'outils modifient le code, les API en amont renvoient des données partielles et les sérialiseurs laissent échapper des champs. Un schéma de sortie peut empêcher un outil de remettre des identifiants secrets, des notes internes ou un mégaoctet de texte inattendu dans le contexte du modèle. Il détecte aussi le cas pénible où l'exécution a réussi, mais où la forme du résultat a changé et conduit l'agent à raisonner à partir de champs absents.
Consignez le résultat de validation avec le nom de l'outil, la version du schéma, l'identifiant d'exécution et le code d'erreur. Ne consignez pas les arguments bruts par défaut. Les entrées d'outils contiennent souvent les données personnelles ou opérationnelles que vous cherchez justement à contrôler. Conservez des empreintes ou quelques champs non sensibles lorsqu'ils apportent une preuve suffisante.
Les lectures et les écritures exigent des capacités séparées
Classez les outils par effet avant que le modèle ne les voie. Une lecture renvoie des informations sans modifier un état durable. Une écriture crée, met à jour, supprime, envoie, publie, paie, déploie ou déclenche un autre système qui accomplit l'une de ces actions. Le verbe HTTP ne permet pas une classification fiable. Un point d'accès GET peut marquer un message comme lu et un point d'accès POST peut effectuer une recherche pure. Classez l'effet métier.
Donnez par défaut des outils de lecture aux agents exploratoires. N'ajoutez les outils d'écriture qu'à l'exécution qui en a besoin, avec une identité dotée des permissions correspondantes côté serveur. Cacher les outils d'écriture dans le prompt ne contrôle aucun droit. Si le moteur peut encore distribuer un appel nommé, une injection de prompt ou une erreur de planification peut le trouver. Le répartiteur doit refuser tout outil absent de l'ensemble de capacités de l'exécution.
Les écritures ont aussi besoin de formes plus étroites. Un outil générique update_record demande à l'agent de comprendre chaque table et chaque colonne modifiable. Exposez des opérations métier comme suspend_invoice_delivery ou change_shipping_address. Le service peut alors imposer les invariants, produire un aperçu utile et associer une règle d'approbation à cet effet précis.
Certaines opérations semblent réversibles sans l'être. Un courriel envoyé ne se rappelle pas de façon fiable. Publier un événement peut lancer plusieurs travaux en aval. Supprimer un nouvel enregistrement n'annule pas la notification déjà envoyée à son sujet. Traitez les communications externes et les déclencheurs en aval comme des écritures, même si votre base locale reste inchangée.
Pour un flux mixte, séparez planification et exécution. L'agent peut lire des enregistrements, calculer une modification proposée et demander à un outil d'aperçu de la chiffrer ou de la valider. L'outil final de commit accepte un identifiant de proposition, pas une nouvelle charge utile libre. Ce seul choix de conception empêche l'opération approuvée de changer entre l'écran et l'écriture.
Une approbation doit désigner une écriture précise
Un bouton d'approbation seul apporte un faible contrôle. L'enregistrement d'approbation doit dire qui a approuvé quoi, contre quelle version de la cible et jusqu'à quand. Sinon, un modèle peut recevoir l'approbation d'une charge utile et en exécuter une autre, ou exécuter la charge approuvée après un changement de l'enregistrement sous-jacent.
Utilisez un objet de proposition créé par du code digne de confiance. L'agent transmet des arguments candidats à un outil d'aperçu. Le service les valide, résout les valeurs par défaut, calcule les conséquences et renvoie une proposition canonique. L'utilisateur voit l'effet canonique, pas le résumé conversationnel du modèle. Un enregistrement d'approbation pratique peut prendre cette forme :
{
"proposal_id": "p_7f31",
"tool": "commit_address_change.v2",
"arguments_sha256": "8be7...a91c",
"target": {"type": "customer", "id": "C-1842", "version": 17},
"effect": "Replace the shipping address for customer C-1842",
"expires_at": "2026-08-14T16:30:00Z",
"approved_by": "user_291"
}
Le point d'accès de commit charge cet enregistrement, vérifie les droits de la personne qui approuve, contrôle l'expiration, compare la version de la cible et calcule de nouveau l'empreinte des arguments canoniques. Il ne doit pas accepter d'arguments de remplacement venant de l'agent. Si quoi que ce soit diffère, l'exécution s'arrête et le système crée une nouvelle proposition.
La règle d'approbation doit suivre la conséquence, pas le nombre d'outils. Un brouillon à faible risque enregistré dans un espace isolé peut ne demander aucune décision humaine. Envoyer ce brouillon à un client en demande une. Une modification en masse, un paiement, une suppression, une rotation d'identifiants secrets, un déploiement en production ou un message externe doit recevoir un niveau d'approbation adapté à sa portée. Conservez la règle dans une table de politique que le moteur peut évaluer. Ne la dispersez pas dans les prompts.
L'écran d'approbation doit montrer les différences concrètes : champs avant et après, destinataires, montant et devise, environnement, nombre d'enregistrements touchés et toute conséquence irréversible. Ne demandez pas à quelqu'un d'approuver run tool call. La lassitude face aux approbations commence lorsque l'écran cache l'effet et oblige l'opérateur à faire confiance au résumé de l'agent.
Les approbations doivent expirer et la plupart ne doivent servir qu'une fois. Enregistrez aussi les refus, avec une brève raison que l'agent pourra employer pour refaire son plan. Ne transformez jamais le silence, un onglet fermé ou un délai dépassé en consentement.
Un échec d'écriture peut ressembler à un succès pendant plusieurs minutes
Prenons un agent qui modifie une adresse de livraison. Il lit la version 17 du client, propose une nouvelle adresse et reçoit l'approbation. La requête de commit atteint le service, qui écrit l'adresse et valide la transaction. La connexion tombe avant que la réponse n'arrive à l'agent. Le moteur voit un délai dépassé. Il ignore si l'écriture a eu lieu.
Une nouvelle tentative naïve renvoie la même modification logique. Si le point d'accès ajoute des adresses ou émet un événement de traitement, la seconde requête peut dupliquer le travail. Si le moteur signale plutôt un échec, l'opérateur peut répéter manuellement la modification. La transcription indique que l'outil a échoué alors que la production a changé. Ce résultat ambigu est un problème normal des systèmes distribués, pas une bizarrerie du modèle.
Chaque appel d'écriture a besoin d'une clé d'idempotence générée hors du modèle. Liez-la à l'exécution, à la proposition et à l'opération. Dans la mesure du possible, le service stocke la clé avec le résultat final dans la même frontière transactionnelle que l'écriture. Une nouvelle tentative avec la même clé renvoie le résultat conservé. Un appel qui réutilise la clé avec des arguments différents doit échouer.
Le moteur doit traiter le délai dépassé selon une séquence fixe :
- Interroger l'état de l'opération avec la clé d'idempotence.
- Si le service a enregistré un succès, renvoyer ce résultat typé à l'agent.
- Si le service a enregistré un échec final, renvoyer l'erreur enregistrée.
- Si l'état reste inconnu, suspendre et escalader au lieu d'inventer un résultat.
La concurrence optimiste ferme une autre brèche. La proposition ci-dessus cible la version 17. Si une personne change l'adresse avant le commit, la version courante devient 18 et le commit échoue avec VERSION_CONFLICT. L'agent doit lire le nouvel état et créer une nouvelle proposition. Réutiliser l'ancienne approbation appliquerait une décision prise à partir de faits qui n'existent plus.
Les nouvelles tentatives automatiques conviennent aux lectures qui se déclarent sûres et aux écritures protégées par l'idempotence avec un protocole d'état connu. Ne laissez pas une bibliothèque générique décider à partir des seules erreurs réseau. La définition de l'outil doit publier sa classe de reprise et l'exécuteur doit la faire respecter.
Les résultats d'outils doivent apporter des preuves
Une réponse réussie doit contenir assez de preuves structurées pour la décision suivante. Done ne suffit pas. Renvoyez l'identifiant de ressource, sa nouvelle version, l'identifiant d'opération, les champs modifiés et tout état suivant dont dépend le flux. Séparez le texte d'affichage des champs de contrôle.
Pour le changement d'adresse, un résultat utile pourrait être :
{
"ok": true,
"operation_id": "op_a812",
"customer_id": "C-1842",
"previous_version": 17,
"new_version": 18,
"changed_fields": ["shipping_address"],
"committed_at": "2026-08-14T16:22:11Z"
}
Cette réponse permet à l'agent d'indiquer ce qui s'est passé sans l'inventer. Elle permet aussi à une étape ultérieure de transmettre new_version à une autre proposition. Si le service renvoie un message humain, considérez-le comme du texte d'affichage, jamais comme l'unique preuve de succès.
Limitez délibérément la taille des résultats. Un outil de recherche doit renvoyer une page bornée et un curseur, pas toutes les lignes correspondantes. Un outil de fichier doit renvoyer des métadonnées et une référence lorsque le contenu dépasse le besoin de travail du modèle. Les grands résultats non typés augmentent le coût et compliquent l'isolement des injections de prompt présentes dans les données récupérées. Marquez les données d'outil comme contenu non fiable dans le moteur, même lorsqu'elles viennent de votre base; un texte stocké peut provenir d'un attaquant.
Masquez les données dans l'adaptateur, avant que le résultat n'entre dans le contexte du modèle. Le droit d'appeler get_customer n'accorde pas celui de révéler toutes les colonnes client. Définissez une vue de résultat pour la tâche et excluez du schéma les secrets, indicateurs internes et données personnelles sans rapport. La validation de sortie protège ensuite cette vue contre les régressions.
Pour les opérations longues, renvoyez une ressource d'opération avec un enum d'état fini comme queued, running, succeeded, failed ou cancelled. Interrogez-la avec un outil de lecture. Ne gardez pas un appel de modèle ouvert pendant un déploiement ou une migration et ne laissez pas l'agent déduire le succès du temps écoulé.
Reprise, annulation et concurrence demandent une sémantique déclarée
Un registre d'outils doit décrire le comportement opérationnel avec les schémas d'entrée et de sortie. Au minimum, indiquez si l'outil lit ou écrit, si des appels identiques peuvent être répétés sans risque, s'il gère l'idempotence, quelle politique d'approbation s'applique et comment fonctionne l'annulation. Ce sont des règles d'exécution, pas des conseils en prose pour le modèle.
L'annulation exige de la précision. Annuler une exécution d'agent peut arrêter les prochains appels d'outils, mais ne peut pas annuler automatiquement une requête déjà acceptée par un autre service. Un point d'accès d'annulation doit dire si l'opération a été arrêtée, était déjà finie ou ne peut être interrompue. Si une compensation existe, exposez-la comme une écriture séparée avec son propre aperçu et sa propre approbation. Ne parlez pas de rollback si la compensation crée un nouvel événement métier.
Les limites de concurrence appartiennent à plusieurs niveaux. Limitez les appels par exécution pour qu'une boucle de planification ne submerge pas une API. Limitez les appels par tenant afin qu'un flux chargé ne prive pas les autres. Sérialisez au niveau de la ressource lorsque deux écritures approuvées sur le même enregistrement entreraient en conflit. Le service existant reste responsable des transactions et des verrous; le moteur d'agent ne remplace pas la correction de la base de données.
Les délais doivent traduire le comportement de l'outil. Une recherche de deux secondes et une longue conversion numérique ne doivent pas partager une échéance arbitraire. La plateforme agentique de CodeHero lit des bases de code anciennes entières en parallèle, tandis que la parité est vérifiée contre du trafic de production enregistré; cette charge demande des opérations bornées et un état d'achèvement explicite plutôt que des suppositions conversationnelles.
Les erreurs de limite de débit doivent dire quand une nouvelle tentative peut réussir, mais le moteur doit toujours respecter l'échéance de l'exécution et la validité de l'approbation. Si une proposition approuvée expire pendant l'attente, l'appel suivant doit échouer et demander une nouvelle approbation. La commodité ne prime pas sur la frontière de consentement.
Les tests de contrat trouvent les échecs ignorés par les tests de prompt
Une évaluation de prompt peut dire si le modèle choisit généralement le bon outil. Les tests de contrat prouvent que le mauvais appel ne peut pas s'exécuter. Les deux sont nécessaires, mais le second ensemble protège la production lorsque le modèle, le prompt ou la description d'outil change.
Construisez des jeux d'essai à partir de vrais cas limites. Pour chaque outil, testez la plus petite requête valide, les champs inconnus, les champs obligatoires absents, les mauvaises branches d'union, les bornes, les versions périmées, l'approbation expirée, un approbateur sans droit, les clés d'idempotence en double et une clé valide réutilisée avec des arguments différents. Vérifiez la validation de sortie et le masquage avec la même rigueur.
Un test de contrat compact peut se lire ainsi :
GIVEN proposal p_7f31 targets customer C-1842 version 17
AND the current customer version is 18
WHEN commit_address_change.v2 executes with idempotency key run9:p_7f31
THEN no address is changed
AND the result code is VERSION_CONFLICT
AND the proposal remains unconsumed
La dernière assertion compte. Si un conflit consomme l'approbation, le flux en exige une nouvelle après la replanification, ce qui peut être correct. Si votre politique permet à la même approbation de survivre à un échec temporaire du service, définissez ce cas séparément. Les tests obligent l'équipe à régler la distinction au lieu de la découvrir pendant un incident.
Testez le répartiteur comme une frontière hostile. Demandez un outil non enregistré, un outil d'écriture dans une exécution en lecture seule, une ancienne version de schéma, un objet d'arguments trop gros et des chaînes contenant des instructions destinées au moteur. Le répartiteur doit analyser les données, imposer les limites et n'appeler qu'un gestionnaire enregistré. Il ne doit jamais évaluer de code produit par le modèle ni construire dynamiquement un nom de méthode.
Conservez aussi un petit ensemble de traces complètes. Enregistrez le catalogue d'outils, la requête du modèle, les appels proposés, les décisions de validation, les approbations, les résultats des services et la réponse finale après retrait des valeurs sensibles. Rejouez ces traces après des changements de schéma. La formulation exacte peut varier, mais les effets autorisés et les invariants doivent rester fixes.
Les tests de contrat doivent aussi figer le catalogue. Conservez pour chaque rôle du moteur la liste attendue des noms d'outils, versions, classes d'effet et politiques d'approbation. Une nouvelle écriture échoue alors en revue si quelqu'un oublie sa politique, et un rôle censé lire seulement échoue si son catalogue reçoit une opération de commit. Cela détecte la dérive des permissions avant qu'un prompt d'évaluation ne choisisse par hasard le nouvel outil.
Générez les cas invalides de façon méthodique, dans les limites d'un schéma que vous comprenez. Pour une chaîne obligatoire, essayez l'absence, le texte vide, une valeur trop grande et le mauvais type primitif. Pour une union, combinez des champs des deux branches et fournissez un discriminant inconnu. Pour les nombres, testez les limites exactes et la valeur la plus proche à l'extérieur. Le but est de prouver que chaque frontière déclarée possède un chemin de refus exécutable.
La télémétrie de production doit répondre à des questions concrètes sans stocker de charges sensibles. Comptez les appels par outil et version, les erreurs de validation par code et champ, les décisions d'approbation, conflits, résultats ambigus, reprises par classe déclarée et erreurs de sortie. Une hausse soudaine des champs inconnus signifie souvent qu'un prompt ou un client a pris de l'avance sur le registre. Des conflits de version répétés peuvent indiquer que les propositions vivent trop longtemps ou que le flux lit trop tôt. Ces signaux indiquent s'il faut modifier le schéma, la description ou la séquence.
Traitez les erreurs de validation comme un retour sur le produit, pas comme un texte à contourner automatiquement. Si le modèle fournit souvent email à un outil qui n'accepte que customer_id, décidez si la recherche doit devenir un outil de lecture séparé ou si l'écriture doit accepter un autre identifiant stable. N'ajoutez pas discrètement des champs facultatifs jusqu'à ce que les appels passent. Chaque nouveau champ étend l'opération et exige ses propres décisions de droit, de masquage et de test.
Injectez des pannes autour de l'exécuteur. Coupez la connexion après le commit du service, renvoyez un corps de succès mal formé, retardez une approbation jusqu'à son expiration, mettez deux propositions en course sur la même version et rendez temporairement indisponible le point d'état. Vérifiez que le moteur signale un résultat inconnu quand les preuves manquent. Un succès inventé peut sembler soigné dans une évaluation, alors faites porter l'assertion sur l'état enregistré du service plutôt que sur la seule phrase finale.
Enfin, testez que l'affichage d'approbation et le commit partagent la même proposition canonique. Affichez l'approbation depuis les données canoniques stockées, approuvez-la, puis modifiez avant le commit chaque copie des arguments contrôlée par l'agent. L'effet exécuté doit rester identique à l'effet affiché. Si ce test est difficile à écrire, la frontière d'approbation dépend probablement de l'état de la conversation, précisément là où elle ne doit pas vivre.
Une surface d'outils réduite est le choix sûr par défaut
Commencez avec le catalogue le plus étroit qui termine un vrai flux. Un outil mérite sa place lorsque son entrée peut être bornée, sa sortie validée, son effet classé et ses échecs représentés sans demander au modèle de deviner. Si vous ne pouvez pas définir ces éléments, l'API n'est pas prête à devenir un outil d'agent.
Résistez au conseil populaire d'exposer tous les points d'accès internes et de laisser le modèle planifier librement. Les équipes l'apprécient parce que la première démonstration arrive vite. En production, il confie l'archéologie de l'API, le choix des permissions et l'interprétation des erreurs à un composant probabiliste. Le modèle consomme alors des tokens pour redécouvrir des règles que les services connaissent déjà, et une erreur plausible peut franchir une frontière d'écriture.
Un catalogue étroit ne rend pas l'agent moins capable. Il explicite ses capacités. Ajoutez un outil lorsque les journaux montrent une opération manquante, pas lorsqu'un prompt gagne un paragraphe expliquant comment faire passer une action sans rapport dans un point d'accès générique. Versionnez le contrat, associez la politique et donnez à l'exécuteur un résultat typé.
Le niveau d'exigence est plus haut pour une écriture. Exigez une proposition canonique, une approbation liée à son empreinte et à la version de cible, un protocole d'idempotence et un résultat qui prouve ce qui a changé. Rendez les résultats inconnus visibles à un opérateur. Un flux suspendu gêne; un agent qui annonce avec assurance un faux état de production coûte cher.
Les outils typés marquent le moment où un agent cesse d'être une interface de chat autour d'identifiants privilégiés et devient un composant logiciel contrôlable. Gardez le raisonnement dans le modèle. Gardez les droits et la vérité à la frontière.
FAQ
Qu'est-ce qu'un outil typé pour un agent IA ?
Un outil typé est une opération nommée dotée de schémas d'entrée et de sortie vérifiables par machine. L'agent choisit l'opération et fournit les arguments, tandis que le code applicatif valide l'appel et exécute un gestionnaire enregistré.
Une sortie JSON du modèle suffit-elle pour utiliser des outils sans risque ?
Non. Un JSON valide prouve seulement que le texte peut être analysé. Il faut encore un contrat qui refuse les champs inconnus et les combinaisons invalides, puis des contrôles métier sur les permissions, versions courantes et identifiants vivants.
Chaque outil d'agent doit-il demander une approbation humaine ?
Non. Les opérations en lecture seule et les brouillons à faible risque peuvent s'exécuter sans approbation si les permissions le permettent. Les écritures aux effets externes, financiers, productifs, massifs ou irréversibles doivent suivre une politique adaptée à leur conséquence.
Que doit contenir un enregistrement d'approbation ?
Liez l'approbation à une proposition canonique, une empreinte des arguments, la version exacte de l'outil, l'identifiant et la version de la cible, l'approbateur et l'expiration. L'opération de commit doit charger cet enregistrement et refuser les arguments de remplacement.
Comment un agent doit-il reprendre une écriture échouée ?
Donnez une clé d'idempotence à chaque écriture et interrogez l'état de l'opération après un délai dépassé. Ne répétez que si la sémantique déclarée de l'outil et l'état enregistré rendent la répétition sûre; sinon, suspendez pour un opérateur.
Pourquoi refuser les propriétés JSON supplémentaires ?
Des champs supplémentaires peuvent faire promettre à la transcription un effet que le gestionnaire ignore en silence. Leur refus révèle les dérives de contrat et empêche les inventions plausibles du modèle de franchir la frontière.
La validation de schéma et l'autorisation sont-elles identiques ?
Non. La validation de schéma contrôle la forme d'un appel. L'autorisation vérifie que cette identité peut réaliser l'opération sur cette ressource, et la validation métier vérifie que l'opération reste valable maintenant.
Que doit renvoyer un outil après une écriture réussie ?
Renvoyez des preuves structurées comme les identifiants d'opération et de ressource, les versions précédente et nouvelle, les champs modifiés et l'heure du commit. Une simple phrase de succès laisse trop de place à l'agent pour inventer des détails.
Comment gérer les outils d'agent de longue durée ?
Renvoyez une ressource d'opération avec un enum d'état borné, puis interrogez-la par un outil de lecture. L'annulation doit dire si le travail a été arrêté, terminé ou ne peut être interrompu, sans prétendre que toute écriture acceptée peut être annulée.
Quelle taille donner au catalogue d'outils d'un agent ?
Conservez seulement les opérations nécessaires au flux et à l'identité de l'exécution courante. Ajoutez un outil lorsqu'une capacité manque réellement, et exigez schémas, classement de l'effet, sémantique d'échec et politique avant son enregistrement.