Aller au contenu
Mohamed Tahiri
Miami --:--
← Tous les articles

Cache de prompt : l’ordre de vos messages est une décision de coût

Un agent relit tout son contexte à chaque tour. Le cache de prompt peut diviser la facture par quatre, ou l’augmenter, selon un détail de mise en page. Avec un simulateur sur dix tours de conversation.

Un agent ne se souvient de rien. À chaque tour, il relit tout : la liste de ses outils, ses instructions, les documents de référence, l’historique complet de la conversation, puis le nouveau message. Au dixième tour, il a lu dix fois le même début de prompt, et on l’a payé dix fois.

Le cache de prompt évite cette répétition. Le fournisseur garde le traitement d’un début de prompt déjà vu et le facture beaucoup moins cher la fois suivante. Chez Anthropic, relire depuis le cache coûte environ un dixième du prix normal, et même moins sur certains modèles récents. Écrire dans le cache, en revanche, coûte 25 % de plus que le prix normal.

Ce dernier chiffre est celui qu’on oublie. Il veut dire qu’un cache mal utilisé ne se contente pas de ne servir à rien : il coûte plus cher que pas de cache du tout.

Une affaire d’octets, pas de sens

Le cache ne comprend pas votre prompt, il compare des octets. Il retrouve le plus long début identique à une requête récente, et tout ce qui suit le premier octet différent est recalculé, puis réécrit. L’ordre de rendu est fixe : les outils d’abord, puis le prompt système, puis les messages.

Conséquence directe : ce qui ne change jamais doit venir en premier, ce qui change souvent à la fin. Une seule valeur qui bouge en tête de prompt invalide tout ce qui la suit. La simulation ci-dessous déroule dix tours d’une conversation avec 17 000 tokens de contexte fixe, et vous laisse commettre les trois erreurs les plus courantes.

Sans erreur, la conversation coûte environ un quart du prix sans cache. Chaque tour relit tout ce qui précède et n’écrit que le dernier échange. Sur un agent qui enchaîne des dizaines d’appels d’outils, comme celui qui fait tourner un petit commerce en ligne, c’est l’économie la plus simple à obtenir, et elle ne coûte rien en qualité : le modèle lit exactement le même texte.

Trois erreurs qui cassent tout

La date dans le prompt système

C’est la plus fréquente. On veut que l’agent connaisse la date, alors on écrit « Nous sommes le 19 octobre, il est 14 h 32 » en haut des instructions. À la minute suivante, le préfixe change juste après les outils, et tout le reste est réécrit à chaque tour. Dans la simulation, la facture passe à 111 % du prix sans cache.

La date va à la fin, dans le dernier message, et au jour près si l’heure ne sert à rien. Même chose pour le nom de l’utilisateur, son abonnement, un identifiant de requête : tout ce qui varie d’une conversation ou d’un appel à l’autre.

Des outils dans le désordre

Les outils sont rendus en premier. Si leur liste est construite à partir d’un registre de plugins, d’un ensemble ou d’une requête en base, leur ordre peut varier d’un appel à l’autre sans que personne ne s’en aperçoive. Le préfixe casse dès le premier octet, tout est réécrit à chaque tour : 125 % du prix. La correction tient en une ligne, trier les outils par nom. Même chose pour un objet JSON sérialisé sans ordre de clés stable : il change d’octets sans changer de sens.

Pour la même raison, on évite d’ajouter ou de retirer des outils en cours de conversation, et de changer de modèle : le cache est propre à chaque modèle.

La fenêtre glissante

Pour garder le contexte court, on supprime les messages les plus anciens au-delà d’une certaine taille. Raisonnable sur le papier. Mais chaque suppression décale tout l’historique : le début identique s’arrête juste avant le premier message, et l’historique entier est réécrit à chaque tour. Le coût reste contenu dans la simulation, 34 %, parce que l’essentiel du prompt est devant. Sur une longue conversation, l’historique devient vite la plus grosse part.

Mieux vaut résumer par paliers, rarement, que glisser à chaque tour. Certains fournisseurs proposent aussi une compaction côté serveur, qui résume l’historique sans casser le préfixe qui le précède.

Le temps compte aussi

Une entrée de cache vit cinq minutes par défaut chez Anthropic, et chaque lecture relance ce compteur. Une conversation active reste donc en cache indéfiniment. Mais un utilisateur qui répond après dix minutes trouve un cache vide, et son tour suivant paie l’écriture complète. Il existe une durée d’une heure, dont l’écriture coûte deux fois le prix normal : rentable seulement si les pauses de cinq minutes à une heure sont fréquentes.

Autre surprise : il y a une taille minimale. Un préfixe trop court ne se met pas en cache, sans erreur ni avertissement. Le seuil dépend du modèle, de quelques centaines à quelques milliers de tokens.

Vérifier plutôt que supposer

La réponse de l’API indique combien de tokens ont été lus depuis le cache et combien y ont été écrits. Ces deux nombres méritent d’être loggés à chaque appel. Si les lectures restent à zéro alors que le début du prompt devrait être stable, quelque chose change en douce. On compare alors deux requêtes successives, octet par octet : la première différence désigne le coupable.

agent.py
response = client.messages.create(
    model=MODEL,
    max_tokens=2048,
    # sorted, so the very first bytes of the prompt never move
    tools=sorted(tools, key=lambda t: t["name"]),
    system=[{
        "type": "text",
        "text": INSTRUCTIONS,  # frozen: no date, no user name, no request id
        "cache_control": {"type": "ephemeral"},
    }],
    # whatever varies goes last, with the new message
    messages=history + [{"role": "user", "content": f"{question}\n\nToday: {today}"}],
    cache_control={"type": "ephemeral"},  # also cache the growing conversation
)

usage = response.usage
log.info(
    "cache read=%s written=%s uncached=%s",
    usage.cache_read_input_tokens,
    usage.cache_creation_input_tokens,
    usage.input_tokens,
)

L’ordre que j’utilise

  1. Les outils, triés par nom, stables pendant toute la conversation.
  2. Les instructions système, figées : ni date, ni nom, ni identifiant.
  3. Les documents de référence qui ne changent pas.
  4. L’historique, en ajout seul.
  5. Le nouveau message, avec tout ce qui varie : date, contexte de l’utilisateur, passages récupérés pour cette question.

Ça ressemble à de la mise en page. Sur la facture, c’est un facteur quatre.

Contact

Construisons quelque chose.

Ou laissez un message