Aller au contenu principal

Aide-mémoire

Dictionnaire du code IA

Dictionnaire du code IA

Approfondir →

Le vocabulaire du code IA, transformé en actions concrètes. Pas de théorie creuse : chaque module te donne une commande à copier-coller et un résultat à vérifier.


Table des modules

Débutant

# Module Temps Ce que tu vas faire
1 Tokens et coûts 15 min lecture — 10 min pratique Estimer la taille d’un prompt en tokens, calculer un budget, utiliser tiktoken
2 Context window 15 min lecture — 10 min pratique Compter les tokens d’un fichier, vérifier si ton prompt tient dans la fenêtre
3 Agent vs Model vs Harness 15 min lecture — 10 min pratique Distinguer les 3 couches et diagnostiquer qui pose problème

Intermédiaire

# Module Temps Ce que tu vas faire
4 Tool calls et MCP 20 min lecture — 20 min pratique Brancher Linear/Slack/GitHub via MCP, faire un tool call manuel
5 Permission modes et Agent mode 15 min lecture — 10 min pratique Choisir YOLO, plan ou accept-edits selon la tâche
6 Hallucinations : détecter et corriger 20 min lecture — 15 min pratique Distinguer factuality vs faithfulness et appliquer le bon fix
7 Specs et Tickets 20 min lecture — 20 min pratique Rédiger une spec, découper en 3-5 tickets, faire un handoff propre

Confirmé

# Module Temps Ce que tu vas faire
8 Memory system et AGENTS.md 20 min lecture — 20 min pratique Structurer un AGENTS.md, configurer des skills, utiliser progressive disclosure
9 Compaction et Autocompact 15 min lecture — 15 min pratique Compacter une session longue sans perdre d’info clé

Playbook

# Module Temps Ce que tu vas faire
10 Playbooks prêts à l’emploi 10 min lecture — 30 min pratique Copier-coller les templates AGENTS.md, Spec, Ticket, checklists pré/post-session

Par où commencer ?

  • Tu débutes avec les agents IA (Claude Code, Cursor, Codex) → Module 1
  • Tu sais ce qu’est un token mais tu ne sais pas pourquoi ton agent rame à la fin des longues sessions → Module 6
  • Tu veux structurer ton projet pour que l’agent se souvienne de ton stack entre les sessions → Module 8
  • Tu veux juste les templates copier-coller → Module 10

Tokens et coûts

Approfondir →

Objectif

À la fin de ce module, tu sais estimer le nombre de tokens d’un prompt, calculer un budget tokens pour une session, et éviter les mauvaises surprises sur ta facture.


1. Qu’est-ce qu’un token

Un token est l’unité atomique qu’un modèle lit et écrit. Ce n’est pas un mot.

  • Un mot commun anglais ≈ 1 token (hello)
  • Un mot rare ou long ≈ 2-4 tokens (tokenizationtoken, ization)
  • Un caractère spécial ou un espace = souvent 1 token
  • Du code avec beaucoup de ponctuation ≈ 20-30 % plus de tokens que de mots

Exemple concret :

"import React from 'react';" → ~6 tokens

2. Compter les tokens d’un texte

Avec tiktoken (Python)

# Installer tiktoken
pip install tiktoken

# Compter les tokens pour GPT-4 / Claude (approximation)
python -c "
import tiktoken
enc = tiktoken.encoding_for_model('gpt-4')
text = 'import React from \"react\";'
print(len(enc.encode(text)))
"

Output attendu :

6

Avec un tokenizer en ligne

  1. Ouvre https://platform.openai.com/tokenizer
  2. Colle ton prompt
  3. Lis le compteur en bas à droite

3. Estimer le coût d’une session

Formule simple :

coût = (input_tokens × prix_input) + (output_tokens × prix_output)

Tarifs indicatifs (juin 2026, vérifier sur le site du provider) :

  • Claude Sonnet 4 : ~$3 / MTok input, ~$15 / MTok output
  • GPT-4o : ~$2.50 / MTok input, ~$10 / MTok output

Calcul rapide :

# Si tu envoies 10k tokens et reçois 2k tokens avec Claude Sonnet
python -c "
input_tok = 10000
output_tok = 2000
cout = (input_tok / 1e6 * 3) + (output_tok / 1e6 * 15)
print(f'Coût estimé : ${cout:.4f}')
"

Output attendu :

Coût estimé : $0.0600

4. Le piège du “re-sending”

À chaque tour de conversation, le harness renvoie tout l’historique au modèle. Une session de 20 tours qui commence à 2k tokens finit à 40k+ tokens d’input.

# Simulation rapide
python -c "
tours = 20
tokens_par_tour = 2000
total_input = sum(tokens_par_tour * i for i in range(1, tours + 1))
print(f'Tokens input cumulés après {tours} tours : {total_input:,}')
print(f'Coût input seul (~$3/MTok) : ${total_input / 1e6 * 3:.2f}')
"

Output attendu :

Tokens input cumulés après 20 tours : 420,000
Coût input seul (~$3/MTok) : $1.26

Fix : compacter ou clearer la session régulièrement (voir Module 9).


Checklist de validation

  • J’ai installé tiktoken et compté les tokens d’un prompt
  • J’ai estimé le coût d’une session avec le calculateur
  • Je comprends pourquoi une longue session coûte plus cher qu’un seul gros prompt
  • Je sais qu’un token n’est pas un mot

Piège courant

Confondre token et mot → Tu penses que ton fichier de 500 mots = 500 tokens. En réalité c’est plutôt 650-750 tokens à cause de la ponctuation, des indentations et des mots rares. Toujours passer par un tokenizer pour estimer.

Context window

Approfondir →

Objectif

À la fin de ce module, tu sais vérifier la taille de ton prompt avant envoi, comprendre quand la fenêtre de contexte déborde, et choisir quoi garder ou jeter.


1. Qu’est-ce que la context window

La context window est tout ce que le modèle voit à chaque requête. C’est finie, spécifique au modèle, et c’est la seule surface par laquelle il perçoit quoi que ce soit.

Ce n’est pas de la mémoire. Ce qui est dans la fenêtre à l’instant T disparaît à T+1 si tu ne le renvoies pas.

Tailles courantes (juin 2026) :

  • Claude Sonnet 4 : 200k tokens
  • GPT-4o : 128k tokens
  • Gemini 2.5 Pro : 1M tokens

2. Compter les tokens d’un fichier

# Compter les tokens d'un fichier source
python -c "
import tiktoken
enc = tiktoken.encoding_for_model('gpt-4')
with open('src/App.tsx', 'r') as f:
    content = f.read()
print(f'Tokens : {len(enc.encode(content))}')
"

Output attendu (exemple) :

Tokens : 1,247

Pour un dossier entier :

# Compter les tokens de tous les fichiers .ts d'un dossier
python -c "
import tiktoken, os
glob = __import__('glob')
enc = tiktoken.encoding_for_model('gpt-4')
total = 0
for path in glob.glob('src/**/*.ts', recursive=True):
    with open(path, 'r') as f:
        total += len(enc.encode(f.read()))
print(f'Total tokens : {total:,}')
"

3. Vérifier si ton prompt tient dans la fenêtre

Règle rapide : additionne les tokens de tous les fichiers que tu veux coller, plus ~20 % pour les instructions et l’historique.

# Script de vérification rapide
python -c "
import tiktoken, glob, os
enc = tiktoken.encoding_for_model('gpt-4')
files = ['src/App.tsx', 'src/utils.ts', 'README.md']
limit = 200000  # Claude Sonnet 4

total = 0
for f in files:
    if os.path.exists(f):
        with open(f, 'r') as fh:
            total += len(enc.encode(fh.read()))
    else:
        print(f'⚠️ {f} introuvable')

buffer = int(total * 1.2)  # +20% pour instructions + historique
print(f'Fichiers : {total:,} tokens')
print(f'Avec buffer : {buffer:,} tokens')
print(f'Tient dans {limit:,} ? {"✅ Oui" if buffer < limit else "❌ Non"}')
"

4. Quand la fenêtre déborde

Symptômes :

  • L’agent “oublie” des instructions données au début de la session
  • Il répète des questions déjà répondues
  • Il commence à inventer des API ou des types qui existent dans les fichiers qu’il a lus
  • Le temps de réponse s’allonge

C’est l’attention degradation (voir Module 6). Le modèle voit toujours le texte, mais le signal s’affaiblit.


5. Que faire quand ça déborde

  1. Réduire le scope : ne garde que les fichiers touchés par la tâche
  2. Utiliser des tool calls : laisser l’agent lire les fichiers à la demande plutôt que de tout coller
  3. Compacter : résumer l’historique et repartir d’une session fraîche (Module 9)
  4. Découper en tickets : une tâche = une session (Module 7)

Checklist de validation

  • J’ai compté les tokens d’un fichier de mon projet
  • J’ai estimé si mon prompt tient dans la context window de mon modèle
  • Je sais reconnaître les 3 symptômes d’une fenêtre qui déborde
  • Je connais 4 techniques pour alléger le contexte

Piège courant

Penser que “200k tokens” = “je peux coller tout mon repo” → Un monorepo moyen fait 500k-2M tokens. Même avec une fenêtre de 200k, tu ne vois qu’un cinquième du code. Solution : sélectionner les fichiers pertinents et laisser l’agent lire le reste via des tool calls.

Agent vs Model vs Harness

Approfondir →

Objectif

À la fin de ce module, tu distingues les 3 couches (model, harness, agent) et tu sais identifier laquelle pose problème quand un agent échoue.


1. Les 3 couches

Model

Les paramètres. Sans état. Fait de la next-token prediction et rien d’autre.

  • Exemples : Claude Opus 4.7, GPT-5, Gemini 2.5 Pro
  • Ne peut pas éditer de fichier, ne peut pas naviguer sur le web
  • C’est juste un moteur de prédiction de texte

Harness

Tout ce qui entoure le model pour en faire un agent : tools, system prompt, gestion de la context window, permissions, hooks.

  • Exemples : Claude Code, Cursor, l’interface Claude.ai
  • Le même model (Claude Sonnet 4) se comporte différemment dans Claude Code et Claude.ai parce que le harness diffère

Agent

Le model + le harness en action. C’est ce à quoi tu parles quand tu ouvres Claude Code ou Cursor.

  • Exemples : “J’utilise Claude Code”, “Passe sur Cursor pour le UI”
  • L’agent prend des tours (turns) avec toi : tu demandes, il répond ou appelle un tool

2. Dialogue type

"Same model, why is Claude Code editing files and Claude.ai just answering questions?"

"Different harnesses — Claude Code a des tools filesystem, un system prompt différent,
et une couche de permissions. Le model n'est pas la variable ici."

3. Diagnostiquer qui est en cause

Quand l’agent échoue, pose-toi ces questions dans l’ordre :

Symptôme Couche suspecte Test rapide
Il invente une API qui n’existe pas Model (parametric knowledge) Colle la doc dans le prompt, redemande
Il dit avoir exécuté un test mais rien n’a bougé Harness (tool call non exécuté) Vérifie le transcript : y a-t-il un tool call ?
Il refuse d’éditer un fichier Harness (permission mode) Vérifie le mode (plan vs accept-edits)
Il oublie ce qu’on a dit au début Agent (context window pleine) Compacter ou clearer (Module 9)
Il répond bien sur un sujet et mal sur un autre Model (attention degradation) Réduire le contexte

4. Exercice pratique

Scénario : tu demandes à Claude Code de refactorer un fichier. Il répond “C’est fait” mais le fichier n’a pas changé.

Étapes de diagnostic :

  1. Vérifier le transcript : cherche un bloc ▔▔▔▔ Tool Use: edit_file ▔▔▔▔ dans la conversation
  2. Si pas de tool call : le model a décrit l’édition sans l’émettre. C’est un problème de model (parametric drift) ou de prompt.
  3. Si tool call présent mais pas exécuté : le harness n’a pas exécuté l’appel. Vérifie les permissions (claude config get permissionMode).
  4. Si tool call exécuté mais erreur : lis le tool result. Souvent un chemin incorrect ou une permission manquante.
# Vérifier le mode de permission dans Claude Code
claude config get permissionMode

# Lister les tools disponibles
claude config get mcpServers

Checklist de validation

  • Je peux expliquer la différence entre model, harness et agent en une phrase chacun
  • Je sais quel symptôme pointe vers quelle couche
  • J’ai vérifié le mode de permission de mon agent
  • Je sais lire un transcript pour trouver un tool call

Piège courant

Changer de model pour régler un problème de harness → Tu passes de Sonnet à Opus parce que “l’agent ne veut pas éditer”. En réalité c’est le permission mode qui bloque. Changer de model ne change pas le harness. Vérifie toujours la config avant de changer de model.

Tool calls et MCP

Approfondir →

Objectif

À la fin de ce module, tu sais configurer un MCP server, faire un tool call manuel, lire un tool result, et brancher Linear/Slack/GitHub via MCP.


1. Qu’est-ce qu’un tool call

Un tool call est la sortie du model qui nomme un tool et ses arguments. C’est juste du texte structuré. Le harness doit le lire et l’exécuter.

Le model ne “fait” rien directement. Il produit un appel. Le harness exécute.


2. Qu’est-ce que MCP

Model Context Protocol. Un protocole pour brancher des serveurs de tools externes dans un harness. L’agent n’appelle jamais “MCP” directement : il appelle un tool, et le harness l’a obtenu via un MCP server.

MCP expose aussi des ressources (données en lecture seule) et des prompts (templates réutilisables), mais le provisionnement de tools est l’usage principal.


3. Configurer un MCP server (Claude Code)

Étape 1 : lister les MCP servers déjà configurés

claude config get mcpServers

Output attendu (si vide) :

{}

Étape 2 : ajouter le MCP server GitHub

# Créer le fichier de config MCP
cat > ~/.claude/mcp-servers.json << 'EOF'
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
      }
    }
  }
}
EOF

Remplace ${GITHUB_TOKEN} par ton token GitHub (Settings → Developer settings → Personal access tokens).

Étape 3 : vérifier que le server est actif

claude config get mcpServers

Output attendu :

{
  "github": {
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-github"],
    "env": {
      "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxx"
    }
  }
}

Étape 4 : tester dans une session

Dans Claude Code, demande :
"Liste les issues ouvertes sur mon repo owner/mon-repo"

L’agent doit émettre un tool call vers github_list_issues et afficher le résultat.


4. Faire un tool call manuel (via API)

Pour comprendre ce qui se passe sous le capot :

# Appel API OpenAI avec tool call (nécessite OPENAI_API_KEY)
curl https://api.openai.com/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o",
    "messages": [
      {"role": "user", "content": "Quel temps fait-il à Paris ?"}
    ],
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "get_weather",
          "description": "Get weather for a city",
          "parameters": {
            "type": "object",
            "properties": {
              "city": {"type": "string"}
            },
            "required": ["city"]
          }
        }
      }
    ],
    "tool_choice": "auto"
  }'

Output attendu (extrait) :

{
  "choices": [{
    "message": {
      "role": "assistant",
      "content": null,
      "tool_calls": [{
        "id": "call_abc123",
        "type": "function",
        "function": {
          "name": "get_weather",
          "arguments": "{\"city\":\"Paris\"}"
        }
      }]
    }
  }]
}

Le model n’a pas appelé une vraie API météo. Il a juste émis du JSON. C’est au harness (ou à ton code) d’exécuter la fonction.


5. Lire un tool result

Dans Claude Code, les tool results s’affichent dans des blocs dépliables :

▔▔▔▔ Tool Use: read_file ▔▔▔▔
  Path: src/App.tsx
  Result:
  import React from 'react';
  ...
▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁

Si le result est vide ou contient une erreur, le model va souvent halluciner une réponse. Vérifie toujours le result toi-même.


6. Brancher Linear et Slack

Linear MCP

cat > ~/.claude/mcp-servers.json << 'EOF'
{
  "mcpServers": {
    "linear": {
      "command": "npx",
      "args": ["-y", "@linear/mcp-server"],
      "env": {
        "LINEAR_API_KEY": "${LINEAR_API_KEY}"
      }
    }
  }
}
EOF

Slack MCP (via community)

npm install -g @modelcontextprotocol/server-slack

cat > ~/.claude/mcp-servers.json << 'EOF'
{
  "mcpServers": {
    "slack": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-slack"],
      "env": {
        "SLACK_BOT_TOKEN": "${SLACK_BOT_TOKEN}",
        "SLACK_TEAM_ID": "${SLACK_TEAM_ID}"
      }
    }
  }
}
EOF

Checklist de validation

  • J’ai listé mes MCP servers configurés
  • J’ai ajouté et testé le MCP server GitHub
  • J’ai fait un tool call manuel via l’API et lu le JSON de sortie
  • Je comprends la différence entre “le model émet un appel” et “le harness l’exécute”
  • J’ai branché au moins un MCP server externe (Linear, Slack ou autre)

Piège courant

Croire que le model a exécuté une action parce qu’il l’a dit → Le model peut dire “J’ai lancé les tests” sans avoir émis de tool call. Vérifie toujours le transcript pour le bloc Tool Use:. Si le bloc n’existe pas, rien n’a été exécuté.

Permission modes et Agent mode

Approfondir →

Objectif

À la fin de ce module, tu sais choisir le bon agent mode pour chaque tâche et configurer les permissions pour ne pas te faire interrompre à chaque tool call.


1. Permission mode vs Agent mode

Permission mode

C’est la partie “sécurité” : quels tool calls déclenchent une demande de confirmation et lesquels passent automatiquement.

  • Ask (ou “prompt”) : demande confirmation pour chaque tool call risqué (écriture fichier, shell)
  • Accept-edits : approuve automatiquement les éditions de fichiers, demande pour le shell
  • Bypass (surnommé YOLO mode) : approuve tout automatiquement

Agent mode

C’est un preset qui combine un permission mode avec des instructions comportementales injectées dans le system prompt.

  • Plan mode : bloque les éditions, oriente l’agent vers la recherche et la planification
  • Accept-edits : autorise les éditions, demande pour le shell
  • YOLO mode : tout passe, tout seul

Tu peux changer de mode en pleine session.


2. Quel mode pour quelle tâche

Tâche Mode recommandé Pourquoi
Exploration de codebase, recherche Plan mode Tu ne veux pas qu’il édite sans ton accord
Refactoring ciblé, feature isolée Accept-edits Il peut éditer, mais tu gardes un œil sur le shell
Run AFK (tout seul la nuit) YOLO mode + sandbox Aucune interruption, mais isole l’environnement
Review de PR, audit Plan mode Lecture seule, pas de modification
Hotfix urgent en prod Accept-edits ou YOLO Tu sais ce que tu fais, pas le temps d’attendre

3. Configurer les modes dans Claude Code

# Voir le mode actuel
claude config get permissionMode

# Passer en plan mode (lecture seule)
claude config set permissionMode plan

# Passer en accept-edits
claude config set permissionMode accept-edits

# Passer en YOLO (bypass)
claude config set permissionMode bypass

Output attendu après chaque commande :

✅ permissionMode updated to "plan"

4. Changer de mode en pleine session

Dans Claude Code, tu peux basculer sans quitter :

/plan

Puis revenir en mode édition :

/accept-edits

Ou en YOLO :

/yolo

Règle d’or : commence toujours une session en plan mode pour explorer, puis bascule en accept-edits quand tu es prêt à faire des modifications.


5. Configurer les permissions par tool

Claude Code permet de régler finement quels tools demandent une confirmation :

# Lister la config détaillée des permissions
claude config get permissionMode

# Dans ~/.claude/settings.json, tu peux surcharger :
cat > ~/.claude/settings.json << 'EOF'
{
  "permissionMode": "accept-edits",
  "autoApprove": ["Read", "Grep", "LSP"],
  "requireApproval": ["Bash", "Write", "Edit"]
}
EOF

Checklist de validation

  • J’ai vérifié mon permission mode actuel
  • J’ai testé les 3 modes (plan, accept-edits, bypass) dans une session
  • Je sais quel mode choisir pour : exploration / refactoring / run AFK
  • J’ai configuré des permissions par tool si besoin

Piège courant

Lancer un run AFK en accept-edits et se faire réveiller par une permission request → Si tu laisses l’agent tourner la nuit, mets-le en bypass (YOLO) et dans un sandbox (container, VM, ou repo isolé). Un run AFK qui s’arrête au milieu parce qu’une permission a bloqué, c’est du temps perdu et potentiellement un état inconsistent.

Hallucinations : détecter et corriger

Approfondir →

Objectif

À la fin de ce module, tu distingues une hallucination factuelle d’une hallucination de fidélité, tu diagnostiques la cause, et tu appliques le bon fix (reload context vs compact).


1. Les deux saveurs d’hallucination

Factuality (invention de faits)

Le model invente une fonction qui n’existe pas, un mauvais signature d’API, une citation fausse.

Cause : parametric knowledge dépassé ou incomplet. Le model “se souvient” mal.

Fix : charger la bonne contextual knowledge (coller la doc, le fichier source, la spec).

Faithfulness (dérive du contexte)

Le model oublie ce qu’il a lu au début de la session, ignore une instruction, ou invente des types qui existent pourtant dans les fichiers chargés.

Cause : attention degradation. Le contexte est trop gros, le signal s’affaiblit.

Fix : clearer ou compacter la session (Module 9).


2. Diagnostic rapide

Quand l’agent dit quelque chose de faux, pose cette question :

"C'est dans les fichiers qu'il a lus, ou c'est quelque chose qu'il 'sait' ?"
Le fait est… Type d’hallucination Fix
Dans les fichiers mais l’agent le dit faux Faithfulness Compact / clear
Absent des fichiers et faux Factuality Charger la doc
Absent des fichiers mais vrai Pas une hallucination Rien

3. Exercice pratique : scénario A (factuality)

Symptôme : L’agent utilise parseAsync sur un schema Zod, mais cette méthode n’existe pas dans ta version.

Diagnostic :

# Vérifier si la méthode existe dans le code
grep -r "parseAsync" node_modules/zod/lib/

Si grep ne retourne rien, la méthode n’existe pas dans ta version. L’agent a halluciné factuellement.

Fix :

Dans la session, dis :
"Voici le fichier node_modules/zod/lib/types.d.ts — montre-moi la méthode parse disponible."

Colle le fichier, redemande. L’agent va maintenant lire la vraie signature.


4. Exercice pratique : scénario B (faithfulness)

Symptôme : Au tour 35, l’agent oublie que tu as décidé d’utiliser PostgreSQL et propose du SQL MySQL.

Diagnostic :

  1. Vérifie que la décision est bien dans l’historique (scroll en haut de la session)
  2. Si oui, c’est de la faithfulness — l’attention s’est dégradée

Fix : compacter manuellement

Dans la session, dis :
"Compacte la session. Garde dans le résumé :
- Stack : PostgreSQL 15, Prisma, Express
- Décision : pas de raw SQL, utiliser Prisma queries
- Prochaine étape : écrire le endpoint GET /users"

Puis relance une nouvelle session avec ce résumé en prompt initial.


5. Script de détection automatique

# Vérifier si un symbole existe dans le codebase
python -c "
import subprocess, sys
sym = sys.argv[1] if len(sys.argv) > 1 else 'parseAsync'
result = subprocess.run(['grep', '-r', sym, 'src/', 'node_modules/'], capture_output=True, text=True)
if result.returncode == 0:
    print(f'✅ {sym} trouvé dans :')
    for line in result.stdout.split('
')[:5]:
        print('  ', line)
else:
    print(f'❌ {sym} non trouvé — probable hallucination factuelle')
" parseAsync

Checklist de validation

  • Je distingue factuality et faithfulness
  • J’ai diagnostiqué un cas de factuality et appliqué le fix (charger la doc)
  • J’ai diagnostiqué un cas de faithfulness et appliqué le fix (compact)
  • Je sais utiliser grep pour vérifier si un symbole existe dans le codebase

Piège courant

Ajouter plus de contexte pour régler une faithfulness hallucination → Si l’agent oublie ce qu’il a lu au début de la session, coller encore plus de docs ne fait qu’aggraver le problème. La fenêtre est déjà pleine. La bonne réponse est de compacter, pas d’empiler.

Specs et Tickets

Approfondir →

Objectif

À la fin de ce module, tu sais rédiger une spec, la découper en 3-5 tickets, et faire un handoff propre d’une session à l’autre.


1. Qu’est-ce qu’une spec

Une spec est un artifact de handoff qui décrit un travail multi-session : quoi on construit, pas comment chaque session fait sa part. Elle évolue au fur et à mesure du travail. Elle est composée de tickets.


2. Qu’est-ce qu’un ticket

Un ticket est un artifact de handoff qui scoppe une session de travail. Il peut être indépendant ou dépendre d’autres tickets. L’ordre de travail découle du graphe de dépendances, pas d’une liste linéaire.


3. Structure d’une spec

# Spec — Authentification OAuth2

## Contexte
L'app utilise actuellement un auth basique. On passe à OAuth2 avec Google.

## Objectif
Permettre la connexion via Google OAuth2 sans casser l'existant.

## Tickets

### Ticket 1 — Schema DB
Ajouter la table `oauth_accounts` (provider, providerAccountId, userId).
**Dépend de :** rien

### Ticket 2 — API OAuth
Implémenter les endpoints `/auth/google` et `/auth/callback`.
**Dépend de :** Ticket 1

### Ticket 3 — UI Login
Remplacer le formulaire basique par un bouton "Sign in with Google".
**Dépend de :** Ticket 2

### Ticket 4 — Migration données
Migrer les users existants vers le nouveau système.
**Dépend de :** Ticket 1

## Non-goals
- Pas de MFA pour l'instant
- Pas de refresh token rotation

## Notes
Stack : Next.js 14, Prisma, PostgreSQL.

4. Structure d’un ticket

# Ticket 2 — API OAuth

## Contexte (copié depuis la spec)
L'app passe à OAuth2 avec Google.

## Objectif de cette session
Implémenter `/auth/google` (redirect) et `/auth/callback` (échange code + création session).

## Fichiers concernés
- `src/app/api/auth/google/route.ts`
- `src/app/api/auth/callback/route.ts`
- `src/lib/auth.ts`

## Décisions déjà prises
- Utiliser `next-auth` v5 (beta)
- Provider : Google uniquement
- Session JWT côté client

## Livrable attendu
- Les deux endpoints répondent 200
- Un test manuel montre la redirection Google

## Prochain ticket
Ticket 3 — UI Login

5. Exercice pratique

Tâche : Écris une spec pour ajouter un système de notifications push à une app React Native.

Étape 1 : créer le fichier spec

mkdir -p docs/specs
cat > docs/specs/notifications-push.md << 'EOF'
# Spec — Notifications Push

## Contexte
L'app n'a pas de notifications. Les users ne savent pas quand ils reçoivent un message.

## Objectif
Envoyer une notification push quand un message arrive.

## Tickets

### Ticket 1 — Config Firebase
Configurer le projet Firebase, ajouter google-services.json et GoogleService-Info.plist.
**Dépend de :** rien

### Ticket 2 — SDK côté client
Intégrer `@react-native-firebase/messaging`, demander les permissions, afficher la notif.
**Dépend de :** Ticket 1

### Ticket 3 — Backend trigger
Déclencher l'envoi de notif depuis l'API quand un message est créé.
**Dépend de :** Ticket 1

### Ticket 4 — Deep link
Ouvrir l'app sur le bon écran quand on tap la notif.
**Dépend de :** Ticket 2, Ticket 3

## Non-goals
- Pas de rich media dans les notifs pour l'instant
- Pas de segmentation par topic

## Notes
Stack : React Native 0.74, Expo, Node.js backend.
EOF

Étape 2 : créer le premier ticket

mkdir -p docs/tickets
cat > docs/tickets/01-config-firebase.md << 'EOF'
# Ticket 1 — Config Firebase

## Contexte
Spec : Notifications Push

## Objectif de cette session
Créer le projet Firebase, télécharger les fichiers de config, les placer dans l'app.

## Fichiers concernés
- `android/app/google-services.json`
- `ios/GoogleService-Info.plist`
- `app.json`

## Décisions déjà prises
- Utiliser Firebase Cloud Messaging (FCM)
- Pas de OneSignal pour l'instant

## Livrable attendu
- `google-services.json` présent dans android/app/
- Build Android passe sans erreur FCM

## Prochain ticket
Ticket 2 — SDK côté client
EOF

6. Faire le handoff

Quand une session est terminée :

  1. Mettre à jour le ticket : ajouter un bloc “Résultat” avec ce qui a été fait, les décisions prises, les fichiers modifiés
  2. Mettre à jour la spec : cocher le ticket comme terminé, ajuster les suivants si besoin
  3. Lancer la session suivante : copier le contenu du prochain ticket dans le prompt initial
Prompt de début de session :
"Voici le ticket de cette session. Lis-le, puis commence l'implémentation.

<paste du ticket>"

Checklist de validation

  • J’ai rédigé une spec avec contexte, objectif, tickets, non-goals
  • J’ai découplé le travail en 3-5 tickets avec dépendances claires
  • J’ai écrit un ticket complet (contexte, objectif, fichiers, décisions, livrable)
  • Je sais faire un handoff d’une session à l’autre via un ticket

Piège courant

Faire tout dans une seule session parce que “c’est pas si gros” → Même une feature “simple” de 3-4 fichiers génère 15-20 tours de conversation. À 2000 tokens par tour, tu atteins la dumb zone avant la fin. Découpe toujours en tickets, même pour du “petit” travail.

Memory system et AGENTS.md

Approfondir →

Objectif

À la fin de ce module, tu sais structurer un AGENTS.md, configurer des skills, et utiliser le progressive disclosure pour ne pas brûler des tokens inutilement.


1. Qu’est-ce qu’un memory system

Un memory system rend un agent stateful entre les sessions. Le model lui-même est stateless — il oublie tout quand tu quittes. Le memory system persiste des informations dans l’environnement (fichiers) et les recharge au début de chaque session.


2. Qu’est-ce qu’un AGENTS.md

Un fichier dans la racine du projet que le harness charge automatiquement au début de chaque session. C’est le brief permanent du projet pour l’agent.

Ce qu’on y met :

  • Stack technique
  • Conventions de nommage
  • Commandes de build/test
  • Ce qu’il ne faut pas faire

Ce qu’on n’y met pas :

  • Toute la doc (trop de tokens)
  • Des instructions spécifiques à une tâche (mettre dans un skill)

3. Créer un AGENTS.md

cat > AGENTS.md << 'EOF'
# AGENTS.md — Mon Projet

## Stack
- Frontend : Next.js 14 (App Router), Tailwind, shadcn/ui
- Backend : tRPC v11, Prisma ORM
- DB : PostgreSQL 15
- Auth : Next-Auth v5 (beta)
- Tests : Vitest, Playwright

## Conventions
- TypeScript strict (`strict: true`)
- Pas de `any` sauf dans les migrations
- Composants UI dans `src/components/ui/`
- API routes dans `src/app/api/` (App Router)

## Commandes
- `npm run dev` — dev server
- `npm run build` — build production
- `npm run test` — tests unitaires
- `npm run test:e2e` — tests Playwright
- `npx prisma migrate dev` — migration DB
- `npx prisma generate` — regénérer le client Prisma

## Ce qu'il ne faut pas faire
- Ne pas modifier `prisma/schema.prisma` sans migration
- Ne pas committer `.env`
- Ne pas utiliser `fetch` directement pour l'API interne (passer par tRPC)

## Architecture
- Monorepo avec `apps/web` et `packages/shared`
- Le package `shared` contient les types et les utilitaires
EOF

Vérifie la taille en tokens :

python -c "
import tiktoken
enc = tiktoken.encoding_for_model('gpt-4')
with open('AGENTS.md', 'r') as f:
    print(f'AGENTS.md : {len(enc.encode(f.read()))} tokens')
"

Objectif : moins de 500 tokens. Si c’est plus, déplace du contenu dans des skills.


4. Qu’est-ce qu’un skill

Un skill est une unité d’instructions pour faire une tâche bien. Il reste hors de la context window jusqu’à ce qu’un context pointer le charge.

Différence clé :

  • Skill = instructions que l’agent lit
  • Tool = action que l’agent appelle

5. Créer un skill

mkdir -p .claude/skills

cat > .claude/skills/deploy.md << 'EOF'
# Skill — Déploiement

## Quand charger ce skill
Quand la tâche implique un déploiement ou un rollback.

## Procédure
1. Vérifier que `main` passe les tests CI
2. Créer un tag `git tag -a vX.Y.Z -m "Release X.Y.Z"`
3. Push le tag : `git push origin vX.Y.Z`
4. Le GitHub Action `deploy.yml` déclenche le déploiement
5. Vérifier le statut sur Vercel Dashboard

## Rollback
- `git revert` sur main, ou
- Redéployer le tag précédent sur Vercel

## Contacts
- Infra : infra@company.com
- PagerDuty : rotation A
EOF

Dans AGENTS.md, ajoute un context pointer :

## Skills disponibles
- Déploiement : `.claude/skills/deploy.md`
- Migration DB : `.claude/skills/migration.md`
- Auth : `.claude/skills/auth.md`

6. Progressive disclosure

Ne charge que ce dont l’agent a besoin maintenant. Le reste reste derrière un context pointer.

Mauvais :

# AGENTS.md (mauvais exemple)
## Style guide complet
### Typography
- H1 : 32px, font-bold...
### Colors
- Primary : #3b82f6...
### 50 pages de guidelines...

→ Tout ça brûle des tokens à chaque tour.

Bon :

# AGENTS.md (bon exemple)
## Style guide
Voir `.claude/skills/style-guide.md` quand tu écris un composant UI.

→ Le style guide n’est chargé que quand l’agent a besoin d’écrire du UI.


7. Exercice pratique

  1. Crée un AGENTS.md pour ton projet (ou un projet fictif)
  2. Compte ses tokens (doit être < 500)
  3. Crée 2 skills dans .claude/skills/
  4. Ajoute les context pointers dans AGENTS.md
  5. Simule une session : “J’ai besoin de déployer” → l’agent charge le skill deploy

Checklist de validation

  • J’ai créé un AGENTS.md < 500 tokens
  • J’ai créé au moins 2 skills avec des context pointers
  • Je comprends la différence entre skill (instructions lues) et tool (action exécutée)
  • J’ai appliqué le progressive disclosure : rien n’est chargé inutilement

Piège courant

Mettre tout le style guide dans AGENTS.md → Quelqu’un a collé 4k tokens de guidelines dans AGENTS.md. Chaque tour de conversation paie ces 4k tokens. Sur 20 tours, c’est 80k tokens brûlés pour rien. Solution : mettre le style guide dans un skill, et ne le charger que quand l’agent écrit du UI.

Compaction et Autocompact

Approfondir →

Objectif

À la fin de ce module, tu sais quand compacter une session, comment compacter sans perdre d’info clé, et vérifier que le contexte important est préservé.


1. Qu’est-ce que la compaction

La compaction est un handoff en mémoire : l’historique de la session est résumé et sert de graine à une session fraîche. C’est lossy — on échange du détail contre de la place.

Elle peut être déclenchée manuellement par toi, ou automatiquement par le harness.


2. Qu’est-ce que l’autocompact

L’autocompact est une compaction déclenchée automatiquement par le harness quand la context window approche de sa limite.

Risque : le harness résume ce qu’il veut. Des décisions importantes peuvent disparaître.


3. Quand compacter

Signes que c’est le moment :

  • L’agent répète des questions déjà répondues
  • Il oublie des décisions prises au début de la session
  • Le temps de réponse s’allonge significativement
  • Tu as dépassé ~100k tokens (sur un modèle 200k)
  • Tu veux changer de sujet dans la même session

Règle : ne pousse pas une session au-delà de la dumb zone. Compacter tôt vaut mieux que compacter tard.


4. Comment compacter manuellement

Étape 1 : identifier ce qui est load-bearing

Ce qu’il faut garder absolument :

  • Décisions d’architecture
  • Choix de stack ou de librairie
  • Contrats d’API (inputs/outputs)
  • Prochaines étapes clairement définies

Ce qu’on peut jeter :

  • L’exploration et les fausses pistes
  • Les messages d’erreur résolus
  • Les reformulations du prompt

Étape 2 : écrire le résumé

Dans la session, dis :
"Compacte la session. Voici ce qui est load-bearing :

- Architecture : monorepo avec apps/web et packages/shared
- Stack : Next.js 14, tRPC v11, Prisma, PostgreSQL
- Décision : auth via Next-Auth v5, pas de Clerk
- Schema : User { id, email, name }, OAuthAccount { provider, providerAccountId }
- Endpoints créés : GET /api/auth/session, POST /api/auth/callback
- Prochaine étape : écrire le composant LoginButton avec le bouton Google
- Fichiers modifiés : src/lib/auth.ts, src/app/api/auth/callback/route.ts"

Étape 3 : lancer une nouvelle session avec le résumé

# Quitter la session actuelle
exit

# Relancer Claude Code avec le résumé en prompt
claude
Prompt initial :
"Reprise de session. Contexte :

- Architecture : monorepo avec apps/web et packages/shared
- Stack : Next.js 14, tRPC v11, Prisma, PostgreSQL
- Décision : auth via Next-Auth v5, pas de Clerk
- Schema : User { id, email, name }, OAuthAccount { provider, providerAccountId }
- Endpoints créés : GET /api/auth/session, POST /api/auth/callback
- Prochaine étape : écrire le composant LoginButton avec le bouton Google
- Fichiers modifiés : src/lib/auth.ts, src/app/api/auth/callback/route.ts

Commence l'implémentation du LoginButton."

5. Vérifier que rien n’a été perdu

Après compaction, pose ces questions à l’agent :

"Quelle est notre stack ?"
"Quelle lib d'auth on utilise ?"
"Quels endpoints sont déjà créés ?"
"Quelle est la prochaine étape ?"

Si une réponse est fausse ou vague, le résumé était incomplet. Ajoute l’info manquante et recompacte.


6. Script de vérification post-compact

# Vérifier la taille de la nouvelle session
python -c "
import tiktoken
enc = tiktoken.encoding_for_model('gpt-4')
summary = '''Architecture: monorepo... Stack: Next.js 14...'''
print(f'Résumé : {len(enc.encode(summary))} tokens')
print(f'Place restante dans 200k window : {200000 - len(enc.encode(summary)):,} tokens')
"

Checklist de validation

  • Je sais reconnaître les 5 signes qu’il faut compacter
  • J’ai compacté une session manuellement avec un résumé load-bearing
  • J’ai vérifié que les décisions clés ont été préservées après compaction
  • Je comprends le risque de l’autocompact (perte d’info contrôlée par le harness)

Piège courant

Laisser l’autocompact faire le travail → L’autocompact résume ce que le harness juge important. Si une décision critique (“on utilise PostgreSQL, pas MySQL”) est jugée secondaire, elle disparaît. Toujours compacter manuellement quand tu as des décisions load-bearing à préserver.

Playbooks prêts à l'emploi

Approfondir →

Objectif

À la fin de ce module, tu as copié-collé les templates dans ton projet et tu les utilises pour chaque session.


1. Template AGENTS.md

Copie ce fichier à la racine de chaque projet :

# AGENTS.md — {{PROJECT_NAME}}

## Stack
- Frontend : {{frontend_stack}}
- Backend : {{backend_stack}}
- DB : {{database}}
- Auth : {{auth_solution}}
- Tests : {{test_stack}}

## Conventions
- {{convention_1}}
- {{convention_2}}
- {{convention_3}}

## Commandes
- `{{cmd_dev}}` — dev server
- `{{cmd_build}}` — build production
- `{{cmd_test}}` — tests unitaires
- `{{cmd_lint}}` — linter

## Ce qu'il ne faut pas faire
- {{forbidden_1}}
- {{forbidden_2}}

## Skills disponibles
- {{skill_1}} : `.claude/skills/{{skill_1_file}}.md`
- {{skill_2}} : `.claude/skills/{{skill_2_file}}.md`

Remplacements rapides :

# Exemple pour un projet Next.js
cat > AGENTS.md << 'EOF'
# AGENTS.md — Mon App

## Stack
- Frontend : Next.js 14 (App Router), Tailwind, shadcn/ui
- Backend : tRPC v11, Prisma ORM
- DB : PostgreSQL 15
- Auth : Next-Auth v5
- Tests : Vitest, Playwright

## Conventions
- TypeScript strict
- Pas de `any`
- Composants UI dans `src/components/ui/`

## Commandes
- `npm run dev` — dev server
- `npm run build` — build production
- `npm run test` — tests unitaires
- `npx prisma migrate dev` — migration DB

## Ce qu'il ne faut pas faire
- Ne pas modifier `prisma/schema.prisma` sans migration
- Ne pas committer `.env`

## Skills disponibles
- Déploiement : `.claude/skills/deploy.md`
- Migration DB : `.claude/skills/migration.md`
EOF

2. Template Spec

# Spec — {{FEATURE_NAME}}

## Contexte
{{pourquoi on fait ça}}

## Objectif
{{quoi on construit}}

## Tickets

### Ticket 1 — {{titre}}
{{description}}
**Dépend de :** {{rien | Ticket X}}

### Ticket 2 — {{titre}}
{{description}}
**Dépend de :** {{Ticket Y}}

### Ticket 3 — {{titre}}
{{description}}
**Dépend de :** {{Ticket Z}}

## Non-goals
- {{ce qu'on ne fait PAS}}
- {{ce qu'on ne fait PAS}}

## Notes
{{stack, liens, références}}

3. Template Ticket

# Ticket {{N}} — {{TITRE}}

## Contexte
Spec : {{nom_de_la_spec}}

## Objectif de cette session
{{une phrase claire}}

## Fichiers concernés
- `{{chemin/fichier_1}}`
- `{{chemin/fichier_2}}`

## Décisions déjà prises
- {{décision_1}}
- {{décision_2}}

## Livrable attendu
- {{critère_1}}
- {{critère_2}}

## Prochain ticket
Ticket {{N+1}} — {{titre_suivant}}

4. Checklist pré-session

Copie cette checklist avant chaque session :

## Pré-session

- [ ] Context window vérifiée (fichiers < 50% de la limite)
- [ ] Permission mode adapté à la tâche
  - [ ] Exploration → plan mode
  - [ ] Refactoring → accept-edits
  - [ ] Run AFK → bypass + sandbox
- [ ] MCP servers nécessaires sont up
  - [ ] `claude config get mcpServers`
- [ ] AGENTS.md à jour (< 500 tokens)
- [ ] Ticket prêt (si multi-session)
- [ ] Branche Git créée : `git checkout -b feat/ticket-n`

5. Checklist post-session

## Post-session

- [ ] Diff review : `git diff`
  - [ ] Pas de fichiers non voulus
  - [ ] Pas de secrets dans le diff
  - [ ] Pas de `console.log` oubliés
- [ ] Tests passent : `npm run test`
- [ ] Build passe : `npm run build`
- [ ] Lint passe : `npm run lint`
- [ ] Ticket mis à jour (résultat, décisions, fichiers modifiés)
- [ ] Spec mise à jour (ticket coché)
- [ ] Commit : `git commit -m "feat: {{description}}"`
- [ ] Session compactée si > 50k tokens

6. Script d’automatisation pré-session

#!/bin/bash
# save as: scripts/pre-session.sh

echo "=== Pré-session check ==="

# Vérifier la taille des fichiers modifiés
if command -v python &> /dev/null; then
    python -c "
import tiktoken, subprocess, os
enc = tiktoken.encoding_for_model('gpt-4')
result = subprocess.run(['git', 'diff', '--name-only'], capture_output=True, text=True)
files = [f for f in result.stdout.strip().split('
') if f and os.path.exists(f)]
total = sum(len(enc.encode(open(f).read())) for f in files)
print(f'Fichiers modifiés : {len(files)} — Tokens estimés : {total:,}')
print(f'Statut : {"✅ OK" if total < 100000 else "⚠️ Trop gros — réduire le scope"}')
"
fi

# Vérifier les tests
echo "=== Tests ==="
npm run test -- --run 2>/dev/null || echo "⚠️ Tests en échec ou non configurés"

# Vérifier le mode
echo "=== Permission mode ==="
claude config get permissionMode 2>/dev/null || echo "⚠️ Claude Code non configuré"

echo "=== Done ==="

Rends-le exécutable :

chmod +x scripts/pre-session.sh
./scripts/pre-session.sh

Checklist de validation

  • J’ai copié le template AGENTS.md dans un projet
  • J’ai rédigé une spec avec le template
  • J’ai écrit un ticket avec le template
  • J’ai utilisé la checklist pré-session avant une session
  • J’ai utilisé la checklist post-session après une session
  • J’ai adapté le script d’automatisation à mon projet

Piège courant

Sauter la checklist post-session parce que “c’était juste un petit fix” → Même un “petit fix” de 3 lignes peut introduire un console.log oublié, un secret en dur, ou casser un test. La checklist post-session prend 2 minutes et évite des problèmes en production.

Fin du pack

Tu as maintenant tout le vocabulaire du code IA transformé en actions concrètes. Retourne au sommaire pour naviguer entre les modules.