8 points par GN⁺ 2025-05-23 | 1 commentaires | Partager sur WhatsApp
  • La manière dont les LLM traitent l’intégralité des résultats d’appel d’outils est lente, coûteuse et peu adaptée au passage à l’échelle
  • À la place, il est proposé de laisser le LLM orchestrer un traitement où les données structurées sont manipulées directement par du code à partir d’un schéma de sortie
  • Cette approche est adaptée au traitement de grands volumes de données grâce à l’enchaînement de fonctions par le code et à la gestion de la mémoire via des variables
  • Le traitement des données fondé sur l’exécution de code offre une excellente précision et une bonne scalabilité, car le LLM n’a pas à reconstituer lui-même les données
  • La mise en place d’un environnement d’exécution IA sécurisé apparaît comme un nouveau défi, avec le besoin d’un environnement d’exécution durable et capable de conserver l’état

LLM function calls don't scale; code orchestration is simpler, more effective.

Limites de l’approche classique qui renvoie les résultats des outils au LLM

  • Lorsqu’on utilise des outils MCP (Machine Context Protocol), on transmet généralement au LLM le résultat produit par l’outil sous forme de message afin de guider l’action suivante
  • Dans des cas d’usage réels, les serveurs MCP de Linear et d’Intercom renvoient de grosses réponses au format JSON
  • Le JSON ressemble à une API, mais sans schéma de sortie défini, le LLM doit parser l’ensemble du texte, ce qui crée une charge importante
  • Par exemple, le résultat d’une requête listant les issues de Linear contient 70 000 caractères pour 50 éléments, soit environ 25 000 tokens, ce qui est très volumineux
  • Beaucoup de champs id n’apportent pas de sens mais consomment des tokens, et si le LLM doit les reproduire tels quels, le coût et le risque d’erreur augmentent

Pourquoi il faut séparer traitement des données et orchestration

  • L’approche actuelle mélange le traitement des données et l’orchestration dans une même session de chat
  • Certains créent pour cela d’autres threads « agents », mais lorsque le JSON est structuré, cette méthode reste inefficace
  • Une meilleure approche consiste à traiter directement les données structurées avec du code
    • Exemple : pour trier des issues, au lieu de demander au LLM de générer la sortie, on exécute sort en code puis on ne renvoie que le tableau résultant

Traitement des données fondé sur l’exécution de code

  • Les calculs IA via exécution de code sont déjà utilisés dans divers interprètes IA
  • Cette approche permet une structure plus simple dans laquelle le LLM n’a pas à produire directement les données et n’a qu’à décider de la manière d’utiliser les outils

Concepts clés

  • Utiliser les variables comme mémoire : affecter une valeur = stocker, l’afficher = la consulter, la transmettre comme argument lors d’un appel de fonction
  • Prise en charge de l’enchaînement de fonctions : combiner plusieurs appels de fonctions en parallèle ou en séquence, avec des dépendances exprimées naturellement dans le flux du code
  • Traitement extensible de gros volumes de données : combiné à NumPy, pandas, etc., ce modèle permet de traiter facilement des milliers à des dizaines de milliers d’éléments
  • Possibilité d’appeler d’autres LLM : le code écrit par le LLM peut à son tour appeler un autre LLM pour traiter des données non structurées

Le MCP est-il prêt ?

  • La spécification MCP définit déjà un schéma d’entrée, et une PR pour le schéma de sortie a récemment été soumise
  • Si les schémas de sortie se généralisent, les usages suivants deviennent possibles :
    • tableau de bord de suivi des issues
    • rapport hebdomadaire des tickets terminés
    • surveillance et relance par l’IA des tickets bloqués

Défis de l’environnement d’exécution de code

  • La sécurité est l’enjeu central : comme on exécute du code généré par l’IA ou par l’utilisateur, il faut concevoir le système de façon à empêcher l’exposition des clés API et des données
  • Dans le cas de Lutra, l’environnement d’exécution est conçu selon une approche sandbox, et seul la documentation des appels API est fournie au modèle
  • Les environnements d’exécution avec conservation d’état (comme Jupyter) sont coûteux, et pour des sessions longues il faut des propriétés stateless + persistent
  • Cela forme une nouvelle catégorie d’AI runtime, dont la conception fait encore l’objet de travaux actifs

Conclusion

  • L’approche classique qui consiste à faire traiter au LLM les résultats d’appel d’outils atteint des limites en coût et en précision
  • L’orchestration par code permet un traitement simple, extensible et précis
  • Les environnements d’exécution de code pour l’IA attirent l’attention en tant que runtimes de nouvelle génération alliant sécurité, persistance et scalabilité

1 commentaires

 
GN⁺ 2025-05-23
Avis Hacker News
  • Partage d’une expérience accumulée sur les deux dernières années : « un agent suffisamment sophistiqué devient indiscernable d’un DSL ». L’idée défendue est qu’il vaut bien mieux enseigner une API au lieu d’exiger qu’un agent internalise un algorithme, puis lui demander de concevoir un algorithme s’appuyant sur cette API et de l’exécuter en user space. Injecter des algorithmes à l’intérieur d’un LLM est jugé inefficace en dehors de cas très limités, notamment en termes de coût ou de précision. Comparaison avec le fait de demander à un développeur d’exécuter mentalement des appels de fonctions
    • Cela est interprété comme un indice que la voie vers l’ASI (superintelligence artificielle) ne passe pas par l’extension des capacités des LLM, mais plutôt par l’extraction et la compilation externes d’algorithmes d’auto-amélioration sous forme d’applications symboliques
    • Demande de références ou d’exemples montrant que le terme « agent » était déjà largement employé dans ce sens il y a deux ans
  • Retour d’expérience sur la construction directe de systèmes agentic pour une activité e-commerce. Évaluation de smolagents : élégant et séduisant, mais avec l’inconvénient d’augmenter fortement la complexité du système. C’est parfait dans des environnements comme le reporting dynamique, où il faut trier et agréger des données sans schéma, mais c’est excessif pour la plupart des tâches. Gemini et OpenAI proposent des fonctionnalités d’interpréteur Python qui couvrent une grande partie du travail des agents de code. Une approche consistant à empiler sans fin des messages d’appels d’outils dans la stack est jugée peu scalable et déconseillée. En pratique, les workflows agentic ont une durée de vie courte, et leur complexité est gérée par la structure et la discipline. Les leçons du développement logiciel traditionnel restent les mêmes : gérer la montée en charge des appels de fonctions et éviter le chaos. La clé d’un bon système est de maîtriser la charge cognitive des développeurs ; une solution simple mais suffisante l’emporte souvent sur une méthode sophistiquée mais plus performante en théorie. La composition d’appels de fonctions est un exemple de solution simple de ce type, et le traitement de données structurées peut aussi très bien reposer sur des méthodes classiques de parsing et de transformation. Quand la structure est inconnue, des modèles peu coûteux peuvent déjà offrir d’excellentes performances de parsing. Au fond, la gestion de la complexité dans les systèmes agentic revient à gérer minutieusement l’état de l’application. La manipulation de la stack de messages permet de construire avec souplesse le contexte actif fourni au modèle, ce qui rappelle la gestion mémoire dans un environnement contraint
    • Résumé jugé très juste des trade-offs des systèmes agentic. Même réflexion lors de la construction d’une solution conversationnelle de recherche produit e-commerce (IsarTech). La composition de fonctions et les données structurées sont au cœur du contrôle de la complexité. D’expérience, des sorties fondées sur un schéma de types clair améliorent concrètement la scalabilité des appels d’outils. Grâce au schéma de types, on peut maîtriser à la fois la charge cognitive et la complexité du système. Il vaut mieux s’appuyer sur des comportements déterministes autant que possible, et n’utiliser les LLM qu’en présence de données sans schéma ou d’ambiguïté. Les LLM sont très efficaces pour mapper des requêtes ambiguës vers des systèmes déterministes. Il faut toutefois trouver un équilibre entre la réduction de complexité sur des entrées à forte entropie (non structurées) et l’augmentation de complexité via des chaînes d’appels d’outils. Dans un environnement commercial réel, il est difficile de s’en tenir à une seule méthode, et les sorties structurées montrent leurs limites face à des intentions ambiguës, ce qui impose des stratégies complémentaires
  • Selon un autre avis, le problème n’est pas l’appel de fonctions en soi, mais la conception et l’usage de MCP. La plupart des MCP ne sont que des duplications d’API et produisent un déversement de données sans intérêt. Le format JSON est imbriqué de manière répétitive, ce qui consomme inutilement beaucoup de contexte d’entrée, avec de nombreuses informations non pertinentes. Il faudrait optimiser en aplatissant les données et en supprimant les champs inutiles. Les SaaS MCP ne sont au fond que des API gateways. Dans son état actuel, MCP est l’un des principaux générateurs de bruit et n’est pas assez optimisé
    • GraphQL est précisément une technologie adaptée à cet objectif. Elle est conçue pour permettre la sélection des seuls champs nécessaires. Développement d’une gateway open source qui convertit plusieurs requêtes GraphQL en un seul serveur MCP
    • Question soulevée : le vrai problème n’est-il pas plutôt que le modèle ne respecte pas correctement des schémas JSON complexes ?
    • MCP n’aide pas, mais filtrer systématiquement n’est pas non plus la meilleure solution. Parfois, un agent doit traiter de grands volumes de données. Dans ce cas, l’exécution de code avec une évaluation simple des données et une description du schéma constitue une approche plus scalable. Bien sûr, si le système grossit trop, des problèmes similaires réapparaissent. La solution ultime serait de reproduire en code la précision de la pensée déterministe humaine, puis de faire appeler ce système décisionnel par le LLM. Cela paraît simple en théorie, mais très difficile à mettre en œuvre en pratique
    • Lors d’un test d’inversion de chaîne avec ChatGPT, il a été très difficile d’obtenir du LLM qu’il ne fournisse qu’un résultat simple, et la fiabilité a semblé faible. Depuis cette expérience, habitude prise de faire vérifier les résultats par plusieurs LLM. Plaisanterie : à ce rythme, il faudra peut-être bientôt préparer son propre datacenter GPU juste pour compter les caractères dans une chaîne
  • L’équipe de Shopify a récemment open sourcé Roast. C’est un outil qui permet d’insérer des tâches LLM non déterministes dans un workflow pour automatiser un immense codebase. Jugé indispensable pour automatiser des tâches complexes
    • Roast fait forte impression. L’équilibre entre déterminisme et non-déterminisme ressort particulièrement bien. Il subsiste une légère confusion sur la manière dont le LLM orchestre plusieurs appels d’outils et décide de leur ordre. Cela semble fonctionner pour des consignes de refactoring, mais on s’interroge sur son adéquation à des tâches composites comme « améliorer → tester en boucle »
    • Il est rafraîchissant de voir que Ruby continue à fonctionner de manière pertinente à l’ère de l’IA
    • Une excellente approche, stimulante intellectuellement rien qu’à la lecture de la documentation. L’empaquetage déclaratif des capacités du LLM est particulièrement marquant
    • Demande de partage d’exemples concrets sur la manière dont ce type de workflow est réellement utilisé en interne chez Shopify
    • Expérience d’avoir fait planter à la fois Claude Code Research Preview et ChatGPT 4.5 Pro Deep Research (avec preuves à l’appui), et recherche en cours d’un outil qui fonctionne vraiment de façon fiable
  • La meilleure réponse se situe non pas dans un extrême, mais dans une approche hybride. Il est préférable de résoudre autant que possible par des méthodes déterministes, et de réserver les LLM aux parties complexes difficiles à spécifier ou à traiter avec des techniques déterministes
    • Une approche intéressante consiste à utiliser les LLM pour générer une solution déterministe (du code), puis à réutiliser ce code comme composant déterministe une fois validé
    • Certains soutiennent que l’objectif doit être de minimiser l’usage des LLM dans le workflow
  • Surprise de voir à quel point ce type d’expérimentations complexes semble s’être banalisé après plus d’un an loin du secteur
    • En réalité, seuls quelques acteurs expérimentent encore, et même s’il n’y a pas de cas révolutionnaires, certains usages sont utiles
    • Autre point de vue : ne pas faire ce travail aujourd’hui, c’est risquer de devoir bientôt quitter à nouveau le secteur
    • Le travail quotidien de certains est déjà largement centré sur l’automatisation de la conception d’agents IA fondés sur des LLM, non par choix explicite mais presque malgré eux
  • Interrogation sur l’intérêt d’utiliser des LLM pour trier des données structurées
    • Le but principal est en réalité un traitement de données plus complexe : création de dashboards, identification automatique de tickets d’incident, revues trimestrielles, etc. Le tri n’était qu’un exemple simple destiné à rendre l’ampleur du problème plus facile à comprendre
  • huggingface smolagent est présenté comme un cas représentatif de cette approche, mais avec le problème que les rollbacks ou récupérations deviennent très difficiles en cas d’échec réel. Une solution de principe existe, comme encapsuler l’ensemble du bloc d’exécution dans une transaction distribuée, mais en pratique le LLM, en essayant de produire du code robuste, s’accorde mal avec ce pattern, ce qui rend le suivi des erreurs et l’identification de leur cause difficiles
    • Accord sur le fait que l’idée de base de smolagent est bonne, mais que la réalité de l’exécution et de la gestion des erreurs pose problème. Exemple : lorsqu’une exécution de code s’interrompt, on voudrait pouvoir reprendre directement depuis cet état. Il a été confirmé que le LLM écrit correctement du code de récupération d’état, et cette capacité fonctionnerait déjà assez bien dans un produit réel (Lutra)
  • Autre approche : amener le LLM à écrire du code appelant MCP comme une fonction, sous la forme d’un script Python. Exemple de code partagé
    • Présentation de Lutra.ai comme cas d’usage concret de cette méthode. Le point clé est la qualité de conception du runtime de code
  • Constat que les LLM sont particulièrement faibles avec JSON, surtout avec de gros volumes de JSON. Rien n’impose qu’un endpoint renvoie forcément des données en JSON ; d’autres formats peuvent convenir. Les LLM semblent parfois bien meilleurs avec XML, et on peut aussi générer un texte narratif à l’aide de templates
    • XML est un format porteur de sens intrinsèque, d’où l’étonnement qu’il ne soit pas davantage utilisé par défaut avec les LLM. Si nécessaire, il peut être transformé de manière déterministe en JSON avant d’être injecté dans le pipeline, ce qui peut être efficace
    • Retour d’expérience indiquant que l’usage de tableaux Markdown pour renvoyer des données à un LLM a donné de très bons résultats
    • Question ouverte : XML est-il plus performant parce qu’il apparaît plus souvent dans les données d’entraînement des LLM, ou parce qu’il contient davantage de tokens textuels ? Hypothèse selon laquelle des blocs de texte fournissent simplement plus de contexte au LLM