schedule18 minsignal_cellular_alt_2_barIntermédiaireLeçon 02

Écrire des specs exploitables par un agent

Objectifs
  • arrow_forwardDistinguer une instruction vague d'une spec exploitable et savoir transformer l'une en l'autre
  • arrow_forwardRédiger une spec avec les cinq éléments qu'un agent a besoin pour produire un diff mergeable
  • arrow_forwardIdentifier les types de contraintes à rendre explicites selon le type de tâche
Connectez-vous pour sauvegarder votre progression et la retrouver sur tous vos appareils.Se connecter

La plupart des résultats décevants avec un agent de code ne viennent pas du modèle — ils viennent de la spec. « Ajoute une page de profil utilisateur » est une instruction. Ce n'est pas une spec. Un agent qui reçoit ça va prendre des dizaines de décisions implicites que vous n'avez pas validées. Le résultat est techniquement correct et probablement pas ce que vous vouliez.

Ce qui distingue une spec d'une instruction

lightbulbL'idée à retenir

Une instruction dit quoi faire. Une spec exploitable dit quoi faire, dans quel périmètre, avec quelles contraintes, avec quel critère de succès. La différence n'est pas la longueur — une bonne spec tient souvent en 10-15 lignes. La différence, c'est la précision : l'agent ne doit prendre aucune décision importante que vous n'avez pas anticipée.

Les cinq éléments d'une spec exploitable

1. Le contexte (où et pourquoi)

Nommez le fichier, le module, la fonction concernés. Expliquez pourquoi la tâche existe maintenant (un bug, un besoin produit, une refonte). L'agent a besoin de ce contexte pour comprendre les implications de ses choix.

2. L'objectif observable

Décrivez le résultat depuis l'extérieur. Pas « implémenter la pagination » mais « GET /api/users?cursor=<token> renvoie 50 résultats max et un nextCursor ». Si vous pouvez écrire un test d'acceptance, écrivez-le dans la spec.

3. Les contraintes techniques

Listez explicitement :

  • Quel pattern utiliser (si un pattern équivalent existe déjà dans le projet)
  • Ce qu'il ne faut pas faire (SQL raw, nouvelle dépendance, modifier tel fichier)
  • Les limites de périmètre (ne toucher qu'à ces fichiers, ne pas refactorer en passant)

4. Les critères d'acceptation

Comment saurez-vous que c'est bon ? Tests à passer, comportement observable, cas limite à couvrir. Si vous ne pouvez pas répondre à cette question, la spec n'est pas prête.

5. Ce qui est hors périmètre (optionnel mais utile)

Ce que l'agent pourrait être tenté de faire mais que vous ne voulez pas maintenant. Ça évite le scope creep involontaire (« j'en ai profité pour refactorer X »).

Avant / après : la transformation d'une instruction en spec

draftExemple

Instruction (vague) :

Ajouter la pagination à la liste des utilisateurs.

Spec exploitable :

Contexte : app/api/users/route.ts retourne actuellement tous les utilisateurs sans pagination. En production, on a 12 000 utilisateurs — le endpoint commence à avoir des problèmes de latence.

Objectif : Implémenter la pagination cursor-based sur GET /api/users. Réponse : { data: User[], nextCursor: string | null }. Taille de page fixe : 50.

Contraintes :

  • Utiliser le pattern cursor-based de app/api/orders/route.ts (déjà en place)
  • Pas d'offset SQL — cursor uniquement (index sur users.createdAt)
  • Pas de nouvelle dépendance
  • Ne pas modifier le schéma Drizzle (la colonne createdAt existe déjà)

Critères d'acceptation :

  • Test dans app/api/users/route.test.ts : premier appel → 50 résultats + nextCursor ; deuxième appel avec nextCursor → 50 résultats suivants
  • Pas de régression sur les tests existants

Hors périmètre : ne pas refactorer UserRepository pour cette tâche.

Quand la spec est trop longue

warningAttention

Si votre spec dépasse 20 lignes, c'est souvent le signe que la tâche est trop grande pour être confiée à un agent en une fois. Pas parce que l'agent ne peut pas techniquement — mais parce que le diff résultant sera trop large pour être revu correctement. La leçon suivante couvre le découpage.

Une spec de 5-15 lignes sur une tâche bien découpée produit un diff lisible et un résultat plus fiable qu'une spec de 40 lignes sur une tâche floue.

Les types de contraintes selon la tâche

Selon ce que vous construisez, les contraintes à rendre explicites changent :

| Type de tâche | Contraintes prioritaires | |---|---| | Nouveau endpoint API | Pattern existant, validation Zod, auth middleware | | Nouveau composant UI | Où il vit, quels tokens de design, quels composants existants réutiliser | | Refactor | Fichiers dans le périmètre, fichiers hors périmètre, comportement à préserver | | Tests | Quel framework, quels cas limites, mocks à utiliser ou éviter | | Migration de données | Réversibilité, backup préalable, ordre d'exécution |

À votre tour

fitness_centerÀ votre tour

Prenez un ticket de votre backlog. Rédigez une spec exploitable en suivant les cinq éléments ci-dessus — sans l'envoyer à un agent pour l'instant.

Posez-vous ces trois questions :

  1. Si l'agent lit uniquement cette spec (pas votre CLAUDE.md, pas le reste du code), quelle décision importante pourrait-il prendre de façon incorrecte ?
  2. Y a-t-il un comportement existant qui pourrait casser et que vous n'avez pas mentionné ?
  3. Avez-vous indiqué un critère de succès vérifiable ?

Corrigez la spec, puis confiez-la à l'agent. Observez combien de corrections de spec (pas de code) sont nécessaires pour arriver à un résultat mergeable.

En résumé

  • Une spec exploitable donne le contexte, l'objectif observable, les contraintes, les critères d'acceptation et ce qui est hors périmètre.
  • Plus la spec est précise sur les contraintes, moins l'agent prend de décisions implicites — et moins vous corrigez.
  • Si la spec dépasse 20 lignes, la tâche est probablement trop grande : découpez-la.
  • Une spec mal écrite est toujours la vraie cause d'un résultat décevant — pas l'agent.
quiz

Vérifiez votre compréhension

3 questions · répondez puis validez.

Une bonne spec pour un agent commence par…
Les contraintes dans une spec servent à…
Si un agent ne respecte pas une contrainte de votre spec, la bonne réaction est…