Le temps mort des conversations agentiques
On passe désormais une bonne partie de la journée à discuter avec un agent. On écrit un message, on l'envoie... et on attend. L'agent lit des fichiers, lance des commandes, réfléchit. Selon la tâche, ça prend quelques secondes ou plusieurs minutes.
Ce temps-là, on le passe souvent à regarder défiler les appels d'outils, ou à changer d'onglet. Et si on en profitait pour progresser sur quelque chose, ou pour produire quelque chose d'utile ?
Mon choix : améliorer mon anglais. Depuis peu, j'écris tous mes prompts en anglais. La matière première est déjà là : chaque message envoyé à Claude Code est un exercice. Il manquait quelqu'un pour le corriger, sans ralentir l'agent et sans polluer sa conversation avec mes fautes.
C'est le rôle d'English coach, un mod Claude Code que j'utilise tous les jours. Voici ce qu'on va couvrir :
- Le cas d'usage : apprendre l'anglais avec ses propres prompts
- Les mods Claude Code : ce que c'est, en bref
- Le trajet d'un message : du prompt à la carte de corrections
- La vitesse : pourquoi Haiku, et ce que disent les mesures
- Construire le vôtre : les briques à retenir
- Au-delà de l'anglais : le même schéma pour d'autres coachs
Mon cas d'usage : apprendre l'anglais avec mes propres prompts
Le principe tient en une phrase : chaque message que je tape est relu par un coach, et ses corrections s'affichent pendant que l'agent travaille.
Ce que je vois
J'envoie mon message. Au-dessus du prompt, un bandeau apparaît : English coach · checking your message…. Une seconde plus tard environ, il laisse place à une carte English tips :
- la tournure fautive, barrée en rouge ;
- la correction, en vert ;
- une catégorie :
[preposition],[calque],[verb-form]...

Quand le message est propre, la carte se résume à ✓ No English findings.

Pendant ce temps, Claude continue sa tâche. Il ne voit pas les corrections : son contexte reste consacré au travail demandé.
Un coach qui s'adapte
Un fichier de progression, ~/.claude/english-coach/progress.md, garde la trace de ce que le coach sait de moi :
- mon palier, sur trois niveaux : les bases (prépositions, formes verbales, calques), puis les tournures naturelles, puis la nuance ;
- mes erreurs récurrentes, et celles que je maîtrise.
Ma langue maternelle, elle, est un réglage du plugin : c'est elle qui dit au coach quels calques et quels faux amis chercher.
Le coach relève les erreurs de mon palier et des paliers au-dessus, plus celles qui gênent la compréhension. Quand je passe au niveau suivant, il arrête de signaler les bases, sauf si elles brouillent le message.
Ce fichier se met à jour tout seul. Au démarrage d'une session, si au moins dix messages ont été relus depuis la dernière fois, un second modèle relit les corrections accumulées : une erreur qui ne revient plus passe dans les acquis, une nouvelle qui revient deux fois rejoint les récurrentes, et le palier monte quand le niveau actuel est maîtrisé.
Suivre ses progrès
La commande /english ouvre un panneau qui agrège toutes les sessions : corrections par message, erreurs pour 100 mots, messages sans faute, un graphique des 30 derniers messages et des tableaux par jour et par mois. Elle s'ouvre même pendant que Claude travaille, grâce à l'option immediate: true passée à l'enregistrement de la commande.

Mes chiffres entre le 8 et le 12 octobre : 1,16 → 0,54 correction par message, et 42 % → 77 % de messages sans faute. À nuancer : mes messages ont aussi raccourci. Rapporté aux mots, je reste entre 4 et 5 erreurs pour 100 mots. Le coach ne fait pas de miracle en une semaine : il rend les erreurs visibles.
Le vrai bénéfice : la pratique quotidienne
Je n'ai ajouté aucune séance d'anglais à mon agenda. J'écris en anglais parce que je travaille, et je lis les corrections pendant que Claude travaille. Pas d'effort en plus : une pratique quotidienne, sur mes propres phrases, avec mes propres erreurs.
L'essayer
English coach est open source, sur mon dépôt Thomgrus/claude-plugins. Deux commandes l'installent :
claude plugin marketplace add Thomgrus/claude-plugins
claude plugin install english-coach@tgruson-public
Redémarrez Claude Code : la première session vous demande votre langue maternelle, modifiable ensuite dans /config. C'est ce qui permet au coach de chercher les bons calques, au point de rattraper l'effort low. Votre premier message crée ensuite le fichier de progression, où vous pouvez choisir un palier plus haut.
Un mod Claude Code, c'est quoi ?
Un mod est un plugin Claude Code dont le code s'exécute à l'intérieur de Claude Code. On l'écrit en JavaScript ou en TypeScript, sous forme de fonctions que Claude Code appelle quand un événement se produit : un prompt envoyé, un appel d'outil, une partie de l'interface à dessiner.
Concrètement, un mod peut :
- dessiner dans l'interface : un panneau à côté de la conversation, un bandeau au-dessus du prompt ;
- intervenir sur un événement : l'observer, le modifier ou y répondre à la place de Claude Code ;
- ajouter une commande qui exécute votre fonction tout de suite, sans tour de Claude ;
- appeler un modèle de son côté, hors de la conversation principale.
C'est ce dernier point qui rend English coach possible.
Trois fichiers suffisent
Un mod minimal tient en trois fichiers :
mon-mod/
├── .claude-plugin/
│ └── plugin.json
└── hooks/
├── hooks.json
└── register.tsx
Arborescence minimale d'un mod — un manifeste, un fichier hooks.json et le module de hooks
plugin.json: le manifeste du plugin ;hooks.json: pointe vers le code,{ "modules": ["./register.tsx"] };register.tsx: le module qui exporte une fonctionregister(on).
Des hooks et une API
Chaque appel on('événement', handler) enregistre un hook. Le handler reçoit $, l'API du moteur, et l'événement. Tout ce qui sort du code du mod passe par $ : $.model pour appeler un modèle, $.ui pour l'interface, $.state et $.store pour l'état, $.fs pour les fichiers, $.clock pour les timers.
English coach s'appuie surtout sur quatre événements :
| Événement | Rôle dans le mod |
|---|---|
prompt.submit |
Récupérer le message envoyé et lancer la relecture |
session.start |
Mettre à jour le fichier de progression |
ui.render |
Dessiner le bandeau au-dessus du prompt et le panneau /english |
command.run |
Ouvrir le panneau avec la commande /english |
Les mods fonctionnent dans le CLI (v2.1.287 ou plus) et dans l'onglet Code de l'application Claude Desktop. En mode claude -p, les hooks tournent mais rien ne s'affiche.
claude plugin validate ./mon-mod liste les événements qu'un mod écoute et les appels qu'il fait, sans l'exécuter.Le trajet d'un message : du prompt à la carte de corrections

Tout part du hook prompt.submit, appelé à chaque message envoyé. Deux chemins en sortent, et ils avancent en parallèle.
Le chemin principal : le message part tout de suite
Le hook ne retient pas le message. Il le rend au moteur avec next(e), et Claude commence son tour immédiatement.
Rien n'est ajouté au passage : ni consigne, ni fichier de progression. Claude reçoit exactement ce que vous avez tapé. Pas besoin de lui demander de répondre en anglais : il répond déjà dans la langue où on lui écrit.
Seuls les messages que vous saisissez sont relus, au clavier ou via Remote Control. Les prompts de claude -p, les notifications et les tâches planifiées sont ignorés.
Le chemin de côté : Haiku relit le message
En parallèle, le hook lance la relecture. Voici le cœur du mod, légèrement simplifié :
const id = await $.clock.now()
await update($, check, () => ({ id, tips: null }))
$.clock.after(0, () =>
coach($, id, countWords(e.text), progress, e.text),
)
Cœur du hook prompt.submit — état « en cours » puis relecture Haiku programmée hors du dispatch
Pourquoi passer par un timer à zéro milliseconde plutôt qu'un appel direct ? Deux pièges à éviter :
- attendre la réponse avec
awaitretarderait l'envoi du message d'autant ; - lancer l'appel sans l'attendre ne suffit pas : un appel
$démarré dans un hook s'arrête avec le traitement de ce hook.
$.clock.after(0, …) programme coach() hors du traitement de prompt.submit. Le hook se termine, le message part, et la relecture continue de son côté. coach() envoie alors le message à Haiku avec $.model.complete, dans un appel séparé : la conversation de Claude n'en voit rien.
L'affichage : un atome d'état
Avant de lancer la relecture, le hook écrit { id, tips: null } dans l'atome check, un état partagé entre les hooks du mod. Le bandeau au-dessus du prompt lit cet atome à chaque rendu :
tipsvautnull: il affiche checking your message… ;tipsest rempli : il affiche la carte de corrections.
Quand l'atome change, l'interface se redessine toute seule. Pas de polling, pas de rafraîchissement manuel.
L'id sert de garde-fou. Si vous envoyez un deuxième message avant la réponse au premier, la réponse tardive n'écrase pas la carte en cours : seule celle du dernier message s'affiche. Et si la relecture échoue, le bandeau disparaît et une ligne grisée s'ajoute au transcript, que Claude ne reçoit pas, sans gêner la session.
L'historique : le store
Chaque message relu est enregistré dans $.store, sous la clé session:<id> : nombre de mots, palier du moment, corrections. Contrairement à l'atome, le store survit à la session. C'est lui que lit le panneau /english à son ouverture pour calculer les indicateurs.
La progression : Sonnet, au démarrage de la session
Reste le fichier de progression. Haiku le lit à chaque message pour savoir quoi signaler, mais il ne l'écrit jamais : c'est le travail du hook session.start.
Au démarrage d'une session, le hook compte les messages relus depuis la dernière mise à jour. À partir de dix, il envoie à Sonnet le fichier actuel et les corrections stockées depuis, avec le même $.clock.after(0, …) : la session démarre sans attendre. Sonnet renvoie le fichier mis à jour, et le mod vérifie que la réponse n'a pas été tronquée, qu'aucune section n'a disparu et que le fichier n'a pas changé entre-temps, avant de l'écrire. Sinon, il garde l'ancien et ajoute une ligne grisée au transcript.
Pourquoi Sonnet et pas Haiku ? Ici, rien ne presse : l'appel tourne une fois par session, en arrière-plan. Et la tâche demande plus de jugement que de vitesse : repérer un motif dans des dizaines de corrections, décider qu'une erreur est acquise, changer de palier.
Résultat : Claude ne voit ni les corrections, ni le fichier de progression. Son contexte ne contient que votre travail.
La vitesse : pourquoi Haiku, et ce que disent les mesures
Le coach n'a qu'une contrainte : afficher ses corrections avant que Claude ait fini. Une carte qui arrive après la réponse de l'agent, on ne la lit plus. Tout le réglage tient en un appel :
$.model.complete({
model: 'haiku',
system: COACH,
prompt: ask(progress, text),
maxTokens: 600,
effort: 'low',
timeoutMs: 30000,
})
Appel du coach — Haiku, effort bas, 600 tokens et 30 secondes au maximum
- Haiku : le plus rapide des modèles Claude, et largement assez bon pour repérer une préposition fautive ;
- effort
low: moins de réflexion avant de répondre ; - 600 tokens : de quoi écrire cinq corrections, le maximum demandé au coach ;
- 30 secondes : au-delà, le mod abandonne et le bandeau disparaît.
Le banc d'essai
Je pensais que l'effort low raterait des fautes. Plutôt que de deviner, j'ai mesuré : 100 messages (60 avec 77 fautes, 40 sans), passés cinq fois à chaque niveau d'effort, le 13 octobre 2026, avec Claude Code 2.1.295 et Haiku 5.5. Sans effort, l'appel prend celui du modèle : medium pour Haiku.
Effort par défaut (medium) |
Effort low |
|
|---|---|---|
| Médiane | 1,10 s | 0,97 s |
| p95 | 2,7 s | 1,5 s |
| Appel le plus lent | 11,8 s | 3,9 s |
| Fautes repérées, langue maternelle inconnue | 72 % | 60 % |
| Fautes repérées, langue maternelle : français | 74 % | 73 % |
| Messages propres signalés à tort | 0/200 | 1/200 |
Premier passage, sans langue maternelle : low rate 12 points de fautes. Il ne se trompe pas, il abandonne : il répond « rien à signaler » deux fois plus souvent, surtout sur les calques (« make a refactoring of ») et les faux amis. Deuxième passage, avec « français » comme langue maternelle : l'écart disparaît. Haiku sait quels calques chercher, même sans réfléchir. J'ai aussi essayé une règle de plus dans la consigne, exemples de calques à l'appui : rien gagné en low, et des faux positifs en plus. Je garde low, et la langue maternelle fait le reste.
Ce que coûte un message
Chaque relecture envoie à Haiku environ 250 tokens de consigne, 450 pour le fichier de progression, plus le message lui-même, et reçoit au plus 600 tokens de réponse, réflexion en plus. Le tout est décompté de votre quota, comme n'importe quel appel.
Et Sonnet ?
La mise à jour du fichier de progression prend de 6 à 7 secondes dans mes essais, selon le nombre de corrections à relire. Personne ne les voit passer : elle tourne en arrière-plan, au démarrage d'une session, et seulement quand dix messages au moins ont été relus.
low, et ce qui le corrigeait : une information, pas une consigne.Construire le vôtre : les briques à retenir
English coach tient en quelques fichiers, à lire sur GitHub. Ce qui se réutilise, ce n'est pas le code d'un coach d'anglais, mais trois briques et une boucle de développement.
Le travail de fond : $.clock.after(0, …)
On l'a vu plus haut : c'est ce qui permet de lancer un appel long sans retarder l'événement ni le voir s'arrêter avec le hook. Un détail en plus : une erreur dans ce callback ne remonte nulle part. Attrapez-la, écrivez-la avec $.ui.log (une ligne grisée dans le transcript, que Claude ne reçoit pas) et effacez le bandeau, sinon il reste bloqué sur checking your message….
$.clock.after(0, () =>
coach($, id, words, progress, text).catch(async error => {
$.ui.log(`english-coach: the check failed: ${String(error)}`)
await update($, check, current => (current?.id === id ? null : current))
}),
)
Travail de fond hors du hook — l'erreur s'affiche dans le transcript et le bandeau s'efface
L'affichage : un atome et un garde-fou
Un atome déclare un état partagé entre les hooks du mod. L'interface qui le lit se redessine quand il change :
const check = atom(
{ plugin: 'english-coach', key: 'check' } as const,
null as { id: number; tips: Tip[] | null } | null,
)
await update($, check, current =>
current?.id === id ? { id, tips } : current,
)
Atome d'état du bandeau — la mise à jour ignore la réponse d'un message plus ancien
La mise à jour compare l'id avant d'écrire. C'est ce qui empêche une réponse lente d'écraser celle d'un message plus récent. Dès qu'un travail de fond écrit dans l'interface, ce garde-fou est indispensable.
La mémoire : le store
L'atome vit le temps de la session, $.store survit. Rangez-y ce que vous voudrez agréger plus tard, avec une clé par session pour ne jamais réécrire l'historique d'une autre.
claude --plugin-dir sous le même nom partagent le même store. Pratique pour tester, piégeux quand on retrouve ses données de test dans ses statistiques. La version installée depuis une marketplace a le sien.La boucle de développement
Trois commandes suffisent :
claude --plugin-dir ./mon-modcharge votre copie locale à la place de la version installée ;claude plugin validate ./mon-modvérifie le module sans l'exécuter ;claude plugin test ./mon-modlance les tests écrits avecclaude-code/testing, où chaque appel$se remplace par une réponse choisie.
Le validateur est strict, et c'est tant mieux. Voici les règles qu'il m'a rappelées :
- un seul module de hooks par plugin ;
- un même événement deux fois, seulement avec un filtre :
on('ui.render', { component: 'AbovePrompt' }, …); - pas de spread dans les arguments de
on(): le validateur doit pouvoir lire chaque hook ; - l'état écrit par le mod doit être déclaré dans ses types.
Au-delà de l'anglais : le même schéma pour d'autres coachs
Retirez l'anglais d'English coach, il reste un schéma en trois temps :
- un hook observe la session : un message, une commande, une réponse ;
- un modèle rapide le commente en arrière-plan, pendant que l'agent travaille ;
- un modèle plus fort tient un profil à jour, de temps en temps, là où la vitesse ne compte pas.
Le contexte de l'agent n'est jamais touché. Seul change ce que le coach regarde, et ce qu'il en dit.
Un coach de prompting
Le plus proche d'English coach : même hook prompt.submit, autre consigne. Au lieu des fautes d'anglais, le modèle relève ce qui manque au prompt : un critère de réussite, un fichier de référence, une contrainte implicite. Le profil garde vos oublis récurrents. Si vous lancez toujours vos demandes sans dire comment vérifier le résultat, le coach finira par vous le rappeler à chaque fois.
Un coach de commandes
L'agent lance des dizaines de commandes par session, et on les regarde défiler sans toujours les comprendre. Avec tool.call, filtré sur l'outil Bash, un modèle rapide peut expliquer chaque commande en une ligne dans le bandeau. Le profil retient celles que vous connaissez déjà, pour ne plus vous les expliquer. Le temps mort devient une leçon de shell, de git ou de kubectl, sur les commandes de votre propre projet.
Un œil sur la sécurité
Même hook, autre question : cette commande est-elle risquée ? Suppression récursive, secret en clair, curl | sh... Le coach vous signale ce qui mérite un second regard : il prévient, il ne bloque pas.
Conclusion
L'attente fait désormais partie du travail avec un agent. On peut la subir, ou en faire un moment utile. English coach me fait pratiquer l'anglais tous les jours sans que j'y pense : sur mes propres phrases, avec mes propres erreurs, sans rien coûter au contexte de Claude.
Les mods rendent ce genre d'outil accessible : trois briques et un validateur strict. Le plus dur n'est pas de l'écrire, c'est de trouver ce qu'on veut apprendre pendant que l'agent travaille.
🎉 Et vous, quel coach écririez-vous ?