Tu veux les meilleurs outils IA avant les autres ?
On teste et on décrypte les nouveaux outils IA chaque soir, en 5 min. Gratuit.
Inclus dès l'inscription : notre sélection des meilleurs guides & comparatifs IA.
Choisis ton rythme
Gratuit · Pas de spam · Désabonnement en 1 clic
La plupart des agents d'IA échouent en production parce qu'ils sont construits à l'envers
Les bons modèles ne sauvent pas une mauvaise architecture, et la plupart des équipes apprennent cela à leurs dépens. Lorsque nous avons constaté qu'un système d'agent d'IA échouait en production, ce n'était pas dramatique. Il n'y a pas eu de crash ni de message d'erreur. Le système continuait simplement à fonctionner et à produire des résultats qui semblaient raisonnables jusqu'à ce que quelqu'un les lise attentivement et remarque qu'il y avait un problème.
Quand nous avons décidé d'examiner la situation, il nous a fallu deux jours de débogage pour comprendre ce qui se passait. Étonnamment, le modèle ne faisait pas d'hallucinations, et les outils d'entrée-sortie produisaient les résultats corrects. Le problème, une fois que nous l'avons enfin trouvé, était architectural. Le modèle et les outils étaient correctement configurés, mais l'idée était que le raisonnement relierait le tout, ce qui, comme vous pouvez le deviner, a évidemment échoué. Il s'avère que le raisonnement ne fait pas ce genre de choses.
Cette expérience est ce à quoi je pense lorsque je me demande pourquoi tant d'agents d'IA qui fonctionnent dans des démonstrations ne survivent pas vraiment à une utilisation dans le monde réel. Ce n'est pas un problème de capacité. C'est un problème architectural. Et si vous avez lu mon précédent article ici sur TDS, "Pourquoi les ingénieurs en IA passent au-delà de LangChain vers des architectures d'agents natives", le schéma devrait vous sembler familier : des systèmes construits de haut en bas, de l'objectif aux outils en passant par le modèle, avec l'hypothèse silencieuse que le comportement intelligent comblera les lacunes. Cette hypothèse est ce que signifie "construit à l'envers". Et c'est plus courant que la plupart des équipes ne le réalisent jusqu'à ce que quelque chose casse.
Les agents ne sont pas des entités. Ce sont des systèmes.
Un agent d'IA en production n'est pas une seule chose intelligente. Il s'agit plutôt d'un ensemble de pièces interagissantes avec différentes responsabilités, modes de défaillance et niveaux d'observabilité. Le LLM (modèle de langage de grande taille) est l'un de ces composants, pas l'ensemble du système. Juste une pièce de celui-ci.
Cela peut sembler évident quand on le dit à voix haute. Mais le cadre de "l'agent autonome" qui a dominé 2023 et la plupart de 2024 a constamment poussé les ingénieurs vers un modèle mental différent : une entité, une boucle de raisonnement, tout géré par le modèle. Tout ce dont vous avez besoin, ce sont des outils, un bon prompt système, et l'espoir que tout s'imbrique correctement.
En revanche, les ingénieurs qui ont expédié de véritables produits basés sur l'IA décrivent rarement leurs systèmes de cette manière. Ce qu'ils décrivent ressemble beaucoup plus à une architecture de systèmes distribués. Pas parce qu'ils ont lu un livre sur les modèles de conception, mais parce qu'ils ont été brûlés suffisamment de fois pour commencer à structurer leur flux de travail plus sérieusement.
Construire de haut en bas, en commençant par "que doit faire cet agent" et en travaillant à rebours vers les outils et les prompts, est rapide pour commencer. C'est aussi ainsi que vous vous retrouvez avec un système où le modèle est responsable de trop de choses, et où rien n'est individuellement débogable. L'architecture a été décidée par l'objectif, pas par les exigences d'ingénierie. C'est cela, la partie "à l'envers".
Alors, que faut-il vraiment pour un système de production ?
La version abstraite est facile à accepter. Voici à quoi cela ressemble réellement. Chaque système d'IA en production que j'ai vu fonctionner correctement a quelque chose comme une couche de décision, que l'équipe l'ait nommée ainsi ou non. C'est la partie où le modèle vit et fait son travail réel.
L'instinct est de tout pousser dans cette couche : analyser les demandes, gérer la mémoire, traiter les réessais, résoudre les échecs d'outils. C'est acceptable si vous travaillez dans un Jupyter notebook. En production, sous charge, avec de vrais utilisateurs, cela devient la partie de votre système où tout est de la faute de tout le monde, et la plupart du temps, rien ne peut être débogué.
La couche de décision doit bien faire une seule chose : décider quoi faire ensuite, étant donné un certain contexte déjà préparé pour cela. C'est tout le travail. Qui prépare le contexte ? Quelque chose d'autre. Qui agit sur la décision ? Également quelque chose d'autre.
Ce "quelque chose d'autre" est la couche d'orchestration, et dans la plupart des systèmes bien construits, c'est simplement du code : des conditionnels, des exécuteurs asynchrones, la gestion des réessais, le routage des files d'attente, peut-être même une machine à états selon la complexité du flux de travail. Au lieu de s'attendre à ce que le modèle fasse tout, traitez-le comme un autre composant. Ici, le code standard fait le gros du travail avec l'état et les outils, de sorte que le LLM n'a qu'à se soucier de prendre la prochaine décision.
De nombreuses équipes se tournent vers des frameworks ici parce que le code d'orchestration nu semble trop simple, comme s'il devait y avoir plus d'infrastructure. Il n'y en a généralement pas. Moins cette couche contient de magie, plus vous trouverez rapidement des bugs lorsqu'ils apparaissent. Et ils apparaîtront.
D'après mon expérience, j'ai appris cela à mes dépens sur un projet où l'orchestration vivait à l'intérieur du modèle d'exécution d'un framework. Quelque chose était en train de réessayer des appels d'outils d'une manière qui corrompait l'état en aval. Nous avons passé deux jours à trouver le problème. Deux jours pour un bug qui aurait pu être résolu en un rien de temps si la logique de réessai avait été trois lignes de Python que j'avais écrites moi-même.
Cela nous amène à la couche d'outils et d'exécution, où toute la communication se produit. Maintenant, la couche d'outils et d'exécution est l'endroit où les choses parlent au monde extérieur. Cette couche a généralement un seul travail, qui est de prendre une entrée bien définie et de produire une sortie prévisible.
Mais l'échec que je voyais constamment, et que je voyais se répéter, était des outils qui essayaient d'être utiles en faisant plus d'une chose. Une seule fonction qui appelle une API, met à jour un cache et fait d'autres choses. Dans une configuration comme celle-là, quand ça casse, vous ne savez pas où. Même lorsque vous essayez de remplacer l'API, vous démêlez une logique qui n'aurait pas dû être entremêlée en premier lieu.
La mémoire et l'état sont les domaines où je pousserais le plus fort, car c'est là que la plupart des équipes sont le plus sous-préparées. La plupart des équipes pensent à la mémoire comme "ce que le modèle sait". La question la plus importante est ce que le système sait, et si cette connaissance est à jour.
Je me souviens d'un jour où il m'a fallu un après-midi pour déboguer ce qui semblait être une simple "hallucination du modèle". Le modèle continuait à faire référence aux préférences des utilisateurs, qui avaient cependant été mises à jour vingt minutes auparavant. Ce n'est pas un problème de modèle. C'est un problème de système. Et c'est étonnamment courant.
Dans les systèmes multi-agents, en particulier, l'état partagé est l'endroit où des défaillances subtiles se développent. Un agent met à jour quelque chose. Les autres ne le savent pas. Tout le monde avance avec assurance dans des directions légèrement différentes. La sortie semble presque correcte, ce qui est presque pire que de sembler incorrect.
Et puis il y a l'évaluation et l'observabilité, que presque tout le monde remet toujours à plus tard jusqu'à ce que quelque chose tourne mal. J'ai aussi été coupable de cela. La différence que je garde à l'esprit est que le logging vous dit ce qui s'est passé. L'observabilité vous dit si ce qui s'est passé était correct. Dans un système déterministe, ces deux choses sont presque identiques.
Dans un système d'IA, ce n'est pas le cas. Vous devez être capable de suivre la demande spécifique du début à la fin, y compris quelles informations le modèle devait considérer, quelle décision il a prise, quel appel API externe il a invoqué et comment il a agi sur sa réponse.
Construire de la bonne manière
Cela commence par l'approche de haut en bas : je veux qu'un agent fasse X, donc je vais lui donner les outils, un bon prompt système, et si le modèle est assez intelligent, tout ira bien. Et c'est exactement ce que les gens utilisent pour faire des prototypes, et pourquoi ne le feraient-ils pas ? Ils n'ont pas tort.
Mais voici le problème : cela traite l'architecture comme une conséquence de l'objectif plutôt que comme quelque chose que vous concevez délibérément. Ensuite, le système grandit. Vous savez, plus d'outils, plus de flux de travail, plus de cas limites, plus d'utilisateurs, et soudain, il n'y a plus de véritable fondation sous tout cela.
L'approche de bas en haut prend plus de temps, mais elle est beaucoup plus confortable. Vous commencez par les blocs de construction de base et vous vous assurez qu'ils fonctionnent réellement. Ensuite, vous déterminez ce que chaque partie doit communiquer, quelles données elle possède et ce dont elle est responsable. Finalement, le système prend forme naturellement à partir de l'interaction de ses parties.
Ce n'est pas un argument du type "les vrais ingénieurs construisent tout à partir de zéro". Ce n'est même pas vraiment une question d'outils. C'est une question du modèle mental que vous construisez. J'ai vu des ingénieurs utiliser des frameworks sophistiqués et construire des systèmes propres parce qu'ils comprenaient ce que chaque couche devait faire. J'ai également vu des ingénieurs écrire du Python basique et créer un désordre indébogable parce qu'ils pensaient encore en termes de "l'agent décide de tout". Les outils découlent du modèle dans votre tête, et non l'inverse.
Le système multi-agents le plus robuste avec lequel j'ai eu l'occasion de travailler de près avait presque aucune infrastructure spécifique à l'IA. Lorsque j'ai vu le dépôt pour la première fois, j'ai honnêtement pensé que je regardais le mauvais code. Une file de messages, des processus de travail avec des portées distinctes, un stockage d'état partagé avec des contrats de lecture/écriture explicites, et un coordinateur prenant des décisions de routage.
Les requêtes du modèle de langage étaient effectuées par les travailleurs eux-mêmes, chacun recevant un ensemble de contexte créé en amont par un autre processus. Au total, le tout faisait environ mille lignes de Python. J'ai vu des agents de démonstration avec plus de code que cela. Chaque partie était traçable. Lorsque quelque chose se comportait de manière inattendue, nous trouvions généralement le problème en moins d'une heure parce qu'il n'y avait pas de magie à examiner. Juste du code avec un chemin clair à travers lui.
Ce système a été construit de bas en haut. L'objectif était défini, mais l'architecture n'était pas dérivée de celui-ci. Les composants ont été conçus en premier, évalués individuellement, puis assemblés pour mettre en œuvre la fonctionnalité souhaitée. Ce dernier aspect est le plus important, pas le premier.
Où je pense que cela va
Autant que je puisse en juger, la direction dans laquelle nous nous dirigeons évolue lentement, passant des "frameworks d'agents" vers une infrastructure appropriée, avec des systèmes pour l'évaluation, le routage des modèles, les solutions de secours et la gestion de l'état. Au moins une partie de cela existe déjà. La majorité reste à venir alors que les gens résolvent des problèmes de production difficiles dans cet espace.
Ce que je vois encore et encore, c'est que les personnes qui construisent les systèmes les plus fiables n'utilisent souvent même pas les meilleurs modèles.