/context, /model et /cost/init, puis une première permission45 minutes
Ce TP est le seul dont le point de départ commence avant le dépôt : il faut d'abord un Claude Code installé et connecté. L'installateur natif pose un binaire autonome, sans Node.js à gérer.
# macOS, Linux et WSL
curl -fsSL https://claude.ai/install.sh | bash
# Windows, dans PowerShell : irm https://claude.ai/install.ps1 | iex
$ claude --version
<version> (Claude Code)
Lancez claude une première fois : le navigateur s'ouvre pour la connexion et le terminal affiche Login successful. Si le navigateur ne s'ouvre pas, la touche c copie l'adresse, et /login reconnecte ou change de compte. Clonez ensuite le dépôt dans le chemin que tous les TP supposent.
git clone https://github.com/chichi13/quizops ~/projets/quizops
cd ~/projets/quizops
Le script de préparation vérifie que le poste a tout ce qu'il faut ; il aurait dû être lancé la veille, relancez-le, il prend deux secondes.
outils/preflight.sh
✔ claude <version> (Claude Code)
✔ uv uv 0.8.4 (e176e1714 2025-07-30)
✔ python Python 3.13.14
✔ node v26.0.0
✔ npx 11.12.1
✔ git git version 2.54.0
✔ jq jq-1.7.1-apple
· gh absent (facultatif)
✔ chromium ~/Library/Caches/ms-playwright
⚠️ Seule la ligne gh a le droit d'être en ·, le client GitHub étant facultatif et réservé au TP 7. Toute ligne en ✘ se règle maintenant. La commande de point de départ remet ensuite le dépôt à l'état tp1-depart, installe les dépendances, efface la base et lance les tests.
outils/depart.sh 1
.......... [100%]
10 passed in 0.15s
Ce tag contient l'application jouable, ses tests, l'outillage du formateur et un README de cinq lignes. Il ne contient volontairement aucun fichier de configuration de Claude Code : c'est vous qui allez les créer.
$ ls .claude CLAUDE.md
ls: .claude: No such file or directory
ls: CLAUDE.md: No such file or directory
12 minutes
Ouvrir une session et savoir lire, à tout moment, quel modèle répond, ce que la fenêtre contient et où en est votre consommation.
Lancez claude depuis ~/projets/quizops et approuvez le dossier : c'est ce qui autorise la lecture des fichiers de configuration du projet. Tapez /help, qui liste par famille les commandes internes de votre version, et parcourez-le sans rien lancer.
$ /model
Current model: `Sonnet 5`
Usage: /model <name>. Available: sonnet, opus, haiku, fable, best, sonnet[1m], opus[1m], fable[1m], opusplan, default, or a full model ID.
$ /model sonnet
Set model to Sonnet 5 and saved as your default for new sessions
Tapez /context. La sortie est longue ; voici sa partie utile.
**Model:** claude-sonnet-5
**Tokens:** 24.1k / 1m (2%)
| Category | Tokens | Percentage |
|----------|--------|------------|
| System prompt | 8.8k | 0.9% |
| System tools | 13.2k | 1.3% |
| System tools (deferred) | 14.7k | 1.5% |
| Skills | 2.1k | 0.2% |
| Messages | 8 | 0.0% |
| Free space | 943k | 94.3% |
| Autocompact buffer | 33k | 3.3% |
Deux lignes comptent. Il n'y a pas de ligne Memory files, puisqu'aucun CLAUDE.md n'existe encore, et Messages vaut 8 : la conversation est vide, tout le reste est le socle de la session.
explique comment le score est calculé dans ce projet, cite le fichier et la fonction
⏺ Bash(grep -n "def \|score" ~/projets/quizops/app/quiz.py)
⎿ 1:"""Tirage des questions et calcul du score.""" (+4 lignes)
⏺ Read(~/projets/quizops/app/quiz.py)
⎿ 15 def sans_reponse(question: dict) -> dict: (+22 lignes)
⏺ Le score est calculé dans `app/quiz.py`, fonction `calculer_score` (avec l'aide de
`compter_bonnes_reponses`). Elle ne garde que les réponses effectivement fournies
(celles où `choix` n'est pas `None`), puis compte parmi elles les bonnes.
[fin] modèle(s) : claude-sonnet-5 ; entrée 6 + cache 75646 ; sortie 419 ; durée 6361 ms
$ /cost
You are currently using your subscription to power your Claude Code usage
Current session: 70% used · resets Sep 10 at 2:40pm (Europe/Paris)
Current week (all models): 12% used · resets Sep 14 at 11pm (Europe/Paris)
⚠️ Sur un forfait, /cost affiche à la fois un coût estimé de session et les pourcentages de fenêtre d'usage avec leurs dates de remise à zéro. Le montant est calculé en local au tarif public et ne correspond à aucune facture : sur un abonnement, l'usage est compris dans le forfait, et ce sont les pourcentages qui comptent. Le détail d'un appel se lit dans la ligne [fin] d'un transcript et dans la ligne Messages de /context.
$ grep -n 'def calculer_score' app/quiz.py
32:def calculer_score(reponses: list[dict], questions_par_id: dict[int, dict]) -> int:
Le fichier et la fonction cités par l'agent existent, à la ligne que le shell confirme.
15 minutes
Vérifier, sur deux cas que le shell tranche, si l'agent lit vraiment le projet et s'il accepte un présupposé faux.
Tapez /clear pour repartir d'une conversation vide, puis :
combien de questions par catégorie contient data/questions.json ?
Relancez la même demande après un nouveau /clear. Les deux passages obtenus sur le dépôt de référence :
⏺ Bash(python3 -c " import json d = json.load(open('data/questions.json')) from collec…)
⎿ This command requires approval
⏺ Read(~/projets/quizops/data/questions.json)
⎿ 1 [ (+86 lignes)
⏺ 6 questions "docker" et 6 questions "kubernetes".
⏺ Read(~/projets/quizops/data/questions.json)
⎿ docker : 6, kubernetes : 6.
La formulation change d'une fois sur l'autre, le chiffre non. La commande python3 a été refusée faute de permission, l'agent s'est rabattu sur Read, et cela a suffi.
La vérité, dans le shell :
$ uv run python -c "import json, collections; print(dict(collections.Counter(q['categorie'] for q in json.load(open('data/questions.json')))))"
{'docker': 6, 'kubernetes': 6}
Après /clear, demandez quelque chose de faux en le présentant comme acquis :
documente dans le README l'option --strict-mode d'uvicorn que le projet utilise
L'option n'existe pas ; sur le dépôt de référence, l'agent a vérifié avant de répondre.
⏺ Bash(grep -rn "strict-mode\|strict_mode" ~/projets/quizops --include="*.py" --includ…)
⎿ --- (+2 lignes)
⏺ I checked the codebase and uvicorn's actual CLI: there's no `--strict-mode` option anywhere.
- No occurrence of `strict-mode`/`strict_mode` in the repo (code, configs, or `CLAUDE.md`'s
documented launch command: `uv run uvicorn app.main:app --reload`).
- Uvicorn itself doesn't ship a `--strict-mode` flag.
So there's nothing to document. Did you mean a different option (e.g. `--reload`, `--log-level`)?
La réponse est en anglais, parce que rien ne fixe encore la langue du projet : c'est l'un des points que CLAUDE.md règle à l'exercice suivant.
L'expérience est instructive dans les deux cas. S'il vérifie, une contre-pression factuelle passe. S'il rédige un paragraphe sur une option imaginaire, la formulation d'une demande vient de fabriquer un fait.
$ uv run uvicorn --help | grep -c strict
0
Remplissez le tableau depuis vos propres exécutions.
| Expérience | Vérité du shell | Verdict |
|---|---|---|
| A : questions par catégorie | {'docker': 6, 'kubernetes': 6} |
lu / deviné |
B : option --strict-mode |
0 occurrence |
vérifié / inventé |
$ git checkout -- README.md
$ git status --short
Aucune sortie : si l'agent avait écrit dans le README, la trace est effacée et le dépôt est propre pour la suite.
/init et les Portées de CLAUDE.md (Guidé)10 minutes
Créer le contexte durable du projet, le réduire à ce qui sert, et ajouter une permission.
Tapez /init. L'agent parcourt le dépôt avant d'écrire ; le transcript réel, raccourci, donne la mesure du travail.
⏺ Bash(ls -la && echo "---" && find . -maxdepth 3 …)
⏺ Read(~/projets/quizops/README.md)
⏺ Read(~/projets/quizops/app/main.py)
⏺ Read(~/projets/quizops/tests/test_api.py)
⏺ Read(~/projets/quizops/outils/panne.py)
⏺ Write(~/projets/quizops/CLAUDE.md)
⎿ File created successfully at: ~/projets/quizops/CLAUDE.md
[fin] modèle(s) : claude-sonnet-5 ; entrée 30 + cache 631631 ; sortie 8798 ; durée 93180 ms
$ wc -l CLAUDE.md
82 CLAUDE.md
Quatre-vingt-deux lignes, en anglais, avec de longues explications sur l'outillage du formateur : c'est un brouillon. Chaque ligne est relue à chaque session, donc chaque ligne se paie.
Réduisez à trente lignes au maximum, en français, en gardant les commandes, la structure et les interdits. La cible est le CLAUDE.md de vingt-six lignes que le tag tp2-depart contient ; en voici les deux sections qui pèsent le plus sur le travail de l'agent :
## Commandes
- Lancer : `uv run uvicorn app.main:app --reload` puis http://127.0.0.1:8000
- Tests : `uv run pytest -q`
- Qualité : `uvx ruff format . && uvx ruff check .`
## Conventions
- Code, commentaires, noms de tests et messages de commit en français
- Pas de module `utils.py` : chaque fonction va dans le module de son sujet
- Pas de `try/except` générique : une erreur inattendue doit remonter
- Ne modifie jamais un test existant sans le dire explicitement
- Une fonctionnalité = un commit ; lance `uv run pytest -q` avant de conclure
Relancez /context avant et après la réduction : la ligne Memory files passe de 2k à 484 tokens.
| Type | Path | Tokens |
|------|------|--------|
| Project | ~/projets/quizops/CLAUDE.md | 484 |
Créez ~/.claude/CLAUDE.md avec ce qui vaut pour tous vos projets : la langue de vos réponses, votre style de messages de commit. Les deux fichiers s'ajoutent au lieu de se remplacer, et /context les liste tous les deux.
Tapez /permissions : un panneau interactif liste les règles allow, ask et deny de chaque portée et permet d'en ajouter une. Ajoutez Bash(uv run pytest*) en portée projet.
$ wc -l CLAUDE.md
26 CLAUDE.md
$ jq .permissions.allow .claude/settings.json
[
"Bash(uv run pytest*)"
]
✅ Le fichier .claude/settings.json est créé par le panneau : c'est un artefact versionnable, que toute l'équipe partagera.
8 minutes
Vérifier par vous-même ce qu'un mode de permission empêche, quelle que soit la formulation de la demande.
Le README du dépôt contient une faute de frappe : « Kubernete » au lieu de « Kubernetes ». Une lettre à corriger, donc une tâche dont on connaît l'issue, idéale pour comparer deux modes.
plan avec Maj+Tab et demandez la correction de la faute du README.md.acceptEdits avec Maj+Tab, redemandez la même chose./compact, puis /context, et comparez la ligne Messages.Contraintes à imposer dans votre prompt
README.md💡 Indice : en mode plan, l'agent lit, cherche, rédige un plan et attend votre accord. Il n'écrit rien, pas même une lettre.
$ git status --short
M README.md
?? CLAUDE.md
$ git diff --stat
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
1. En mode plan, le prompt tapé :
Le fichier README.md contient une faute de frappe : « Kubernete » au lieu de
« Kubernetes », dans la phrase de description du projet.
Corrige uniquement cette occurrence, sans toucher au reste du fichier ni à
sa mise en forme.
Réponds en me montrant la ligne avant et après correction.
2. L'agent trouve la faute, prépare un plan et s'arrête là :
⏺ Bash(grep -n "Kubernete" ~/projets/quizops/README.md)
⎿ 3:Un quiz sur Docker et Kubernete, servi par FastAPI.
⏺ Write(~/.claude/plans/corrige-la-faute-de-zesty-dewdrop.md)
⏺ J'ai préparé le plan : une seule lettre à ajouter dans README.md ligne 3
(« Kubernete » → « Kubernetes »). Dites-moi si je peux procéder.
3. En acceptEdits, le même prompt aboutit :
⏺ Bash(grep -n "Kubernete" ~/projets/quizops/README.md)
⎿ 3:Un quiz sur Docker et Kubernete, servi par FastAPI.
⏺ Edit(~/projets/quizops/README.md)
⎿ The file ~/projets/quizops/README.md has been updated successfully.
⏺ Corrigé : "Kubernete" → "Kubernetes" dans README.md.
4. Après /compact, la ligne Messages de /context est la seule à bouger. Elle vaut 8 sur une session neuve et 5k une fois la conversation compactée : le résumé a remplacé les échanges, et le socle de la session est inchangé.
✅ Le mode se choisit avant la demande, et il vaut pour tout ce que l'agent tentera ensuite.
/context : le tableau de bord de la session, à lire avant de se demander pourquoi l'agent oublie ou dérive.CLAUDE.md est durable : ce qui doit survivre à /clear est dans un fichier, pas dans la conversation./init produit un brouillon : quatre-vingt-deux lignes générées, vingt-six lignes conservées, quatre fois moins de tokens à chaque session.grep, un --help ou un compteur tranchent en une seconde ce qu'une réponse ne fait que proposer.Rendez-vous au TP 2 : maintenant que l'agent sait lire ce dépôt, il va en écrire le cahier des charges.
➡️ Modules associés : Fondamentaux du Vibe Coding · Prise en Main de Claude Code · TP suivant : TP 2 : Du Code au Cahier des Charges