J'ai Abandonné le Coding à l'Instinct pour les « Contrats de Prompts » — Mon Code Claude est Passé du Hasard à la Livraison

11 min read

Pas parce que le code était mauvais. Il compilait. Il tournait. Il avait même l'air propre.

Mais il résolvait le mauvais problème. J'avais demandé un système d'auth Supabase avec row-level security. Ce que j'ai reçu était un magnifique système d'authentification production-ready — utilisant Firebase.
Claude Code m'a fait un reverse card digne d'Uno sur toute ma stack. Comme commander une pizza et recevoir un risotto parfaitement cuisiné. Techniquement impressionnant. Fondamentalement faux.

C'est à ce moment que j'ai réalisé quelque chose d'inconfortable : Je ne codais pas avec Claude Code. Je jouais au casino avec.

Et si vous tapez des prompts en langage naturel dans Claude Code 🧑‍💻 en croisant les doigts, vous lancez les dés aussi. Sauf que le maître du donjon est une IA sans contexte et avec une confiance infinie.

Développeur frustré face à Claude Code générant du code incorrect malgré compilation
Quand Claude Code livre Firebase au lieu de Supabase comme prévu

Le Piège du Vibe Coding

Voici à quoi ressemble le vibe coding dans la nature :

> Construis-moi un dashboard pour mon SaaS

Claude Code écrit 3 000 lignes sur 14 fichiers. Vous plissez les yeux sur le résultat comme si vous essayiez de voir une image stéréoscopique. Une partie semble correcte.

Vous l'exécutez.

Quelque chose plante.

Vous dites "répare ça."

Il répare un truc, en casse trois autres. Ce n'est pas du debug. C'est du tape-taupe avec un abonnement à 100€/mois.

Il y a quelques semaines, je suis tombé sur un concept d'un ex-ingénieur OpenAI : les Contrats de Prompt

Quarante-cinq minutes plus tard, vous avez livré quelque chose qui fonctionne mais que vous ne comprenez pas totalement. Félicitations, vous maintenez maintenant une codebase écrite par une intelligence alien qui ne se souvient pas l'avoir écrite. Qu'est-ce qui pourrait mal se passer.

J'ai vécu dans cette boucle pendant des mois. J'ai livré deux produits SaaS presque entièrement avec Claude Code, et je n'exagère pas quand je dis que 30% de mon temps était passé à défaire des choses que Claude Code avait construites avec confiance dans la mauvaise direction. C'est comme faire du pair programming avec un génie qui a une amnésie et aucune notion de votre repo.

Le problème n'a jamais été l'intelligence de Claude Code. Opus 4.6 est absurdement capable — c'est basiquement un développeur senior qui a lu toutes les réponses Stack Overflow jamais postées et les a toutes retenues, y compris les mauvaises.

Le problème était que mes prompts étaient des vibes, pas des spécifications.

"Rends-le responsive." "Ajoute la gestion d'erreurs." "Utilise les bonnes pratiques."

Ce ne sont pas des instructions. Ce sont des horoscopes. Et Claude Code n'est pas un voyant — c'est un entrepreneur. Vous ne donneriez pas à un entrepreneur une serviette qui dit "construis maison, fais joli" et vous attendriez votre maison de rêve. Vous auriez une maison. Elle pourrait même avoir des murs. Mais les toilettes seraient dans la cuisine parce que vous n'avez jamais dit qu'elles ne devaient pas y être.


Contrats de Prompt : La Solution

Il y a quelques semaines, je suis tombé sur un concept d'un ex-ingénieur OpenAI : les Contrats de Prompt. L'idée est simple — au lieu d'écrire des prompts comme des briefs créatifs, écrivez-les comme des contrats légaux avec quatre clauses exécutoires :

Objectif — la métrique de succès exacte. Contraintes — les limites dures qui ne peuvent pas être franchies. Format de Sortie — la structure spécifique que vous attendez. Conditions d'Échec — ce qui rend la sortie inacceptable.

Je me suis dit : "C'est mignon pour les articles de blog ChatGPT. Mais est-ce que ça peut survivre à Claude Code construisant un vrai backend à 3h du matin quand vous tournez à la caféine et aux mauvais choix de vie ?"

Alors je l'ai testé. Pendant trois semaines d'affilée, sur deux projets SaaS, j'ai remplacé chaque prompt vibe par un Contrat de Prompt.

Spoiler : je dors maintenant.


Composant 1 : OBJECTIF — Arrêtez de Dire "Construis-moi X"

La plus grosse amélioration était de me forcer à définir à quoi ressemble terminé avant que Claude Code écrive une seule ligne.

Avant (vibe) :

> Ajoute un système d'abonnement à l'app

C'est l'équivalent prompt de dire à votre GPS "emmène-moi quelque part de sympa." Vous finirez quelque part. Ça pourrait être un restaurant étoilé. Ça pourrait être une station-service dans la Creuse.

Après (contrat) :

> OBJECTIF : Implémenter la gestion d'abonnements Stripe où les utilisateurs
> peuvent s'abonner à 3 tiers (gratuit/pro/équipe), upgrade/downgrade
> instantanément, et voir le statut de facturation sur /settings/billing.
> Succès = un utilisateur gratuit peut s'abonner au Pro,
> voir la charge sur le dashboard Stripe, et accéder aux
> fonctionnalités gatées en moins de 5 secondes.

La différence n'est pas juste le détail — c'est la testabilité. Quand Claude Code finit, je peux vérifier l'objectif en moins d'une minute. Pas d'ambiguïté. Pas de "bon, ça marche un peu" — le chat de Schrödinger des démos logicielles.

Ça seul a réduit mes allers-retours avec Claude Code d'environ la moitié. Quand l'IA sait à quoi ressemble la ligne d'arrivée, elle arrête de se balader sur la piste en prenant des selfies.


Composant 2 : CONTRAINTES — Les Murs Qui Vous Sauvent

C'est là que les choses deviennent spécifiques à Claude Code, parce que sans contraintes, Claude Code va absolument réinventer votre stack pour vous. C'est comme embaucher un rénovateur de cuisine qui débarque et dit "j'ai aussi démoli le mur de votre salon parce que le feng shui était foireux."

Je garde maintenant un CLAUDE.md à la racine de chaque projet qui agit comme une couche de contraintes permanente :

# CLAUDE.md — Contraintes Projet (toujours actives)

## Stack (non-négociable, je vais mass git revert)
- Frontend : Next.js 14+ App Router, TypeScript strict
- Backend : Convex pour les données temps réel, Supabase pour auth + storage
- Auth : Clerk (jamais d'auth custom, on n'est pas des animaux)
- Styling : Tailwind uniquement — pas de CSS modules, pas de styled-components

## Règles Dures
- Jamais installer une nouvelle dépendance sans demander d'abord
- Jamais modifier le schéma de base de données sans montrer le plan de migration
- Tous les appels API passent par les fonctions Convex, jamais d'appels
client Supabase directs depuis les composants
- Variables d'environnement dans .env.local, jamais hardcodées
(je vous trouverai et je vous reverterai)

## Patterns
- Utiliser les server components par défaut, client components seulement quand
l'interactivité est requise
- Error boundaries sur chaque segment de route
- Validation Zod sur chaque input utilisateur

Avant CLAUDE.md, Claude Code décidait aléatoirement d'utiliser Prisma au lieu de Convex, ou d'échanger Clerk pour NextAuth parce que "c'est plus commun." C'est comme votre barista qui décide que vous vouliez en fait du thé parce que plus de gens boivent du thé globalement. Je n'ai pas demandé une démocratie. J'ai demandé Clerk.

Maintenant ? Il reste dans sa lane. À chaque fois.

Pro tip : Quand vous commencez une nouvelle session Claude Code, votre premier message devrait être :

> Lis CLAUDE.md et confirme que tu comprends les contraintes du projet
> avant de faire quoi que ce soit.

Ça force un handshake. Pensez-y comme les droits Miranda de votre codebase. Claude Code répète les contraintes, vous vous mettez d'accord sur la réalité, et ensuite le travail commence. Sans ça, vous commencez essentiellement chaque session en donnant les clés à quelqu'un qui ne sait pas quelle voiture il conduit.


Composant 3 : FORMAT — Dites-lui Exactement Quoi Vous Donner

Le vibe coding laisse Claude Code décider de la structure. C'est comme dire à un chef "surprends-moi" et être choqué quand vous recevez une salade César déconstructée servie dans une chaussure.

Avant :

> Crée un endpoint API pour l'onboarding utilisateur

Claude Code décide : un fichier massif, validation inline, pas de types, tout dans une seule fonction de 800 lignes qui fait auth, appels base de données, et envoi d'emails en une respiration. Ça marche. C'est aussi un crime de guerre contre le vous-du-futur qui devra le maintenir.

Après :

> FORMAT :
> 1. Fonction Convex dans convex/users.ts (mutation, pas action)
> 2. Schéma Zod pour validation input dans convex/schemas/onboarding.ts
> 3. Types TypeScript exportés depuis convex/types/user.ts
> 4. Inclure JSDoc sur la fonction publique
> 5. Retourner { success: boolean, userId: string, error?: string }

Maintenant j'obtiens du code modulaire, typé, documenté — à chaque fois. Pas parce que Claude Code ne peut pas produire ça tout seul, mais parce que sans instructions de format explicites, il optimise pour la vitesse, pas la maintenabilité. Il fait du speedrun de votre codebase. Vous avez besoin qu'il joue le long terme.

Ça compte encore plus quand vous utilisez la fonctionnalité d'équipes d'agents de Claude Code pour paralléliser le travail. Si vos sous-agents ne suivent pas le même contrat de format, vous finissez par merger du code qui ressemble à quelque chose écrit par cinq développeurs qui communiquent exclusivement par messages de commit passifs-agressifs.


Composant 4 : CONDITIONS D'ÉCHEC — L'Arme Secrète

C'est le composant qui a tout changé. Si l'Objectif est la carotte, les Conditions d'Échec sont le bâton. Et Claude Code répond aux bâtons comme un développeur répond à un message Slack la prod est down — immédiatement et avec toute son attention.

Définir ce qui casse le contrat donne à Claude Code une cible négative. C'est comme dresser un chien : "assis" c'est bien, mais "PAS sur le canapé, PAS sur la table, PAS sur la belle-famille en visite" c'est ce qui sauve vraiment vos meubles.

Voici un vrai Contrat de Prompt que j'ai utilisé la semaine dernière :

> Construis la page /dashboard.
>
> OBJECTIF : Afficher les projets actifs de l'utilisateur avec mises à jour
> temps réel. First meaningful paint sous 1 seconde. L'utilisateur peut créer,
> archiver, et renommer les projets inline.
>
> CONTRAINTES : Convex useQuery pour les données, pas de polling, pas de SWR.
> Clerk useUser() pour vérif auth. Redirection vers /sign-in si
> non-authentifié. Max 150 lignes par fichier composant.
>
> FORMAT : Composant Page dans app/dashboard/page.tsx (wrapper server
> component), client component dans components/dashboard/ProjectList.tsx,
> requête Convex dans convex/projects.ts. Tailwind uniquement.
>
> CONDITIONS D'ÉCHEC :
> - Utilise useState pour des données qui devraient être dans Convex
> - Un composant dépasse 150 lignes
> - Récupère les données côté client quand ça pourrait être côté serveur
> - Utilise une UI library autre que les classes utilitaires Tailwind
> - États loading et error manquants
> - Types TypeScript manquants sur les paramètres de fonction

Quand j'ai lancé ça, Claude Code a produit un dashboard propre et temps réel du premier coup. Pas de Firebase. Pas de Prisma. Pas de packages npm mystères de 2019 avec 12 étoiles GitHub et un README qui dit "TODO." Pas de god-component de 1 200 lignes que le moi-du-futur aurait besoin de thérapie pour refactoriser.

Comparez ça à ce qui s'est passé le mois d'avant, quand "construis-moi un dashboard" a produit un composant qui importait Material UI (je n'utilise pas Material UI), utilisait useEffect pour récupérer les données (on a Convex pour une raison), et avait zéro états de loading. Juste de l'optimisme brut et non protégé que les données seraient toujours là instantanément. L'équivalent logiciel de laisser votre maison ouverte parce que "c'est un quartier sympa."

Les conditions d'échec agissent comme des garde-fous. Claude Code n'a pas à deviner ce que "bien" signifie quand vous lui avez déjà dit à quoi ressemble "mal." C'est la différence entre "conduis prudemment" et "ne dépasse pas 130, ne grille pas les feux, ne prends pas l'autoroute aux heures de pointe." L'un est une prière. L'autre est un système de navigation.

🔄 Update : Un contrat que je n'ai pas mentionné dans la version originale de cet article parce qu'il n'existait pas encore : `/security-review`. Tapez-le avant de push. Claude scanne vos changements en attente pour injection SQL, contournements d'auth, secrets hardcodés — les trucs que vous ratez quand vous êtes en mode feature profond. J'ai écrit une analyse complète de comment ça marche et comment le personnaliser pour votre stack. Version courte : c'est le filet de sécurité post-contrat. Vos Contrats de Prompt font que Claude construit la bonne chose. `/security-review` s'assure que la bonne chose n'a pas de trou dedans.


Les Résultats (3 Semaines de Contrats de Prompt)

J'ai tracké mon workflow sur deux projets actifs. Les chiffres ne sont pas peer-reviewed — je suis un développeur dans une pièce sombre, pas un labo de recherche — mais le pattern était indéniable.

Taux d'annulation/revert est passé d'environ 1 sur 3 générations à environ 1 sur 10. Claude Code a arrêté de construire des choses que je n'avais pas demandées. Ma mémoire musculaire git revert s'estompe déjà. Je pourrais avoir besoin de réapprendre la commande un jour. Ou pas. Je suis en paix avec ça.

Temps du prompt au code utilisable est passé d'une moyenne de 3 tours d'allers-retours à 1,2 tours. La plupart des sorties de Contrat de Prompt étaient utilisables à la première ou deuxième génération. Ça a libéré du temps que je passe maintenant sur des choses importantes, comme sur-ingénierer mon CLAUDE.md et ajouter des conditions d'échec pour les conditions d'échec.

Violations CLAUDE.md (mauvaise librairie, mauvais pattern, valeurs hardcodées) sont passées de quelques-unes par jour à essentiellement zéro une fois que j'ai ajouté le handshake de contraintes au début de session. La combo CLAUDE.md + handshake est basiquement une checklist de pré-vol. Les pilotes ne la sautent pas. Vous non plus ne devriez pas. Sauf si vous aimez que votre code s'écrase dans une montagne métaphorique.

La plus grosse surprise ? Mes prompts sont devenus plus courts avec le temps, pas plus longs. Une fois que CLAUDE.md tient les contraintes permanentes et que vous internalisez la structure à 4 composants, un Contrat de Prompt pour une fonctionnalité complexe prend peut-être 60 secondes à écrire. C'est 60 secondes qui vous sauvent 45 minutes de debug et de remise en question de vos choix de carrière.


Comment Commencer Aujourd'hui

Vous n'avez pas besoin de révolutionner votre workflow. Vous n'avez pas besoin de lire un livre de 400 pages sur l'ingénierie de prompt. Vous n'avez pas besoin de regarder une vidéo YouTube de 3 heures où quelqu'un explique le concept dans les 4 premières minutes et vous vend ensuite un cours pendant les 2 heures et 56 minutes restantes.

Commencez avec deux choses :

  • D'abord, créez un CLAUDE.md à la racine de votre projet avec votre stack, règles dures, et patterns. C'est votre couche Contraintes permanente. Chaque session Claude Code commence en le lisant. Pensez-y comme la Constitution de votre repo — sauf que celle-ci est vraiment suivie.
  • Ensuite, la prochaine fois que vous êtes sur le point de taper un prompt vibe comme "ajoute page paramètres utilisateur," arrêtez-vous. Prenez 30 secondes et ajoutez un OBJECTIF, une CONTRAINTE, et une CONDITION D'ÉCHEC. Juste un de chaque. Vous sentirez la différence immédiatement. C'est comme passer de "j'espère que ça marche" à "je sais que ça marche" — un sentiment si rare en développement logiciel qu'il devrait être classé comme substance contrôlée.

Le framework Contrat de Prompt ne consiste pas à écrire plus. Il s'agit de réfléchir pendant 60 secondes pour que Claude Code n'ait pas à deviner pendant 60 minutes.

Je suis passé du casino à la livraison. À vous de jouer.


Si vous construisez du SaaS avec Claude Code et voulez plus d'analyses tactiques comme celle-ci, suivez-moi pour des deep dives hebdomadaires. Je livre, casse, et mass-revert des trucs en public pour que vous n'ayez pas à le faire.


Votre code Claude dérive constamment ? Découvrez comment passer du hasard à la livraison avec les « Contrats de Prompts » — la méthode qui transforme l'IA de développeur capricieux en assistant fiable.

Rejoindre la newsletter