Routage multi-modèle pour agents de codage : guide
Le routage multi-modèle invalide le prompt cache et augmente vos coûts. Découvrez quand épingler un modèle par session et calculez le seuil de rentabilité réel de vos agents.
L'impact du routage multi-modèle sur un agent de codage
Le routage multi-modèle envoie chaque requête vers le modèle le moins coûteux capable de la traiter. Cela fonctionne bien pour le trafic de chat. Pour un agent de codage, cela coûte généralement plus cher que cela ne permet d'économiser, car la facture d'un agent est dominée par un préfixe de prompt mis en cache par modèle, et le changement de modèle invalide ce cache.
La règle défendue dans cet article est la suivante : routez entre les fournisseurs pour la disponibilité, routez entre les niveaux de performance pour le coût uniquement aux limites des tâches, et fixez un seul modèle par session pour tout ce qui est agentique. Tout ce qui suit détaille ce raisonnement.
Quatre termes, définis une fois. Un router choisit un modèle par requête. Une gateway est le proxy par lequel passe la requête, qui peut ou non effectuer un routage. Un prompt cache est le fournisseur qui stocke le préfixe traité de votre prompt, de sorte qu'une requête ultérieure répétant ce préfixe soit facturée à une fraction du prix d'entrée. Un KV cache (key value cache) repose sur le même principe au sein d'un serveur que vous gérez vous-même.
Pourquoi le trafic de chat est bien routé alors que celui des agents ne l'est pas
Une requête de chat est un échange unique. Elle arrive, elle est classifiée, elle est traitée par un modèle, puis elle renvoie une réponse. Aucune donnée n'est conservée pour la requête suivante. Un routeur peut envoyer cette question à un petit modèle et la suivante à un modèle plus large, sans que les deux requêtes ne soient conscientes de l'existence de l'autre. C'est la charge de travail que mesurent presque tous les benchmarks de routage, et les bons routeurs y excellent réellement.
Un tour d'agent ne se limite pas à une seule requête. Une instruction telle que « corrige le test en échec » se transforme en vingt à soixante appels API. Chaque appel renvoie l'intégralité de la conversation : le system prompt, chaque définition d'outil, chaque fichier lu par l'agent, chaque sortie de commande observée. Le contexte ne fait que croître. Au trentième appel, le préfixe répété peut atteindre des dizaines de milliers de tokens, alors que le contenu réellement nouveau dans chaque appel ne représente que quelques centaines de tokens.
Cette structure modifie la définition du terme « coûteux ». Dans le chat, le coût correspond approximativement au prix du modèle multiplié par la requête. Dans une boucle d'agent, le coût est celui du préfixe, refacturé à chaque appel individuel. La suite de cet article découle de ce seul fait.
Le cache de prompt est spécifique à chaque modèle, et l'agent réside à l'intérieur
Anthropic facture une lecture de cache à 0,1 fois le prix d'entrée de base, et une écriture de cache de cinq minutes à 1,25 fois. Il s'agit des prix catalogue publiés, en date d'août 2026.
The data behind this chart
[
{
"label": "Opus 5",
"uncached_input_usd": "5.00",
"cache_read_usd": "0.50"
},
{
"label": "Sonnet 5",
"uncached_input_usd": "2.00",
"cache_read_usd": "0.20"
},
{
"label": "Haiku 4.5",
"uncached_input_usd": "1.00",
"cache_read_usd": "0.10"
}
]Comparez la deuxième série à la première, en lisant les lignes plutôt que les colonnes. Une lecture de cache sur Opus 5 coûte 0.50 dollars par million de tokens. Une entrée non mise en cache sur Haiku 4.5, le modèle le moins cher listé, coûte 1.00 dollars. Ainsi, relire un préfixe chaud sur le modèle le plus coûteux revient moins cher par token d'entrée que de lire ce même préfixe à froid sur le modèle le moins cher.
Cette simple comparaison invalide la plupart des stratégies de routage. Un routeur qui déplace une tâche vers une gamme inférieure compare les prix catalogue. Mais un agent en pleine session ne paie pas le prix catalogue du modèle qu'il utilise déjà. Il paie le prix de lecture du cache, qui est déjà inférieur au tarif non mis en cache du modèle économique.
Les caches sont indexés par un hash du préfixe du prompt, et ils sont spécifiques à chaque modèle. Une requête vers un modèle différent est comparée à un stockage qui ne l'a jamais vue ; elle ne trouve donc rien et paie le prix fort. Le cache est également hiérarchique : les outils d'abord, puis le système, puis les messages. Une modification à n'importe quel niveau invalide ce niveau et tout ce qui suit, ce qui signifie que la modification d'une définition d'outil rejette le cache du prompt système situé derrière. Les agents qui enregistrent des outils à l'exécution sont confrontés à ce problème sans même solliciter un routeur.
Le coût réel d'un changement de modèle en cours de session
Prenons une session avec un préfixe stable de 40 000 tokens, une taille courante une fois qu'un agent a lu quelques fichiers. Ci-dessous, le coût du préfixe pour un seul tour, calculé à partir des prix catalogue ci-dessus.
The data behind this chart
[
{
"label": "Opus 5, cache warm",
"prefix_cost_usd": "0.020"
},
{
"label": "Sonnet 5, turn after switch",
"prefix_cost_usd": "0.100"
},
{
"label": "Opus 5, cache re-warmed",
"prefix_cost_usd": "0.250"
}
]Rester sur Opus 5 avec un cache chaud coûte 0.020 dollars pour le préfixe de ce tour. Le premier tour après une redirection vers Sonnet 5 coûte 0.100 dollars, car Sonnet ne possède aucune entrée pour ce préfixe et doit en écrire une. Revenir sur Opus 5 coûte 0.250 dollars, car l'entrée originale a expiré pendant que la session était ailleurs.
Ainsi, l'aller-retour entraîne deux écritures en cache pour éviter deux lectures en cache. En contrepartie, le changement a permis d'obtenir un tour de sortie au prix de Sonnet au lieu de celui d'Opus. Le bloc de détails détaille l'intégralité du trajet : l'économie se chiffre en fractions de centime, tandis que la pénalité liée au cache se chiffre en dizaines de centimes. La pénalité est supérieure d'un ordre de grandeur, et elle augmente avec la longueur du préfixe, contrairement à l'économie.
Comment ces chiffres sont calculés
Chaque nombre ici est le résultat d'un calcul arithmétique basé sur les prix catalogue publiés dans le premier tableau. Il s'agit d'un modèle de coût plutôt que d'un benchmark, et aucune requête n'a été envoyée pour le produire. Modifiez la taille du préfixe et le ratio changera en conséquence.
Préfixe : 40 000 tokens, maintenus constants tout au long du tour.
Opus 5, warm read 40,000 x $0.50 / 1e6 = $0.020
Sonnet 5, cache write 40,000 x $2.50 / 1e6 = $0.100 (1.25 x $2 base)
Opus 5, cache write 40,000 x $6.25 / 1e6 = $0.250 (1.25 x $5 base)Aller-retour : 0,100 $ + 0,250 $ = 0,350 $. Les deux tours sur Opus avec cache chaud qu'il a remplacés : 0,040 $. Coût supplémentaire du détour : 0,310 $.
L'économie, sur un tour de 800 tokens de sortie, correspond à l'écart de prix de sortie entre Opus 5 à 25 $ par million et Sonnet 5 à 10 $ par million :
800 x ($25 - $10) / 1e6 = $0.012Dépenser 0,310 $ pour économiser 0,012 $ est environ vingt-cinq fois moins rentable. L'économie est proportionnelle aux tokens de sortie, qui sont peu nombreux et relativement fixes par tour. La pénalité est proportionnelle à la taille du préfixe, qui augmente tout au long de la session. Des sessions plus longues aggravent la situation, sans jamais l'améliorer.
Les formats d'appel d'outils diffèrent selon les fournisseurs
Un agent est une boucle d'appel d'outils ; le format d'appel d'outil est donc crucial, contrairement à une discussion classique. L'API Messages d'Anthropic renvoie un bloc de contenu tool_use et attend un bloc tool_result en retour. Les API compatibles OpenAI renvoient un tableau tool_calls dans lequel function.arguments est une chaîne encodée en JSON plutôt qu'un objet imbriqué. Une passerelle assure la traduction entre les deux, et pour les appels ordinaires, la conversion est propre.
Les problèmes apparaissent aux limites. Les appels d'outils parallèles, où un modèle émet plusieurs appels dans une seule réponse, sont représentés différemment et ne sont pas supportés de manière identique partout. L'application stricte d'un schéma est une fonctionnalité propre à chaque fournisseur ; un modèle qui garantit des arguments conformes au schéma sur un point de terminaison ne tend qu'à produire des arguments valides sur un autre. L'agent perçoit cette différence comme un résultat d'outil contenant une erreur d'analyse, qu'il tente ensuite de corriger en utilisant un tour supplémentaire. Ces tours de correction sont facturés au prix total du préfixe ; une incompatibilité de format se répercute donc sur la facture autant que dans la transcription.
Les points de terminaison auto-hébergés nécessitent une configuration explicite. Le serveur compatible OpenAI de vLLM requiert --enable-auto-tool-choice ainsi qu'un --tool-call-parser adapté à la famille du modèle (hermes, mistral, llama3_json et autres), en plus d'un modèle de chat (chat template) gérant les messages avec un rôle d'outil. La documentation de vLLM est directe sur les limites de cette approche : avec tool_choice="auto" et sans contrainte stricte de schéma, vLLM extrait les appels d'outils à partir de texte brut ; les arguments peuvent donc parfois être mal formés ou violer le schéma des paramètres de la fonction. Choisir le mauvais analyseur pour votre modèle est une erreur de configuration qui se manifeste par un agent incapable d'appeler des outils, ce qu'il est utile de savoir avant d'y acheminer du trafic. La différence entre Ollama et vLLM pour l'auto-hébergement de modèles est importante ici, car les deux exposent l'appel d'outils selon des modalités différentes.
Un repli en cours de tâche modifie le comportement sans erreur
Le routage de repli (fallback) est la fonctionnalité la plus susceptible d'être activée par accident. Une passerelle est configurée pour réessayer sur un autre modèle lorsque le premier renvoie une limite de débit ou une erreur 5xx, puis place le modèle défaillant en période de refroidissement pendant quelques secondes. Pour du trafic de chat, c'est exactement ce qu'il faut. Au sein d'une tâche d'agent longue, cela signifie que la seconde moitié de votre tâche a été exécutée par un modèle que vous n'aviez pas choisi.
Rien ne signale ce changement. La tâche ne tombe pas en échec, l'agent n'émet aucun avertissement et le code de sortie indique un succès. Vous obtenez une tâche dont le plan a été rédigé par un modèle et les modifications effectuées par un autre, avec un ton et des habitudes qui changent en cours de route. Le seul signal fiable est le champ model dans le journal des requêtes de la passerelle ou dans les métadonnées de réponse. Si vous utilisez des replis, journalisez ce champ pour chaque requête et consultez-le lorsqu'un résultat vous surprend. Déboguer un comportement sans savoir quel modèle l'a produit fait perdre plus de temps que le repli n'en a fait gagner.
Le même piège s'applique à la compression de contexte. De nombreux agents résument un historique long en appelant un petit modèle. Si cet appel utilise un modèle différent ou un prompt système différent, il écrit sa propre entrée de cache et ne rafraîchit pas celle de la session principale. Le tour complet suivant subit donc un préfixe froid. La compression a économisé des tokens mais a perdu le cache.
La surcharge de routage est réelle, mais ce n'est pas là que la latence pose problème
Les routeurs ajoutent effectivement du travail par requête, et il est utile d'être précis sur l'ampleur de ce travail. DigitalOcean indique que leur modèle Arch-Router résout l'intention de routage en environ 51 millisecondes, avec une précision de routage de 93,17 % selon leur propre évaluation. Ce sont leurs chiffres, issus de leurs mesures et de leur benchmark, pas les nôtres ni un résultat universel. Prenez-les tels quels et la conclusion est rassurante : 51 millisecondes sur quarante appels d'agents représentent environ deux secondes ajoutées à une tâche qui dure plusieurs minutes.
Ce ne sont pas ces deux secondes qui rendent le routage coûteux ici. La surcharge qui pose problème est celle d'un routeur qui classifie via un appel complet au modèle, car il s'agit d'une seconde inférence à chaque requête, facturée et mise en file d'attente comme n'importe quelle autre. En dessous des deux, on retrouve l'arithmétique de cache mentionnée plus haut, qui n'est pas une surcharge. C'est le coût de l'élément que le routage était censé optimiser.
Sur un serveur que vous gérez vous-même, la même règle s'applique avec moins de marge de manœuvre. L'équivalent local du cache de prompt est la mise en cache de préfixe dans le KV cache, qui réside dans la mémoire GPU. Héberger deux modèles sur un seul GPU divise cette mémoire entre eux, de sorte que chacun conserve un KV cache plus petit et évince les préfixes plus rapidement. Le routage entre deux modèles locaux peut donc réduire le taux de succès du cache pour les deux simultanément. Si vous dimensionnez le matériel pour cela, le guide sur la mémoire et le CPU dont un agent de codage a réellement besoin sur un VPS est un point de départ plus utile qu'un routeur.
La règle de décision
- Routez entre les fournisseurs pour la disponibilité. Quand l'alternative est une requête en échec, n'importe quel coût est justifié. Fixez le repli sur un modèle utilisant le même format d'appel d'outil afin que la boucle de l'agent reste fonctionnelle, et journalisez quel modèle a traité chaque appel.
- Routez entre les niveaux de performance pour le coût uniquement aux limites des tâches. Choisir Haiku pour renommer un fichier et Opus pour une refactorisation est une décision pertinente prise une fois, avant le début de la session. C'est une mauvaise décision si elle est prise au trentième tour de cette même session.
- Fixez un modèle par session pour tout ce qui est agentique. La valeur d'une session réside dans son cache chaud. Considérez le changement de modèle comme vous considéreriez la purge de ce cache, car c'est exactement ce qui se produit.
- Routez librement les sous-agents. Un sous-agent qui démarre avec un contexte restreint et vierge n'a pas de cache chaud à perdre ; il peut donc s'exécuter sur le modèle le mieux adapté à sa tâche. C'est le seul endroit au sein d'un agent où le routage est quasiment gratuit.
Pour mettre cela en œuvre, la passerelle effectue le travail : alias de modèles et listes de repli explicites. Une configuration minimale de proxy LiteLLM ressemble à ceci.
model_list:
- model_name: agent-primary
litellm_params:
model: anthropic/claude-opus-5
api_key: os.environ/ANTHROPIC_API_KEY
- model_name: agent-standby
litellm_params:
model: anthropic/claude-sonnet-5
api_key: os.environ/ANTHROPIC_API_KEY
router_settings:
fallbacks: [{"agent-primary": ["agent-standby"]}]
num_retries: 2
cooldown_time: 30Pointez l'agent vers agent-primary et il restera sur un modèle jusqu'à ce que celui-ci soit injoignable. Les deux entrées se trouvent chez le même fournisseur, donc le format d'appel d'outil ne change pas lors du déclenchement du repli. Vous acceptez tout de même un changement de niveau à ce moment-là, ce qui est un compromis acceptable uniquement parce que l'alternative est l'échec de la requête. Il s'agit d'un routage de disponibilité sans routage de coût associé, ce qui constitue la combinaison recherchée par la plupart des agents de développement. La configuration complète, incluant les clés et les budgets, est traitée dans l'exécution d'une passerelle LiteLLM auto-hébergée sur votre propre VPS, et cet article ne la répète volontairement pas.
Quand un modèle bien choisi surpasse n'importe quel routeur
Le routage est une solution à la variance de difficulté des requêtes. Un agent de codage présente moins de variance qu'il n'y paraît, car la partie coûteuse de chaque appel est le même préfixe, quelle que soit la demande. Une fois que le préfixe domine, la différence entre votre niveau de service économique et votre niveau coûteux se réduit à la différence de leurs prix de sortie, et la sortie ne représente qu'une faible part des tokens d'un agent.
Par conséquent, l'approche par défaut la plus honnête consiste à utiliser un seul modèle, choisi une fois, avec la mise en cache activée et un TTL (durée de vie) suffisamment long pour couvrir les pauses lorsque vous vous arrêtez pour lire un diff. Anthropic propose une écriture en cache d'une heure à 2 fois le prix de l'entrée de base, ce qui est rentabilisé après deux lectures ; c'est souvent un levier plus efficace que n'importe quel routeur. Choisissez délibérément votre niveau de service en utilisant une comparaison directe entre Opus, Sonnet et Haiku, et si la facture reste le problème, réduisez-la avec des budgets et des contextes plus restreints comme indiqué dans le contrôle des coûts des agents IA sur un VPS plutôt qu'avec des changements de modèle en cours de session.
Utilisez le routage lorsque les requêtes sont indépendantes et courtes, ou lorsque les sous-agents démarrent avec de nouveaux contextes. Fixez le modèle lorsque vous avez une longue session effectuant une seule tâche. La majeure partie du travail d'un agent de codage relève du second cas, c'est pourquoi le routeur qui permet d'économiser de l'argent sur votre produit de chat vous en fera perdre ici. Si vous n'avez pas encore arrêté votre choix sur l'agent lui-même, la comparaison de Claude Code face à Cursor, Codex et Copilot détaille la manière dont chacun gère la sélection du modèle, certains prenant même cette décision à votre place.
FAQ
Changer de modèle en cours de session entraîne-t-il réellement la perte du cache de prompt ?
Oui. Les caches de prompt sont indexés par un hash du préfixe du prompt et sont stockés par modèle. Une requête envoyée à un modèle différent est comparée à un stockage qui n'a jamais vu ce préfixe. Il ne trouve rien et paie le prix total de l'entrée non mise en cache, puis paie une écriture en cache si celle-ci est activée. Revenir au modèle précédent ne permet pas non plus de récupérer l'entrée initiale, car la durée de vie par défaut de cinq minutes est généralement expirée à ce moment-là. Vérifiez les champs cache_read_input_tokens et cache_creation_input_tokens dans l'objet d'utilisation de la réponse : un tour qui lit zéro jeton mis en cache sur une longue session en est le symptôme.
Le routage vers un modèle moins coûteux est-il toujours avantageux pour un agent ?
Uniquement lorsqu'il n'y a pas de cache chaud à perdre. Une lecture en cache chez Anthropic coûte 0,1 fois l'entrée de base, ce qui rend une lecture chaude sur Opus 5 moins chère que le tarif d'entrée non mis en cache sur Haiku 4,5. Dès qu'une session possède un large préfixe mis en cache, le modèle en place est déjà l'option la moins chère en entrée. Le routage est rentable lorsque le contexte est frais et réduit : au début d'une tâche, ou dans un sous-agent qui ne transporte que le contexte dont il a besoin.
Pourquoi mon agent s'est-il comporté différemment au milieu d'une tâche ?
Vérifiez si un repli (fallback) de passerelle s'est déclenché. Une limite de débit ou une erreur 5xx sur le modèle principal force la passerelle à réessayer sur le modèle de secours et à placer le modèle principal en période de refroidissement pendant quelques secondes ; le reste de la tâche s'exécute donc ailleurs. Cela ne produit ni erreur ni avertissement, et la tâche indique toujours un succès. Le champ model dans le journal des requêtes de la passerelle ou dans les métadonnées de réponse est le seul enregistrement fiable ; journalisez-le donc par requête si vous utilisez des mécanismes de repli.
Les appels d'outils fonctionnent-ils de la même manière chez tous les fournisseurs ?
Pas exactement. L'API Messages d'Anthropic utilise des blocs de contenu tool_use et tool_result, tandis que les API compatibles OpenAI utilisent un tableau tool_calls dont le function.arguments est une chaîne encodée en JSON. Une passerelle traduit bien les cas courants, mais les appels d'outils parallèles et l'application stricte des schémas diffèrent selon le fournisseur. Sur vLLM auto-hébergé, vous devez définir --enable-auto-tool-choice et un --tool-call-parser correspondant à votre famille de modèles. La documentation de vLLM précise que sans contrainte de schéma stricte, le serveur extrait les appels d'outils à partir du texte brut, ce qui peut occasionnellement entraîner des arguments mal formés.
Quelle durée de vie (TTL) de cache dois-je définir pour une session de développement ?
Utilisez la durée de vie par défaut de cinq minutes pour un travail continu, et l'option d'une heure lorsqu'un humain lit des diffs entre les tours. Anthropic facture l'écriture de cinq minutes à 1,25 fois l'entrée de base et l'écriture d'une heure à 2 fois, contre une lecture à 0,1 fois. L'écriture de cinq minutes est rentabilisée par une seule lecture, et celle d'une heure par deux. Ainsi, pour toute session où vous prévoyez de revenir et de continuer, la durée de vie la plus longue coûte généralement moins cher que de payer pour un préfixe froid.