Je regardais mon tableau de bord Langfuse à 23h un jeudi quand j'ai remarqué quelque chose qui m'a fait fermer mon laptop et m'éloigner de mon bureau. Une seule exécution d'agent -- une tâche, une requête utilisateur -- avait brûlé 76 000 tokens et effectué 56 appels d'outils distincts. Le pire ? Il avait quand même donné la mauvaise réponse. Il avait manqué deux membres de l'équipe qui avaient dépassé leurs limites budgétaires, et le client allait voir ce rapport le lendemain matin.
Cet agent avait accès à 60 outils répartis sur deux serveurs MCP. Chacune de ces définitions d'outils se chargeait dans la fenêtre de contexte au début de chaque conversation. Treize mille tokens partis avant même que l'agent ne commence à réfléchir à la tâche réelle. J'avais construit ce que je pensais être un système capable. Ce que j'avais réellement construit était une fournaise à tokens avec un problème de précision.
La solution est venue de deux fonctionnalités que j'ignorais dans la documentation d'Anthropic depuis des semaines : la recherche d'outils et l'appel programmatique d'outils. Ce qui s'est passé après les avoir implémentées est la raison pour laquelle j'écris cet article. Mais la vraie histoire n'est pas l'économie de tokens -- c'est un changement fondamental dans ma façon de penser l'architecture des agents.
Le Problème Dont Personne Ne Parle Jusqu'à l'Arrivée de la Facture
Voici le scénario que la plupart des développeurs d'agents IA connaissent intimement, qu'ils l'admettent ou non. Vous commencez à construire un agent. Il doit lire des fichiers, interroger des bases de données, appeler des APIs, peut-être interagir avec GitHub ou Slack. Chaque capacité signifie un outil de plus. Votre premier prototype a 8 outils et fonctionne à merveille. Contexte propre, réponses rapides, résultats précis.
Puis les demandes de fonctionnalités arrivent. L'agent doit gérer la planification de calendrier. Ajoutez trois outils. Il doit créer des tickets Jira. Deux outils de plus. Intégration Slack ? Cinq de plus. Avant de vous en rendre compte, vous êtes à 35, 40, 60 outils -- et votre agent a développé un trouble de la personnalité. Il choisit le mauvais outil la moitié du temps, hallucine des valeurs de paramètres et coûte trois fois ce que vous aviez budgété.
J'ai heurté ce mur de plein fouet sur un projet pour un client qui voulait un agent d'opérations unifié. L'agent avait besoin d'accéder à leurs repos GitHub, espace Notion, canaux Slack, calendrier et une API d'inventaire personnalisée. Soixante outils au total quand on comptait tout des deux serveurs MCP.
Trois choses me tuaient :
Les définitions d'outils seules consommaient environ 13 000 tokens par conversation. C'est de l'espace de fenêtre de contexte qui aurait pu être utilisé pour du raisonnement réel. Sur Claude 3.5 Sonnet, ce n'est pas anodin -- et sur les conversations plus longues, je frôlais les limites de contexte avant que l'agent ait terminé son travail.
Les sorties intermédiaires des appels séquentiels d'outils polluaient le contexte. Quand l'agent devait vérifier les budgets d'une équipe, il appelait « obtenir les membres de l'équipe », puis appelait « obtenir les dépenses » pour chaque personne, puis appelait « obtenir le budget par niveau » pour le rôle de chaque personne. Chaque réponse déversait du JSON brut dans le contexte. Quand il atteignait le dernier membre de l'équipe, les données précédentes étaient poussées hors de la zone d'attention effective.
La précision de sélection d'outils se dégradait à mesure que le nombre d'outils augmentait. Avec 60 définitions d'outils dans le contexte, le modèle devait les parcourir toutes chaque fois qu'il décidait quel outil utiliser. Imaginez donner à quelqu'un un menu de 60 pages dans un restaurant et s'attendre à ce qu'il commande rapidement et correctement. Même problème.
J'ai essayé les corrections évidentes. De meilleures descriptions d'outils. Moins d'outils avec plus de paramètres. Catégoriser les outils en groupes. Aucune n'a résolu le problème fondamental : trop de définitions chargées trop tôt, et trop de données intermédiaires s'accumulant trop vite.
Puis j'ai trouvé les deux fonctionnalités qui ont tout changé dans ma façon de construire des agents.
Recherche d'Outils : Charger Ce Dont Vous Avez Besoin, Quand Vous en Avez Besoin
Le concept derrière la recherche d'outils est si simple que c'est presque vexant que je n'y aie pas pensé moi-même. Au lieu de charger les 60 définitions d'outils dans le contexte au départ, vous différez la plupart. L'agent reçoit un petit ensemble d'outils essentiels plus un outil spécial : l'outil de recherche d'outils lui-même. Quand l'agent a besoin d'une capacité qu'il n'a pas actuellement, il recherche le bon outil par mot-clé ou nom, charge uniquement le schéma de cet outil et poursuit.
Les mathématiques sont convaincantes. Ma configuration à 60 outils consommait environ 13 000 tokens en définitions d'outils. Après avoir implémenté la recherche d'outils et ne charger que 12 outils essentiels au départ, ce nombre est tombé à 6 300 tokens. Presque la moitié de la surcharge de définitions, éliminée.
Mais les économies de tokens n'étaient même pas l'amélioration la plus importante. La précision de sélection d'outils a augmenté de manière spectaculaire. Quand l'agent n'a que 12 outils en contexte au lieu de 60, il choisit le bon plus régulièrement. C'est la même raison pour laquelle un artisan concentré avec 5 outils sur l'établi travaille plus précisément qu'un entouré de 50 -- moins de bruit, meilleur signal.
Voici à quoi ressemble le flux de travail en pratique. Disons que l'agent doit lister les commits récents d'un dépôt GitHub. Avec l'approche traditionnelle, les outils GitHub MCP sont déjà chargés -- les 35, consommant environ 26 000 tokens (bien que les versions plus récentes de MCP aient réduit cela à environ 4 000 tokens, ce qui est une amélioration massive dont je parlerai plus tard). L'agent doit parcourir chacun pour trouver le bon outil, puis déterminer les bons paramètres.
Avec la recherche d'outils, ces outils GitHub ne sont pas du tout chargés. L'agent reconnaît qu'il a besoin de données de commits, appelle l'outil de recherche avec une requête comme « list commits », obtient l'outil spécifique dont il a besoin et charge uniquement ce schéma. Un outil. Quelques centaines de tokens. Et une fois cet outil chargé, il reste en contexte pour tous les appels suivants -- pas de chargement répété, pas de tokens gaspillés.
Je veux être précis sur le fonctionnement parce que les détails d'implémentation comptent. L'outil de recherche accepte soit une requête par mot-clé, soit un nom d'outil direct. La recherche par mot-clé est floue -- vous pouvez chercher « slack message » et il retournera les outils Slack pertinents classés par pertinence. La sélection directe utilise un préfixe « select: » quand vous savez exactement quel outil vous voulez. Les deux approches chargent les outils retournés immédiatement, donc il n'y a pas de processus en deux étapes de chercher puis charger séparément.
Une chose que j'ai apprise à mes dépens : vous devez réfléchir soigneusement à quels outils restent dans l'ensemble « toujours chargé » versus lesquels sont différés. Les outils que l'agent utilise dans presque chaque conversation devraient rester chargés. Les outils qui ne sont nécessaires que pour des tâches spécifiques devraient être différés. Se tromper sur cette répartition signifie que votre agent perd du temps à chercher des outils courants ou charge encore trop de définitions au départ.
Pour mon agent d'opérations, j'ai gardé les outils essentiels comme la lecture de fichiers, les appels API basiques et l'outil de recherche lui-même dans l'ensemble toujours chargé. Tout le reste -- opérations GitHub, messagerie Slack, gestion de calendrier, requêtes Notion -- a été différé. L'agent a appris à les rechercher naturellement, et le flux de conversation a à peine changé du point de vue de l'utilisateur.
Cela a résolu le problème d'inflation des définitions. Mais j'avais encore le problème des sorties intermédiaires -- tout ce JSON brut des appels séquentiels d'outils s'accumulant dans le contexte. Pour cela, j'avais besoin de la deuxième fonctionnalité.
Appel Programmatique d'Outils : Écrivez du Code, Pas des Chaînes d'Appels
C'est là que les choses deviennent véritablement intéressantes et, honnêtement, un peu vertigineuses si vous construisez des agents de manière traditionnelle.
L'appel standard d'outils fonctionne ainsi : le LLM décide qu'il a besoin de données, fait un appel d'outil, reçoit le résultat, le traite, décide qu'il a besoin de plus de données, fait un autre appel d'outil, reçoit ce résultat, et ainsi de suite. Chaque appel et chaque réponse vit dans le contexte de la conversation. Pour des tâches simples avec deux ou trois appels, c'est bien. Pour des tâches complexes nécessitant des données de dizaines de sources, c'est un désastre.
L'appel programmatique d'outils inverse le modèle. Au lieu de faire des appels individuels d'outils à travers la conversation, l'agent génère un script de code -- Python, typiquement -- qui gère tout le flux de travail de manière programmatique. Le script s'exécute dans un environnement sandboxé, effectue tous les appels d'outils nécessaires en interne, traite les données avec une vraie logique de code et ne retourne que le résultat final au contexte de la conversation.
Laissez-moi vous montrer la différence avec un exemple concret qui s'est réellement produit dans mon projet de conformité budgétaire.
La tâche était simple : vérifier si les dépenses d'un membre de l'équipe dépassaient son budget autorisé pour son niveau de rôle. Trois outils étaient disponibles : obtenir les membres de l'équipe (retourne une liste de personnes et leurs rôles), obtenir les dépenses (retourne les données de dépenses pour une personne spécifique) et obtenir le budget par niveau (retourne le plafond budgétaire autorisé pour un rôle).
Avec l'appel traditionnel d'outils, l'agent a d'abord appelé « obtenir les membres de l'équipe ». Il a obtenu une liste de, disons, 15 personnes. Puis il a appelé « obtenir les dépenses » pour la personne un. A obtenu ses données de dépenses. A appelé « obtenir le budget par niveau » pour le rôle de la personne un. A comparé les chiffres. Est passé à la personne deux. A appelé « obtenir les dépenses ». A appelé « obtenir le budget par niveau ». Et ainsi de suite. Cinquante-six appels d'outils au total. Chaque réponse -- 15 enregistrements de membres, 15 rapports de dépenses, 15 consultations de budget -- se trouvait dans le contexte de la conversation, consommant des tokens.
Le résultat ? Environ 76 000 tokens consommés. Et l'agent a manqué un membre de l'équipe qui avait dépassé son budget, probablement parce que quand il a traité les dernières personnes, l'attention aux données précédentes s'était dégradée. L'attention de la fenêtre de contexte n'est pas uniforme -- les modèles prêtent moins d'attention aux informations au milieu de longs contextes, et mes appels séquentiels d'outils avaient créé exactement les conditions où cette faiblesse allait mordre.
Avec l'appel programmatique d'outils, la même tâche était complètement différente. L'agent a analysé ce qu'il devait accomplir, puis a généré un script Python. Le script a appelé « obtenir les membres de l'équipe » une fois, a itéré à travers la liste de manière programmatique, a appelé « obtenir les dépenses » et « obtenir le budget par niveau » pour chaque personne dans une boucle, a comparé les valeurs en code et a retourné un résumé propre de qui avait dépassé son budget et de combien.
Les chiffres parlent d'eux-mêmes. L'utilisation de tokens est tombée entre 45 000 et 58 000 tokens sur plusieurs exécutions. Les appels d'outils sont passés de 56 à entre 4 et 12. Et la précision ? Parfaite. Le code n'avait pas de problèmes de dégradation d'attention. Une boucle for traite le quinzième élément exactement aussi bien que le premier.
Je dois être honnête sur quelque chose, cependant. L'approche programmatique n'a pas été parfaite du premier coup à chaque fois. Lors de mes tests, l'agent générait parfois du code avec des bugs au premier essai. Un mauvais nom de variable, une vérification null manquante, une hypothèse incorrecte de structure de données. Le sandbox retournait une erreur, et l'agent analysait l'erreur, corrigeait le code et réessayait. Ce cycle itératif fait partie du design, pas un défaut. Le développement logiciel réel fonctionne exactement ainsi -- écrire, exécuter, déboguer, affiner.
Certaines exécutions ont pris deux itérations, certaines quatre. Mais même avec le surcoût d'itération, l'utilisation totale de tokens et les appels d'outils étaient substantiellement inférieurs à l'approche traditionnelle. Et la précision était systématiquement meilleure parce que la logique de comparaison vivait dans du vrai code plutôt que dans la mémoire de travail du LLM.
Cette nature itérative est en fait une des choses que j'apprécie le plus dans cette approche. Elle reflète ma façon de travailler en tant que développeur. Je n'écris pas du code parfait du premier coup. J'écris quelque chose de raisonnable, je le teste, je corrige ce qui casse et j'itère. L'appel programmatique d'outils donne à l'agent le même flux de travail, et il s'avère que les LLMs sont étonnamment bons pour déboguer leur propre code généré quand ils reçoivent des messages d'erreur clairs du sandbox.
L'Architecture Sandbox Qui Rend Cela Sûr
Maintenant, si vous venez de lire cette section et que vos instincts de sécurité se sont activés, bien. Laisser un agent IA générer et exécuter du code arbitraire est le genre de chose qui empêche les ingénieurs sécurité de dormir. L'architecture derrière cette fonctionnalité est ce qui la rend viable pour la production, et la comprendre est essentiel avant d'implémenter quoi que ce soit.
Le système utilise des conteneurs Docker sandboxés. Chaque exécution de code se déroule dans un conteneur isolé sans accès internet. Le script Python généré ne peut pas atteindre le monde extérieur, ne peut pas accéder au système de fichiers de l'hôte, ne peut pas lire les variables d'environnement de l'hôte et ne peut rien faire de ce qu'un script malveillant voudrait faire.
Mais attendez -- le script a besoin d'appeler des outils. Il a besoin d'accéder à des APIs. Comment fait-il sans accès internet ?
C'est là qu'intervient le pont d'outils, et c'est une pièce d'architecture ingénieuse. Le sandbox a accès à un seul point de terminaison : le serveur pont d'outils tournant sur l'hôte (ou dans un conteneur sidecar). Quand le script Python dans le sandbox a besoin d'appeler un outil -- disons, « obtenir les dépenses » d'un membre de l'équipe -- il fait une requête au pont d'outils. Le pont authentifie la requête en utilisant un ID de session, vérifie que l'appel d'outil est autorisé, exécute l'appel API réel au nom du sandbox et retourne le résultat.
La propriété de sécurité critique ici est que le code du sandbox ne voit jamais les identifiants API, tokens ou secrets. Le pont d'outils détient tout le matériel d'authentification. Le sandbox ne connaît que le point de terminaison du pont et son ID de session. Si le code généré était d'une quelconque manière malveillant ou fuitait, aucune credential ne serait exposée.
J'ai configuré mon sandbox en utilisant le dépôt GitHub LLM sandbox, qui abstrait la majeure partie de la complexité de gestion Docker. Il supporte Python nativement et gère le cycle de vie du conteneur, la capture de sortie et le nettoyage. Pour les équipes exécutant cela en production, je recommande fortement d'ajouter GVisor en plus de l'isolation Docker standard. Les conteneurs Docker partagent le noyau de l'hôte, ce qui signifie qu'un exploit du noyau pourrait théoriquement s'échapper du sandbox. GVisor fournit une couche d'isolation supplémentaire en interceptant les appels système via son propre noyau en espace utilisateur, réduisant significativement cette surface d'attaque.
Une chose que je n'avais pas appréciée avant de le construire : l'approche sandbox est agnostique au langage en principe. Le repo LLM sandbox supporte plusieurs langages, donc vous pourriez faire générer à votre agent du JavaScript, du Go ou même des scripts shell selon la tâche. En pratique, je suis resté sur Python parce que les LLMs génèrent le meilleur code Python -- ils ont vu le plus de données d'entraînement en Python, et la syntaxe de Python facilite l'expression de logique procédurale par le modèle.
Concevoir des Outils Qui Ne Gaspillent Pas Votre Budget de Contexte
La recherche d'outils et l'appel programmatique résolvent deux problèmes majeurs : l'inflation des définitions et l'inflation des sorties intermédiaires. Mais il y a une troisième couche d'optimisation que j'ai failli négliger, et elle a fait une différence plus grande que prévu : la conception des outils elle-même.
Quand j'ai connecté pour la première fois le serveur MCP GitHub à mon agent, l'ensemble complet de 35 outils consommait environ 26 000 tokens en définitions. C'est absurde. La version plus récente du même serveur MCP fournit une fonctionnalité équivalente en environ 4 000 tokens. La différence ? Des descriptions plus resserrées, des paramètres consolidés et la suppression de variantes d'outils redondantes.
Si vous construisez des outils personnalisés pour vos agents, chaque token dans votre définition d'outil compte. Réduisez les descriptions aux informations essentielles. Utilisez des noms de paramètres clairs et concis dont le modèle peut déduire l'usage. Supprimez les champs que l'agent utilise rarement -- vous pouvez toujours les rajouter avec la recherche d'outils si nécessaire.
Et voici un conseil qui a considérablement amélioré la précision de mon agent avec la gestion des paramètres : incluez des exemples d'utilisation d'outils. Fournir un seul exemple d'utilisation correcte d'outil -- montrant les valeurs attendues pour chaque paramètre -- a fait passer ma précision de paramètres d'environ 72% à environ 90%. Ce n'est pas une amélioration mineure. C'est la différence entre un agent qui fonctionne la plupart du temps et un qui fonctionne de manière fiable.
Pensez aux exemples d'utilisation d'outils comme du prompting multi-shot pour les appels d'outils. Quand le modèle voit un exemple comme {"date": "2026-01-15"}, il comprend que le format attendu est année-mois-jour. Sans cet exemple, il pourrait générer « January 15, 2026 » ou « 01/15/2026 » ou « 15-01-2026 » -- toutes des représentations de date valides, mais une seule correspond à ce que l'API attend. Un seul exemple élimine cette ambiguïté presque entièrement.
Je traite maintenant l'optimisation des définitions d'outils comme une tâche d'ingénierie de premier ordre, pas comme une réflexion après coup. Avant d'ajouter un outil à un agent, je demande : Combien de tokens cette définition consomme-t-elle ? Puis-je rendre la description plus courte sans perdre en clarté ? Ai-je inclus un exemple d'utilisation ? Cet outil peut-il être différé derrière la recherche, ou doit-il être toujours chargé ?
Ces questions économisent des milliers de tokens par conversation, ce qui se compose en argent réel sur des milliers d'exécutions d'agents.
Assembler le Tout : L'Architecture Qui Passe Réellement en Production
C'est ici que je relie les fils, parce que ces fonctionnalités ne sont pas des interrupteurs indépendants que vous activez. Elles fonctionnent mieux comme des couches dans une architecture délibérée.
Couche 1 : Recherche d'outils pour la gestion des définitions. Différez tout ce qui n'est pas nécessaire dans chaque conversation. Gardez votre ensemble toujours chargé petit et ciblé. Laissez l'agent découvrir les outils spécialisés à la demande. Cela gère l'inflation des définitions.
Couche 2 : Appel programmatique d'outils pour les flux de travail complexes. Toute tâche qui nécessite d'itérer sur des données, de comparer des valeurs de plusieurs sources ou de faire plus de cinq appels séquentiels d'outils est candidate à l'exécution programmatique. Envoyez ces flux de travail au sandbox. Cela gère l'inflation des sorties intermédiaires et améliore la précision pour les tâches à forte intensité de données.
Couche 3 : Exemples d'utilisation d'outils pour la précision des paramètres. Chaque outil qui accepte des formats de paramètres non évidents -- dates, enums, IDs, objets imbriqués -- obtient au moins un exemple d'utilisation dans sa définition. Cela gère le tueur silencieux de précision que la plupart des développeurs ne mesurent même pas.
Quand j'ai appliqué les trois couches à mon agent d'opérations, les résultats étaient frappants. Les conversations qui consommaient plus de 80 000 tokens sont tombées dans la fourchette 35 000-50 000. Le nombre d'appels d'outils pour les tâches complexes est passé de 40-60 à 5-15. Les erreurs de paramètres ont essentiellement disparu. Et l'agent a commencé à gérer correctement dès le premier essai des tâches qui nécessitaient auparavant une intervention humaine.
Mais je veux être clair sur quelque chose : ce n'est pas gratuit. Implémenter la recherche d'outils nécessite de repenser l'organisation de vos outils et de décider quoi différer. L'appel programmatique nécessite de mettre en place et maintenir une infrastructure de sandbox. Les exemples d'utilisation d'outils nécessitent des tests pour trouver les bons exemples qui améliorent réellement la précision. Chaque couche ajoute de la complexité d'implémentation.
Ma recommandation est de les ajouter incrémentalement. Commencez par la recherche d'outils si vous avez plus de 15-20 outils. Ajoutez l'appel programmatique quand vous identifiez des flux de travail spécifiques où les appels séquentiels d'outils causent des problèmes de précision ou de coût. Ajoutez des exemples d'utilisation à tout outil où vous voyez des erreurs de paramètres dans vos logs.
Ce Que J'ai Mal Fait et Ce Que Je Ferais Différemment
Je veux partager trois erreurs que j'ai faites pendant cette transition parce que je pense que ce sont des erreurs que la plupart des gens feront.
Premièrement, j'ai différé trop agressivement avec la recherche d'outils. J'ai déplacé presque tout derrière la recherche, y compris des outils que l'agent utilisait dans 80% des conversations. Le résultat était que la plupart des conversations commençaient avec l'agent recherchant immédiatement des outils dont il avait presque toujours besoin. Ça fonctionnait encore, mais l'étape de recherche ajoutait de la latence et un petit nombre de tokens. J'ai dû ajuster l'ensemble toujours chargé pendant environ deux semaines en surveillant les schémas réels d'utilisation pour trouver le point idéal.
Deuxièmement, j'ai supposé que l'appel programmatique serait toujours moins cher. Pour des tâches simples avec deux ou trois appels d'outils, la surcharge de générer du code, lancer un sandbox et exécuter le script coûte en fait plus que de simplement faire les appels directement. L'appel programmatique brille quand l'approche traditionnelle nécessiterait plus d'environ cinq appels séquentiels. En dessous de ce seuil, la méthode traditionnelle est plus simple et souvent moins chère.
Troisièmement, j'ai sous-estimé le temps que je passerais à écrire de bons exemples d'utilisation d'outils. Un mauvais exemple est pire que pas d'exemple parce qu'il peut induire le modèle en erreur. J'avais un outil où j'avais fourni un exemple avec une date au format « 2025-12-01 », mais l'API attendait en fait des timestamps Unix. Le modèle a fidèlement suivi mon exemple et envoyé des dates formatées, que l'API rejetait à chaque fois. Tester vos exemples contre l'API réelle est non négociable.
Il y a aussi une leçon architecturale plus large que je suis encore en train de digérer. Ces fonctionnalités m'ont poussé à penser aux agents moins comme des chatbots qui utilisent accessoirement des outils et plus comme des systèmes d'orchestration qui utilisent accessoirement des LLMs. Le travail de l'agent n'est pas d'avoir une conversation -- c'est de décomposer une tâche, sélectionner la bonne stratégie d'exécution pour chaque sous-tâche et assembler les résultats. La recherche d'outils concerne le chargement dynamique de capacités. L'appel programmatique concerne l'exécution efficace. Quand on le présente ainsi, ce ne sont pas des fonctionnalités spécifiques à Claude. Ce sont des patrons de conception qui s'appliquent à n'importe quel framework d'agents.
Faire Fonctionner Cela Au-delà de Claude
J'ai mentionné que ce sont des patrons de conception, pas seulement des fonctionnalités Claude, et je veux être précis à ce sujet parce que c'est important.
La recherche d'outils est fondamentalement un patron de chargement différé. Si vous construisez des agents sur LangChain, CrewAI ou n'importe quel framework personnalisé, vous pouvez implémenter le même concept. Maintenez un registre d'outils disponibles avec des métadonnées légères. Donnez à votre agent une fonction « rechercher des outils » qui interroge le registre par mot-clé. Chargez les schémas d'outils dans le prompt uniquement quand ils sont sélectionnés. Les détails d'implémentation diffèrent, mais l'architecture est portable.
L'appel programmatique d'outils est un patron de génération et exécution de code. N'importe quel framework d'agents peut être étendu pour générer des scripts Python, les exécuter dans un sandbox et ramener les résultats. L'approche sandbox basée sur Docker fonctionne quel que soit le LLM que vous utilisez. L'architecture du pont d'outils est agnostique au modèle -- c'est juste un serveur HTTP qui proxy des appels API authentifiés.
Même les exemples d'utilisation d'outils sont portables. Chaque LLM bénéficie de voir des valeurs d'exemple pour les paramètres. Que vous utilisiez Claude, GPT-4, Gemini ou un modèle open-source, inclure des exemples dans vos descriptions d'outils améliore la précision des paramètres. L'amélioration spécifique varie selon le modèle, mais la direction est cohérente.
J'ai commencé à appliquer ces patrons à un projet parallèle qui utilise un mélange de Claude et GPT-4o selon la complexité de la tâche. La couche de recherche d'outils fonctionne de manière identique pour les deux modèles. Le sandbox d'appel programmatique ne se soucie pas de quel modèle a généré le code. La seule pièce spécifique au modèle est d'ajuster les définitions d'outils pour les forces et faiblesses particulières de chaque modèle en génération de code.
Si vous êtes verrouillé sur un framework ou modèle spécifique, ne rejetez pas ces techniques comme des « fonctionnalités réservées à Anthropic ». Extrayez les patrons, adaptez l'implémentation et appliquez-les partout où vous construisez des agents.
Les Chiffres Après 30 Jours en Production
Je fais tourner l'architecture d'agent optimisée depuis environ un mois, et je veux partager des chiffres réels de production parce que j'en ai assez des articles de blog qui montrent des benchmarks triés sur le volet.
L'utilisation moyenne de tokens par conversation a baissé de 42% par rapport à l'architecture précédente. Pour l'agent d'opérations spécifiquement, c'est environ 0,03 $ par conversation au lieu de 0,05 $. Avec environ 200 conversations par jour pour l'ensemble des utilisateurs, cela économise environ 4 $/jour soit environ 120 $/mois. Pas de quoi changer une vie, mais c'est une réduction de 42% qui n'a nécessité aucun changement dans les capacités de l'agent.
Les erreurs d'appels d'outils -- cas où l'agent a appelé le mauvais outil ou passé des paramètres invalides -- sont tombées d'environ 8% des appels à moins de 2%. La plupart des erreurs restantes sont des cas limites avec des noms d'outils ambigus que je suis encore en train d'affiner.
La précision de complétion de bout en bout pour le flux de travail de conformité budgétaire s'est améliorée d'environ 85% (l'approche traditionnelle manquait parfois des cas limites) à 97% avec l'appel programmatique. Le taux d'échec de 3% est presque entièrement dû au sandbox atteignant des limites de timeout sur des jeux de données inhabituellement grands, ce que je résous en augmentant le timeout du conteneur.
La latence perçue par l'utilisateur a en fait légèrement augmenté pour les requêtes simples -- environ 200ms de surcharge de la recherche d'outils à la première utilisation. Pour les requêtes complexes qui nécessitaient précédemment plus de 30 appels séquentiels d'outils, la latence a diminué significativement parce que le sandbox exécute les appels d'outils plus vite que la boucle de raisonnement séquentiel du LLM.
Ces chiffres ne sont pas hypothétiques. Ils proviennent de traces Langfuse sur un système de production gérant de vraies requêtes utilisateurs. Vos chiffres spécifiques dépendront de votre nombre d'outils, de la complexité des tâches et des schémas de conversation. Mais l'amélioration directionnelle devrait être similaire pour quiconque fait face à l'inflation d'outils ou à la surcharge d'appels séquentiels.
La Question Qui Devrait Vous Garder en Train de Construire
Il y a six mois, je pensais que le chemin vers de meilleurs agents IA était un meilleur prompting. Écrire des instructions plus claires, fournir plus de contexte, utiliser des system prompts plus sophistiqués. Et le prompting compte -- je ne le rejette pas. Mais le prompting seul ne peut pas résoudre des problèmes architecturaux. Vous ne pouvez pas prompter votre sortie d'une surcharge de 13 000 tokens en définitions d'outils. Vous ne pouvez pas prompter vers un traitement précis des données quand les résultats intermédiaires inondent votre fenêtre de contexte.
Les vrais gains résident dans l'architecture d'exécution : comment les outils se chargent, comment les données circulent, comment le code s'exécute et comment l'agent choisit entre les stratégies. La recherche d'outils, l'appel programmatique et la conception réfléchie d'outils sont la première génération de ces outils architecturaux. Ils ne seront pas les derniers.
La question que je n'arrête pas de me poser -- et celle que je vous mets au défi de considérer -- est celle-ci : À quoi ressemblerait votre architecture d'agent si vous la conceviez pour 500 outils au lieu de 50 ? Parce que c'est là que nous allons. L'écosystème de serveurs MCP, d'intégrations API et d'outils personnalisés grandit vite. Les agents qui prospéreront ne seront pas ceux avec les prompts les plus astucieux. Ce seront ceux avec des architectures qui évoluent élégamment quand le nombre d'outils double, puis double encore.
Commencez par les trois couches. Mesurez votre utilisation de tokens. Surveillez vos métriques de précision. Et construisez les fondations maintenant, parce que la complexité ne va faire qu'augmenter.
Travaillons Ensemble
Vous cherchez à construire des systèmes d'IA, automatiser des flux de travail ou faire évoluer votre infrastructure technologique ? Je serais ravi de vous aider.
- Fiverr (builds personnalisés et intégrations) : fiverr.com/s/EgxYmWD
- Portfolio : mejba.me
- Ramlit Limited (solutions entreprise) : ramlit.com
- ColorPark (design et branding) : colorpark.io
- xCyberSecurity (services de sécurité) : xcybersecurity.io