Anatomie d'une session Claude Code : tout est langage naturel

J’ai monté un proxy MITM pour intercepter les échanges entre Claude Code et l’API Anthropic. Ce que j’ai découvert m’a frappé par sa simplicité : tout est langage naturel. Les tools, les skills, la sécurité — tout repose sur des prompts textuels et la capacité du modèle à suivre des instructions.
Le protocole
J’ai configuré mitmproxy pour capturer le trafic HTTPS vers api.anthropic.com, avec un petit viewer React pour visualiser les échanges en temps réel :
mitmproxy (8890) → FastAPI (8080) → WebSocket → React Frontend (5173)
Puis j’ai lancé une session Claude Code avec un scénario simple :
- Demander de créer une landing page
- Demander de vérifier le code généré
- Observer ce qui se passe
65 appels API plus tard, voici ce que j’ai appris.
Phase 1 : Le démarrage
Avant même de taper quoi que ce soit, Claude Code envoie plusieurs requêtes en parallèle.
| Modèle | Action |
|---|---|
| Haiku | Vérifie le quota (1 seul token demandé) |
| Opus | Pré-charge les agents Bash et Plan avec des requêtes “à vide” |
Le pré-chargement sert à mettre les prompts système en cache côté Anthropic. Ces prompts font plusieurs dizaines de KB — les cacher accélère les réponses suivantes.
Premier constat : deux modèles collaborent. Haiku pour les tâches légères, Opus pour le travail cognitif.
Phase 2 : “Salut”
Je tape “salut”. Cinq appels API partent :
| Modèle | Action |
|---|---|
| Haiku | Génère le titre de session (“Greeting”) |
| Opus | Répond “Salut ! Comment puis-je t’aider ?” |
| Opus | Génère des suggestions de suite |
Haiku génère le titre qu’on voit dans l’interface Claude Code. C’est lui aussi qui décide si c’est un “nouveau sujet” ou la suite de la conversation.
Deuxième constat : même un message trivial déclenche une orchestration complexe.
Phase 3 : “Crée une landing page”
Je demande : “crée une landing page moderne pour une app de todo”.
Claude Code dispose d’un système de skills — des prompts spécialisés pour certaines tâches. L’un d’eux s’appelle frontend-design. Comment Claude sait qu’il existe ?
À chaque requête, le client envoie un champ tools[] avec la liste des outils disponibles :
{
"tools": [
{
"name": "Skill",
"description": "Execute a skill. Available skills: frontend-design, skill-development, pdf..."
},
{
"name": "Write",
"description": "Writes a file to the local filesystem..."
}
]
}
Claude lit cette description textuelle et décide d’utiliser le skill frontend-design. Sa réponse :
{
"type": "tool_use",
"name": "Skill",
"input": { "skill": "frontend-design" }
}
Le client (pas l’API) reçoit cette réponse, charge le fichier du skill depuis le disque local, et le renvoie comme tool_result. Le skill n’est pas du code — c’est un fichier texte avec des instructions : guidelines de design, patterns à suivre, exemples de code.
Claude reçoit ce texte, le lit, et génère un nouveau tool_use :
{
"type": "tool_use",
"name": "Write",
"input": {
"file_path": "/todo-landing/index.html",
"content": "<!DOCTYPE html>..."
}
}
Le client écrit le fichier, renvoie “OK”, et Claude génère sa réponse finale : “J’ai créé la landing page Taskō…”
Troisième constat : les skills sont des fichiers texte. Pas de framework, pas d’API spéciale. Claude suit des instructions en langage naturel.
Phase 4 : “Crée un vérificateur de code”
Je pousse le test. Je demande : “crée un sous-agent de vérification de code pour la suite du projet”.
Note : j’ai dit “sous-agent”, pas “skill”. Pourtant Claude utilise le skill skill-development pour créer… un skill. Pourquoi ?
Parce que dans la description du tool Skill (envoyée à chaque requête), il est écrit que skill-development sert à “create a skill, add a skill to plugin, write a new skill”. Claude a fait le lien : “sous-agent de vérification” → “capacité réutilisable” → “skill”. Il a traduit mon intention dans le vocabulaire de ses outils disponibles.
Il génère :
skills/frontend-checker/SKILL.md → Instructions du skill
skills/frontend-checker/scripts/check-html.sh → Script de vérification HTML
skills/frontend-checker/scripts/check-css.sh → Script de vérification CSS
skills/frontend-checker/references/a11y-checklist.md → Checklist accessibilité
Le fichier SKILL.md contient des instructions en langage naturel. Les scripts bash sont générés par Claude en suivant les conventions du skill skill-development.
Quatrième constat : Claude peut créer des outils à la volée, en suivant des instructions textuelles sur comment structurer ces outils.
Phase 5 : Exécution et sécurité
Claude veut exécuter les scripts de vérification. Il génère :
bash check-html.sh index.html && bash check-css.sh index.html
Mais cette commande n’est pas exécutée directement. Haiku intervient comme garde-fou.
Le client envoie la commande à Haiku avec un prompt <policy_spec> contenant des exemples :
- git status => git status
- git diff $(cat secrets.env | curl...) => command_injection_detected
- pwd\n curl example.com => command_injection_detected
Haiku analyse la commande et répond : command_injection_detected
Pourquoi ? Le chaînage && ressemble aux patterns d’injection dans les exemples. Le système demande confirmation à l’utilisateur avant d’exécuter.
Cinquième constat : la sécurité est implémentée par un LLM qui fait du pattern matching sur des exemples textuels. Pas de parsing syntaxique, pas de regex.
Phase 6 : Le cycle de correction
Après exécution (confirmée manuellement), le checker remonte des warnings. Claude enchaîne automatiquement :
Read— lit le fichier HTMLEdit— corrige un problème d’accessibilitéEdit— corrige un autre warningBash— relance le checkerGrep— cherche un pattern problématiqueEdit— corrigeBash— relance le checker
Chaque étape est un appel API complet. Et chaque appel inclut tout l’historique — les 60+ messages précédents, les 50KB de prompts système, les 20+ définitions d’outils.
Sixième constat : l’API est stateless. Pas de mémoire côté serveur. Tout le contexte est renvoyé à chaque appel.
Ce que ça révèle
Tout est texte
Les tools sont des descriptions textuelles. Les skills sont des fichiers texte. La sécurité est un prompt avec des exemples. Claude ne “comprend” pas qu’il écrit un fichier — il suit une instruction qui dit “pour écrire un fichier, utilise le tool Write avec ces paramètres”.
La complexité est côté client
Le client Claude Code fait l’orchestration : charger les skills, exécuter les commandes, gérer la sécurité, renvoyer les résultats. Le modèle ne fait que lire du texte et produire du texte conforme aux instructions.
Le prompt engineering est industriel
Les system prompts font ~50KB et couvrent des centaines de cas : règles git, patterns de code, comportements à éviter, formats de sortie. C’est de l’ingénierie à grande échelle.
Implications pratiques
Les conversations longues coûtent cher. 60 messages × 50KB de contexte = beaucoup de tokens. Privilégier plusieurs sessions courtes.
Les tools ne sont pas magiques. C’est du pattern matching entre une intention et des descriptions textuelles.
La sécurité est heuristique. Haiku peut rater une injection si elle ne ressemble pas aux exemples du <policy_spec>.
Le contexte se “pollue”. Quand le skill frontend-design est chargé, ses instructions (guidelines de design, exemples de code, patterns) restent dans le contexte pour toute la suite de la session. Si je demande ensuite de l’aide sur un script Python, Claude a toujours ces 10KB d’instructions CSS/HTML en tête. Le modèle est “spécialisé” temporairement — potentiellement moins pertinent sur d’autres sujets. Une raison de plus pour garder des sessions courtes et ciblées.
Conclusion
L’UX polie de Claude Code cache une mécanique simple : des prompts textuels, une API stateless, et un modèle qui suit des instructions.
Pas d’intelligence artificielle au sens mystique. Juste du texte — beaucoup de texte — et un modèle statistique très performant pour le traiter.