1 points par GN⁺ 3 시간 전 | 1 commentaires | Partager sur WhatsApp
  • Les agents LLM sont performants pour la génération de code à partir de spécifications souples, mais restent encore fragiles lorsqu’il faut respecter les contrats d’API, l’architecture, la base de données et les contraintes ORM exigés par un backend de niveau production
  • Les exigences fonctionnelles sont fixées à partir d’une même spécification OpenAPI, et les mêmes tests de comportement sont appliqués à 80 tâches greenfield et 20 tâches d’implémentation de fonctionnalités sur 8 frameworks web
  • Les contraintes non fonctionnelles sont réparties en 4 dimensions — choix du framework, pattern d’architecture, backend de base de données et intégration ORM — afin d’isoler l’impact de la complexité structurelle
  • Le constraint decay désigne le phénomène de chute brutale des performances à mesure que les exigences structurelles s’accumulent, avec une baisse moyenne de 30 points du taux de réussite des assertions sur les tâches entièrement spécifiées et fortement configurées
  • Le cœur des échecs vient des défaillances de la couche de données : une mauvaise construction des requêtes et des violations d’exécution ORM représentent environ 45 % des échecs de logique des agents

Problème central et configuration de l’évaluation

  • Les agents LLM sont performants pour la génération autonome de code à partir de spécifications souples, mais leur capacité à respecter rigoureusement les contraintes structurelles nécessaires à un logiciel backend de niveau production n’a pas encore été suffisamment évaluée
  • Un backend de niveau production doit satisfaire non seulement des endpoints conformes au contrat d’API, mais aussi des exigences hors fonctionnalité comme des patterns d’architecture, l’intégration de la base de données et une couche ORM imposée
  • Les benchmarks existants récompensent souvent des solutions fonctionnellement correctes mais structurellement arbitraires, et ne capturent donc pas pleinement la difficulté du développement backend multi-fichiers sous contraintes
  • Les travaux antérieurs se sont surtout concentrés sur la résolution d’incidents spécifiques dans des bases de code existantes, sur la génération non contrainte à partir de prompts en langage naturel, sur des solutions en fichier unique ou sur la complétion de code squelette, sans traiter l’effet d’une variation systématique du niveau de contrainte structurelle
  • Les exigences fonctionnelles sont fixées à partir d’une même spécification OpenAPI, et les mêmes tests de comportement de bout en bout sont appliqués à toutes les conditions afin d’isoler l’impact de la complexité structurelle
  • L’expérience se compose de 80 tâches de génération greenfield et de 20 tâches d’implémentation de fonctionnalités couvrant 8 frameworks web
  • Les contraintes non fonctionnelles sont divisées en 4 dimensions : choix du framework, pattern d’architecture, backend de base de données et intégration ORM
  • Dans la condition de base, seule la même spécification d’API est fournie ; dans la condition sous contraintes, des exigences supplémentaires comme clean architecture, PostgreSQL et SQLAlchemy sont ajoutées
  • L’évaluation combine des tests de comportement de bout en bout et un validateur statique afin de distinguer la précision fonctionnelle du respect structurel

Principaux résultats et leur signification

  • Le constraint decay est confirmé comme le phénomène selon lequel les performances des agents chutent fortement à mesure que les exigences structurelles s’accumulent
  • Même pour les configurations les plus performantes, le taux de réussite des assertions baisse en moyenne de 30 points entre la condition de base et les tâches entièrement spécifiées ; certaines configurations plus faibles tombent presque à 0
  • À contrat d’API identique, les taux de réussite varient fortement selon le framework, et les agents s’en sortent mieux avec des frameworks légers et explicites comme Flask
  • Dans des environnements plus conventionnels comme FastAPI ou Django, les performances moyennes sont nettement plus faibles
  • L’analyse des erreurs montre que les défaillances de la couche de données constituent la cause principale, notamment une mauvaise construction des requêtes et des violations d’exécution ORM
  • Les défaillances de la couche de données sont classées comme la cause majeure d’environ 45 % des échecs de logique des agents
  • Satisfaire simultanément les exigences fonctionnelles et les exigences structurelles reste un problème important encore non résolu pour les agents de code
  • Le pipeline d’évaluation, l’ensemble de tâches, les trajectoires d’exécution des agents et les scripts d’analyse sont disponibles sur constraint-decay

1 commentaires

 
GN⁺ 3 시간 전
Commentaires sur Hacker News
  • J’étais totalement sceptique vis-à-vis de la génération de code par les LLM, mais désormais plus de 80 % du code que j’utilise au travail est du code généré
    Cela dit, les limites sont devenues assez nettes, elles commencent à apparaître dans certains projets, et cet article semble confirmer mes doutes
    Plus la tâche est complexe, plus on finit par ajouter des spécifications Markdown, des règles, des contraintes sur les skills, des guides de style, des cas limites, de la gestion d’erreurs et des consignes d’optimisation
    À un moment, on a l’impression de déplacer la complexité du monde plus formel et déterministe des langages de programmation vers le monde informel et non déterministe du langage naturel
    Le gain de vitesse d’écriture est énorme, et les entreprises y voient naturellement un gain de productivité, mais le prix à payer est évident, même si beaucoup semblent l’ignorer

    • C’est précisément le problème dont personne ne parle. La codebase grossit avec des fichiers Markdown remplis d’instructions, de guidelines et de demandes destinées au LLM, et tout cela ne cesse de s’accumuler
      Personne ne les relit à 100 %, et même quand c’est le cas, c’est très subjectif
      La différence entre « suivre une approche RESTful », « nous utilisons REST et pas GraphQL » et « 90 % des endpoints sont orientés ressources, mais certains ressemblent à du RPC donc ignorez cela » reste floue
      Tout cela paraît assez idiot
    • C’est comparable à utiliser un compilateur qui génère, à chaque exécution, un code dont le sens change
      En pratique, c’est comme compiler un programme rempli de comportements indéfinis, mais qui semble la plupart du temps « fonctionner »
      Que les entreprises considèrent cela comme un gain de productivité donne l’impression de revenir à une époque où l’on mesurait de nouveau la « productivité » en lignes de code par seconde
    • Même avec des codebases très grandes et complexes, je ne souffre pas énormément. Les types statiques forts aident clairement beaucoup, y compris à des tailles de plus de 50 Mo de sources brutes, mais ce n’est pas toute l’histoire
      Dès que la codebase ne tient plus dans les 20 % initiaux de la fenêtre de contexte et sort du cadre d’un raisonnement entièrement reproductible en une seule passe, le harness d’exécution et les techniques de patch de code deviennent bien plus importants
      L’approche apply_patch qu’OAI a affinée pour ses modèles semble être la meilleure pour les codebases géantes
      Les approches fondées sur des plages de lignes ou de simples recherches-remplacements s’effondrent sur les cas limites, et il faut plusieurs ancres spatiales pour traiter des cas délicats comme les fichiers cshtml
      Les opérations prepare/commit sont idéales pour itérer sur un contexte ambigu réparti sur de gros fichiers et affiner les ancres
    • Si 80 % du code généré vient d’un LLM, on est surtout dans la recombinaison de l’existant, et au final c’est du slop
      Les LLM ne peuvent pas créer quelque chose de vraiment nouveau
  • « Une étude systématique met en évidence un phénomène de désintégration des contraintes dans les agents de codage basés sur les LLM. Les modèles actuels excellent dans la génération sans contrainte, mais leurs performances chutent lorsqu’ils doivent respecter des règles d’architecture explicites. Pour l’utilisateur final, cette dichotomie signifie que les agents sont dignes de confiance pour le prototypage rapide, mais restent difficiles à juger fiables pour le développement backend de niveau production. »
    La grande faiblesse de cette étude est qu’elle n’a pas suffisamment testé les modèles de pointe à cause des coûts, donc il faut prendre les chiffres de performance précis avec prudence
    Malgré cela, la conclusion selon laquelle les performances des modèles baissent lorsqu’il faut à la fois respecter le comportement et l’architecture est intéressante et mérite d’être suivie

    • Cela ressemble à un effet en aval du problème selon lequel « on ne peut pas optimiser simultanément deux objectifs différents »
      S’il n’y a que des exigences fonctionnelles, on est en quelque sorte dans de la synthèse de programme, et le reinforcement learning peut l’optimiser très fortement
      Quand on mélange exigences fonctionnelles et non fonctionnelles, on donne en réalité au modèle une spécification incomplète, et il doit alors deviner dans une certaine mesure l’intention de l’utilisateur pour combler les vides
      C’est aussi pour cela qu’inclure dans le prompt des exemples du style de code souhaité est extrêmement puissant
    • J’ai observé un phénomène similaire dans un livre écrit avec assistance IA. Au début c’est correct, mais après quelques chapitres, le début de chaque chapitre répète la fin du précédent, et les tics caractéristiques des LLM apparaissent plus souvent
      Plus il y a de matière de référence, plus le système dépend de la répétition de ce qui a déjà été dit
      Il est aussi possible que les auteurs fassent moins attention et consacrent moins d’efforts à l’édition à mesure qu’ils avancent vers les derniers chapitres
      Amazon déborde de volumes, mais les LLM n’en sont pas encore au stade où ils écrivent bien
    • En planifiant avec Opus sur plusieurs interactions, j’ai vécu quelque chose de similaire
      Lorsqu’il propose une solution incompatible et qu’on lui ajoute du contexte et des exigences supplémentaires, il a tendance à se figer sur l’architecture d’origine et à avoir du mal à s’adapter
      Parfois, il essaie même de glisser en douce des changements qui servent encore le plan initial
    • Cela peut être le même problème que celui qu’on voit quand les prompts essaient d’imposer un « alignement » ou des « guardrails ». Les performances chutent
      On a l’impression que de gros pans de l’espace des solutions possibles deviennent inaccessibles
      Par exemple, il y a environ un an, quand on appliquait des guardrails aux générateurs d’images, tout le monde finissait par se ressembler, et les générateurs d’histoires se mettaient à n’utiliser que quelques prénoms standard
      Je me demande si cela se produit encore dans les modèles de pointe
    • Même GPT 5.2, le modèle de pointe le plus puissant utilisé dans cette étude, me paraît tout juste passable pour la programmation agentique
      Je ne m’intéresse pas particulièrement à l’analyse des faiblesses de ce type de modèles. D’après mon expérience, à mesure que les modèles progressent et qu’on augmente l’effort de raisonnement, beaucoup de faiblesses disparaissent complètement
      C’est particulièrement vrai lorsqu’on explicite clairement le comportement souhaité, et il n’est pas surprenant que le taux d’échec augmente quand on multiplie les critères d’acceptation
  • La situation est pire encore. Non seulement les agents ont plus de mal sous des contraintes structurelles, mais ils sont encore moins bons quand ces contraintes structurelles elles-mêmes doivent changer
    Quand on conçoit un système ou un composant, on établit des idées qui deviennent des invariants
    Certains invariants sont vastes, comme une architecture globale, d’autres sont petits, comme le choix d’une structure de données
    Mais il arrive toujours un moment où l’on veut ajouter une fonctionnalité qui entre en conflit avec ces invariants
    À ce moment-là, il y a généralement trois options : ne pas ajouter la fonctionnalité, la greffer de manière peu élégante ou inefficace par-dessus les invariants, ou revenir en arrière pour modifier les invariants
    En général, une seule de ces options est la bonne, et au moins une est très fortement erronée et mène à de mauvais résultats
    Les agents sont très mauvais pour reconnaître le moment où il faut modifier les contraintes, même lorsqu’ils sont capables de les suivre

    • J’ai des attentes très limitées vis-à-vis du codage agentique, mais je l’ai quand même un peu utilisé, et cela correspond tout à fait à mon expérience
      C’est l’une des frontières entre reconnaissance de motifs et raisonnement, et contrairement au discours marketing sur la « chaîne de pensée », les LLM ne raisonnent absolument pas
      Toutes les tentatives visant à leur donner l’apparence du raisonnement me semblent relever d’un effort récursif d’isolation, où le harness essaie de mettre la foudre en bouteille
  • Cela me rappelle un article récent qui confiait à des LLM des tâches d’édition de documents dans plusieurs domaines https://arxiv.org/abs/2604.15597
    Dans cet article, ils considéraient que la programmation était pratiquement le seul domaine où la plupart des LLM pouvaient accomplir des tâches à long horizon sans accumuler d’erreurs ni dégrader le document
    Je n’ai lu que le résumé de cet article-ci pour l’instant, mais il semble examiner la programmation plus finement et montrer un phénomène similaire
    Cela dit, cela ressemble moins à des tâches à long horizon qu’à un « long horizon de style » appliqué à un ensemble plus large de contraintes structurelles
    Discussion associée : https://news.ycombinator.com/item?id=48073246

    • Les LLM ne sont pas doués pour les tâches qu’on ne peut pas vérifier facilement
  • Article très intéressant, et je suis entièrement d’accord, mais je n’y vois rien de vraiment nouveau
    Dès le départ, il y avait un léger décalage avec l’attente initiale selon laquelle on pourrait déposer n’importe quelle solution de codage agentique dans un projet, lui lancer une liste de tâches, et qu’elle suivrait comme par magie les contraintes prédéfinies du projet
    Je ne crois pas qu’aucune pile de codage agentique sache faire cela en l’état par défaut
    Il faut toujours des mécanismes appropriés pour que l’agent comprenne de manière fiable le contexte, les contraintes et les objectifs, et le fait que les grands labos d’IA continuent à mettre à jour leurs outils, compétences et processus montre bien que c’est encore un domaine en cours de maturation
    Cette couche supplémentaire pourrait d’ailleurs être bien plus rentable que le simple modèle brut et la consommation de tokens
    Je pense même que des modèles ouverts du niveau de ceux qui semblent avoir été testés ici peuvent déjà produire du code de production qui respecte les contraintes voulues, s’ils sont correctement orchestrés
    Je serais curieux de savoir à quoi a ressemblé votre code de production ces derniers mois

  • J’ai pas mal expérimenté le codage agentique à long horizon https://medium.com/@vishvananda/i-spent-2-billion-tokens-wri... et j’ai aussi constaté que forcer certains motifs d’architecture dégrade les performances de l’agent
    C’est un peu mieux quand on introduit les contraintes au fil de l’exécution plutôt que de les ajouter après coup
    Il y a aussi un effet secondaire que j’appelle calcification : dès qu’un certain motif commence à apparaître dans la base de code, l’agent s’y accroche, ce motif finit par dominer le contexte et s’auto-renforce
    Dans une base de code existante, cela peut être une force ou une faiblesse selon la qualité du code
    On aura probablement plus d’enseignements quand davantage d’exécutions sur de nouvelles bases de code, avec des consignes d’architecture dès le départ, arriveront à leur terme

    • J’ai vu la même chose. Les agents et les modèles ont un style propre, qui se résume le plus souvent à une verbosité excessive
      Les modèles se débrouillent aussi à peu près pour modulariser quand on leur laisse de la place pour « planifier » l’implémentation, mais il est rare qu’ils décident d’eux-mêmes qu’une abstraction sera utile plus tard
      C’est particulièrement vrai après plusieurs itérations sur une nouvelle base de code ou lorsqu’on les lâche sur une base legacy, et cela mène souvent à des fichiers géants
      Quand l’utilisateur le leur signale, les modèles en font une critique pertinente, ce qui est assez drôle quand il s’agit du code qu’ils ont eux-mêmes écrit au départ
  • On dirait une autre version de « plus la conversation s’allonge, plus les garde-fous semblent s’estomper »
    C’est la raison pour laquelle on ne peut pas exploiter toute la fenêtre de contexte : vers la fin, la sortie cesse de respecter les contraintes ou les garde-fous
    Or, pour produire du code de niveau production de façon fiable, le modèle doit avoir une vision large, ce qui remplit très vite la fenêtre de contexte
    C’est comme demander : « fais ce changement en gardant à l’esprit tout ce qu’il y a dans ces 6 répertoires » ; mais le simple fait de tout garder à l’esprit suffit déjà à saturer la fenêtre de contexte et à lui faire perdre sa capacité à respecter les contraintes

    • Ce n’est pas un problème nouveau. C’est précisément pour cela qu’on s’est mis à utiliser du code modulaire et des interfaces strictes
    • Est-ce qu’il ne suffirait pas de garde-fous plus forts ? Du genre Sonarcube
      Cela dit, le mode d’échec risquerait alors de se déplacer vers une focalisation excessive sur la satisfaction du linter, avec un oubli progressif des exigences
      Et les boucles répétées essai/échec ne sont sûrement pas bonnes du tout pour le contexte
  • L’étude utilisait des langages à typage dynamique comme Python et JS
    D’après mon expérience, les bases de code à typage statique sont plus faciles à maintenir pour les humains, donc elles le sont peut-être aussi pour les agents
    En Go, avec Codex ou Claude Code, j’ai vu d’innombrables fois l’agent faire un changement, lancer une build, repérer les erreurs, puis corriger à nouveau

    • Il suffit d’ajouter des types aux règles du harnais et d’exécuter ty après chaque modification
      Les modèles d’aujourd’hui gèrent plutôt bien les types Python
    • Je trouve étrange que tant de gens considèrent Python comme un langage dynamiquement typé par défaut
      Python propose depuis plusieurs années un typage statique robuste en option, et cela devrait simplement être la valeur par défaut
  • Ils parlent de « tâches réparties sur 8 frameworks web », et je me demande si d’autres ont aussi l’impression que les LLM produisent mieux du HTML+CSS+JS pur que du travail sur des frameworks existants

    • Les frameworks web semblent être dans une « situation délicate » depuis gpt-5.4. Il devient difficile d’imaginer utiliser quelque chose comme React maintenant
      La combinaison la plus impressionnante que j’ai vue récemment, c’est Razor Pages avec de l’amélioration progressive en JavaScript
      Dans cette configuration, les modèles récents jugent plutôt bien ce qui doit se passer côté serveur (cshtml) et ce qui doit se passer côté client (js)
  • Je recommande de prendre le temps de remettre d’abord certaines parties de la base de code dans une forme idiomatique, puis de désigner ces fichiers avec @ comme fichiers d’exemple
    Cela marche bien mieux que d’essayer de piloter le modèle en Markdown
    Avec FastAPI par exemple, ça fonctionne plutôt bien, mais JavaScript semble être le pire cas
    Même avec des consignes et des exemples, il a tendance à inliner un tas de code inutile au lieu d’utiliser l’API indiquée