Skip to main content
Chaque réponse LLM comporte un objet usage qui indique les tokens consommés par la requête. Sunra rapporte l’utilisation selon la sémantique de l’endpoint que vous avez appelé : une réponse Messages suit le contrat Anthropic, et une réponse Chat Completions ou Responses suit le contrat OpenAI. Ces structures diffèrent, délibérément. Un SDK OpenAI qui lit une réponse Chat Completions suppose une sémantique OpenAI, et un SDK Anthropic qui lit une réponse Messages suppose une sémantique Anthropic. Chaque endpoint respecte ce que sa propre spécification promet plutôt que d’être forcé dans une structure unique et partagée.
/v1/messages et /v1/responses utilisent tous deux le nom de champ input_tokens, et il ne signifie pas la même chose dans les deux cas. Sur Messages, il s’agit uniquement de l’entrée fraîche. Sur Responses, il s’agit de l’intégralité du prompt, tokens en cache inclus.

Messages

Sur /v1/messages, les trois buckets d’entrée sont mutuellement exclusifs. Aucun token n’est compté deux fois, le total du prompt est donc leur somme :
integer
Uniquement les tokens d’entrée frais. Exclut les deux buckets de cache.
integer
Tokens écrits dans le cache par cette requête.
integer
Tokens servis à cette requête depuis le cache.
integer
Tokens générés par le modèle.
integer
Les trois buckets d’entrée plus output_tokens. Présent sur les réponses non-streaming.
Un bucket absent ou null compte pour zéro.

Exemple détaillé

Le même préfixe de 19 000 tokens envoyé deux fois vers claude-opus-4-8. La première requête écrit le cache ; la seconde le lit.
Requête à froid (écriture dans le cache)
Requête à chaud (lecture depuis le cache)
input_tokens reste à 8 pour les deux requêtes, car 8 correspond à l’entrée réellement nouvelle à chaque fois. Le préfixe de 19 349 tokens passe du bucket de création au bucket de lecture. Les deux requêtes totalisent les mêmes 19 359 tokens mais ne coûtent pas la même chose : les écritures de cache et les lectures de cache sont facturées à leurs propres tarifs par token, ce qui explique qu’elles soient rapportées comme des buckets distincts.

Chat Completions et Responses

Ces endpoints rapportent la sémantique OpenAI, inchangée. Le comptage du prompt correspond au prompt entier, et les tokens en cache en sont un sous-ensemble rapporté séparément.
/v1/chat/completions
Additionner prompt_tokens et cached_tokens revient à compter deux fois. Pour obtenir l’entrée fraîche sur ces endpoints, soustrayez :
La même règle s’applique à /v1/responses avec input_tokens et input_tokens_details.cached_tokens.

Le marqueur sunra_usage_semantics

Les réponses que Sunra a normalisées portent un marqueur à l’intérieur de usage :
Le marqueur est une promesse portant sur la réponse, et non sur un événement ou un champ particulier. Sur une réponse sans streaming, il apparaît dans l’objet usage racine ; sur une réponse en streaming, il apparaît dans message_start, l’événement qui porte les buckets d’entrée. Lorsqu’il est présent avec cette valeur, les garanties de cette page s’appliquent : les trois buckets d’entrée sont mutuellement exclusifs, et total_tokens — lorsqu’il est présent — est leur somme plus output_tokens. Son absence est également une promesse. Sunra ne normalise que les structures de réponse qu’il a mesurées. Tout le reste est transmis tel quel depuis le fournisseur en amont et laissé sans marqueur, et une réponse sans le marqueur est une réponse pour laquelle Sunra ne se porte pas garant des buckets. Appuyez-vous sur le marqueur plutôt que d’inspecter les nombres pour deviner quelle convention suit une réponse. La détection par la forme est précisément ce que ce champ existe pour remplacer — une heuristique telle que « les buckets doivent être exclusifs puisque leur somme dépasse le comptage du prompt » est satisfaite par plus d’une convention et finira par lire une réponse de travers.
Seules les réponses de /v1/messages portent le marqueur. Chat Completions et Responses suivent la spécification OpenAI et ne sont pas marquées. La valeur est versionnée. Un changement cassant de la signification de ces champs est livré sous une nouvelle valeur, de sorte qu’un test d’égalité avec anthropic.exclusive.v1 ne se mettra pas silencieusement à lire un contrat différent.

Streaming

Sur une requête Messages en streaming, l’utilisation arrive à travers deux événements. message_start porte le côté entrée et le marqueur. Le message_delta terminal ne porte que output_tokens. Appuyez-vous sur le marqueur de message_start, puis fusionnez les deux événements comme d’habitude — appliquer l’utilisation de l’événement le plus tardif par-dessus celle du plus ancien — pour obtenir les valeurs documentées ci-dessus. total_tokens est omis des réponses en streaming. Aucun événement isolé ne connaît à la fois le côté entrée et le côté sortie, donc tout total calculé en cours de stream serait faux. Additionnez vous-même les buckets une fois le stream terminé.

Migration depuis le comportement précédent

Sunra transmettait auparavant tel quel l’objet usage en amont sur /v1/messages. La couche de traduction placée devant certains fournisseurs replie les tokens de création de cache dans input_tokens, de sorte qu’un appelant qui suivait le contrat Anthropic et additionnait les trois buckets comptait deux fois les tokens de création de cache.
  • Si vous additionnez les trois buckets, comme le décrit le contrat Anthropic, vous êtes désormais dans le vrai. Aucun changement n’est requis de votre côté.
  • Si vous compensiez l’ancien comportement — en soustrayant vous-même cache_creation_input_tokens de input_tokens, ou en rétro-concevant le repli d’une autre manière — arrêtez. Cette correction soustrait maintenant des tokens qui étaient déjà exclus et sous-estimera votre entrée.
  • Si vous lisez total_tokens, il continue de rapporter le compte complet : l’entrée fraîche, les deux buckets de cache et la sortie.
Conditionnez le changement au marqueur plutôt qu’à une date de déploiement, afin que le même chemin de code soit correct aussi bien face aux réponses marquées que non marquées.