Série AI Interview 16 : À quoi ressemble un bon Spec Coding ?
Un bon Spec Coding (codage piloté par les spécifications) consiste à transformer des « idées floues » en « contrats précis, vérifiables et exécutables ». Il ne s'agit pas seulement d'écrire un document, mais d'établir un langage de communication sans ambiguïté entre humains et IA (ou entre humains). Ci-dessous, je détaille ce qu'est un bon spec à travers quatre dimensions : la structure du contenu, les principes de rédaction, le processus de collaboration avec l'IA et la validation de la qualité.
I. Structure standard d'un document de spécification (exemple d'un module fonctionnel)
| Section | Contenu obligatoire | Exemple |
|---|---|---|
| 1. Objectif et périmètre | Une phrase pour décrire ce qui est fait, préciser ce qui n'est pas fait | « Implémenter l'API d'inscription utilisateur, sans l'envoi d'email de vérification » |
| 2. Contrat entrée/sortie | Structure des données, types, champs obligatoires/optionnels, exemples de valeurs | Corps de la requête POST /register : {email: string, password: string}, réponse 201 ou 400 avec code d'erreur |
| 3. Comportement et logique | Règles métier, conditions limites, transitions d'état | « Le mot de passe doit faire 8 à 20 caractères et contenir au moins un chiffre ; si l'email existe déjà, retourner 409 » |
| 4. Gestion des erreurs | Tous les scénarios d'exception possibles avec codes/messages d'erreur correspondants | « Échec de connexion à la base de données → retourner 503, sans exposer la pile d'appels » |
| 5. Exigences non fonctionnelles | Performance (temps de réponse < 200 ms), sécurité (requêtes paramétrées), journalisation, observabilité | « Toutes les requêtes SQL doivent être précompilées ; journaliser email mais pas password » |
| 6. Cas de test (crucial) | Au moins 3 entrées typiques + 2 entrées limites/exceptionnelles, avec résultat attendu | Voir le tableau ci-dessous |
| 7. Dépendances et contraintes | Bibliothèques utilisées, versions, variables d'environnement | « Python 3.10+, FastAPI, variable d'environnement DB_URL » |
Exemple de cas de test (intégré dans le spec)
| Scénario | Entrée | Résultat attendu |
|---|---|---|
| Inscription normale | email : a@b.com, mdp : Pass1234 |
201, retourne user_id |
| Mot de passe trop court | mdp : Ab1 |
400, code d'erreur WEAK_PASSWORD |
| Email déjà existant | même email | 409, code d'erreur EMAIL_EXISTS |
Un bon Spec doit d'abord écrire les cas de test, car l'IA peut directement générer des tests unitaires à partir d'eux, puis les exécuter automatiquement pour vérifier.
II. Principes fondamentaux de rédaction d'un Spec (variante SMART)
| Principe | Explication | Contre-exemple |
|---|---|---|
| Précis | Utiliser des chiffres concrets, des types, des conditions booléennes ; éviter « autant que possible », « généralement » | ❌ « Le mot de passe doit être suffisamment sécurisé » → ✅ « Le mot de passe doit comporter au moins 8 caractères, inclure une majuscule, une minuscule, un chiffre » |
| Vérifiable | Chaque exigence doit pouvoir être validée par un test automatique ou une inspection manuelle (succès/échec) | ❌ « Le code doit être élégant » → ✅ « La complexité cyclomatique des fonctions ≤ 10, pas de blocs de code dupliqués » |
| Sans ambiguïté | Un même terme doit avoir la même signification dans tout le document ; fournir un glossaire si nécessaire | ❌ « Si l'utilisateur n'existe pas, retourner une erreur » → ✅ « Utilisateur inexistant → retourner 404 avec {code: 'USER_NOT_FOUND'} » |
| Complet | Couvrir le chemin heureux, tous les chemins d'exception et les exigences non fonctionnelles | ❌ Seul le scénario de succès est écrit → ✅ Inclure les timeouts de base de données, les permissions insuffisantes, etc. |
| Atomique | Un spec ne décrit qu'un seul point fonctionnel livrable indépendamment (facilite le travail de l'IA en une fois) | ❌ Un spec pour « tout le système de paiement » → ✅ Découper en « génération de facture », « vérification de signature de callback », « remboursement » |
III. Processus de Spec Coding en collaboration avec l'IA
- L'humain écrit le spec (structure ci-dessus, en particulier les cas de test et les signatures de fonctions).
- On donne le spec en une fois à l'IA (pas de demandes supplémentaires en mode dialogue, pour éviter la contamination du vibe).
- L'IA produit le code + les tests unitaires (les tests doivent être exécutables et basés sur les cas de test du spec).
- Exécution des tests : si tous passent, passer à l'étape suivante ; sinon, modifier le spec ou corriger directement le code (petite boucle possible, mais enregistrer les changements).
- Révision humaine : vérifier qu'aucune fonctionnalité hors spec n'a été ajoutée (scope creep), vérifier la sécurité/performance.
- Figer : soumettre le document de spec et le code final dans le dépôt, comme documentation permanente.
Pratique clé : Spécification sous forme de code — utiliser
spec.md+test_spec.py, où le fichier de test provient directement des exemples du spec. Ainsi, toute modification ultérieure du code peut être vérifiée en exécutant les tests pour voir si le spec est respecté.
IV. Effets d'un bon Spec (peut servir de critère d'acceptation)
- Déterminisme : Un même spec donné à différentes IA (ou à différentes personnes) produit des implémentations similaires.
- Testabilité : Dès que le code est écrit, on peut automatiquement vérifier 90 % de sa correction.
- Maintenabilité : Six mois plus tard, n'importe qui en regardant le spec comprend l'intention de conception initiale.
- Faible coût de communication : L'équipe discute du spec, pas des lignes de code spécifiques.
- Sécurité/qualité intégrées : Les exigences de sécurité (comme les requêtes paramétrées) et les conditions limites sont écrites dans le spec, l'IA doit les respecter.
V. Exemple concret d'un bon Spec (version simplifiée)
# Spec : API d'inscription utilisateur
## Périmètre
- Accepter email, mot de passe
- Ne pas envoyer d'email de vérification, ne pas vérifier l'authenticité de l'email
## Contrat
POST /register
Content-Type: application/json
Requête : { "email": string, "password": string }
Réponse 201 : { "user_id": string }
Réponse 400 : { "code": "INVALID_PASSWORD" | "INVALID_EMAIL" }
Réponse 409 : { "code": "EMAIL_ALREADY_EXISTS" }
## Comportement
- L'email doit respecter le format de base RFC 5322 (a@b.c)
- Mot de passe : longueur 8-20, au moins un chiffre et une majuscule
- Utiliser bcrypt pour le hachage, coût de sel 10
- Si avant l'insertion en base l'email existe déjà → 409
## Cas de test (entrée -> code de statut attendu + champ de réponse)
| Email entré | Mot de passe | Résultat attendu |
|-------------|--------------|------------------|
| test@x.com | Pass1234 | 201, user_id présent |
| test@x.com | pass | 400, INVALID_PASSWORD |
| bad | Pass1234 | 400, INVALID_EMAIL |
| (email déjà existant) | Pass1234 | 409, EMAIL_ALREADY_EXISTS |
## Non fonctionnel
- Les requêtes SQL doivent utiliser des paramètres préparés (protection contre les injections)
- Journaliser l'IP d'origine de l'inscription, ne pas journaliser le mot de passe
- Temps de réponse : 95 % des requêtes < 100 ms (hors bcrypt)
## Dépendances
- Python 3.10+, FastAPI, bcrypt, asyncpg
Un bon Spec Coding = transformer les décisions de conception humaines en cas de test + signatures de types + contraintes de comportement pour la machine : l'IA ne fait que remplir l'implémentation, tandis que l'humain garde le contrôle de la qualité et de la direction.
评论
暂无已展示的评论。
发表评论(匿名)