Écrit
Faire agir Grok : notes d'un correctif système en production
12 juin 2026 · IA agentique
À 23 h, j’auditais une fuite de tokens sur un déploiement client. J’ai confié la tâche à Grok, dans une boucle Hermes Agent.
Il a narré pendant dix minutes.
« Je vais maintenant vérifier les logs. » Il n’a pas vérifié les logs. « Examinons la configuration du cron. » Aucun appel d’outil. Je l’ai corrigé trois fois. Sa proposition finale : un cron budget_guard toutes les 3 minutes — une solution consommatrice de tokens à un problème de consommation de tokens.
Je suis ergonome cognitif ; j’ai écrit ailleurs pourquoi ce mode d’échec est un gouffre d’exécution (Norman, 1986) : l’opérateur formule l’intention mais ne franchit jamais le pont vers l’action. Cette note raconte ce qui s’est passé quand j’ai arrêté de décrire le problème pour le corriger — et ce que je peux, ou non, affirmer de ce correctif.
Le correctif
GROK_EXECUTION_GUIDANCE est un bloc système balisé XML qui interdit les phrases d’intention et force le comportement outil-d’abord. Sa forme (désormais upstream dans le prompt builder de hermes-agent, comme guidance d’enforcement d’outils) :
<tool_persistence>
- Use tools whenever they improve correctness, completeness, or grounding.
- Do not stop early when another tool call would materially improve the result.
- If a tool returns empty or partial results, retry with a different query or
strategy before giving up.
- Keep calling tools until: (1) the task is complete, AND (2) you have verified
the result.
</tool_persistence>
<mandatory_tool_use>
NEVER answer these from memory or mental computation — ALWAYS use a tool:
- Arithmetic, math, calculations → terminal or execute_code
- Hashes, encodings, checksums → terminal
- Current time, date, timezone → terminal
- System state: OS, CPU, memory, disk, ports, processes → terminal
- File contents, sizes, line counts → read_file, search_files, or terminal
- Git history, branches, diffs → terminal
- Current facts (weather, news, versions) → web_search
</mandatory_tool_use>
Le principe est plus vieux que les LLM : ne pas laisser l’opérateur se fier à sa mémoire de travail quand l’état réel du système est à une observation de distance (Reason, 1990 — erreurs basées sur les règles ; Baddeley, 1986 — limites de la mémoire de travail).
Ce que j’ai mesuré
Même tâche, même session, même modèle, avec le bloc injecté :
| Mesure | Avant | Après |
|---|---|---|
| Temps jusqu’au correctif | ~10 min de planification narrée | 33,9 s |
| Corrections utilisateur | 3 | 0 |
| Appels API | nombreux (boucle de narration) | 2 |
Un cas. Pas un benchmark — une reproduction.
Deux mesures au niveau du corpus situent l’enjeu au-delà d’une session :
- Taux de « texte + appels d’outils dans le même tour » sur mon corpus de sessions : Claude ~20,7 %, Grok ~6,9 %. Grok rend du raisonnement pur là où Claude enchaîne lire → exécuter → patcher dans une seule réponse.
- Le bloc a depuis tourné dans 47 sessions, avec 124 tests passants dans le harnais qui l’entoure.
Corpus : 150+ sessions, 12+ instances Hermes Agent gérées (avril 2026), capture métadonnées uniquement, aucun contenu client.
L’A/B que j’ai conçu — et le run que j’ai refusé de compter
Une reproduction plus des corrélations de corpus, ce n’est pas une preuve causale. J’ai donc monté un A/B apparié sur le runtime courant :
| Condition | Bloc prompt | Garde runtime sur les claims |
|---|---|---|
| C0_current_stock | non | non |
| G1_prompt_caed | oui | non |
Même point d’entrée, même modèle et même niveau de raisonnement, 2 conditions × 14 cas × 3 répétitions = 84 tentatives.
Le premier lancement a produit 42 tentatives toutes échouées en hermes_session_not_found — une régression du harnais, pas un comportement du modèle. Ce run est marqué invalide dans mes notes avec cette phrase : « ne doit pas être interprété comme un comportement du modèle ». Si vous avez déjà lu un papier de benchmark en vous demandant combien de runs invalides sont silencieusement devenus des points de données : voilà comment ça arrive — l’échec ressemblait superficiellement à un timeout du modèle.
Le run apparié corrigé est documenté et lancé ; les deltas consolidés ne sont pas encore publics. La hiérarchie honnête des claims, aujourd’hui :
- Prouvé : une reproduction avant/après (33,9 s, 0 correction) avec le bloc exact publié ci-dessus.
- Mesuré : l’écart de feedforward au niveau corpus (20,7 % vs 6,9 %) et 124 tests passants autour du bloc.
- Conçu, pas encore revendicable : le delta causal de l’A/B. Quand il arrivera, il arrivera avec les chiffres — pas avant.
Cet ordre est toute la discipline : affirmation finale ≤ preuve observable.
Là où ça ne marche pas
Le bloc corrige le gouffre d’exécution. Il ne corrige pas :
- Les blocages en réponse vide — Grok émettant des tokens de raisonnement sans aucun texte. Il faut une détection runtime et une relance one-shot, pas du texte de prompt.
- Les erreurs de poursuite de plan — rejouer exactement le même appel échoué. Forcer l’usage d’outils n’enseigne pas l’adaptation ; ça peut faire le même mauvais appel, plus vite.
- Le sur-outillage — l’usage obligatoire d’outils fait passer par le terminal une arithmétique qu’un humain ferait de tête. Sur les requêtes triviales, ça coûte de la latence et des tokens. Le bon arbitrage en boucle de production, le mauvais en chat.
Trace upstream
Tout est vérifiable sans me croire sur parole :
- Enforcement d’outils pour Grok : proposé dans #5531, adopté et mergé par le mainteneur de hermes-agent dans #5595 (« Closes #5531 »).
- Prompt caching xAI : proposé dans #5548, cherry-pické upstream dans #5604 — le corps de la PR crédite « Cherry-picked from #5548 by @Julientalbot ».
- Le format dans lequel ces observations se réduisent : la spec eval-case v1 et un cas réduit complet.
L’échec n’est pas dans le code. Il est dans la cognition — et le correctif se mesure.
— Julien Talbot
Cette analyse vient de l’observatoire terrain — cas rejouables, oracles et familles d’échec documentés sur Labs.