Arrêtez le "vibe coding" et commencez à créer des logiciels maintenables avec les LLM
Depuis que les grands modèles de langage (LLM) se sont démocratisés, j'ai observé les ingénieurs transformer leurs méthodes de travail. Avec des outils comme ChatGPT, Claude et GitHub Copilot à leur disposition, les développeurs créent leurs logiciels par conversation - mais ils s'y prennent mal.
Je vais vous montrer pourquoi cette approche courante mène à des logiciels fragiles et difficiles à maintenir, qui deviennent un cauchemar à faire évoluer - même avec l'assistance de l'IA. Plus important encore, je vais vous présenter une méthode qui produit du code propre, précis, résistant aux bugs et de haute qualité, qui reste facile à maintenir tant par les humains que par les LLM.
Le problème du "Vibe Coding"
Quand la plupart des développeurs utilisent les LLM, ils suivent ce que j'appelle le flux de travail du "vibe coding" :
- Concevoir une idée vague
- Demander à un LLM de l'implémenter
- Obtenir un bloc de code en réponse
- Le tester, trouver des problèmes
- Renvoyer le code au LLM avec des demandes de correction
- Répéter les étapes 4-5 indéfiniment
Cette approche semble initialement magique. Vous pouvez matérialiser des applications complexes en minutes au lieu de jours. Mais tout comme demander à un sculpteur de "faire quelque chose de cool" sans spécifications, vous finissez avec quelque chose qui fonctionne momentanément mais devient impossible à reproduire, étendre ou maintenir.

Le défaut fondamental ? Les développeurs itèrent sur le code plutôt que sur les exigences.
Les LLM ne sont pas conçus pour comprendre et modifier des bases de code complexes. Ils excellent à suivre des descriptions et à générer de nouvelles implémentations. Quand vous les forcez à modifier récursivement du code, vous luttez contre leurs forces tout en amplifiant leurs faiblesses.
La solution : Itérer sur les spécifications, pas sur le code
La révélation qui a transformé mon flux de travail est venue en cherchant à contourner les limitations de contexte des premières sessions de LLM. Au lieu d'essayer de faire rentrer une base de code entière dans la fenêtre de contexte, j'ai commencé à itérer sur les spécifications.
Voici l'idée clé : Les LLM sont bien meilleurs pour écrire du nouveau code que pour éditer du code existant.
Alors ne leur donnez pas du code à corriger - donnez-leur des spécifications à implémenter.
J'appelle cette approche le Développement Orienté Spécifications:
- Commencer avec une spécification écrite claire
- Demander à un LLM de l'implémenter
- Tester l'implémentation
- Au lieu de modifier le code, mettre à jour la spécification
- Demander au LLM d'implémenter la spécification mise à jour (soit depuis la dernière version, soit de zéro)
- Répéter selon les besoins

Cette méthode offre plusieurs avantages immédiats :
- Modularité inhérente - les applications complexes se décomposent naturellement en spécifications de composants
- Utilisation drastiquement réduite de tokens – specs are compact compared to code, and modern LLMs only update the parts of the code that need to be
- Pas de débordement de contexte - même des applications complexes peuvent être décrites succinctement
- Indépendance de plateforme - la même spécification peut cibler différentes plateformes ou langages
- Flexibilité de framework - changez de framework en cours de développement sans réécriture
- Documentation intégrée - vos spécifications documentent exactement ce que fait votre logiciel
Comment écrire des spécifications efficaces
Le cœur de cette approche est la rédaction de bonnes spécifications. Voici mon processus :
1. Commencer par une description d'une phrase
Débutez avec la description minimale absolue de votre application :
Une application pour automatiser la création de captures d'écran pour l'App Store.
Cette phrase fondamentale vous aide à rester concentré sur l'objectif principal.
2. Développer une description fonctionnelle basique
Élaborez légèrement sur la forme et la fonction, sans détails techniques :
Une application iOS et Android qui présente une interface simple permettant aux utilisateurs de créer, éditer et produire des mises en page de captures d'écran. L'outil aurait des fonctionnalités de base comme l'import/export et un éditeur visuel de mise en page avec des options pour ajuster le placement, le dimensionnement et la rotation des éléments importés.
3. Détailler la spécification complète
Créez maintenant une spécification détaillée couvrant l'interface, les fonctionnalités et le comportement :
Style d'interface : Style plat minimaliste, boutons aux coins arrondis, thème de couleur bleu, gris clair et blanc.
Disposition de l'interface : Éditeur WYSIWYG plein écran, deux boutons flottants en bas : 'Importer', 'Exporter'.
Éléments visuels par défaut :
- Un titre de capture d'écran par défaut affiché sous forme de texte flottant éditable : 'titre'.
- Un sous-titre de capture d'écran par défaut affiché sous le titre : 'sous-titre'.
- Un cadre vide affiché sous le sous-titre, centré horizontalement et verticalement.
Interactions :
- Bouton Importer : Ouvre le navigateur de photos natif du système d'exploitation.
- Bouton Exporter : Ouvre le panneau de partage natif du système avec les options : 'Exporter en PNG', 'Enregistrer la photo'.
- Sélection d'élément : Cliquer sur un élément affiche un cadre autour avec des poignées pour déplacer, redimensionner et faire pivoter.
- Rotation : Une icône de rotation apparaît en bas à droite du cadre de sélection. La faire glisser fait pivoter l'élément avec un alignement à 90°.
- Positionnement : Les éléments s'alignent sur une grille fine semi-transparente centrée sur l'écran.
Quand vos spécifications atteignent ce niveau de détail, n'importe quel LLM peut produire une implémentation solide. Au fur et à mesure que vous recueillez des retours et affinez votre application, vous mettez à jour ce document de spécification plutôt que le code généré.
Un flux de développement réel
Voyons cette approche en action :
Premier prompt pour analyser et formaliser votre idée
J'ai une description basique d'une application que je veux construire. Pourriez-vous :
1. La transformer en une spécification formelle
2. Identifier les détails manquants
3. Poser des questions clarificatrices sur les zones ambiguës
Description de l'application :
[votre description initiale]
Prompt pour générer du code à partir d'une spécification
Basé sur la spécification suivante, générez une implémentation complète utilisant [langage/framework]. Le code doit être propre, bien commenté et suivre les meilleures pratiques. Ne supposez aucune fonctionnalité non explicitement mentionnée dans la spécification.
SPÉCIFICATION :
[votre spécification détaillée]
Prompt pour mettre à jour les spécifications après retour
J'ai reçu des retours sur l'implémentation initiale. J'aimerais mettre à jour la spécification pour inclure ces changements :
[liste des changements]
Veuillez réécrire la spécification complète pour incorporer ces changements tout en maintenant la cohérence avec les exigences originales.
Prompt pour générer une implémentation mise à jour
En utilisant cette spécification mise à jour, générez une nouvelle implémentation. Ne changez pas le code utilisé pour implémenter les fonctions existantes, et n'ajoutez du code que pour implémenter les nouvelles fonctionnalités demandées. Concentrez-vous sur l'implémentation exacte de ce qui est décrit dans la spécification, ni plus, ni moins.
SPÉCIFICATION MISE À JOUR :
[votre spécification mise à jour]
Sauver des projets existants de "Vibe Coding"
Si vous avez déjà accumulé un désordre de code généré par IA via l'approche de vibe coding, vous pouvez encore récupérer :
Prompt pour extraire des spécifications du code existant
Analysez le code suivant et générez un document de spécification complet qui décrit ce qu'il fait, pas comment il le fait. Incluez toutes les fonctionnalités, comportements, règles métier et éléments d'interface que vous pouvez identifier. Formatez cela comme une spécification structurée qu'un autre ingénieur pourrait implémenter à partir de zéro.
CODE :
[votre code existant]
Une fois que vous avez ces spécifications extraites, vous pouvez les nettoyer, supprimer les redondances et les utiliser comme base pour une nouvelle implémentation.
Versionnement de vos spécifications
Traitez vos spécifications comme les actifs précieux qu'elles sont :
- Stockez-les dans un système de contrôle de version
- Utilisez un versionnement sémantique (v0.1, v0.2, etc.)
- Pour les applications complexes, divisez les spécifications en modules (Cœur, Interface, Couche de données, etc.)
- Incluez une section "Leçons apprises" documentant les détails d'implémentation délicats
Votre fichier de spécification devrait être le premier fichier que vous créez dans un projet et le dernier que vous mettez à jour dans chaque session de développement.
Pourquoi cette approche transforme le développement avec l'IA
L'approche orientée spécifications change fondamentalement votre conception du développement logiciel avec l'IA :
- Le code devient jetable - Vous n'êtes plus attaché à des implémentations spécifiques
- Les implémentations multiples deviennent triviales - Générez des versions iOS, Android et web à partir de la même spécification
- Les LLM deviennent interchangeables - Votre spécification fonctionne avec n'importe quel modèle ou outil
- Vous gardez le contrôle de l'architecture - L'humain se concentre sur le quoi, l'IA sur le comment
- Votre logiciel devient pérenne - À mesure que les LLM s'améliorent, régénérez de meilleures implémentations à partir des mêmes spécifications
Considérez cela comme un retour à l'essence de l'ingénierie logicielle : définir clairement le problème avant de le résoudre. La différence est que maintenant, avec les LLM, le chemin de la spécification à l'implémentation est devenu presque instantané.
Et Les Gros Projets ?
Je suis sûr que certain d'entre vous vous demanderez si cette méthode fonctionne pour les projets de grande taille. En fait, la méthode fonctionne pour les projets de toutes tailles, du moment que les spécifications sont à la hauteur. Pour les projets de très grande taille, je recommande généralement de prendre une approche hybride : on commence par itérer sur les spécifications pour arriver au MVP, puis on descend d'un niveau et on travaille au niveau du module, du composant ou même de la fonction. Il n'y a pas vraiment de limite, du moment qu'on continue à appliquer la méthode au niveau où on se trouve dans le projet.
La méta-couche : le code comme une vue
L'aperçu le plus profond de cette approche est de voir le code comme simplement une vue possible de vos spécifications. Vos spécifications deviennent la source de vérité, et le code n'est qu'une manifestation.
À partir d'une seule spécification, vous pouvez générer :
- Des implémentations pour plusieurs plateformes
- Des suites de tests
- De la documentation
- Des guides utilisateur
- Des interfaces d'API
Chacun n'est qu'une projection différente de la même spécification sous-jacente.
Commencer dès aujourd'hui
Pour adopter le développement orienté spécifications dans votre flux de travail :
- Pour votre prochain projet, rédigez des spécifications avant de générer du code
- Quand vous rencontrez des bugs ou avez besoin de nouvelles fonctionnalités, mettez à jour la spécification avant de toucher au code
- Créez une bibliothèque de modèles de spécifications réutilisables pour les composants communs
- Expérimentez la génération de plusieurs implémentations à partir de la même spécification
Plus vous vous habituez à penser en termes de spécifications plutôt qu'en implémentations, plus votre processus de développement devient puissant.
Cette approche a transformé ma façon de construire des logiciels avec l'IA. Ma productivité a été multipliée, mais plus important encore, la qualité et la maintenabilité de mes logiciels se sont considérablement améliorées. J'aimerais savoir comment le développement orienté spécifications fonctionne pour vous.