usage, сообщающий о токенах, которые израсходовал запрос. Sunra сообщает об использовании в семантике того endpoint, который вы вызвали: ответ Messages следует контракту Anthropic, а ответ Chat Completions или Responses — контракту OpenAI.
Эти структуры различаются, и это сделано намеренно. OpenAI SDK, читающий ответ Chat Completions, предполагает семантику OpenAI, а Anthropic SDK, читающий ответ Messages, предполагает семантику Anthropic. Каждый endpoint соблюдает то, что обещает его собственная спецификация, вместо того чтобы принудительно приводиться к одной общей структуре.
Messages
В/v1/messages три входные корзины взаимоисключающие. Ни один токен не учитывается дважды, поэтому итог по промпту — их сумма:
integer
Только свежие входные токены. Исключает обе корзины кэша.
integer
Токены, записанные в кэш этим запросом.
integer
Токены, переданные этому запросу из кэша.
integer
Токены, сгенерированные моделью.
integer
Три входные корзины плюс
output_tokens. Присутствует в непотоковых ответах.null считается нулём.
Разобранный пример
Один и тот же префикс в 19 000 токенов, отправленный дважды кclaude-opus-4-8. Первый запрос записывает кэш, второй — читает его.
Холодный запрос (запись в кэш)
Тёплый запрос (чтение из кэша)
input_tokens остаётся равным 8 в обоих запросах, потому что 8 — это действительно новый ввод в каждом случае. Префикс в 19 349 токенов перемещается из корзины создания в корзину чтения. Оба запроса дают в сумме одинаковые 19 359 токенов, но стоят они не одинаково: запись в кэш и чтение из кэша тарифицируются по своим собственным ставкам за токен, поэтому они и указываются как отдельные корзины.
Chat Completions и Responses
Эти endpoint сообщают семантику OpenAI без изменений. Количество токенов промпта — это весь промпт, а кэшированные токены являются его подмножеством, указываемым отдельно./v1/chat/completions
prompt_tokens и cached_tokens приводит к двойному учёту. Чтобы получить свежий ввод на этих endpoint, вычтите:
/v1/responses с input_tokens и input_tokens_details.cached_tokens.
Маркер sunra_usage_semantics
Ответы, которые Sunra нормализовала, несут маркер внутри usage:
usage; в потоковом ответе он появляется в message_start — событии, которое несёт входные корзины. Когда он присутствует с этим значением, гарантии, описанные на этой странице, действуют: три входные корзины взаимоисключающие, а total_tokens — там, где он присутствует, — равен их сумме плюс output_tokens.
Его отсутствие — тоже обещание. Sunra нормализует только те структуры ответов, которые она измерила. Всё остальное передаётся от вышестоящего провайдера без изменений и остаётся без маркера, а ответ без маркера — это ответ, за корзины которого Sunra не ручается.
Проверяйте маркер, а не изучайте числа, чтобы угадать, какому соглашению следует ответ. Именно определение соглашения по структуре это поле и призвано заменить: эвристика вроде «корзины должны быть взаимоисключающими, потому что их сумма больше количества токенов промпта» удовлетворяется более чем одним соглашением и рано или поздно прочитает ответ неверно.
/v1/messages. Chat Completions и Responses следуют спецификации OpenAI и не маркируются.
Значение версионировано. Ломающее изменение смысла этих полей выйдет под новым значением, поэтому проверка на равенство с anthropic.exclusive.v1 не начнёт незаметно читать другой контракт.
Streaming
В потоковом запросе Messages данные usage приходят в двух событиях.message_start несёт входную сторону и маркер. Завершающее message_delta несёт только output_tokens. Проверяйте маркер в message_start, а затем выполните обычное слияние двух событий — наложите usage более позднего события поверх более раннего — чтобы получить значения, описанные выше.
total_tokens не включается в потоковые ответы. Ни одно отдельное событие не знает одновременно входную и выходную сторону, поэтому любой итог, вычисленный в середине потока, будет неверным. Просуммируйте корзины самостоятельно после завершения потока.
Переход с прежнего поведения
Раньше Sunra передавала на/v1/messages объект usage от вышестоящего провайдера дословно. Слой преобразования перед некоторыми провайдерами включает токены создания кэша внутрь input_tokens, поэтому вызывающая сторона, которая следовала контракту Anthropic и суммировала три корзины, учитывала токены создания кэша дважды.
- Если вы суммируете три корзины, как описано в контракте Anthropic, теперь вы считаете правильно. Изменений с вашей стороны не требуется.
- Если вы компенсировали старое поведение — самостоятельно вычитая
cache_creation_input_tokensизinput_tokensили иным образом восстанавливая логику этого включения — прекратите. Теперь эта поправка вычитает токены, которые уже исключены, и занизит ваш ввод. - Если вы читаете
total_tokens, он по-прежнему сообщает полное количество: свежий ввод, обе корзины кэша и вывод.