Diriger le trafic de Claude Code via des en-têtes plutôt que d’analyser la requête
Découvrez comment les en-têtes d’indication du système d’inscription volontaire de Claude Code permettent à un gateway d’LLM de prioriser, allouer des ressources et gérer les caches à partir des métadonnées de la requête, sans avoir à analyser le corps du prompt.
Lorsqu’une entreprise envoie du trafic Claude Code via une passerelle LLM, cette dernière doit prendre des décisions concernant chaque demande avant de la transmettre : le système source à utiliser, la file d’attente à rejoindre, le seuil de limitation de vitesse à appliquer et la priorité à attribuer. Jusqu’à récemment, les seules informations permettant de comprendre ces décisions se trouvaient dans le corps de la demande, c’est-à-dire vos instructions, le contenu des fichiers, les résultats des outils et CLAUDE.md. Un ensemble d’en-têtes de demande facultatifs ajoutés dans une récente version de Claude Code transfère ces informations sur l’enveloppe de la demande. Ci-dessous, vous verrez ce que chaque en-tête permet de déterminer, comment un proxy change lorsqu’il peut les utiliser, et dans quels cas vous ne devez toujours pas leur faire confiance.
Pourquoi les passerelles finissent par lire vos instructions
L’inspection du corps du message n’est pas une question théorique ; c’est ainsi que fonctionnent de nombreux routeurs aujourd’hui. Les routeurs sémantiques tels que le vLLM Semantic Router extraient la requête de l’utilisateur, l’incorporent à l’aide d’un modèle de type BERT et comparent le vecteur obtenu aux vecteurs des tâches de référence afin de classer la demande. Les routeurs optimisés pour une latence minimale peuvent déduire le nom du modèle à partir du premier kilooctet environ et transmettre le reste, mais tout routeur qui doit effectuer une classification doit mettre en mémoire tampon et inspecter l’intégralité du contenu.
Cette inspection constitue la fonctionnalité clé du produit, et elle fait également du gateway une frontière de confiance bien plus sensible que ne le suggère son nom modeste. Il voit, et peut potentiellement stocker, tout ce que l’agent d’un développeur envoie.
Claude Code 2.1.273, daté du 15 septembre 2026 dans le changelog, a ajouté cinq en-têtes destinés aux opérateurs de passerelles. Ensemble, ils constituent moins une fonctionnalité d’observabilité que les métadonnées minimales dont une passerelle a besoin pour agir en tant que planificateur sans fonctionner en tant que lecteur.
Les limites des en-têtes d’identificateurs originaux
Auparavant, dans la version 2.1.273, le guide de compatibilité pour les passerelles décrivait trois en-têtes Claude Code, tous étant des identificateurs :
+--------------------------------+---------------------------------+
| HEADER | WHAT IT IS |
+--------------------------------+---------------------------------+
| x-claude-code-session-id | which session |
| x-claude-code-agent-id | which subagent (if any) |
| x-claude-code-parent-agent-id | which agent spawned it |
+--------------------------------+---------------------------------+
|
v
good for GROUPING after the fact
useless for DECIDING before forwarding
La documentation les présente comme étant conçus pour l’agrégation : l’ID de session permet de regrouper tout ce que la session envoie sans avoir à analyser le corps des données, tandis que l’ID de l’agent, combiné à l’ID de session, permet d’attribuer un coût aux agents qui fonctionnent en parallèle. Il s’agit donc de comptabilité. Cela suffit pour un tableau de bord des coûts, mais pas pour la planification. Savoir qu’une requête provient de la session abc et de l’agent def ne dit rien sur son coût potentiel, le temps qu’elle nécessitera ou si elle peut se permettre d’attendre. Tout pare-feu souhaitant être plus intelligent qu’un simple compteur devait donc pouvoir accéder au corps des données.
Les cinq nouveaux en-têtes d’indication
D’après le changelog, la version 2.1.273 a introduit cinq en-têtes, tous activés simultanément avec CLAUDE_CODE_GATEWAY_HINT_HEADERS=1. Deux décrivent l’appelant (x-claude-code-agent-type et x-claude-code-request-class), un décrit les temps d’exécution récents (x-claude-code-prev-tool-durations), et une paire décrit les réécritures de contexte (x-claude-code-context-compacted ainsi que x-claude-code-compaction).
Une mise en garde importante : au moment de la rédaction, le tableau des en-têtes de requête dans le guide de compatibilité du gateway ne montre toujours que les trois en-têtes d’identifiant, et la variable fait défaut dans la référence aux variables d’environnement. Les noms des en-têtes proviennent du journal des modifications, mais leurs formats de valeurs ne sont pas encore documentés. Tout ce qui suit décrit ce que chaque en-tête permet au gateway de déterminer, et non un format de transmission garanti. Examinez votre propre trafic avant de vous fier à des valeurs spécifiques, et consultez la documentation actuelle, qui a pu être mise à jour.
Groupillés par la décision que chacun permet de prendre :
+---------------------------+------------------------------------------+
| HEADER | DECISION IT UNBLOCKS AT THE EDGE |
+---------------------------+------------------------------------------+
| request-class | is this a real turn, or a small |
| | internal call? -> priority, cheap pool |
+---------------------------+------------------------------------------+
| agent-type | which kind of subagent is asking |
| | -> per-agent-type budgets and quotas |
+---------------------------+------------------------------------------+
| prev-tool-durations | how long the last tools took |
| | -> timeout and retry window sizing |
+---------------------------+------------------------------------------+
| compaction | this turn IS the summarization call |
| | -> never count it as user latency |
+---------------------------+------------------------------------------+
| context-compacted | the prefix just changed under you |
| | -> do not expect a cache hit this turn |
+---------------------------+------------------------------------------+
En bref :
- request-class permet de distinguer les véritables échanges conversationnels des appels internes mineurs, afin de pouvoir donner la priorité aux premiers et envoyer les seconds vers un pool moins coûteux.
- agent-type identifie le type de sous-agent qui effectue l’appel, ce qui permet d’établir des budgets et des quotas par type d’agent.
- prev-tool-durations indique la durée des exécutions récentes des outils, ce qui aide à déterminer les délais de timeout et les fenêtres de tentative.
- compaction marque la requête qui effectue elle-même la synthèse, de sorte qu’elle ne doit jamais être prise en compte dans la latence perçue par l’utilisateur.
- context-compacted signale que le préfixe de la conversation a été réécrit, ce qui fait qu’on ne s’attend pas à un accès en cache.
Rien de tout cela n’est une information nouvelle. Un gateway pourrait déjà déduire la classe de la demande en distinguant le prompt complet du système Claude Code d’un prompt de classification simplifié, déterminer le type d’agent à partir de la section correspondante du prompt système, et repérer une compression en analysant la structure du tableau de messages. Les en-têtes ne révèlent rien d’additionnel à votre sujet. Ce qui change, c’est le coût des connaissances : au lieu d’analyser jusqu’à un mégaoctet de code source, le gateway lit une courte chaîne de caractères contenue dans les en-têtes.
Même règle de routage, avant et après
Prenons un objectif concret : diriger la synthèse en arrière-plan vers un pool moins coûteux. Sans indications supplémentaires, le proxy doit stocker temporairement et analyser la conversation, puis deviner son contenu :
// BEFORE: the router has to read the conversation to classify it
const body = await readEntireBody(req); // buffers the whole prompt
const parsed = JSON.parse(body); // your files are now in gateway memory
const sys = flattenSystemBlocks(parsed.system);
const isBackground =
sys.includes("summarize the conversation") ||
parsed.messages.length > COMPACT_THRESHOLD;
et ce n’est qu’alors qu’il envoie le corps du message stocké temporairement :
route(isBackground ? "cheap-pool" : "interactive-pool", body);
Cette approche présente trois problèmes, du moins grave au plus grave. Le stockage en mémoire tampon de tout le contenu détruit la latence de streaming. La correspondance basée sur les mots du prompt est fragile, car ces mots changent entre les différentes versions de Claude Code. Pire encore, le texte intégral de votre répertoire se trouve désormais dans la mémoire en cours d’exécution de la couche de routage, dans ses fichiers de dump mémoire et très probablement dans ses journaux, un endroit qui n’apparaît sur aucun schéma d’architecture et que personne n’a pensé à protéger.
Avec les en-têtes de suggestion, le routeur lit deux valeurs dans l’enveloppe :
// AFTER: the router decides on the envelope and never touches the body
const cls = req.headers["x-claude-code-request-class"];
const comp = req.headers["x-claude-code-compaction"];
et dirige le flux de requête inchangé. Comme l’indique le commentaire dans l’extrait, les chaînes de valeurs littérales sont à titre illustratif, car le format n’a pas encore été documenté :
// value strings below are illustrative: confirm them against your own
// traffic, since the wire format is not documented yet
const isBackground = Boolean(comp) || cls === "background";route(isBackground ? "cheap-pool" : "interactive-pool", req); // streams through
Il n’y a ni tamponnage, ni analyse JSON, ni message conservé en mémoire. Le guide de compatibilité autorise déjà ce schéma : à part anthropic-workspace-id, anthropic-beta et anthropic-version, les en-têtes sont décrits comme des données que le gateway peut utiliser pour le suivi, l’attribution ou le routage, sans qu’il soit obligé de les transmettre. Ces indications sont conçues pour rester au niveau du gateway ; comme le modèle ne les voit jamais, elles peuvent être simples et peu coûteuses.
Le couple de compactage est un signal de mise en cache
Deux de ces en-têtes semblent redondants, mais ils répondent à des questions différentes. Le premier, x-claude-code-compaction, est défini lors de l’appel qui génère le résumé. Le second, x-claude-code-context-compacted, apparaît lors des appels ultérieurs, une fois le compactage déjà effectué.
La distinction est importante lorsque l’on gère un cache. Les clés de cache pour les prompts sont des préfixes composés à partir des outils, suivis du prompt système, puis des messages ; par conséquent, toute modification près du début rend invalide tout ce qui suit. Les écritures dans le cache coûtent également plus cher que les lectures, de sorte que des écritures inutiles représentent un coût supplémentaire purement superflu. La compression est le principal facteur d’invalidation lors d’une session ordinaire : elle remplace l’historique accumulé par un résumé, ce qui crée par définition un préfixe entièrement nouveau.
turn N turn N+1 (compaction) turn N+2
+---------+ +------------------+ +------------------+
| prefix | | compaction: 1 | | context- |
| stable | --> | rewrites history | --> | compacted: 1 |
| cache | | EXPECT A MISS | | new prefix is |
| hits | | bill it as | | now the stable |
+---------+ | background | | one, re-warm it |
+------------------+ +------------------+
Un gateway qui gère sa propre mémoire cache mais ne connaît rien à la compression se comporte de la pire des manières lors du processus de compression : il effectue une recherche complète, échoue, enregistre une entrée pour un préfixe qui deviendra obsolète dès le tour suivant, puis signale une baisse du taux de réussite des recherches, ce qui est interprété comme un défaut. Grâce aux en-têtes appropriés, il peut éviter cette recherche lors de la demande de compression, traiter cet appel en tant que tâche en arrière-plan, et faire exprès de « réchauffer » le nouveau préfixe au tour suivant, lorsque celui-ci deviendra stable.
Les indications sont des affirmations du client, pas des identifiants
Tant le journal des modifications que le nom de la variable font référence à ces en-têtes d’indication, et le choix des mots est important. Une indication correspond à une affirmation non vérifiée émise par le client. La valeur de x-claude-code-request-class est celle que Claude Code choisit d’envoyer ; aucun composant intermédiaire ne la vérifie.
Supposons que votre passerelle récompense les demandes étiquetées comme en arrière-plan par des taux réduits, des quotas plus importants ou des limites de vitesse assouplies. Dans ce cas, une chaîne de caractères fournie par le client prend discrètement la décision d’autorisation. Un développeur qui modifie son environnement de shell, ou toute personne exécutant un petit proxy local devant la passerelle, peut choisir l’étiquette qui bénéficie du traitement le plus généreux. Les indications constituent de bons éléments pour la mise en file d’attente, les décisions de cache et la mesure de la latence, mais jamais pour déterminer ce à quoi un appelant a droit.
Le deuxième problème pratique concerne l’adoption de ces fonctionnalités. Les en-têtes sont désactivés sauf si leur activation est explicitement demandée, ce qui constitue le choix approprié pour les métadonnées qui révèlent la structure de la session à un intermédiaire. Compte tenu de leur absence dans les références aux variables d’environnement au moment de la rédaction, il est peu probable que de nombreuses installations les aient activés. Au sein d’une organisation, ils devront généralement être déployés via des paramètres gérés par un administrateur qui aura remarqué une seule ligne dans le journal des modifications.
Un plan de déploiement pour les opérateurs de passerelles
Si votre équipe gère une passerelle pour le trafic de Claude Code, une approche d’adoption prudente pourrait se présenter comme suit :
- Activer
CLAUDE_CODE_GATEWAY_HINT_HEADERS=1pour un petit groupe pilote. - Enregistrer les valeurs de ces cinq en-têtes pendant environ une semaine sans prendre aucune action à leur égard.
- Comparer ces valeurs aux décisions prises par votre classeur actuel de parsing du contenu.
Le résultat est un rayon d’impact nettement plus réduit : le code source de vos développeurs n’a plus besoin de passer par la mémoire de la couche de routage, et cela ne nécessite qu’une seule variable d’environnement.
Conclusion
Les en-têtes eux-mêmes sont spécifiques à Claude Code, mais la leçon de conception s’applique à toute plateforme d’agent. Toute couche placée devant un agent doit classer les requêtes avant de les transmettre, et il n’y a que deux façons de le faire : déduire la réponse à partir du payload, ou la recevoir sous forme de métadonnées explicites. La déduction fonctionne toujours, mais elle laisse systématiquement une copie de contenu sensible dans un composant qui n’avait aucune raison de le conserver. Un canal de métadonnées explicites exige plus de travail de conception au départ, mais c’est le seul arrangement permettant à l’intermédiaire d’affecter correctement les requêtes sans jamais recevoir les données elles-mêmes. Pour une vue d’ensemble plus large de ce qu’offre un gateway, consultez l’aperçu du gateway LLM dans les documents de Claude Code.