Понимание использования токенов
TypeScript и Python SDK предоставляют одни и те же данные об использовании с разными названиями полей:- TypeScript предоставляет разбивку токенов по шагам для каждого сообщения ассистента (
message.message.id,message.message.usage), стоимость для каждой модели черезmodelUsageв результирующем сообщении и совокупный итог в результирующем сообщении. - Python предоставляет разбивку токенов по шагам для каждого сообщения ассистента как
message.usageиmessage.message_id, стоимость для каждой модели черезmodel_usageв результирующем сообщении и совокупный итог в результирующем сообщении какtotal_cost_usd.
- Вызов
query(): одно вызывание функцииquery()SDK. Один вызов может включать несколько шагов: Claude отвечает, использует инструменты, получает результаты и отвечает снова. Каждый вызов создает одно сообщениеresultв конце, за исключением режима потоковой передачи входных данных, где один вызовquery()содержит несколько ходов пользователя и каждый ход выдает свое собственное сообщениеresult. - Шаг: один цикл запроса/ответа в рамках вызова
query(). Каждый шаг создает сообщения ассистента с использованием токенов. - Сеанс: серия вызовов
query(), связанных идентификатором сеанса через опциюresume. Результаты возобновленного вызова сообщают об общих расходах сеанса, а не только о расходах этого вызова. См. Накопление стоимости при нескольких вызовах для получения информации о том, как переносятся итоги.
query() с использованием токенов, указанным на каждом шаге и совокупной оценкой в конце:
1
Каждый шаг создает сообщения ассистента
Когда Claude отвечает, он отправляет одно или несколько сообщений ассистента. В TypeScript каждое сообщение ассистента содержит вложенный
BetaMessage (доступный через message.message) с id и объектом usage с подсчетом токенов (input_tokens, output_tokens). В Python класс данных AssistantMessage предоставляет одни и те же данные непосредственно через message.usage и message.message_id. Когда Claude использует несколько инструментов в одном ходе, все сообщения в этом ходе имеют одинаковый ID, поэтому дедублируйте по ID, чтобы избежать двойного подсчета.2
Результирующее сообщение предоставляет совокупную оценку
Когда вызов
query() завершается, SDK выдает результирующее сообщение с total_cost_usd и совокупным usage, типизированное как SDKResultMessage в TypeScript и ResultMessage в Python. Если вам нужна только предполагаемая сумма, вы можете игнорировать использование по шагам и прочитать это единственное значение.Если вы делаете несколько независимых вызовов query(), каждый результат отражает только стоимость этого отдельного вызова. Вызов, который возобновляет сеанс, также учитывает более ранние расходы сеанса.В режиме потоковой передачи входных данных каждый ход выдает свое собственное результирующее сообщение. См. Отслеживание стоимости в режиме потоковой передачи входных данных для получения информации о том, как читать итоги вызовов в этом режиме.Отслеживание затрат в режиме потоковой передачи входных данных
В режиме потоковой передачи входных данных один вызовquery() содержит несколько ходов пользователя, и каждый ход выдает собственное сообщение результата. Поля результата различаются по области действия:
usage: охватывает только этот ход и в его пределах только основной цикл агента, а не какие-либо подагенты, которые он запустил.total_cost_usdиmodelUsage, илиmodel_usageв Python: содержат текущий итог для всего вызова на данный момент, плюс любые расходы, восстановленные при возобновлении вызовом сеанса.
/clear, /reset или /new, прочитайте последний результат для итогов вызова, а не суммируйте результаты.
Текущие итоги начинаются заново каждый раз, когда ваше приложение отправляет одну из этих трех команд, и внутри вызова query() ничто другое их не сбрасывает. Три результата имеют значение для вашего учета:
- Собственный результат хода
/clear: охватывает только то, что было запущено с момента сброса, и содержит новыйsession_id. - Каждый последующий результат: продолжает отсчет с этого сброса.
- Последний результат перед каждым
/clear: содержит итог для ходов с момента предыдущего сброса.
/clear к финальному результату вызова. Все остальные результаты, включая собственный результат хода /clear, заменяются более поздним.
В TypeScript SDK также выдает SDKConversationResetMessage при каждом сбросе, поэтому вы можете обнаружить сбросы из потока. В Python SDK аналогично выдает ConversationResetMessage. До версии Python SDK v0.2.137 итератор Python отбрасывал это сообщение, поэтому в этих версиях считайте сбросы самостоятельно из ходов /clear, которые отправляет ваше приложение.
maxBudgetUsd (TypeScript) или max_budget_usd (Python) считает только расходы самого вызова: итоги, восстановленные из возобновленного сеанса, не учитываются в нем, и /clear начинает бюджет заново.
Получить общую стоимость запроса
Результирующее сообщение, типизированное какSDKResultMessage в TypeScript и ResultMessage в Python, отмечает конец цикла агента для вызова query(). Оно включает total_cost_usd, совокупную предполагаемую стоимость всех шагов в этом вызове. Вызов, который возобновляет сеанс, также учитывает более ранние расходы сеанса. При чтении значения применяются два предостережения:
- В Python это поле типизировано как опциональное, поэтому проверьте, что оно не равно
Noneперед его чтением. - Результаты успеха и ошибки оба содержат его, хотя финальный результат сбоя сеанса может содержать его обнуленным.
modelUsage или model_usage в Python для учета токенов всего дерева; поле usage недосчитывает, как только происходит вложение.
В режиме ввода одного сообщения, когда фоновые подагенты все еще работают в конце финального хода, Claude Code ждет их, вплоть до лимита, описанного в фоновых задачах при выходе, перед отправкой результата.
total_cost_usd, duration_api_ms и modelUsage результата, или model_usage в Python, включают работу, выполненную во время этого ожидания.
Следующие примеры перебирают поток сообщений из вызова query() и выводят общую стоимость, когда приходит сообщение result:
total_cost_usd, установите лимиты глубины, параллелизма и расходов на запросе.
Отслеживание использования на каждом шаге и для каждой модели
Примеры в этом разделе используют имена полей TypeScript. В Python эквивалентные поля — этоAssistantMessage.usage и AssistantMessage.message_id для использования на каждом шаге, а также ResultMessage.model_usage для разбивки по моделям.
Отслеживание использования на каждом шаге
Каждое сообщение ассистента содержит вложенныйBetaMessage (доступный через message.message) с id и объектом usage с подсчётом токенов. Когда Claude использует инструменты параллельно, несколько сообщений имеют одинаковый id с идентичными данными использования. Отслеживайте, какие ID вы уже подсчитали, и пропускайте дубликаты, чтобы избежать завышенных итогов.
Следующий пример накапливает входные токены на всех шагах, подсчитывая каждый уникальный ID сообщения основного цикла только один раз и пропуская сообщения подагентов, а также читает выходной итог из сообщения результата, который охватывает основной цикл:
Разбивка использования по моделям
Сообщение результата включаетmodelUsage, карту имён моделей на подсчёты токенов для каждой модели и стоимость. Это полезно, когда вы запускаете несколько моделей (например, Haiku для подагентов и Opus для основного агента) и хотите увидеть, куда идут токены.
Поле costBasis каждой записи указывает, какая таблица цен определила цену последнего запроса этой модели: list для цены списка, managed для таблицы modelPricing, или unknown, когда ни одна из них не совпала с ID модели. Это поле требует Claude Code версии 2.1.246 или позже.
Следующий пример запускает запрос и выводит разбивку стоимости и токенов для каждой используемой модели:
Накопление затрат при нескольких вызовах
Каждый вызовquery() возвращает total_cost_usd в своих результатах. Способ объединения значений зависит от того, используют ли вызовы один сеанс:
- Независимые вызовы без опции
resumeилиcontinue: каждый результат охватывает только свой собственный вызов, поэтому складывайте итоги самостоятельно, как это делается в примерах ниже. - Вызовы, которые возобновляют один и тот же сеанс: Claude Code сохраняет итоги сеанса в его транскрипт при нормальном завершении процесса и восстанавливает их, когда последующий вызов возобновляет или разветвляет сеанс. Каждый результат уже включает более ранние расходы сеанса. Прочитайте последний результат для получения общей суммы сеанса; суммирование результатов приводит к двойному подсчёту восстановленных расходов. До версии 2.1.277 сеанс, который вы возобновили через SDK или
claude -p, начинал свои итоги с нуля, поэтому результаты каждого вызова охватывали только этот вызов.
query() последовательно, каждый total_cost_usd вызова добавляется к текущему итогу, и выводятся как стоимость для каждого вызова, так и общая стоимость:
Обработка ошибок, кеширование и подсчет выходных токенов
Для точного отслеживания затрат учитывайте количество выходных токенов-заполнителей в сообщениях ассистента, токены, потребленные неудачным разговором, и цены на токены кеша.Чтение выходных токенов из результирующего сообщения
Claude Code создает каждое сообщение ассистента на основе использования, которое API сообщил при начале ответа, поэтомуoutput_tokens сообщения — это только количество, которое API сообщил в message_start, до того как был сгенерирован ответ. Один ответ API может создать несколько сообщений ассистента, и каждое из них содержит этот же заполнитель.
API сообщает реальное количество выходных данных в конце ответа, и Claude Code добавляет его в результирующее сообщение. Читайте выходные токены из usage результата или из modelUsage для разбивки по моделям.
Чтобы наблюдать, как растет количество выходных данных ответа во время потоковой передачи, установите includePartialMessages или include_partial_messages в Python и читайте usage из каждого события потока message_delta, типизированного как SDKPartialAssistantMessage в TypeScript и StreamEvent в Python.
Отслеживание затрат при неудачных разговорах
Оба результирующих сообщения об успехе и ошибке включаютusage и total_cost_usd; в Python оба поля типизированы как необязательные, поэтому проверьте, что они не равны None перед их чтением.
Если разговор прерывается на полпути, вы все равно потребили токены до момента сбоя. Читайте данные о затратах из каждого результирующего сообщения, независимо от того, является ли его subtype success или одним из подтипов ошибок. На некоторых результатах ошибок usage сообщает меньше, чем потратил вызов:
error_during_executionпосле сбоя сеанса: каждое поле затрат может быть обнулено.error_max_budget_usd:usageисключает ответ, который превысил бюджет, в то время какtotal_cost_usdиmodelUsageвключают его.
total_cost_usd или modelUsage вместо usage.
Восстановление итогов после сбоя сеанса
Когда процесс Claude Code падает, он выдает финальный результатerror_during_execution и выходит как в режиме одноразового ввода, так и в режиме потокового ввода. Этот результат может содержать обнуленные usage, total_cost_usd и modelUsage, поэтому восстановите итоги вызова из того, что пришло до него. Шаг 1 восстанавливает полные итоги всякий раз, когда существует более ранний результат; резервный вариант на шаге 2 восстанавливает только входные токены и токены кеша основного цикла.
- Используйте результат хода перед сбоем. В режиме потокового ввода он содержит текущий итог, описанный в Track costs in streaming input mode. Перейдите к шагу 2, если этот результат не может вам помочь:
- Вызов был одноразовым, поэтому более ранний результат не существует.
- Сбой произошел на первом ходу.
- Ход перед сбоем был самим
/clear, поэтому его результат охватывает только сброс.
- Вместо этого суммируйте
usageв сообщениях ассистента, считая каждый ответ API один раз, как это делает пример Track per-step usage. В режиме одноразового ввода суммируйте все из них; в режиме потокового ввода суммируйте те, которые пришли после последнего результата. Это дает вам входные токены и токены кеша основного цикла. Использование подагента не восстанавливается таким образом, и выходные токены или стоимость в USD тоже, потому что выходные токены на шаг — это заполнитель.
Отслеживание токенов кеша
Agent SDK автоматически использует prompt caching для снижения затрат на повторяющееся содержимое. Вам не нужно самостоятельно настраивать кеширование. Объект использования включает два дополнительных поля для отслеживания кеша:cache_creation_input_tokens: токены, используемые для создания новых записей кеша (взимаются по более высокой ставке, чем стандартные входные токены).cache_read_input_tokens: токены, прочитанные из существующих записей кеша (взимаются по сниженной ставке).
input_tokens, чтобы понять экономию кеша. В TypeScript эти поля типизированы на объекте Usage. В Python они появляются как ключи в словаре ResultMessage.usage (например, message.usage.get("cache_read_input_tokens", 0)).
Расширение TTL кеша подсказок до одного часа
Ваши собственные ходы попадают в основной сегмент TTL разговора, вместе с помощниками, которые Claude Code запускает встроенными с ними. Запросы, которые Claude Code делает вне этого разговора, такие как подагенты, имеют отдельное управление TTL. Записи кеша для ваших собственных ходов используют TTL по умолчанию 5 минут, когда вы аутентифицируетесь с помощью ключа API или запускаете на Amazon Bedrock, платформе агентов Google Cloud, Microsoft Foundry или Claude Platform on AWS. Если ваша рабочая нагрузка запускает много коротких сеансов с одной и той же системной подсказкой и контекстом с промежутками более 5 минут между ними, кеш истекает между сеансами и каждый новый сеанс платит полную входную цену. Чтобы запросить TTL в 1 час при записи кеша, установите переменную окруженияENABLE_PROMPT_CACHING_1H. Вы можете экспортировать ее в окружение вашей оболочки или контейнера или передать ее через options.env.
Следующий пример включает TTL в 1 час для агента, работающего на Amazon Bedrock. Поскольку он устанавливает CLAUDE_CODE_USE_BEDROCK, он требует рабочих учетных данных AWS для Amazon Bedrock; без них запрос не выполняется.
ENABLE_PROMPT_CACHING_1H запрашивает TTL в 1 час для каждого запроса в обоих сегментах. Чтобы выбрать TTL для каждого сегмента отдельно, используйте эти элементы управления вместо этого. Каждый принимает 5m или 1h и имеет приоритет над ENABLE_PROMPT_CACHING_1H:
- Основной разговор: переменная окружения
CLAUDE_CODE_PROMPT_CACHE_TTLили параметрpromptCacheTtl - Все остальное: переменная окружения
CLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTLили параметрsubagentPromptCacheTtl
promptCacheTtl на 1h сохраняет кеш в 1 час на основном разговоре, пока вы используете кредиты использования. Для полного порядка приоритета см. выбор TTL самостоятельно.
Связанная документация
- Справочник TypeScript SDK - Полная документация API
- Обзор SDK - Начало работы с SDK
- Разрешения SDK - Управление разрешениями инструментов