Le bonheur est dans le prompt (non)
Le travail du dev se résume-t-il à interroger un programme comme
ChatGPT
, Perplexity
ou LeChat
, puis à copier-coller la réponse dans son éditeur ?
Si on écoute la petite musique actuelle de l'innovation numérique, c'est le
futur radieux qui se dessine pour l'ensemble des développeurs.
Utiliser un langage de programmation reste un moyen sûr de créer un programme et d'obtenir le comportement souhaité. La génération de code est séduisante mais ne me convainc pas.
La promptomanie, ou la manie de prompter excessivement
La tech chante la gloire éternelle des agents intelligents construits sur les
grands modèles de langage (LLM
). Une foule de gens, souvent ignorants, nous
explique à longueur de tribunes que des professions pourraient bientôt se
réduire à l'enchainement de quelques prompts bien sentis : création d'image,
rédaction et maintenant programmation informatique. C'est fatiguant. La semaine
dernière, dans le New York Times, un papier faisait récemment l'éloge de cette
transformation et du vibecoding.
Vibecoding, a term that was popularized by the A.I. researcher Andrej Karpathy, is useful shorthand for the way that today’s A.I. tools allow even nontechnical hobbyists to build fully functioning apps and websites, just by typing prompts into a text box. You don’t have to know how to code to vibecode — just having an idea, and a little patience, is usually enough. Kevin Roose, Not a Coder? With AI, Just Having an Idea Can Be Enough.
Et de continuer :
Few of these tools are world-changing in their own right. What’s new and notable is that with a few keystrokes, amateurs can now build products that would have previously required teams of engineers. [ ...] And I worry that software engineering is just the first white-collar profession to experience the labor-replacing effects of A.I. tools. But for now, building apps to automate annoying or time-consuming tasks in my life seems as good a use of A.I. as any. So I’m going to keep vibecoding. Kevin Roose, see above
Gary Marcus, sorte d'alter-ego américain, l'a promptement remis à sa place dans un court debunking. Je garde cette saillie :
Needless to say, the art of coding generally lies in building something new. Here Roose has displayed the cardinal sin of looking only at regurgitation rather than generalization. Gary Marcus
La fin du code, vraiment ?
Le travail de développement informatique peut-il se réduire à
l'interrogation d'un agent conversationnel ? La programmation est-elle soluble
dans la GenAI
? Allons-nous faire IA-remplacer ?
... en passant, juste une précision : la génération de contenu (texte, image) ne relève désormais plus de l'IA, puisque cette technologie fonctionne ...
99.99% du code est déjà écrit par des programmes
Les programmes ne sont plus écrits dans un langage exécutable nativement par un
processeur. À moins d'être particulièrement masochiste ou extrêmement compétent,
les développeurs écrivent leur code dans un langage de haut niveau (ex: C
,
Java
, Python
, etc) et le
compilent en un code machine comprend le processeur. Ils utilisent un ... programme, appelé compilateur. Nos programmes sont donc déjà écrits par
des programmes.
Le processus est en réalité plus compliqué : la compilation peut se faire en plusieurs étapes avec des langages intermédiaires, certains langages sont interprétés, et autres finasseries techniquement passionnantes et extrêmement complexes, mais ce n'est pas le sujet.
Les programmes apprennent bien mais ne comprennent pas
Utiliser un agent ou un outil n'est équivalent à comprendre son fonctionnement. Idem pour l'entraînement ou le fine tuning de modèles d'apprentissage. Ces outils sont maintenant relativement faciles à configurer et entraîner. L'intelligence artificielle ressemble à la cuisine : aimer manger et acheter compulsivement des livres de recettes n'a jamais transformé personne en grand chef. Peut-être en critique gastronomique, à la rigueur.
Qui peut se revendiquer être un expert des systèmes de génération de contenu ?
Qui comprend comment fonctionne réellement l'apprentissage d'un réseau de
neurones ou un LLM
?
Très peu de monde en réalité.
Nous sommes aujourd'hui à l'ère des grands modèles de langage (
LLM
), d'immenses réseaux neuronaux pré-entraînés sur d'énormes quantités de données textuelles générées par l'homme, qui semblent bien plus performants que les systèmes d'apprentissage automatique plus petits, moins bien entraînés et plus fragiles de l'époque précédente. Melanie Mitchell (2025)
Quelle est la représentation du monde d'un système de génération ? Les
scientifiques hésitent encore sur le niveau de compréhension des
LLM
. Qu'apprennent-ils ? Que comprennent-ils ? Ont-ils une représentation
interne du monde ? C'est un sujet difficile et le consensus scientifique est
loin d'être atteint.
Je renvoie aux articles récents LLMs and World Models
Part
1 et Part
2 de Melanie
Mitchell qui permettent aux non-spécialistes de se
faire une idée des débats.
La communauté de l'IA s'interroge vivement sur la manière dont ces systèmes obtiennent de telles performances. Ont-ils essentiellement mémorisé leurs données d'apprentissage et les ont-ils ensuite récupérées (de manière approximative) pour résoudre de nouveaux problèmes ? Ont-ils appris des raccourcis heuristiques beaucoup plus nombreux et détaillés, mais encore fragiles ? Ou bien ont-ils quelque chose de plus proche des modèles de monde robustes que les humains semblent utiliser pour comprendre et agir dans le monde ? Melanie Mitchell (2025)
Sur les représentations du monde ou modèles de monde (world model) :
La notion de modèle de monde n'est pas rigoureusement définie ; lorsque l'on se demande si un agent [IA] possède un type particulier de modèle du monde, il faut se demander à quels types de questions un tel modèle doit pouvoir répondre, dans quelle mesure il doit être facile ou difficile pour l'agent d'obtenir des réponses à partir du modèle, et dans quelle mesure on peut s'attendre à ce que le modèle permette à l'agent de s'adapter à des situations inédites. Melanie Mitchell (2025)
Sur les performances des agents IA :
Les affirmations relatives à l'émergence de modèles abstraits du monde dans les
LLM
ne sont pas encore étayées par des preuves solides. Il existe des preuves de l'émergence de tels modèles du monde chez des systèmes entraînés sur des domaines limités (Othello, échecs, labyrinthes, etc), mais aussi des preuves que leurs capacités ne proviennent pas de modèles internes semblables à ceux des humains, mais de vastes sacs d'heuristiques. Melanie Mitchell (2025)
Il est précipité d'affirmer que les LLM
comprennent le monde sur lequel ils
sont entraînés. Pour reprendre un exemple cité par Mitchell, un système IA peut
très bien être imbattable à un jeu comme Othello sans toutefois comprendre le
fonctionnement du jeu ni ses règles.
Faut-il encore apprendre à programmer ?
Doit-on encore écrire des programmes, ou peut-on faire écrire ces programmes directement par d'autres programmes ?
Prompter, c'est écrire un texte où on décrit ce que le programme doit faire, sans écrire directement ce programme. On formule ce qu'on souhaite générer, en s'exprimant dans un langage naturel (ex: anglais, français). Il faut être très spécifique pour contrôler au mieux la génération - ou très chanceux.
Expliquer ce qu'on veut faire faire à un programme, c'est programmer. Il faut
s'exprimer de manière très précise. En informatique, les doubles sens sont des
blasphèmes, les flous sont interdits, les non-dits sont bannis. Le langage
naturel n'est donc pas adapté, car il est trop souple, trop imprécis, trop
ambigü. Inversement, on ne pense pas le Bateau Ivre en Lisp
ou en
ALGOL
.
Les langages de programmation sont utilisés pour faire exécuter des tâches à un ordinateur, dans l'ordre souhaité. Le lecteur dubitatif ira explorer 70 ans d'histoire de la programmation informatique, dans une de ces références.
Penser qu'on triomphera en enchaînant des prompts est totalement contre-productif. Pourquoi perdre son temps à générer un programme alors qu'on peut simplement l'écrire ?
On peut parfois se permettre d'être fainéant
Dans les faits, on peut faire générer des programmes efficaces s'ils sont assez simples et classiques. Je m'en sers parfois pour les opérations de plomberie ou les tâches purement techniques (~ boiler plate), comme traverser un répertoire avec os.walk ou autres fonctions inintéressantes. J'ai fait générer des routines de conversion entre formats d'image avec scikit-image car je ne voulais pas m'embêter à comprendre. Le code est souvent fonctionnel, bravo.
La génération de code m'évite de copier-coller une fonction que j'ai écrite 170 fois, ou de lancer une recherche sur SO. Je gagne au mieux quelques minutes par jour de développement, et souvent rien.
J'ai tenté quelques fois de faire générer des fonctions plus complexes pour m'épargner une recherche dans la documentation de certaines bibliothèques (libs). Le succès n'a pas été au rendez-vous. J'aurais du lire la documentation, ça aurait été plus rapide et j'aurais appris des trucs.
Read the fucking manual RTFM
Et pour l'architecture des programmes ?
Un programme, c'est d'abord un code source. Un code source, c'est comme une maison : sans structure saine, sans fondation, ça s'écroule. On ne peut rien construire sur du sable. C'est trivial ? C'est surtout crucial, pour douze mille raisons différentes.
Je vais donner trois raisons principales.
Pour écrire un programme :
1. formuler un problème ;
2. comprendre ce problème ;
3. résoudre ce problème.
Jusqu'à preuve du contraire, remplir ces trois conditions nécessite un cerveau et des milliers d'heures de pratique. Comprendre ce qu'on fait est généralement une bonne stratégie.
Un programme est toujours spécifique. Si certains cas reviennent régulièrement, les contextes et les données ne sont jamais identiques. Citons par exemple : un site web, une application, un jeu d'échec, un programme de détection de fraude bancaire, un système de détection des defaillance par usure de pièces mécaniques grâce à l'étude des vibrations etc. Les cas réellement nouveaux sont rares (et précieux).
Il se trouve que les systèmes de génération actuels, s'ils sont impressionnants, montrent une limite dure : malgré les discours technophiles et optimistes, ces programmes ne comprennent rien. Ce n'est pas leur fonction. Ils sont aujourd'hui entrainés à répéter et assembler des trucs de manière complexe. Ils ne sont pas entraînés à comprendre. Or, c'est un pré-requis pour concevoir un programme : il faut comprendre ce qu'on veut faire.
Accumuler du contexte ne fait pas tout
Oui mais plus tard on aura un contexte énorme, avec des millions de token, on pourra faire trop de trucs.
Les systèmes génératifs actuels ne peuvent pas tout absorber. Ils ont un
contexte limité. C'est une limite technique. Ce contexte est fourni lors du
prompt, ou des prompts successifs. En Février 2025, ce contexte est limité à une
centaine de milliers de token (~mots). D'ici quelques années, le contexte sera
probablement suffisant pour fournir un ensemble de spécifications à un LLM
et
lui demander de générer un programme entier. Peut-être.
Tu peux générér ce que tu veux, lapin, si tu ne comprends pas ce que tu génères, tu finiras dans le ravin.
Oui mais on pourra donner tout le code à une IA pour regénérer une structure saine.
Restructurer, simplifier, améliorer ? Peut-être. Qui veut tenter l'aventure ? Qui maintiendra le code ? Qui corrigera les bugs ?
La dette technique est un problème majeur en informatique
A force d'ajouter des fonctionnalités, de corriger des bugs, de modifier des machins, bref de faire vivre le code, on ajoute des verrues un peu partout sans forcément respecter le plan d'ensemble ou l'organisation générale. Or tout programme obéit aux lois de la thermodynamique et augmente son entropie. Techniquement, on parle de laisser enfler des gros bordels ingérables, et on préfère les éviter.
Il faut régulierement reprendre la structure d'un code. C'est inévitable. Il parait difficile, voire impossible, de gérer la dette technique d'un programme non trivial à l'aide de la génération de code. À moins de lui fournir tout le code et de lui faire une totale confiance. Mais alors comment s'assurer que le fonctionnement du programme soit celui attendu après ce grand chamboulement ?
Les tests permettent de vérifier qu'un code ne tombe pas en marche
Très gros sujet. Tester son code, c'est un moyen de s'assurer qu'on ne casse pas
tout quand on corrige un bug ou quand on ajoute une fonctionnalité. C'est un
moyen de survivre à une refactorisation ambitieuse ou une réduction de dette technique. Un
code sans tests de bout en bout (end-to-end) ou unitaires (unit) est un
monstre en puissance. Repensez aux ovomorphs
(ah) et les facehuggers
(beurk) de Alien
, et vous aurez une
idée du risque dont je parle.
Lorsqu'on fait évoluer une base de code, on a tendance à morceller la base de tests, voire à la briser. Elle n'est plus utile. Il faut la faire évoluer, elle aussi. La tentation est grande de générer les tests, eux aussi : pourquoi pas ? Mettre en production du code généré par un programme, testé par un programme à partir de spécifications elles-aussi générées par un programme, est-ce une bonne idée ? Pour un site web, on peut tenter l'exercice. Pour un système de freinage d'un camion de 32 tonnes qui arpente des routes givrées, mieux vaut avoir un contrat d'assurance bien béton.
Je ne suis pas devin, ni Devin. Mais tout ceci me semble très aventureux. A trop générer, le developpeur ne maitrise plus son code. Est-ce futé ? Est-ce souhaitable ?
Et pourtant, les programmes de demain seront générés !
Un programme conséquent ne devrait pas être écrit par un système qui colle, assemble, bluffe. Un programme conséquent ne devrait pas être généré à partir de notre langage flou et ambigü d'humains souples et ambigüs.
C'est pourtant ce qu'il va se passer. Parce que les gens qui allouent les budgets n'ont aucune putain d'expérience en conception ou en implémentation de programmes (prove me wrong). La réduction des coûts à court terme sera le grand moteur de ce bazar, comme d'hab'. Tant pis pour les juniors.
Un programme généré doit être très bien conçu
Scénario de film d'horreur.
Ok, comment faire ?
On commence par fixer un véritable cahier des charges. On définit le problème à traiter, on découpe en sous-problèmes, on isole les parties, on définit les API, on définit le schéma de données etc. Bref on pense tout bien, en amont et proprement. Il ne peut donc pas s'agir de code de traitement de données, R&D etc où le cahier des charges n'est fixé qu'à la fin du premier prototype 😍.
La conception est réalisée et validée, les blocs sont identifiés et isolés, les interfaces sont fixées. À ce moment, 90% du travail intellectuel est réalisé. Les 10% restants relèvent de l'implémentation du code : c'est critique mais ça se fait plutot vite, sauf si on débute. C'est ici que la génération peut être utilisée. Le gain de temps sera donc faible, en réalité. Et il faudra tester intensément le code généré.
Pour ceux qui connaissent, ce style ressemble beaucoup à ce que défend F. Brooks dans son Mythical Man-Month, avec une approche classique de waterfall et divide & conqueer. Avec les limites associées, notamment la difficulté de diviser un problème complexe en sous-problèmes indépendants. On est en terrain connu, balisé, N fois parcouru (N grand).
On aura donc ainsi généré un programme non trivial, dont personne ne maitrise les détails de l'implémentation. Cette démarche vertueuse (?) ne règle pas les problèmes de reconception, de refactorisation massive ou de réduction de la dette technique.
May you live in interesting times
Le marché a besoin de se manger une claque.
Elle sera forte.
Et qui devra
reprendre la conception de ces programmes générés ? Mmmh ?
Préparez les budgets.
Corriger les bugs et inepties d'un programme généré par un agent dit intelligent, ça se paiera au prix fort.
J'annonce des dettes techniques extraordinaires.
Créer un programme non trivial requiert (encore) la présence d'un cerveau
Il n'y a, à nos yeux, aucune raison de faire suffisamment confiance aux outils de génération pour leur confier des tâches qui, habituellement, requièrent la présence d'un cerveau fonctionnel.
Les ordinateurs sont de bons serviteurs, très efficaces, mais je n'ai aucune envie de les servir. Capitaine Spock, USS Enterprise
Un autre billet sur le même thème, avec un angle un peu différent : The Death of the Junior Developer.