
L’insoutenable légèreté du codage
Il y a un mois, j’ai construit un système de récupération complet avec des intégrations, une recherche hybride et une interface graphique en 25 heures environ. Le week-end dernier, j’ai passé deux jours à essayer de corriger un bug et j’ai réalisé que je n’avais aucune idée du fonctionnement de mon propre logiciel.
Soyons honnêtes : j’ai poussé un dépôt GitHub sans avoir écrit une seule ligne de code. Est-ce que je me sens mal à ce sujet ? Type de. La quantité de doutes techniques pèse lourdement sur mes épaules, bien plus que d’habitude. Vais-je le regretter ? Peut être. Veux-tu?
Je voulais partager mon histoire ici parce que je pense que c’est quelque chose que de nombreux développeurs vivent actuellement, et encore plus le feront dans les années à venir.
Car avouons-le : vous pouvez avoir un code d’honneur et être fier de votre savoir-faire, mais rien ne vaut la vitesse de GitHub Copilot & Co. Si votre collègue sous stéroïdes IA fournit des fonctionnalités et publie des mises à jour deux fois (largement sous-estimé) aussi vite que vous, qui, selon vous, est le plus proche de la porte de l’entreprise lorsque les budgets se resserrent ?
Les gains de productivité sont réels, même si vous utilisez ces outils uniquement à des fins de documentation. Et il y a un petit pas à partir de :
« Écrivez des docstrings pour cette fonction.«
à
« Écrivez la fonction.«
Cette petite étape rapide vous propulse dans un domaine de productivité complètement différent.
Mais voici mon histoire très personnelle, ce que j’ai appris et où je pense que cela nous laisse en tant que développeurs.
Le projet : construire mon propre NotebookLM (mais plus strict)
Pour le contexte, j’ai décidé de créer un système de récupération de texte de style RAG dans l’esprit de NotebookLM, mais en plus strict. Le système prend une bibliothèque PDF privée, la traite, puis récupère les réponses textuellement de ce corpus. Pas de paraphrase, pas de phrases hallucinées, juste « donnez-moi le passage exact qui répond à ma question pour que je puisse le rechercher à nouveau dans le PDF original ».
Certes, c’est une manière très scientifique, un peu paranoïaque, d’utiliser votre littérature. Mais je ne suis probablement pas le seul à en avoir assez de vérifier chaque réponse de LLM par rapport à la source.
L’architecture du logiciel était assez simple :
- Un pipeline d’ingestion robuste : parcourir les arborescences de répertoires, extraire le texte des PDF et le normaliser en paragraphes et en morceaux qui se chevauchent.
- Hybrid Storage & Retrieval : une couche de stockage combinant des tables SQL standard, un moteur de recherche en texte intégral à index inversé (pour les correspondances exactes de mots clés) et une base de données vectorielle (pour la compréhension sémantique).
- Une stratégie de reclassement : une certaine logique pour extraire un large pool de candidats via une recherche lexicale, puis reclasser les résultats en utilisant une similarité vectorielle dense pour obtenir le meilleur des deux mondes.
- Une interface utilisateur complète : un tableau de bord pour gérer la bibliothèque PDF, surveiller la progression de l’ingestion et afficher les résultats avec des liens profonds vers le texte source.
Sur le papier, tout cela est assez simple. Python, Streamlit, SQLite+FTS5, FAISS, un modèle de transformation de phrases, le tout enveloppé dans un conteneur Docker. Pas de dépendances exotiques au cloud, juste un outil privé NotebookLM exécuté sur ma machine.
L’approche documentaire d’abord
Je n’ai pas commencé par le code, mais par la documentation. J’avais déjà mon squelette de projet habituel à partir d’un modèle à l’emporte-pièce, donc la structure était là : une place pour les exigences, pour les décisions de conception, pour la façon de déployer et de tester, le tout soigneusement rangé dans un dossier de documentation en attente d’être rempli.
J’ai noté le cas d’utilisation, esquissé l’architecture, les algorithmes à implémenter, les exigences. J’ai décrit les objectifs, les contraintes et les principaux composants en quelques puces, puis j’ai laissé genAI m’aider à étendre les sections plus longues une fois que j’ai eu l’idée approximative en place. Je suis donc passé progressivement d’une idée de base à la réalisation de documents plus détaillés décrivant l’outil. Le résultat n’était pas la meilleure documentation jamais réalisée, mais il était suffisamment clair qu’en théorie, j’aurais pu confier l’ensemble à un développeur junior et il aurait su quoi construire.
Libérer mon collègue IA dans la base de code
Au lieu de cela, je l’ai remis à la machine.
J’ai ouvert les portes et laissé mon collègue GitHub Copilot entrer dans la base de code. Je lui ai demandé de créer une structure de projet comme bon lui semble ainsi que de remplir les fichiers scripts requis. Une fois qu’une structure de base a été définie et que l’outil a semblé fonctionner avec un seul algorithme, je lui ai également demandé de générer la suite pytest, d’exécuter le test et d’itérer une fois qu’il rencontrait des erreurs. Une fois cela fait, j’ai continué à lui demander d’implémenter d’autres algorithmes et de couvrir certains cas extrêmes.
Essentiellement, j’ai suivi mon approche habituelle du développement logiciel : commencer avec un noyau fonctionnel, puis étendre avec des fonctionnalités supplémentaires et corriger les choses chaque fois que la construction en pleine croissance rencontre des problèmes majeurs. Est-ce une architecture globalement optimale ? Probablement pas. Mais cela est tout à fait dans l’esprit du programmeur pragmatique : garder les choses simples, répéter et « expédier » fréquemment – même si l’envoi est uniquement interne et uniquement pour moi-même.
Et il y a quelque chose de profondément gratifiant à voir ses idées se matérialiser en un outil de travail en une journée. Travailler avec mon collègue IA m’a donné l’impression d’être le chef de projet que j’ai toujours voulu être : même mes souhaits à moitié cuits ont été anticipés et mis en œuvre en quelques secondes sous forme de code essentiellement fonctionnel.
Lorsque le code ne fonctionnait pas, je copiais la trace de la pile dans le chat et laissais l’agent se déboguer lui-même. S’il restait coincé dans un terrier de lapin auto-induit, je changeais de modèle de GPT5 à Grok ou inversement et ils se déboguaient mutuellement comme des frères et sœurs rivaux.
Suivre leur processus de réflexion et voir la base de code croître si rapidement était fascinant. Je n’ai gardé qu’une estimation très approximative du temps de ce projet, car il s’agissait d’une expérience parallèle, mais il ne fallait certainement pas plus de 25 heures pour produire >5000 lignes de code. Ce qui est certainement une belle réussite pour un outil relativement complexe qui aurait autrement pu m’occuper plusieurs mois. C’est encore loin d’être parfait, mais cela fait ce que je voulais : je peux expérimenter différents modèles et algorithmes de synthèse au-dessus d’un noyau de récupération qui renvoie les réponses textuelles de ma propre bibliothèque, ainsi que la source exacte, afin de pouvoir accéder directement au document sous-jacent.
Et puis je l’ai laissé tranquille pendant un mois.
La gueule de bois technique de la dette
À mon retour, je ne souhaitais pas ajouter de fonctionnalité majeure. Je voulais juste conteneuriser l’application dans Docker afin de pouvoir la partager avec un ami.
Dans ma tête, c’était une tâche intéressante du samedi matin. Au lieu de cela, cela s’est transformé en un week-end de cauchemar à plein temps avec des problèmes de configuration Docker, des chemins ne se résolvant pas correctement à l’intérieur du conteneur, des caches intégrés et des index FAISS vivant dans des endroits que je n’avais pas clairement séparés du code, et des tests passant sur ma machine locale mais échouant (ou ne fonctionnant jamais correctement) dans CI/CD.
Certaines de ces questions dépendent entièrement de moi. J’ai volontiers supposé que mon pipeline CI/CD (également généré par l’IA) « s’en occuperait » en exécutant des tests sur GitHub, afin que les incohérences multiplateformes apparaissent rapidement. Spoiler : ils ne l’ont pas fait.
à l’époque où Copilot suggérait une solution apparemment simple : « Ajoutez simplement une référence au répertoire de travail ici. » Au lieu de le laisser toucher au code, je voulais garder le contrôle et demander uniquement mon chemin. Je ne voulais pas que cela fasse des ravages dans une base de code que je n’avais pas consultée depuis des semaines.
C’est à ce moment-là que j’ai réalisé à quel point j’avais externalisé.
Non seulement je n’ai pas réalisé pourquoi l’erreur s’était produite en premier lieu, mais je n’ai pu identifier ni le fichier ni le passage dans lequel j’étais censé effectuer la modification. Je n’avais aucune idée de ce qui se passait.
Comparez cela à un autre projet que j’ai réalisé avec un collègue il y a trois ans. Je me souviens encore de la façon dont certaines fonctions étaient imbriquées et du stupide bug que nous avons passé des heures à rechercher, pour découvrir que l’un de nous avait mal orthographié le nom d’un objet.
La vérité inconfortable
J’ai économisé un temps de développement énorme en évitant le travail d’implémentation de bas niveau. Je suis resté maître de l’architecture, des objectifs et des décisions de conception.
Mais pas les détails.
Je suis effectivement devenu le responsable technique d’un projet dont le seul développeur était une IA. Le résultat ressemble à quelque chose qu’un entrepreneur très rapide et très avisé a construit pour moi. Le code a une documentation exceptionnellement bonne et des tests décents, mais ses modèles mentaux ne me sont jamais entrés en tête.
Serais-je capable de réparer quoi que ce soit si j’avais besoin d’effectuer un changement et qu’Internet était en panne ? En réalité : non. Ou du moins pas plus vite que si j’héritais de cette base de code d’un collègue qui a quitté l’entreprise il y a un an.
Malgré une documentation meilleure que la moyenne, je bute toujours sur des morceaux de code « WTF ». Pour être honnête, cela se produit également avec le code écrit par des humains, y compris le mien d’il y a quelques mois. Alors, GenAI aggrave-t-il la situation ? Ou juste plus vite ?
Alors… le vibe coding est-il bon ou mauvais ?
Honnêtement : les deux.
La vitesse est folle. L’effet de levier est réel. L’écart de productivité entre les personnes qui utilisent ces outils de manière agressive et ceux qui ne les utilisent pas ne fera que se creuser. Mais vous échangez l’intimité de la mise en œuvre contre le contrôle architectural.
Vous passez d’artisan à chef d’orchestre. Du constructeur au chef de projet. De la connaissance de chaque vis de la machine à la confiance dans le robot qui a assemblé la voiture. Et c’est peut-être simplement ce vers quoi le génie logiciel est en train de se transformer tranquillement.
Personnellement, je me sens désormais beaucoup plus comme un chef de projet ou un architecte principal : je contrôle la situation dans son ensemble et je suis convaincu que je pourrai reprendre le projet dans un an et le prolonger. Mais en même temps, cela ne ressemble pas à « mon » code. De la même manière que, dans une configuration classique, l’architecte principal ne « possède » pas chaque ligne écrite par son équipe.
C’est mon système, ma conception, ma responsabilité.
Mais le code ? Le code appartient à la machine.



