Article

Outiller un agent : du code, pas des outils sur mesure

Multiplier les outils sur mesure (façon MCP) réintroduit du RPC et noie le contexte. Exposez au LLM ce qu'il maîtrise déjà : du code et des API REST.

Pour donner des capacités à un agent, le réflexe est de lui déclarer des outils : un par besoin métier. C'est refaire, sous un nom neuf, une erreur que le Web avait corrigée il y a vingt ans.
Avant / après : une nuée d'outils ad hoc contre un seul executeCode vers REST, SQL, CLI
Un seul outil d'exécution de code, vers les interfaces que le modèle connaît déjà, plutôt qu'un catalogue d'outils sur mesure.

Un agent doit agir : envoyer un message, interroger une base, appeler un service. La manière dont on lui donne ces moyens n'est pas un détail d'implémentation — elle décide de sa fiabilité, de son coût et de la quantité de contexte gâchée à chaque conversation. Et la solution la plus répandue, la bibliothèque d'outils dédiés, est la moins bonne.

Un outil sur mesure, c'est du RPC

Exposer une liste d'« outils » nommés, chacun avec sa signature et sa sémantique propres, c'est du RPC (remote procedure call) : on appelle des procédures distantes par leur nom. C'est un retour en arrière par rapport à REST, le style du Web, dont les contraintes — ressources adressables et stables, méthodes HTTP à sémantique uniforme, codes de statut interprétables, représentations négociées, liens hypermédia — ont justement été pensées pour qu'un client n'ait pas à connaître à l'avance toutes les actions possibles.

Empiler des verbes métier dans un protocole d'outils (creer_facture, annuler_commande), c'est refaire l'anti-pattern de l'« API d'action » que REST corrige précisément. On rejoue le RPC des années 1990, à un détail près : le client est désormais un modèle de langage qui, lui, connaît REST sur le bout des doigts.

On cache au modèle ce qu'il sait déjà

Car c'est là le vrai gâchis. Un LLM sait manipuler HTTP, SQL, le shell et le code applicatif — Python, JavaScript, Ruby — parce qu'il les a rencontrés des millions de fois à l'entraînement. Ce sont, pour lui, des langues maternelles. Un outil envoyer_mail sur mesure, à l'inverse, doit être réappris à chaque conversation : sa signature est réinjectée dans le contexte, sa sémantique devinée, ses cas limites ignorés.

Pire : cet outil cache une implémentation que le modèle maîtrisait déjà — envoyer un courriel en SMTP, par une commande, via une API connue. On échange une compétence native, robuste et généralisable, contre un contrat propriétaire, fragile et local. On ajoute de la surface à apprendre sans ajouter le moindre pouvoir.

Le JSON n'est pas un langage, c'est un document

Il y a plus fondamental encore. Quand un modèle « appelle un outil », il ne code pas : il produit un objet JSON — un nom de fonction, des arguments. Or le JSON est un format de document, pas un langage de programmation : ni variable, ni boucle, ni condition, ni composition. Dès qu'il faut enchaîner ou conditionner des actions, on se met à empiler des conventions dans ce JSON — un appel qui en référence un autre, un champ qui encode un branchement — autrement dit on réinvente un pseudo-langage de programmation à l'intérieur d'un format de données. C'est doublement perdant : on bricole un mauvais langage là où un vrai existe, et on demande au modèle de l'écrire dans une notation qu'il n'a presque jamais rencontrée. Le code, lui, a déjà la composition, le contrôle de flux et les types — et le modèle le parle nativement.

Code-as-action : un outil au lieu de cent

La conséquence est logique : demander à un agent d'« envoyer un mail », c'est lui demander d'écrire le code qui l'envoie — ce qu'il fait naturellement. Un unique outil d'exécution de code, dans un bac à sable contrôlé, remplace alors des dizaines de déclarations d'outils métier. Les effets se cumulent :

  • le catalogue fond : on cesse de déclarer ce que le modèle sait déjà coder ;
  • le contexte respire : chaque outil déclaré occupe de la place, et au-delà de quelques fonctions la sélection se dégrade — l'agent confond les outils, hallucine des paramètres. Moins d'outils, ce sont de meilleurs choix ;
  • l'agent compose librement : boucles, conditions, appels chaînés, sans qu'on ait dû anticiper chaque combinaison sous la forme d'un outil supplémentaire.

Le bon périmètre n'est donc pas « un outil par capacité » mais un petit jeu d'outils génériques — exécuter du code contre l'API, déléguer, escalader — et des API propres derrière. La capacité métier s'écrit ; elle ne se déclare pas.

Ce constat n'est pas une lubie d'arcate. Cloudflare le dit sans détour : « les LLM ont vu énormément de code ; ils n'ont pas vu beaucoup d'appels d'outils » — du code réel issu de millions de projets, contre un jeu d'entraînement artificiel fabriqué pour l'occasion. En présentant 2 500 endpoints comme une API de code plutôt que comme des outils, ils font tomber leur empreinte de 1,17 million de tokens à environ mille. Anthropic mesure le même effet — un cas ramené de 150 000 à 2 000 tokens — et un travail de recherche (CodeAct, 2024) montre que les actions exprimées en code réussissent jusqu'à 20 % plus souvent que les mêmes actions en JSON, avec un tiers d'étapes en moins. Reste qu'exécuter ce code sans danger est un sujet d'ingénierie à part entière — l'objet d'un retour d'expérience compagnon : notre bac à sable JavaScript.

La bonne réponse : des API agent-friendly

Cela ne dispense pas de soigner ses interfaces — au contraire. La sortie n'est pas « un nouveau protocole d'outils », mais des API existantes rendues lisibles par un agent : ressources claires, contrats stables, erreurs interprétables, liens qui disent les transitions possibles. Une bonne API REST est déjà l'outil idéal d'un agent ; une pseudo-API RPC opaque, elle, le pousse à contourner les frontières.

Une précision honnête s'impose : Cloudflare et Anthropic conservent MCP sous cette couche de code — ils emballent les outils en une API que le modèle programme, sans retirer le protocole. Ils concèdent donc l'essentiel — le code bat l'appel d'outil, le catalogue obèse étouffe le contexte — tout en gardant l'intermédiaire. La position défendue ici va un cran plus loin : puisque le modèle écrit du code, autant le laisser viser directement les interfaces qu'il maîtrise, sans réintroduire un protocole d'outils à apprendre. Que l'auteur même de MCP recommande aujourd'hui d'écrire du code plutôt que d'appeler ses outils en dit long : c'est déjà la moitié du chemin parcouru.

Le bénéfice caché : le déterminisme

Il reste une vertu, décisive. Le code qu'un agent produit pour agir n'est pas jetable. Une fois écrit et prouvé, il est rejouable sans le modèle : on l'extrait, on le fige, on l'exécute. On passe d'une étape indéterministe — le modèle décide et improvise — à une étape déterministe — un programme exécute. Un outil sur mesure n'offre jamais cela : il reste une boîte appelée par un modèle. Le code, lui, est le premier pas vers l'industrialisation — l'objet du dernier article de cette série.

Laisser un commentaire

Vous devez être connecté pour pouvoir laisser un commentaire.