D’où est-ce que je viens ?

Mon histoire de programmeur commence comme beaucoup d’autres dans ce métier. J’ai écrit mes premières lignes de code vers 7 ou 8 ans, et ma première vraie application logicielle à l’âge canonique de 16 ans. Je m’en souviens avec tendresse. C’était un bloc-notes musical pour noter les idées de mélodies qui me venaient à des moments imprévisibles, sur l’ordinateur le plus basique auquel j’avais accès à l’époque. Tout tenait dans un unique fichier Pascal gigantesque, c’était brouillon, c’était inefficace, c’était bricolé, et j’étais tellement fier des solutions astucieuses que j’avais trouvées pour afficher une pseudo interface graphique sur un écran en mode texte, ou produire des sons sans carte son, juste avec le haut-parleur système de la carte mère. C’était rudimentaire, je suis resté son seul utilisateur, mais c’était une expérience incroyablement satisfaisante. L’année suivante, j’ai profité des nouveaux cours d’informatique et de meilleurs outils pour réécrire Note Pad Score en une vraie application à la souris, avec du son MIDI. Et la suite appartient à l’histoire… J’étais tombé amoureux des casse-têtes, de la résolution de problèmes, de la micro-créativité, du design d’interfaces, des heures de lutte avant la décharge de dopamine quand un point-virgule trouve enfin sa place. J’ai étudié l’informatique et j’en ai fait ma carrière. J’ai travaillé 5 ans dans une société de conseil avant de me sentir enfin prêt à voler de mes propres ailes et de passer indépendant.

Au fil des années, j’ai réussi à me construire une carrière, et à élargir mes compétences de façon à pouvoir prendre en charge tous les aspects d’un projet logiciel, de la gestion d’équipe à l’analyse fonctionnelle et technique, en passant par l’architecture, le design, le développement et la gestion des déploiements. Et côté construction pure, j’ai appris à bâtir aussi bien des backends que des frontends, qu’ils soient desktop, web ou mobiles. Cette polyvalence est devenue particulièrement précieuse quand j’ai décidé de devenir totalement nomade en 2018, parce qu’elle m’a permis de travailler avec des startups et des petites entreprises en gérant tout le cycle de vie logiciel depuis n’importe où dans le monde, avec un minimum de réunions qui auraient restreint mon exploration du globe. Je travaillais généralement sur 2 ou 3 projets à la fois, j’aidais des entrepreneurs créatifs à transformer leurs idées en réalité, et j’adorais chaque aspect de cette vie.

Puis, il y a 2 ans, tout s’est effondré. Là où j’avais toujours trouvé de nouveaux projets et de nouveaux clients assez facilement, par le bouche-à-oreille et grâce à ma réputation, les pistes se sont soudain taries. Certains de mes clients habituels se sont mis à « vibe coder » leurs propres prototypes, les budgets ont fondu à mesure que les gens se persuadaient qu’un simple chatbot pouvait faire mon travail. Les négociations sont devenues plus dures, et j’ai même perdu des clients après quelques mois de collaboration parce qu’ils avaient cédé aux sirènes du vibe coding.

Alors a commencé une longue période de deuil.

D’abord le déni : j’ai continué à chercher des projets comme je l’avais toujours fait, en contactant des dirigeants et des sociétés de conseil, en espérant trouver quelqu’un que l’infection de l’IA n’avait pas encore atteint.

Puis est venue la colère, quand j’ai compris qu’aucun de ceux qui rejetaient mon expertise au profit des LLM ne comprenait ce que j’offrais, que c’était tellement plus que juste écrire du code. Évidemment, ils ne voyaient pas qu’ils fonçaient droit dans le mur, parce que tout semblait fonctionner, jusqu’au jour où ils auraient de vrais utilisateurs, avec de vraies données personnelles, et où il faudrait faire de vrais changements.

Ensuite, j’ai réalisé que je nageais à contre-courant, en lutte contre l’avidité et la médiocrité. Le marché ne se souciait plus de logiciels propres, sécurisés, scalables et évolutifs, en tout cas plus assez pour les valoriser comme avant. Alors j’ai commencé à baisser mes tarifs, à travailler quelques jours par mois sur chaque projet au lieu de quelques semaines, à montrer à mes clients que nous pouvions faire tellement plus avec le même budget, et à utiliser l’IA là où elle semblait pertinente, tout en gardant la main ferme là où elle semblait manquer de discernement.

Mais j’étais malheureux, parce que cela changeait tout du travail que j’aimais tant : cela me privait de tous les petits casse-têtes qui faisaient mes journées, cela me faisait culpabiliser de ne pas être l’auteur de chaque ligne de code que je livrais, cela me faisait lire des milliers de lignes de code que je n’avais même pas écrites. Et surtout, j’avais le sentiment que tout ce temps passé à affûter mon métier, à construire mes compétences, à développer mon intuition et ma pensée design, n’avait servi à rien.

Le déclic

Puis, début 2026, 3 choses, 3 événements se sont en quelque sorte télescopés.

D’abord, une révélation : j’ai réalisé que tout cela s’était déjà produit, même si c’était à plus petite échelle. Dans les années septante et quatre-vingt, quand les programmeurs sont passés du code machine aux compilateurs et aux langages de plus haut niveau, beaucoup ont regretté l’époque où ils pouvaient ajuster finement l’usage de la mémoire et optimiser chaque instruction envoyée à la machine. Mais il a bien fallu admettre que la plupart des compilateurs faisaient un bien meilleur travail qu’eux, et que cela permettait aux programmeurs de se concentrer sur des abstractions de plus haut niveau pour résoudre des problèmes plus grands. Et me voilà, face au même bond technologique, en train de refuser d’adopter des outils qui me permettraient de construire des logiciels vraiment utiles, ce qui avait toujours été ma finalité de toute façon.

Ensuite, de nouveaux modèles sont sortis, accompagnés de nouveaux workflows comme les boucles Ralph, qui ont enfin rendu possible la construction de vraies fonctionnalités, de bout en bout, avec un encadrement d’expert digne de ce nom. Un merci tout particulier à David Nguyen, s’ouvre dans un nouvel onglet pour m’avoir orienté dans cette direction et m’avoir montré comment il travaillait.

Et enfin, il y avait ce projet personnel dont je rêvais depuis des années déjà, devenu tellement plus faisable grâce aux LLM, non seulement comme outil de développement, mais aussi comme composant interne capable de donner du sens à des documents complexes non structurés.

Et comme par le passé j’avais toujours utilisé mes projets personnels pour apprendre de nouvelles technologies et ajouter de nouvelles cordes à mon arc, j’ai décidé d’adopter les LLM sur mon propre projet, pour expérimenter ces nouvelles techniques sans faire courir de risque à l’activité d’un client.

5 mois plus tard, je publiais la première version de Skaoot, s’ouvre dans un nouvel onglet, mon assistant de voyage pour nomades numériques, avec un périmètre fonctionnel, un niveau de sophistication et de qualité qu’il m’aurait fallu des années pour atteindre si j’avais écrit tout le code moi-même. Et me voici aujourd’hui, 7 mois après le début de cette expérience, la deuxième version publiée, plus confiant que jamais dans les outils que j’ai réussi à apprivoiser et à sélectionner, encore un peu triste d’avoir perdu une partie de la satisfaction créative, mais enthousiaste face aux nouvelles possibilités qui s’ouvrent à moi.

Alors je me suis dit que j’allais partager quelques-unes des choses que j’ai apprises pendant cette transition, en espérant que cela aide d’autres ingénieurs logiciels expérimentés comme moi à la traverser, ainsi que toutes les parties prenantes qui dépendent (encore) de nous.

La confiance se construit avec le temps

Et changer sa perception de ce que l’IA peut et ne peut pas faire ne se décrète pas, cela s’expérimente.

J’entends parler de beaucoup d’entreprises où la seule stratégie d’adoption de l’IA de la direction ressemble à « Voilà des tokens, allez-y, servez-vous, et gardez un œil sur le classement de consommation ». Le problème, c’est que ces modèles ont une barrière à l’entrée très basse grâce à leur interface de chatbot, ce qui laisse beaucoup de gens perplexes : comment passe-t-on de demander à ChatGPT la durée de gestation d’un orang-outan à piloter Claude Code pour construire une fonctionnalité entière, surtout quand on a déjà vu une IA se tromper avec aplomb sur la question de la gestation ?

Et ce problème de confiance est encore plus marqué chez les experts techniques, comme les ingénieurs logiciels, qui ont passé des années, voire des décennies, à affûter leur métier, avec toutes les histoires de tranchées pour le prouver.

Au tout début, comme beaucoup de développeurs, j’utilisais l’IA surtout comme un moteur de complétion de code plus puissant, le fameux développement à coups de Tab : vous commencez à taper du code, et vous regardez, fasciné, votre environnement de développement deviner ce que vous vouliez faire et vous proposer d’appuyer sur Tab pour accepter sa suggestion. Et la suggestion est parfois si bonne que c’est tout ce qu’il faut pour générer des centaines de lignes de code. Jusqu’au jour où vous réalisez qu’elle était fausse, qu’une erreur s’est glissée dans le code généré, et qu’il vous faut presque autant de temps pour corriger l’erreur et remettre le devin sur les rails que si vous aviez écrit le code à la main. Et quand cela arrive, votre confiance s’érode.

Autre situation typique : vous demandez au LLM de créer un morceau de code précis, ou de générer un petit script de test bien délimité, et l’IA n’a pas le bon contexte, fait un tas de suppositions sans vous demander de clarifications, et génère des milliers de lignes de code. Et comme vos hypothèses implicites vous semblent évidentes, vous ne vérifiez pas forcément ce qui a été généré, et vous ajoutez simplement de la dette technique à votre code, que vous finirez par rembourser plus tard à cause de ce décalage d’hypothèses.

Toutes ces erreurs, combinées au biais de confirmation de l’expert, créent une situation où le développeur ne fait pas confiance au modèle, et par conséquent arrête complètement de l’utiliser, continue de l’utiliser de la mauvaise façon parce qu’il n’a pas eu l’occasion de comprendre ce qui avait précisément mal tourné, ou refuse simplement de confier au modèle des tâches plus ambitieuses, puisqu’il a déjà échoué sur de si petites choses.

La réponse à ces problèmes, ce sont les workflows progressifs : au lieu de gaver votre IA de tous les problèmes de la même manière, il faut expérimenter, sur des tâches de plus en plus grosses, les techniques à mettre en œuvre à chaque niveau pour exploiter toute la puissance de votre modèle en minimisant les erreurs et les gaspillages.

Pour la génération de code générique, vous apprenez à pointer votre IA vers des fichiers d’exemple où du code similaire existe déjà, et à gérer votre fichier de contexte principal pour garder trace de vos habitudes et conventions de code.

Pour les tests, vous apprenez à utiliser une compétence de Test-Driven Development pour vous assurer que tous les cas limites sont couverts.

Pour le développement de fonctionnalités plus ambitieuses, vous intégrez un framework de workflow qui crée une boucle : analyse des besoins, génération d’une spécification, critique adversariale de cette spécification, transformation de la spécification en plan d’action, avec une revue des livrables après chacune de ces étapes avant de passer à l’implémentation.

Mais tout cela s’apprend progressivement, par l’expérimentation, sur un projet à faible enjeu et au périmètre minimal, avant d’appliquer ces apprentissages à un vrai projet. En réalité, intégrer un modèle d’IA dans votre équipe logicielle, c’est comme accueillir un nouveau développeur junior. L’équipe en place a besoin de temps pour faire confiance à la nouvelle recrue, et pour repositionner son propre travail autour de l’intégration de ce nouveau coéquipier. Cela ne se fait pas du jour au lendemain. Il m’a fallu un mois ou deux.

Le vibe coding ne vous mènera pas bien loin

Le vibe coding désigne la pratique consistant à générer le code d’applications ou de sites web sans jamais voir ce code ni vraiment le comprendre, par une boucle d’essais et d’erreurs avec retour visuel. Dans l’esprit, c’est le prolongement de ce qui existait avant l’IA sous le nom de no-code. En substance, il promet à des gens qui n’ont aucune notion de génie logiciel ou de programmation de générer des applications et des sites entiers sans aucune assistance, juste en écrivant des prompts à ChatGPT, Claude, Lovable ou n’importe quelle autre IA.

Le principal problème, c’est que la plupart des outils et pratiques de vibe coding visent précisément des gens qui ne comprennent pas comment on construit un logiciel, et qui supposent souvent qu’il s’agit surtout de traduire des idées brutes en charabia de code, comme si les développeurs n’étaient que des interprètes. Rien n’est plus faux. Même quand j’écrivais encore mon code à la main, l’écriture de code représentait au plus 20 % de mon travail, le reste étant consacré à :

  • Intégrer des bibliothèques et des packages externes et lire leur documentation, pour ne pas réinventer la roue sur des besoins génériques. Ce qui impliquait aussi de tester plusieurs bibliothèques concurrentes pour la même chose afin de choisir la meilleure pour la tâche, en tenant compte de toutes les contraintes. Puis de maintenir ces dépendances tierces, de surveiller les bugs et les montées de version, et de gérer les effets domino quand des dépendances deviennent incompatibles entre elles.
  • Concevoir les composants avec la sécurité en tête, s’assurer que personne ne peut accéder à des données qui ne le regardent pas, anticiper les surfaces d’attaque, communes ou moins communes, qui permettraient à des pirates d’entrer et de voler les informations personnelles des utilisateurs, et rester en conformité avec les réglementations sur la vie privée comme le RGPD.
  • Architecturer les systèmes selon les contraintes propres à l’application : les utilisateurs doivent-ils accéder à leurs données hors ligne ? sur quels canaux doivent-ils y accéder (web, mobile, etc.) ? et ainsi de suite.
  • Optimiser le code pour la scalabilité, parce qu’il y a mille façons de charger et de modifier des données, et que beaucoup fonctionnent très bien quand on teste avec un utilisateur et un petit volume de données, mais tournent au désastre une fois en production. Les temps de chargement peuvent avoir une influence énorme sur votre activité : ils peuvent faire tomber des systèmes, frustrer les utilisateurs, et même rendre votre application totalement inutilisable.
  • Comme je le racontais au début, ma toute première application tenait dans un seul fichier de plusieurs milliers de lignes où tout était enchevêtré. Techniquement, ça marchait, mais y changer quoi que ce soit, ajouter des fonctionnalités, corriger des bugs, tester, aurait été un cauchemar. Concevoir du code capable d’évoluer, de s’améliorer et d’être testé relève plus de l’art que de la science : c’est un métier fait d’années d’expérience, de bonnes pratiques et d’une intuition générale souvent même pas consciente.
  • Combler les trous. Très souvent, quand on pense à une fonctionnalité, on pense au scénario idéal, celui où tout se passe bien et où l’utilisateur fait ce qu’on attend de lui. Mais les applications interagissent avec tout un écosystème de connexions tierces, de connectivité changeante, de matériel complexe, où votre code doit encaisser ces contraintes mouvantes avec grâce, sans planter, sans dérouter les utilisateurs, en trouvant des solutions de contournement. Et bien sûr, la plus grande variable de toutes, c’est l’utilisateur final : il a tendance à faire des choses que vous n’attendez pas. Il oublie de remplir un champ obligatoire, il clique plusieurs fois sur un bouton parce qu’il s’impatiente, il fait les choses dans le désordre. Et en tant que développeur, c’est votre travail d’anticiper toutes ces variables, d’expliciter le non-dit, de gérer tous les cas limites, de poser les questions : quels champs sont obligatoires, quel est leur type de données, dans quel fuseau horaire les dates doivent-elles s’afficher, et ainsi de suite.
  • Améliorer l’expérience utilisateur : cela ne vous agace-t-il pas quand une énième application vous demande votre prénom et qu’il faut le taper en entier au lieu de cliquer sur une suggestion, ou quand le clavier d’une application mobile ne s’adapte pas au fait que vous saisissez une adresse email, avec le signe @ directement accessible ? Il peut y avoir une différence énorme entre une implémentation qui fonctionne et une implémentation qui intègre toutes ces micro-améliorations d’expérience qui minimisent les clics et travaillent pour l’utilisateur.

Parfois, j’étais aidé par des analystes métier, des analystes fonctionnels, des analystes techniques, des designers, des testeurs QA, mais dans tous les cas, c’est un travail de réflexion qu’il fallait accomplir.

Les modèles d’IA modernes réfléchissent de mieux en mieux à ces questions, mais il faut souvent ajouter du contexte, intégrer des compétences, pointer le modèle vers des sources de connaissances, et maintenir tout cela à jour dans la durée.

Et puis il y a tout le travail satellite qu’on néglige souvent quand on ignore jusqu’à son existence, par exemple :

  • Le contrôle de version : comment garder trace de l’historique des changements du code de l’application, pour pouvoir facilement revenir en arrière, ou répliquer une solution au lieu de la reconstruire de zéro ? C’est là qu’il devient crucial de suivre l’histoire du code, même généré par l’IA, parce que les développeurs comme les machines ont souvent besoin de se remémorer ce qui est arrivé à votre projet.
  • L’intégration : que se passe-t-il quand un système tiers doit s’intégrer au vôtre, quand vous devez envoyer ou recevoir des données via des points de connexion sécurisés ? Il faut documenter cela, pas seulement l’implémenter, sinon il sera presque impossible pour des collaborateurs externes, humains ou IA, de s’intégrer à votre système.
  • Le diagnostic : quand un problème survient, vous voulez que votre système vous dise ce qui a mal tourné et où, pour résoudre l’incident au plus vite et ne pas perturber votre activité au pire moment. Cela demande généralement de l’instrumentation, la journalisation des erreurs, le suivi et l’enregistrement de ce que font les utilisateurs en temps réel, puis des outils pour dépanner rapidement.
  • La gestion des versions : si vous construisez une application mobile par exemple, elle doit être publiée sur un app store, et les utilisateurs ont ensuite le choix de la mettre à jour ou non, pendant que vous continuez à livrer des fonctionnalités côté serveur (le backend) auquel l’application se connecte. Que se passe-t-il quand une vieille version de votre application mobile (frontend) se connecte à votre backend flambant neuf ? Va-t-elle planter ? Encaisser les changements avec élégance ? Corrompre vos données ? Ce sont des choses qu’il faut intégrer en permanence quand on code. Et bien sûr, il faut aussi préparer l’avenir. La toute première version de Skaoot ne traitait que les réservations de vols et d’hébergements, mais au moment de la publier, je savais déjà que je devrais bientôt gérer les réservations de train, les locations de véhicules et d’autres types de réservations. Parfois ces évolutions exigent des changements de code, parfois ce ne sont que des paramètres de configuration modifiables sans nouvelle version. Et savoir où ces changements s’implémentent fait aussi partie du travail.

Et ce ne sont que quelques exemples de ce à quoi on ne pense pas forcément quand on demande à Lovable de permettre à ses utilisateurs de se connecter au site avec leur adresse email et un mot de passe.

Le vibe coding peut suffire pour des cas d’usage simples et génériques, comme générer une landing page complète pour une nouvelle activité avec un formulaire de contact. Il peut suffire pour un prototype jetable à usage unique, avec vous et votre cofondateur comme seuls utilisateurs.

Mais vous n’êtes pas obligés de croire le vieux développeur biaisé et intéressé que je suis : lisez toutes les histoires d’horreur, s’ouvre dans un nouvel onglet de gens qui ont vibe codé, s’ouvre dans un nouvel onglet des systèmes entiers jusqu’en production (quand ils y sont seulement arrivés) et tous les problèmes de sécurité, de performance, de fiabilité, s’ouvre dans un nouvel onglet, d’évolutivité qu’ils ont rencontrés.

Maintenant, si l’on peut générer certaines choses très vite sans rien connaître au code, imaginez ce qu’un développeur expérimenté peut faire en confiant à une IA tout le travail chronophage, en mobilisant toute son expertise pour éviter la plupart des pièges et piloter l’IA dans la bonne direction.

C’est comme si vous n’aviez jamais appris à piloter, et que vous veniez d’obtenir votre licence de pilote privé : vous savez piloter un petit Cessna monomoteur. Êtes-vous vraiment sûr que vous sauriez poser un Airbus A350 en un seul morceau ?

La gestion du contexte est primordiale

Quand vous déléguez le développement logiciel à une IA, vous ne passez pas seulement le relais sur l’écriture du code, mais aussi sur la mémoire du contexte dans lequel ce code s’inscrit. Toutes les erreurs déjà commises, toutes les bonnes idées à répliquer, tous les changements opérés au fil du temps et le raisonnement derrière eux, toute la connaissance métier qui a servi de socle à ces décisions.

Typiquement, cette connaissance vit dans la tête des développeurs, dans une documentation ou des commentaires de code périmés, et bien sûr dans le code existant et son historique. Quand un développeur entame une tâche, il doit charger sélectivement une partie de ce contexte dans sa propre mémoire et travailler à partir de là. C’est imparfait, c’est brouillon, c’est limité dans le temps, c’est troué, c’est généralement fragmenté entre plusieurs personnes de l’équipe, mais c’est une part importante du travail de tout développeur, parce que c’est ce qui garde le logiciel cohérent dans la durée.

Si vous en voulez la preuve, regardez le désastre produit quand des équipes à fort turnover développent un logiciel : les solutions sont court-termistes, le code est dupliqué et inmaintenable, corriger les bugs revient à jouer au chamboule-tout, les fonctionnalités sont incohérentes.

Les LLM de code fonctionnent généralement sur plusieurs couches de contexte :

  • Une mémoire à court terme, généralement autour d’un million de tokens, réinitialisable à tout moment, par session
  • Un contexte projet (CLAUDE.md, AGENTS.md, etc.) qui documente l’architecture générale d’un projet, quels dossiers contiennent quoi, ainsi que les bonnes pratiques générales à suivre dans le projet
  • Un système de mémoire à plus long terme fait de fichiers texte stockés dans la configuration du LLM ou dans un wiki de code comme Obsidian par exemple
  • Une forme d’historique des spécifications, plans et autres documents propres aux tâches, décrivant les implémentations passées du projet (voire parfois de plusieurs projets)
  • Des compétences (skills) qui documentent comment réaliser certaines tâches répétitives, comme mener une revue de code ou générer tel jeu de données de test
  • Un accès sélectif et sécurisé à votre propre infrastructure, aux logs de votre serveur, aux logs distants de votre frontend, à votre base de données, à vos fichiers, etc.
  • Et bien sûr, la plupart des LLM ont accès à internet, où ils peuvent aller chercher la documentation des outils et bibliothèques que vous utilisez, entre autres informations utiles

Ce que j’ai appris avec le temps, c’est que pour améliorer les résultats, il faut être très rigoureux dans la gestion de toutes ces formes de contexte. Si vous n’en faites rien, c’est ce qui mène aux bugs, aux incohérences, aux problèmes de maintenabilité et à énormément de dette technique.

Une architecture pensée pour l’IA

L’architecture logicielle compte déjà quand on code à la main. Il y a quantité de principes d’ingénierie à appliquer pour garder un code testable, facile à maintenir, facile à faire évoluer, facile à déboguer. Le monde du génie logiciel regorge d’acronymes comme SOC (Separation of Concerns), YAGNI (You Ain’t Gonna Need It), KISS (Keep It Simple, Stupid), DRY (Don’t Repeat Yourself), de styles d’architecture comme les microservices, MVC (Modèle-Vue-Contrôleur), MVVM (Model-View-View Model) et d’autres patrons de conception que les développeurs apprennent à appliquer très tôt pour garder les choses propres et durables.

Certains de ces principes sont assez universels et tranchés, d’autres relèvent du contexte du projet, voire de la préférence personnelle. Et leur mise en œuvre varie aussi largement d’une technologie à l’autre.

Alors si vous ignorez tout cela, il est facile de passer à côté dans un contexte de génération par IA, et de laisser votre LLM faire n’importe quoi en matière d’architecture et de conception du code. Mais après tout, pourquoi s’en soucier, si le résultat est une application qui fonctionne ?

La vérité, c’est que ces principes sont nés d’une nécessité du développement humain, et qu’ils sont encore plus cruciaux dans un environnement piloté par l’IA.

Si chaque fonctionnalité est organisée de façon standard, il est plus facile pour votre LLM de comprendre où se trouvent les choses et où insérer le nouveau code. Il lui est plus facile de générer les bons tests pour minimiser les régressions au fil du temps (le fameux effet chamboule-tout). Le contexte de travail est moins complexe, ce qui réduit la consommation de tokens. Et si les flux de données sont faciles à observer, il est plus facile pour votre modèle de remonter à la source d’un problème et de le corriger avec moins de tokens, en moins de temps.

C’est pourquoi, quand j’ai commencé à travailler sur Skaoot avec Claude Code, j’avais déjà mis en place un projet de base implémentant l’architecture en couches d’Andrea pour Flutter et Firebase, s’ouvre dans un nouvel onglet. Et chaque nouvelle fonctionnalité ajoutée depuis a suivi le même principe et organisé le code de la même manière, et chaque fois que j’ai eu un bug à corriger ou une fonctionnalité à ajouter, cela a considérablement accéléré les choses. Grâce à ce travail préliminaire, j’ai aujourd’hui une grande confiance dans la robustesse de ma base de code.

Le génie logiciel est mort, vive l’ingénierie produit

J’ai vu ce matin la vidéo d’une développeuse qui expliquait qu’avant l’IA, elle ne s’intéressait pas vraiment au produit sur lequel elle travaillait, au métier qu’il servait, parce que ce qu’elle aimait vraiment, c’étaient les casse-têtes, la micro-créativité, les aspects techniques. Mais maintenant que tout cela est pour l’essentiel délégué aux générateurs LLM, si elle ne s’intéresse pas à la raison pour laquelle elle construit les choses, tout devient assez ennuyeux. Et je m’y reconnais tellement.

C’est incroyable à quel point notre travail a complètement changé en quelques mois à peine. Avant, il fallait comprendre les subtilités des technologies utilisées au point que certains se sentaient obligés de se spécialiser, d’être développeur frontend ou backend par exemple. Écrire du code était déjà une petite partie de notre quotidien, mais cela demandait beaucoup de lecture, de recherche, de formation, d’expérimentation, d’essais-erreurs avant d’écrire enfin ce code qui fonctionne. Sans parler de tous les frais généraux d’alignement d’équipes entières d’ingénieurs frontend, d’ingénieurs backend, d’ingénieurs infrastructure, de designers, de testeurs QA, de product managers, de chefs de projet, et j’en passe.

Mais aujourd’hui, ces jours-là sont pour ainsi dire révolus. Du moins quand on choisit d’embrasser cette révolution et d’utiliser les outils de la bonne manière.

J’ai eu la chance d’avoir décidé il y a longtemps déjà d’étendre mes compétences à un large éventail d’activités couvrant tout le cycle de vie logiciel. Je suis nomade numérique depuis 8 ans maintenant, je voyage constamment, et je ne pouvais tout simplement pas passer mes journées en réunion dans des fuseaux horaires impossibles, loin de mes clients. J’ai donc dû consolider mes compétences frontend et backend, les combiner à mon expérience de chef de projet, développer mon expertise de product manager, et travailler directement avec des fondateurs de startups et des dirigeants de petites entreprises pour construire des solutions à partir de zéro.

Et maintenant, la partie écriture de code a pour ainsi dire entièrement disparu. Je passe l’essentiel de mes journées à écrire et à relire des spécifications et des plans techniques pour amener les modèles d’IA à générer le bon code, après quoi je peux tester ce que l’IA a produit, décider de la suite, et avancer. Je continue de pousser les modèles à utiliser des technologies que je comprends et à générer du code que je peux lire et sur lequel je peux intervenir si nécessaire, mais pour l’essentiel, je n’écris plus de code.

Ce qui compte, c’est que même sans écrire le code moi-même, j’influence toujours fortement la façon dont l’IA le génère :

  • Par les technologies et frameworks que je lui demande d’utiliser
  • Par l’architecture que je mets en place au début de mes projets, la coquille dans laquelle l’IA opère et dont elle s’inspire
  • Par le contexte détaillé que j’inclus dans chaque interaction avec l’IA, les points d’attention que je lui signale, la vision que je décris, les choses sur lesquelles j’insiste. Par exemple, pour Skaoot, dans toutes les couches de contexte que je transmets à Claude Code, j’insiste sur l’importance de la confidentialité des données, de la réduction du bruit dans les données, de la minimisation de l’effort utilisateur, et tous ces principes généraux se traduisent ensuite en choix d’architecture, en conventions de code, et ainsi de suite.
  • Par les workflows que je mets en place

L’importance des workflows

Une des choses que je détestais vraiment quand j’ai commencé à expérimenter avec l’IA, c’était que tout ce code généré, c’était toujours moi qui le committais dans le contrôle de version, c’était toujours moi le responsable, ce qui voulait dire que je ne me voyais pas le déployer en production sans le lire, le relire et le corriger.

Et autant j’aime écrire du code et résoudre des casse-têtes, autant j’ai toujours détesté les revues de code : lire le code de quelqu’un d’autre, m’agacer de toutes les façons dont j’aurais fait autrement, lutter sans cesse contre moi-même pour distinguer ce qui devait vraiment être corrigé de ce qui n’était qu’une préférence personnelle. Et soyons honnêtes, les premiers modèles d’IA généraient du code qui fonctionnait à peu près, mais pas nécessairement du code de qualité. C’était donc comme être privé de la gratification de résoudre le moindre problème soi-même, et passer son temps à relire et corriger le travail de 20 développeurs juniors à la fois. C’était atroce.

Et puis les modèles se sont améliorés, ils sont devenus meilleurs pour imiter mon style de code, suivre mes instructions et vérifier leur propre travail, et les workflows sont apparus.

Le premier que j’ai essayé était la boucle Ralph, s’ouvre dans un nouvel onglet. C’était en gros un ensemble complet de skills et de prompts pour guider l’IA à travers un processus : spécification d’une nouvelle fonctionnalité, transformation de cette spécification en liste de tâches, puis lancement du modèle dans une série de boucles autonomes où il prenait le contexte de la spécification pour une tâche, l’implémentait, vérifiait sa propre implémentation, puis réinitialisait le contexte et passait à la tâche suivante.

Je l’ai utilisée pendant quelques mois et c’était vraiment révolutionnaire. Certains développements prenaient quelques heures entre la spécification d’origine et la fin de l’implémentation, puis je passais encore quelques heures à tester le résultat, à demander à Claude de corriger certaines choses, mais il était rare que je doive jeter une fonctionnalité entière. Quand cela arrivait, c’était parce que j’avais oublié un élément de contexte clé que je tenais pour acquis et que je n’avais pas pris la peine d’inclure dans ma spécification, et le processus étant conçu pour être totalement autonome, il prenait des initiatives et devinait pour le rester.

Autre observation : le multi-tâches ne fonctionnait pas très bien pour mes projets. Dans une boucle Ralph, on peut définir combien d’agents travaillent en parallèle sur les tâches individuelles, mais monter ce nombre au-dessus de 1 pour aller plus vite finissait en réalité par me ralentir, à cause de toute la négociation de dépendances (« avant de travailler là-dessus, il me faut ceci de terminé ») et de toutes les fusions nécessaires quand les agents se marchaient sur les pieds.

Mais une chose avec laquelle je me suis senti de plus en plus à l’aise grâce aux boucles Ralph, c’est que je n’avais plus besoin de relire chaque ligne de code générée. Mes revues de code devenaient de plus en plus inutiles à mesure que je me concentrais sur la relecture des spécifications et des plans qui précédaient le code. Par son propre processus de vérification, le modèle générait aussi des tests unitaires et pouvait même interagir directement avec l’application pour des tests d’intégration. Et j’ai aussi commencé à utiliser des skills spéciaux pour faire relire le code par des modèles d’IA eux-mêmes.

Mais globalement, je trouvais que l’aspect autonome des boucles Ralph faisait obstacle à la méta-évolution. Ce que j’appelle méta-évolution, c’est l’évolution non pas du code lui-même, mais de la façon dont le code se fabrique. En génie logiciel en général, une pratique clé consiste à toujours privilégier les solutions systémiques.

Quand un bug survient, on ne se contente pas de le corriger : on se demande pourquoi il a pu être là, et on se demande « pourquoi » autant de fois qu’il faut pour atteindre un niveau de solution où l’on est confiant que des bugs similaires ne réapparaîtront plus.

Appliqué aux modèles d’IA et à leurs contextes, c’est pareil : quand vous remarquez que Claude a fait une erreur, deviné de travers, ou posé une hypothèse incorrecte, il ne suffit pas de corriger le résultat. Il faut comprendre quel élément de contexte manquait, où il manquait, pour qu’il ne refasse plus cette erreur à l’avenir. C’est ainsi que la qualité du code généré s’améliore et que la construction devient de plus en plus productive.

Avec les boucles Ralph, j’avais le sentiment de manquer de visibilité et de points d’intervention pour voir ces erreurs, et le temps qu’elles se soient accumulées dans un logiciel complexe, elles étaient plus difficiles à analyser et à remonter jusqu’à la cause racine. L’amélioration incrémentale était donc plus lente, comme une sélection naturelle avec des générations très longues et pas assez d’occasions de mutations.

Alors je suis passé à l’Agentic Coding Toolkit, s’ouvre dans un nouvel onglet, développé par Andrea Bizzotto, que j’ai toujours respecté et dont j’ai beaucoup appris pour son expertise en architecture d’applications Flutter et Firebase. Avec ACT, il a conçu un workflow parfait pour les technologies que j’utilise, tout en me donnant plus de contrôle et de points d’intervention tout au long du cycle de développement d’une fonctionnalité. Et c’est ce que j’utilise encore aujourd’hui :

  • Je décris l’idée générale de la nouvelle fonctionnalité que je veux construire
  • ACT me pose des questions pour mieux comprendre et délimiter le périmètre dans le contexte de l’application existante
  • Une fois toutes mes réponses données, ACT utilise toute la connaissance à sa disposition et toutes mes réponses pour créer un document de spécification
  • ACT relit ensuite cette spécification de façon adversariale, en vérifiant chacune des hypothèses posées pendant la génération, et il met la spécification à jour
  • Puis je lis la spécification en détail (quelques centaines de lignes) pour m’assurer que nous n’avons rien oublié ni posé d’hypothèses incorrectes. Sinon, je demande à Claude d’amender la spécification jusqu’à ce que j’en sois satisfait.
  • Je committe alors cette spécification dans l’historique du code pour m’en souvenir lors des évolutions futures, je réinitialise le contexte, et je demande à ACT de transformer la spécification en plan d’implémentation concret, une série de tâches aux frontières claires avec des références à la spécification
  • Je relis généralement cette partie plus rapidement, parce qu’elle référence beaucoup de points d’entrée dans du code que je n’ai pas écrit moi-même, mais je vérifie qu’elle ne propose pas de faire quelque chose de complètement inhabituel par rapport au code existant, ou de réinventer la roue au lieu d’utiliser une bibliothèque tierce pour résoudre un problème courant, ce genre de choses.
  • Je committe le plan, je réinitialise à nouveau le contexte, et je lance le travail sur la première tâche de la liste.
  • À la fin de chaque tâche, je vérifie le rapport de tâche pour m’assurer qu’aucun problème récurrent n’est apparu ; si c’est le cas, j’amende le contexte avec une solution systémique, ou j’ajoute une tâche de suivi au plan, ou je corrige la spécification d’une manière ou d’une autre.
  • Puis je regarde le taux de remplissage de mon contexte de session. S’il est entre 33 et 50 %, je lance un skill de réflexion spécial (j’y reviens plus loin), puis je réinitialise le contexte. Et je passe à la tâche suivante jusqu’à ce que tout soit terminé.

Quand le code produit ainsi est vraiment gros ou complexe, j’utilise un skill spécial de Claude Code pour relire le code et proposer des améliorations que je le laisse implémenter. Quand la sécurité des données ou le contrôle d’accès est en jeu, je lance aussi un skill de revue de sécurité.

Et comme je l’expliquais, chaque fois que je veux réinitialiser le contexte après une grosse session de travail, je lance un skill spécial de « réflexion » qui analyse la session et cherche automatiquement des occasions d’améliorer le contexte local du projet, le contexte général de Claude Code, ou de créer des skills réutilisables pour les tâches répétitives. C’est mon processus de méta-évolution automatisé. C’est ça, l’ingénierie produit. C’est ça, mon travail désormais.

L’instrumentation

Dans ces workflows, qu’il s’agisse d’une boucle Ralph, d’ACT ou de n’importe quelle autre variante, un élément clé consiste à donner du pouvoir à votre modèle d’IA en le connectant à un maximum de sources de contexte, pour qu’il puisse prendre des décisions éclairées et agir en votre nom sans que vous ayez à intervenir à chaque tournant. C’est aussi ce qui rend les modèles d’IA si productifs.

Certains vont jusqu’à lâcher totalement la bride à leur IA avec des outils comme OpenClaw, s’ouvre dans un nouvel onglet. Dans le contexte de systèmes logiciels qui peuvent servir beaucoup de monde et doivent rester fiables, tout en protégeant les données des utilisateurs, il faut être un peu plus subtil et prudent. Mais voici tout de même quelques exemples de ce à quoi mon Claude Code a accès (de façon sécurisée) quand je construis Skaoot :

Avec l’accès à tous ces outils, Claude Code peut :

  • diagnostiquer les incidents en analysant les rapports de crash et les logs backend et frontend, et proposer des solutions pertinentes que je peux déployer en minutes au lieu d’heures
  • intégrer du nouveau code à l’existant en préservant la cohérence et en optimisant la réutilisation
  • écrire et exécuter des tests d’intégration qui interagissent avec l’application et vérifient le résultat de chaque tâche d’implémentation ou de correction
  • mettre à jour ou installer de nouvelles dépendances et les intégrer sur la base d’une documentation correcte
  • garder mon plan projet à jour

La connexion de tous ces outils via des serveurs MCP s’est faite en implémentant des solutions systémiques et en faisant évoluer mon approche. Quand j’ai réalisé que je passais mon temps à copier-coller des logs backend dans le terminal de Claude Code, je lui ai donné un accès direct aux logs des Cloud Functions pour ne plus avoir à le faire. Quand il devait sans cesse réparer des données corrompues ou générer des données de test, je lui ai donné un accès direct à Firestore avec des garde-fous pour être sûr qu’il ne détruise rien en production. Au total, cela a produit moins d’hallucinations, moins de suppositions, parfois plus de consommation de tokens, mais de meilleures solutions au bout du compte.

Le comment contre le quoi et le pourquoi

Même si écrire du code n’a jamais été qu’une petite partie de mon travail (mais une grande partie de mon plaisir quotidien), lire du code, organiser du code, gérer des dépendances, architecturer des données et des comportements relevaient tous du « comment » de mon métier, et cette partie-là était grosse. Maintenant que ce « comment » est devenu beaucoup moins cher, soit par externalisation pure (je n’ai plus à le faire), soit par d’énormes bonds de productivité (je dois encore le faire, mais beaucoup plus vite), le « comment » n’est plus le goulot d’étranglement. Mon attention s’est déplacée vers le « pourquoi » et le « quoi ».

D’ailleurs, le « comment » coûtait tellement cher que les gens avaient inventé quantité d’outils et de techniques pour analyser le « pourquoi » et le « quoi », afin de ne pas gaspiller d’argent à construire des choses dont personne ne voulait : lean startup, méthodes agiles, kanban, etc.

Maintenant qu’expérimenter, essayer des choses, coûte tellement moins cher, c’est moins critique, et la plupart des gens peuvent se permettre de perdre un peu de temps et de tokens à construire la mauvaise chose. Mais même si, en valeur absolue, on passe moins de temps à réfléchir au « quoi » et au « pourquoi », cela représente désormais la majorité du travail.

Les priorités ont donc complètement basculé. Et avec elles, les compétences nécessaires pour construire du logiciel ont radicalement changé. On a moins besoin d’expertise technique pointue et profonde, mais il faut de meilleures capacités à voir la grande image, à articuler une vision, à identifier les problèmes, à concevoir des solutions, à les exprimer et à les intégrer de façon à amener l’IA à générer du logiciel sécurisé, scalable et évolutif.

En substance, là où il fallait toute une équipe d’ingénieurs, de designers, de testeurs, de chefs de projet et j’en passe, il faut maintenant un product owner surpuissant, doté d’une solide compréhension technique et d’un bon sens du design, et cette personne seule peut potentiellement posséder tout le cycle de construction logicielle. C’est ce que j’appelle un Product Engineer. Quelqu’un qui se concentre sur le « pourquoi » et le « quoi », tout en en sachant assez sur le « comment » pour produire du logiciel durable, vite et en continu.

Et c’est aussi pourquoi je pense que beaucoup d’entreprises sous-estiment complètement la dimension conduite du changement de l’adoption de l’IA. Elles licencient généralement les développeurs les plus chers, arrêtent d’embaucher des juniors, ordonnent aux ingénieurs restants d’utiliser un maximum de tokens, et ne changent rien à leur organisation interne ni à leur culture.

Mais à mon avis, au vu de la façon dont mon propre travail a évolué, je suis désormais convaincu que les entreprises doivent repenser complètement les profils dont elles ont besoin, réfléchir sérieusement à qui elles gardent ou laissent partir, former leurs équipes à faire confiance aux modèles d’IA et à les exploiter intelligemment, et réorganiser leurs équipes et la façon dont le logiciel est géré, possédé et maintenu. Ce n’est pas une mince affaire, et cela doit se traiter au cas par cas, en tenant compte des contraintes et des atouts propres à chaque entreprise, de son histoire, de son niveau d’expertise, de ses résistances, de ses peurs et de sa curiosité. Aucun outil ni aucune méthodologie miracle et générique ne vous aidera vraiment à optimiser cette transition.

L’IA n’est pas cet outil miracle qui réduit les coûts sur simple achat de licence. La meilleure façon de vraiment gagner en productivité sans dégrader la qualité du logiciel produit, tout en faisant plus qu’avant avec le même budget voire un budget plus petit, c’est d’opérer une transition soignée et d’adapter toute l’organisation autour de ce nouveau paradigme rendu possible par l’IA. Il y aura toujours ceux qui prennent des raccourcis et font l’impasse sur ce travail de conduite du changement, mais dans la plupart des cas ils échoueront, et en rejetteront la faute sur l’IA. Imaginez si, après l’invention de l’imprimerie, nous n’avions construit des presses que pour les monastères, à l’usage des moines copistes.

La productivité

Dans sa forme la plus simple, la productivité est un ratio entre ce que vous pouvez construire et ce que cela vous coûte de le construire. La façon la plus évidente d’augmenter la productivité est donc de construire la même valeur logicielle en diminuant l’investissement.

Mais il y a une autre voie. Vous pouvez aussi garder votre investissement tel quel, et considérer tout ce que vous ne construisiez pas avant, toute la valeur que vous n’extrayiez pas parce que cela ne valait tout simplement pas l’effort, et augmenter radicalement le périmètre de ce que vous pouvez construire. Chaque révolution technologique a toujours été l’occasion d’un bond quantique dans le niveau et l’échelle des problèmes qu’il devient rentable d’attaquer. Serions-nous allés sur la Lune sans les mainframes IBM à la place des calculateurs humains ? Aurais-je pu construire une application aussi sophistiquée que Skaoot tout seul sans l’IA ? Je ne crois pas.

D’ailleurs, Skaoot m’a fait réaliser autre chose de très important : bien sûr, le développement piloté par l’IA a multiplié ce que je peux faire dans le même temps, mais il m’a aussi permis de construire des fonctionnalités dont je n’aurais même pas pu rêver avant, sans le moindre chatbot. Trop de produits logiciels utilisent aujourd’hui les LLM pour ajouter une interface de chatbot à leur application, proposer des suggestions dont les utilisateurs n’avaient pas vraiment besoin, ou remplacer des humains par des robots là où cela n’a clairement aucun sens.

Mais les utilisateurs finaux en ont assez, et je ne crois pas que ce soit là que se crée le plus de valeur. Dans Skaoot, j’utilise aussi la génération par IA pour analyser des emails non structurés dans n’importe quel format ou langue et en extraire des données structurées. J’utilise Gemini pour combiner l’historique existant avec les nouvelles données entrantes en un instantané qui a du sens pour l’utilisateur final. Et bientôt, je compte utiliser la generative UI (et non l’IA générative) pour personnaliser en temps réel la façon dont les données sont présentées à l’utilisateur. Sans chatbot ni popup de suggestion.

« Donnez-moi un levier et je soulèverai le monde », disait Archimède. Eh bien, on vient de nous donner un levier immense, et jusqu’ici nous nous sommes surtout employés à réduire la taille de la personne qui pèse sur le levier pour soulever le même monde, ou à lui coller un logo IA dans le dos. Maintenant, vous savez ce qu’il nous reste à faire.

La prochaine étape

Comme je l’expliquais au début de ce roman d’article, j’ai été ingénieur logiciel pendant 20 ans avant que l’IA n’arrive et ne fasse voler en éclats toutes mes certitudes. J’ai traversé un processus de deuil complet, qui a maintenant atteint sa conclusion.

Je ne suis plus un ingénieur logiciel, je suis un ingénieur produit.

Ce qui m’amène à réorienter ma carrière de consultant selon 3 grands axes :

  1. Skaoot : je vais continuer à travailler sur mon nouveau produit, Skaoot, et le faire grandir autant que possible, entièrement seul, sans employés ni investisseurs, en cherchant de l’aide extérieure uniquement là où il me manque encore le minimum de compétences pour atteindre le levier de l’IA. Ce sera mon terrain de jeu, ma vitrine, et une source de revenus.
  2. Adopt an AI : je vais commencer à partager mon parcours de transition avec les entreprises et les équipes qui peinent à adopter l’IA et à l’exploiter correctement, à travers des interventions de coaching et de formation sur mesure, centrées sur la construction progressive de la confiance et l’intégration de l’adoption de l’IA dans une vraie démarche de conduite du changement.
  3. Augmented Intelligence : et je vais proposer mes services aux entrepreneurs et aux entreprises pour les aider à transformer des idées plus grandes en business cases réussis, en mobilisant toute l’étendue de mon expertise pour construire des logiciels encore plus ambitieux, avec l’IA comme outil ET comme levier de fonctionnalités, exactement comme je le fais sur Skaoot.

Si mon premier chantier vous intéresse et que vous êtes nomade numérique ou voyageur fréquent, allez voir le site de Skaoot, s’ouvre dans un nouvel onglet. Pour les deux derniers points, c’est ma nouvelle maison de conseil qu’il faut visiter.