8 points par GN⁺ 2025-08-15 | 2 commentaires | Partager sur WhatsApp
  • Un ingénieur logiciel efficace construit et maintient un modèle mental clair des exigences et du code, puis effectue en boucle des comparaisons et des mises à jour répétées
  • Les LLM peuvent écrire et modifier du code, rédiger des tests et déboguer, mais ils manquent de capacité à maintenir un modèle mental précis, ce qui les amène à se perdre dans les tâches complexes
  • Aujourd’hui, les LLM ont des limites pour identifier avec précision les écarts entre le code et les exigences puis les corriger de manière appropriée, en raison de problèmes d’omission de contexte, de biais de récence et d’hallucinations
  • Les humains peuvent changer de mode de pensée avec souplesse selon la situation, par exemple en stockant temporairement le contexte global ou en masquant momentanément les détails pour voir la situation d’ensemble, mais les LLM ne savent pas le faire
  • Les LLM sont utiles pour les tâches aux exigences simples, mais dans le développement logiciel complexe, c’est au final l’ingénieur logiciel de prendre directement la responsabilité de la clarté des exigences et du comportement du code, les LLM jouant un rôle d’outil d’assistance

La boucle de l’ingénierie logicielle

  • Un ingénieur expérimenté travaille en répétant les étapes suivantes
    1. Construire un modèle mental des exigences
    2. Écrire le code en fonction de ce modèle
    3. Comprendre ce que fait réellement le code produit
    4. Identifier les écarts et corriger le code ou les exigences
  • Le cœur de cette boucle est la capacité à disposer d’un modèle mental exact et maintenable

Les limites des LLM

  • Les LLM peuvent écrire du code, repérer un problème puis le corriger, rédiger et exécuter des tests, ajouter des logs et utiliser un débogueur
  • Mais comme ils ne parviennent pas à maintenir un modèle mental, les problèmes suivants apparaissent
    • Ils supposent que le code qu’ils ont écrit fonctionne bien
    • Quand un test échoue, ils s’appuient sur des suppositions pour décider s’il faut corriger le code ou le test
    • Lorsqu’ils sont perdus, ils suppriment tout le code et recommencent depuis zéro
  • Contrairement à un humain, ils manquent de souplesse pour examiner leur modèle quand un test échoue et décider de la direction de correction, ou pour dénouer le problème par l’échange lorsqu’ils sont bloqués
  • Un ingénieur logiciel exécute des tests en cours de travail et peut déterminer clairement quelle partie doit être corrigée lorsqu’un problème survient
  • Parfois, même lorsqu’il faut recommencer l’ensemble du travail, cela conduit à une compréhension plus profonde du problème

Possibilités futures

  • Les choses pourraient changer à mesure que les modèles progresseront, mais l’ingénierie logicielle exige plus que la simple génération de code
  • Lorsqu’un humain résout un problème important, il peut extraire temporairement le contexte global de sa mémoire pour le manipuler, se concentrer sur un point précis ou prendre du recul sur l’ensemble
  • L’important n’est pas d’empiler toujours plus d’informations de contexte, mais d’adopter une manière de penser qui traite sélectivement les informations nécessaires
  • Les LLM ne disposent pas de cette capacité, propre aux humains, à stocker et restaurer temporairement le contexte, ni à naviguer entre la vue d’ensemble et les détails
  • Principales limites actuelles des LLM
    • Omission de contexte (Context omission) : difficulté à repérer les parties où des informations nécessaires manquent
    • Biais de récence (Recency bias) : tendance excessive à privilégier les informations les plus récentes dans la fenêtre de contexte
    • Hallucination (Hallucination) : invention de détails qui n’existent pas
  • L’ajout de fonctions de mémoire pourrait améliorer certains points, mais au-delà d’un certain niveau de complexité, ils échouent encore à comprendre le contexte et à maintenir un modèle
  • Ils peinent à conserver deux modèles mentaux similaires, à analyser leurs différences et à décider où modifier les exigences ou le code

Rôle actuel et usages

  • Les LLM excellent dans la génération rapide de code et l’intégration des exigences et de la documentation, ce qui les rend tout à fait exploitables pour des tâches simples et bien définies
  • Mais pour les problèmes non triviaux, il leur est difficile de conserver un contexte suffisant et de procéder à des améliorations itératives
  • En conséquence, la clarification des exigences et la vérification du code restent de la responsabilité de l’ingénieur logiciel
  • On vise un environnement où humains et agents (LLM) construisent des logiciels ensemble, mais à l’heure actuelle, l’ingénieur doit garder la main et le LLM doit être utilisé comme un outil

2 commentaires

 
kandk 2025-08-18

Pourquoi les LLM d'« aujourd'hui » ne peuvent pas réellement créer des logiciels...

 
GN⁺ 2025-08-15
Avis Hacker News
  • Nous ne résolvons pas les problèmes simplement en ajoutant plus de mots dans la fenêtre de contexte, sinon nous finirions par perdre la raison
    Quand un problème survient, nous ne le regardons pas non plus uniquement comme du texte
    Si une erreur d’authentification apparaît dans le débogueur, nous ne nous disons pas : « Et si on supprimait juste la validation du token dans le code ? »
    En pratique, nous prenons du recul pour examiner l’ensemble de la situation afin d’identifier la cause racine du problème
    Par exemple, s’il y a une erreur d’authentification, nous revérifions tout le processus de validation du token ainsi que les permissions de l’utilisateur appelant, et nous pouvons nous rendre compte que c’est le test lui-même qui est erroné
    Au cours de ce processus, on découvre aussi qu’il faut distinguer plus finement les cas, par exemple si un code 401 vient simplement d’une absence d’authentification ou d’un manque d’autorisation
    Voir Grugbrain.dev

    • Je considère que le travail du programmeur consiste à traduire des règles métier en une forme rigoureuse qu’un ordinateur peut comprendre
      Cette traduction n’est pas toujours simple, car il faut comprendre à la fois le sens des règles et la manière dont l’ordinateur — ou le framework et les couches d’abstraction utilisés — fonctionne
      En particulier, quand de nouvelles exigences cassent toutes les hypothèses précédentes ou se contredisent, on n’a souvent pas d’autre choix que de reprendre plusieurs fois
      La traduction entre langues humaines est déjà complexe à cause de l’ambiguïté, mais l’ordinateur exécute exactement ce qu’on lui dit, donc la moindre erreur peut devenir un gros problème

    • Je pense personnellement qu’une approche réaliste consiste à garder l’humain impliqué en continu, de façon itérative
      Comme cette méthode permet de travailler plus vite et avec une meilleure qualité, je continue à l’utiliser

    • Personnellement, je peux absorber de très grandes quantités de contexte
      Le texte du code lui-même est vite évacué, et mon cerveau parse le code comme une structure de type AST (arbre syntaxique abstrait), voire comme un graphe spatial
      Je modélise logiquement le programme lui-même et je le perçois comme une structure totalement distincte du texte
      Vu sous cet angle, les LLM ne comprennent pas l’architecture logicielle, parce qu’ils se concentrent sur le texte sans construire de modèle logique du programme
      Concevoir l’architecture de systèmes à grande échelle, qui demande une pensée abstraite, exige énormément d’effort mental, et les LLM manquent de cette capacité d’abstraction

    • Ma méthode est la suivante
      Quand un échec de test est signalé, j’identifie d’abord le composant concerné, puis j’analyse en profondeur sa finalité, son flux de contrôle interne, ses changements d’état et ses hypothèses sur le contexte environnant, avant d’en faire une synthèse Markdown (<nom-du-composant>-mental-model.md)
      Ensuite, je me réfère toujours à ce modèle mental quand je traite un problème de test
      Si je colle cette analyse dans un prompt Claude, le LLM peut produire de meilleurs résultats
      Je peux même lire et corriger directement le modèle mental construit par le LLM

    • L’IA peut aussi conseiller d’utiliser un 403 au lieu d’un 401 en cas d’autorisation insuffisante

  • L’auteur semble mal comprendre les capacités actuelles des LLM et des outils de coding
    L’affirmation selon laquelle un LLM se contente de deviner si le code est juste ou si le test est faux quand un test échoue, puis finit par supprimer tout le code par frustration, ne correspond pas du tout à mon expérience
    Un ingénieur logiciel cherche toujours à identifier concrètement la cause d’un échec de test en la confrontant à son propre modèle mental
    J’utilise Cline et Anthropic Sonnet 3.7 pour développer en TDD sur Rails, et je fais toujours écrire les tests d’abord au LLM, puis le code
    Je découpe le travail en petites unités que je peux relire séparément, et quand un test échoue il raisonne plutôt bien sur la partie à corriger et fait souvent juste
    Les LLM sont loin d’être parfaits, mais ils obtiennent souvent des résultats comparables, voire meilleurs, que ceux d’un ingénieur junior humain
    Ils échouent parfois à corriger un bug, mais les développeurs débutants aussi, en réalité

    • Les LLM fonctionnent particulièrement bien pour les opérations CRUD dans un framework éprouvé comme Rails
      En revanche, quand j’ai essayé de créer une application Windows native avec Direct2D et Rust, c’était catastrophique
      J’aimerais voir des évaluations plus ouvertes selon les cas

    • Le fait que les modèles utilisent des combines et astuces, comme le hardcoding, pour faire passer des tests en échec est un phénomène très bien connu

    • D’après mon expérience, il y a une forte variabilité selon le langage, la plateforme et le domaine
      Récemment, je n’ai pas refait d’expériences sur Rails parce que je ne manipule plus beaucoup Ruby moi-même, mais Rails a une culture de programmation tellement cohérente que les LLM peuvent probablement s’en sortir correctement
      À l’inverse, en Python, les styles de code très différents s’entremêlent, si bien que les LLM mélangent plusieurs patterns et j’ai souvent vu des tests devenir instables
      Il faut modifier le code à répétition, et alors que la vraie erreur est un « tri manquant dans le résultat de la requête », le LLM peut bizarrement recommander de retirer SqlAlchemy et de basculer vers Django
      Avec le langage R, obtenir du code qui fonctionne correctement conformément à la spécification est déjà en soi difficile

    • Si on limite les LLM au niveau d’un ingénieur débutant, ils trouvent et appliquent des solutions très vite, surtout sur des problèmes qu’ils ont déjà vus
      En revanche, sur des problèmes nouveaux pour eux, ils ont besoin de plus d’explications ou de directives ; dans ce cas, mon rôle revient simplement à être le mentor
      Dans notre équipe, nous utilisons activement l’approche « claude-code » pour des refactorings simples restés longtemps dans le backlog, ou pour des tâches répétitives bien connues comme des systèmes d’analyse secondaire
      Personnellement, j’aime sélectionner un bloc de code et demander « explique-moi ça comme si j’avais 5 ans » ou « cherche s’il y a un risque de race condition »
      Comme le code généré diffère souvent du code existant et de son style, je dois fréquemment le retoucher moi-même pour qu’il respecte la convention de style
      On entend même aujourd’hui qu’il faudrait « écrire du code lisible pour l’IA », mais j’ai encore le sentiment que le bénéfice n’est pas énorme au regard de la charge supplémentaire

    • À propos de l’idée que « les LLM sont parfois comparables, voire meilleurs, qu’un junior », je me demande plutôt si ce n’est pas un reflet du niveau récent du recrutement de développeurs
      Si j’avais recruté un junior moins bon que Sonnet 3.7, je serais vraiment déçu

  • La plupart des critiques adressées aux LLM sont peut-être justes, mais des années d’expérience en investissement m’ont appris qu’il faut aussi regarder les technologies ou entreprises qui « ne sont pas terribles, mais continuent à progresser »
    Au début et au milieu des années 1990, beaucoup se plaignaient d’Internet, mais les gens ont continué à l’utiliser ; Twitter tombait souvent en panne, mais il s’est tout de même imposé comme plateforme d’actualité
    Les véhicules électriques, les smartphones et d’autres exemples étaient eux aussi imparfaits, mais comme ils apportaient de la valeur, ils se sont continuellement améliorés
    Les LLM ne sont pas encore parfaits pour de nombreuses tâches, mais ils ont déjà progressé d’un facteur 10 depuis 2022, et je pense que la plupart des problèmes mentionnés ici seront résolus dans les 5 prochaines années

    • Mais dans tous les exemples cités plus haut, les attentes n’ont pas toujours été alignées avec la réalité
      Même si Internet est devenu plus rapide, le métavers n’est jamais devenu dominant, et des limites physiques comme le mal des transports en VR ne sont toujours pas résolues
      À l’époque, il n’y avait pas vraiment de fortes plaintes sur la lenteur des téléphones, parce que les usages attendus étaient différents
      Observer la trajectoire d’évolution d’autres technologies ne garantit pas que les LLM suivront le même schéma
      Il faut garder à l’esprit qu’une autre technologie peut apporter une meilleure solution
      L’an dernier, il est vrai que le champ d’application s’est élargi, mais il n’y a toujours pas eu de percée qu’on pourrait qualifier de révolutionnaire

    • Même si les anciens téléphones portables étaient lents et avaient une mauvaise qualité photo, leur usage principal à l’époque — pouvoir contacter quelqu’un à tout moment, où que l’on soit — suffisait déjà à les rendre indispensables
      Les avancées spectaculaires n’étaient qu’un bonus ; les gens n’attendaient pas en se demandant « quand est-ce que ce téléphone deviendra vraiment bon ? »

    • Je pense qu’il y a aussi un biais de mémoire
      Contrairement à l’idée d’un mécontentement massif vis-à-vis d’Internet dans les années 1990, les utilisateurs restaient peu nombreux et l’adoption grand public est venue bien plus tard
      Il existe en réalité peu de preuves qu’un large public se plaignait alors de la lenteur d’Internet

    • On ne se souvient que des quelques produits qui ont réussi à progresser ; la plupart ont été vite oubliés ou ont disparu sans s’améliorer
      Plutôt que de parier sur une amélioration future, je préfère juger à partir de la situation présente

    • J’ai du mal à adhérer à la logique simpliste selon laquelle les progrès fulgurants des dernières années vont nécessairement se poursuivre au même rythme pour les LLM
      Ils peuvent atteindre une limite de croissance, et j’ai le sentiment que leur incapacité à découvrir de nouvelles connaissances ou à raisonner sur de l’information inconnue constitue leur limite décisive
      Je ne dis pas que ce sont des outils inutiles, mais je ne participerai pas à l’emballement excessif

  • Attendre d’un LLM qu’il entende seulement quelques phrases puis code immédiatement un prototype est irréaliste
    Si l’on faisait travailler une équipe de développeurs humains de cette manière, elle n’arriverait pas non plus à construire quelque chose de correct ; je me demande donc pourquoi on a de telles attentes envers les LLM
    Pour améliorer nettement la qualité des productions logicielles issues des LLM, il faut utiliser activement les processus et outils dont se servent déjà les équipes de développement
    article sur autonomous-software

    • J’ai lancé un projet appelé steadytext, codé de façon totalement autonome avec une approche surtout vibe, et le LLM a écrit jusqu’à un projet complexe de 7 000 lignes (bibliothèque Python, CLI, extension Postgres) en gérant lui-même les issues et les demandes de fonctionnalités
      Je n’ai même jamais regardé 90 % du code, et malgré cela la couverture de test globale, le passage de la CI et l’usage réel en production ne posent aucun problème
      Il faut impérativement un plan très détaillé dans CLAUDE.md, ainsi que des issues et des demandes formulées avec une précision concrète, mais avec cette préparation cela fonctionne bien
      Gérer ou produire efficacement du code avec des agents de coding n’est pas simple, mais mon expérience est positive
      GitHub de steadytext

    • J’accepte volontiers les points de vue critiques, mais pour résoudre des problèmes flous, l’essentiel reste que toute l’équipe partage beaucoup de contexte
      Même les solutions les plus créatives naissent de contraintes explicites et implicites
      Les LLM n’ont pas la capacité d’identifier ces contraintes ni de concevoir une nouvelle solution dans des contraintes mal définies
      Ce n’est qu’une fois que l’humain a défini le problème, son périmètre et les contraintes que le LLM peut devenir un outil d’aide à l’implémentation
      Pour l’instant, cela ne fait qu’ajouter une option de plus du type « avec quel outil vais-je terminer ce code ? »
      À mon avis, vouloir ramener tout ce débat à une solution unique et absolue, en mode tout ou rien, est justement irréaliste

    • En réalité, beaucoup d’ingénieurs humains travaillent déjà correctement dans ce type de situation
      Si donner des instructions à un LLM n’est pas si simple, je me demande alors quelle est sa raison d’être

    • Kiro applique cette approche ; ce n’est pas encore parfait car c’est encore tôt, mais quand on l’utilise comme prévu, c’est plutôt correct

  • En utilisant claude code, je ressens de plus en plus de frustration face au fait que « les LLM ne construisent pas de modèle mental clair »
    Je ne sais pas vraiment si des LLM purement textuels peuvent résoudre correctement ce problème

    • Cela me fait penser au cas de Google Genie 3, qui perdrait son état interne au bout d’environ une minute
      Intuitivement, j’ai l’impression qu’il faudra une nouvelle architecture au-delà du transformeur pour résoudre ce problème, capable de gérer le contexte court et long terme ainsi qu’un ajustement de ses propres poids, une sorte d’imitation de l’apprentissage
      Voir : discussion liée

    • Dernièrement, je me dis qu’une architecture d’agents hiérarchiques est peut-être une alternative réaliste
      Ce serait bien qu’un agent de plus haut niveau conserve seulement le modèle mental global, tandis que des agents de niveau inférieur se répartiraient le travail entre eux
      On pourrait probablement déjà mettre en place quelque chose de similaire avec les fonctions d’agent des outils Code ; je serais preneur de toute stratégie partagée à ce sujet

    • J’ai essayé claude-code-requirements-builder, c’est un peu mieux, mais je ne suis toujours pas satisfait

    • Dans la réalité du terrain, même un développeur junior « moyen » n’est pas très différent de ce qui est décrit plus bas
      Il pense que le code qu’il a écrit est forcément correct, panique quand un test échoue, et s’il ne trouve plus la direction à prendre, il finit au pire par tout supprimer pour repartir de zéro
      On voit du copier-coller depuis StackOverflow, des accusations contre le compilateur, et même des histoires de « rayonnement cosmique »

    • À force d’utiliser les LLM, je constate moi-même que je dois finalement garder la main sur le planning et la conception
      J’apprécie de pouvoir déléguer aux LLM les tâches répétitives de bas niveau et les tests, ce qui me laisse plus de temps pour réfléchir à la vue d’ensemble
      En revanche, j’aimerais beaucoup que la revue des résultats des LLM et leurs suggestions de changements deviennent bien plus interactives

  • Je pense que l’orientation prise par les startups IA est le vrai cœur du problème aujourd’hui
    Il ne faut pas une simple interface de chat, mais un workflow IA intégré naturellement dans l’IDE
    C’est déjà la tendance avec Visual Studio, InteliJ et Android Studio
    Je veux des outils qui se rapprochent d’un vrai programmeur : pouvoir donner des instructions à la voix dans ma langue maternelle, laisser l’IA comprendre tout le contexte du projet pour aller jusqu’au refactoring, à l’analyse statique et au feedback IA, faire l’UI à partir d’un croquis, coder à partir d’écriture manuscrite, générer des messages de commit à partir des changements de code, etc.

  • Je suis d’accord sur le fait que les LLM sont très utiles pour les tâches de niveau junior
    Ces derniers temps, cela m’a même fait reconsidérer l’ancienne idée selon laquelle « la vitesse de frappe n’est pas très importante »
    Avant, la vitesse de saisie du code comptait relativement peu, parce que la conception globale et la structuration avaient beaucoup plus d’importance
    Mais en utilisant Claude, j’ai réalisé qu’on peut désormais faire sans effort des modifications de code qu’on évitait auparavant parce qu’elles étaient trop pénibles
    Autrefois, ajouter une simple valeur à un enum obligeait à penser à toutes les parties correspondantes à modifier ; un LLM peut maintenant faire ces corrections automatiquement
    Les tâches fastidieuses où il fallait corriger les erreurs de compilation une à une peuvent aussi être confiées à Claude de manière itérative
    Comme plusieurs agents peuvent retoucher en parallèle différentes parties du code, je peux utiliser ce temps pour réfléchir à la structure d’ensemble ou même écrire sur HN
    En d’autres termes, ne plus avoir à corriger soi-même les erreurs de compilation permet d’appliquer davantage de changements plus rapidement, et d’achever d’un coup ce qui aurait autrefois occupé un junior toute une journée
    On peut donc se concentrer davantage sur l’architecture globale, régler enfin tout un tas de corvées de code repoussées depuis longtemps, et c’est très motivant

    • Je suis d’accord avec l’idée que « même si on tape plus vite, on n’atteint pas forcément plus vite l’objectif, parce que le vrai goulot d’étranglement, c’est la conception »
      Les LLM sont souvent mauvais pour produire une bonne conception, et même les petites fonctions qu’ils écrivent demandent presque toujours du refactoring
      Le gain de productivité existe au niveau de l’implémentation, mais il s’agit surtout de concrétiser des idées qui existaient déjà dans ma tête ou dans des documents
      C’est aussi utile pour le brainstorming
      Si je lui donne tout le code et les tests en demandant « est-ce qu’il y a des edge cases que j’ai ratés ? », une ou deux réponses sur dix sont réellement utiles
      Le correctif fonctionnel à court terme et l’excellence structurelle à long terme sont des problèmes tellement différents qu’on ignore encore si les LLM pourront un jour atteindre la seconde

    • À propos du fait qu’« il y a plein de choses qu’on aimerait faire dans la codebase », je constate en réalité que le vrai goulot d’étranglement, ce n’est pas la modification du code, mais la review

    • Si le fait que « le LLM fait vite ce qui prendrait toute la journée à un junior » finit par supprimer des occasions d’apprentissage pour les débutants et réduire les recrutements, je m’inquiète de savoir qui les fera progresser ensuite

  • Concernant le fait qu’un LLM « n’arrive pas à décider s’il faut corriger le code ou corriger le test quand un test échoue »
    Utiliser le langage « Red-Green-Refactor » aide
    Je précise désormais clairement au LLM le déroulé : phase RED (l’échec du test est normal), phase GREEN (obtenir un état qui passe avec le minimum de code), phase REFACTOR (améliorer le code sans casser les tests)
    Cela permet au LLM de ne pas voir la situation comme un simple « code cassé à réparer », mais de reconnaître le modèle mental du TDD

  • Il me semble clair que les LLM ne sont pas encore à la hauteur pour un projet entièrement nouveau du type « crée-moi mon propre Facebook »
    En revanche, pour des tâches plus précises comme « ajoute cette modale et aligne le style sur le code existant », j’ai souvent obtenu le résultat voulu
    En découpant le problème en petites unités et en les traitant une par une, on obtient de bien meilleurs résultats

    • Copier le code existant et le modifier soi-même comme on le souhaite, je sais déjà le faire
      Mon presse-papiers système, lui, fonctionne toujours de manière déterministe, contrairement au LLM, et ne crée pas sans fin de nouveaux problèmes inattendus

    • Je me demande comment un nouvel outil comme v0 réagirait à ce type de demande

  • Le processus en quatre étapes présenté au début de l’article me semble très proche de Deutsch dans « The Beginning of Infinity »
    Nos théories naissent de « conjectures », et la connaissance se construit par une boucle de « conjecture et critique »
    Écrire du code revient à faire une sorte de « conjecture », et créer des tests revient à produire une « critique » de cette conjecture
    Dans les deux cas, il s’agit d’un processus visant à se rapprocher d’une explication mentale, d’un idéal platonicien