Le code est devenu moins cher
(htmx.org)- Avec la généralisation des outils de codage par IA, le coût d’écriture du code a fortement baissé, mais en contrepartie le coût de compréhension du code généré a augmenté
- Les LLM sont non déterministes, ne conservent pas le code source d’origine et produisent des sorties bien au-delà du périmètre des logiciels classiques, donc on ne peut pas les assimiler à la sortie d’un compilateur
- Les LLM génèrent du code bien plus vite qu’un humain ne peut le comprendre, d’où la recommandation d’un usage progressif (incremental) pour éviter des changements massifs que personne ne maîtrise
- Quand le code devient bon marché, le risque central est la complexité, qui augmente au minimum de façon géométrique avec la taille du système, tandis que les LLM sont des codeurs prolifiques sans crainte de la complexité
- Comme réponse, l’auteur propose l’ingénieur soustractif (subtractive engineer), qui retire et simplifie au lieu d’ajouter du code, afin de préserver l’art de la programmation informatique
L’ère du code bon marché
- Depuis un an, l’IA produit très vite et en grande quantité du code d’une qualité assez correcte, ce qui a fortement fait baisser le coût de génération du code
- À l’affirmation selon laquelle « le codage n’a jamais été le vrai problème », l’auteur répond que le codage faisait bien partie du problème, et que cette part a été largement réduite par les outils de codage IA
- Il interroge ce que signifie, pour les développeurs qui tiraient autrefois leur fierté de leur capacité à coder, la baisse d’importance du codage pur
La hausse du coût de compréhension (Understanding is Expensive(er))
- Quand le code n’est plus produit laborieusement par les programmeurs mais généré en masse, la compréhension de ce code n’existe tout simplement pas
- Si une compréhension est nécessaire, il faut l’acquérir en lisant le code après coup
- En règle générale, lire le code écrit par quelqu’un d’autre est plus difficile que d’écrire son propre code
- L’argument pro-IA selon lequel « on ne comprend pas non plus la sortie d’un compilateur » est qualifié d’erreur de catégorie (category error)
- Un compilateur est déterministe, alors qu’un LLM est par conception non déterministe
- Le workflow d’un compilateur conserve le code source d’origine, tandis que celui d’un LLM ne le fait généralement pas
- La sortie d’un compilateur est limitée au domaine étroit du code machine, alors que celle d’un LLM n’est pas bornée au logiciel généralisé
- Dans la plupart des cas, et tout particulièrement pour les logiciels critiques, les développeurs doivent comprendre le code sous-jacent même s’il a été généré par un LLM
- Les LLM peuvent produire du code à une vitesse que personne ne peut suivre, ce qui crée un risque de dépassement de la capacité de compréhension
- D’où la recommandation d’un usage progressif, plutôt que de générer d’un coup d’immenses listes de modifications
- Cela peut convenir à du refactoring mécanique, mais devient extrêmement risqué lorsqu’il s’agit d’introduire de nouvelles sémantiques dans une base de code
Le piège de l’apprenti sorcier (The Sorcerer’s Apprentice Trap)
- La séquence de « The Sorcerer’s Apprentice » dans le film Disney Fantasia est proposée comme une métaphore pertinente pour l’ère de l’IA
- Pour s’épargner la corvée du ménage, l’apprenti ensorcelle un balai, qui se met à nettoyer de plus en plus frénétiquement jusqu’à rendre la situation incontrôlable
- Finalement, le sorcier réapparaît, reprend la situation en main, réprimande la folie de l’apprenti et met fin au chaos
- La leçon de cette métaphore est qu’il faut être le sorcier, pas l’apprenti — et le sorcier doit comprendre le code
La complexité reste un problème (Complexity: Still Bad)
- Les humains comprennent mal les courbes géométriques ou exponentielles et considèrent volontiers des phénomènes comme les intérêts composés comme s’il s’agissait de contes
- Quand le code devient bon marché, le risque central est la complexité, qui, selon l’auteur (sans démonstration), augmente au minimum de façon géométrique, et souvent exponentielle, avec la taille du système
- Il existait déjà des codeurs prolifiques (prolific coders) avant les LLM
- Un codeur prolifique qui n’a aucune crainte de la complexité continue d’empiler du code sur les problèmes existants, jusqu’à faire s’effondrer le système dans un état de stagnation irréparable où chaque correction crée autant de bugs qu’elle n’en résout
- Les LLM sont dangereux précisément parce qu’ils sont à la fois prolifiques et totalement dépourvus de peur face à la complexité
L’ingénieur soustractif, qui contraint (The Subtractive, Constraining Engineer)
- Pour répondre aux risques du code généré par les LLM, l’auteur propose la figure de l’ingénieur soustractif, qui contraint (subtractive, constraining engineer)
- Cet ingénieur sait dire « non », examine minutieusement la sortie des LLM, propose des simplifications et garde fermement le contrôle
- Il tire sa fierté non pas du code qu’il a produit, mais du code — et des couches — qu’il a supprimés ou empêchés d’entrer dans le système
- Cette posture relève davantage du sculpteur que du constructeur
- La posture du constructeur reste valable au niveau de la conception système
- Un bon ingénieur doit savoir assembler efficacement des composants pour construire un système
- Mais même à ce niveau, une logique soustractive reste utile pour supprimer les composants inutiles et les frontières système superflues, afin de simplifier le déploiement et les interactions
- L’ingénieur soustractif représente un profil différent de celui de la majorité des codeurs d’autrefois ; il est plus en affinité avec le fait de savoir dire « non » et de préférer l’amélioration des systèmes existants aux grandes réécritures héroïques
- Cette approche reconnaît une double réalité — le code est devenu moins cher, et la complexité reste le prédateur suprême (apex predator) — et constitue une manière productive de préserver l’art de la programmation informatique
1 commentaires
Commentaires sur Lobste.rs
L’article de 1985 de Peter Naur, Programming as Theory Building, semble valoir plusieurs relectures supplémentaires aujourd’hui
Dire que « les LLM ne savent pas craindre la complexité » me paraît relever davantage de l’exagération
Le mode d’échec existe bel et bien. Si on donne des consignes trop larges, les LLM ajoutent des couches, produisent des abstractions et génèrent souvent du code disproportionné par rapport au problème. Mais ce comportement est facile à observer, facile à relire, et étonnamment facile à réorienter. Il suffit d’aligner le style logiciel voulu avec des fichiers AGENTS/CLAUDE.md
Il suffit d’exiger le plus petit changement possible, de demander ce qu’on peut supprimer, et de demander si l’abstraction apporte vraiment quelque chose. On peut aussi poser des questions sur les invariants, les points de couplage et la charge cognitive, puis demander une seconde passe pour retirer les effets de manche ; en général, il suit cette pression. Si on l’inscrit dans le prompt, on peut même lui faire éviter cela dès le départ
Le risque n’est pas que les LLM soient incapables, par principe, de respecter la complexité ; c’est qu’ils produisent volontiers la forme de code que les processus autour d’eux récompensent. Les équipes qui récompensent la quantité obtiennent de la quantité, et celles qui récompensent la simplicité peuvent en général obtenir cela aussi
Les modèles actuels sont meilleurs que la plupart des humains, et ils vont encore s’améliorer. Si le code n’est pas bon, il faut faire pression sur les labos d’IA via le feedback. Par exemple, je trouve que la famille GPT est nulle pour rédiger de la bonne documentation
Donc dire que c’est « impossible » n’est peut-être pas le meilleur choix de mots, mais je pense qu’il existe, par défaut, plusieurs biais qui les font pencher vers la complexité
Il y a aussi un biais en faveur de faire quelque chose plutôt que de ne rien faire. Un bon programmeur mobilise bien plus de contexte qu’un manager qui lance simplement une demande précise, et il propose parfois des alternatives. Les LLM pourraient peut-être le faire, mais aujourd’hui, même avec des mécanismes de type « poser des questions pendant la planification » ou de détection de boucles, ils ne sont pas doués pour poser les bonnes questions. Il est aussi probable que ce type de données d’entraînement soit rare
D’une certaine manière, le prompt engineering ressemble à un horrible bricolage autour de tout cet ensemble de problèmes
D’un autre côté, il m’est arrivé de devoir convaincre et rassurer un LLM après avoir reçu une réponse du genre : « Je ne le recommande pas pour un projet d’un mois. Pourquoi ne pas le commit tel quel et le garder comme démo ? » alors que je savais que les deux options prendraient moins d’une heure. En revanche, si on lui dit : « Vas-y, fais quelque chose de totalement nouveau. Trouve toi-même la méthode », il essaie quand même ; en ce sens, on peut aussi dire qu’il n’a pas peur
Blague à part, je suis d’accord. Ça correspond aussi à mon expérience
Je ne suis pas vraiment d’accord, de façon générale, avec l’idée que « le coût de compréhension du code a augmenté »
Cela peut être vrai pour du code LLM généré sans réflexion, mais si on le guide correctement, un LLM peut aussi produire du code facile à lire et bien structuré en couches. Bien sûr, dans ce cas, la plupart des choix d’architecture sont faits par un humain, et à mon avis c’est justement comme ça que ça devrait être
À l’inverse, j’ai trouvé les LLM très bons pour comprendre du code écrit par quelqu’un qui ne m’est pas familier. Je peux demander à Claude Code d’analyser en profondeur un code précis, d’en faire un document Markdown expliquant chaque partie, et même de me proposer dans quel ordre commencer ma relecture ou ma compréhension
Cela a vraiment beaucoup de valeur
« Les humains comprennent généralement mal les courbes exponentielles. C’est pour ça qu’ils croient à des contes de fées comme les intérêts composés » : cela veut dire que les intérêts composés sont un conte de fées ? Est-ce que j’ai raté quelque chose ?