Перейти к основному содержанию
Claude Agent SDK предоставляет подробную информацию об использовании токенов для каждого взаимодействия с Claude. Это руководство объясняет, как правильно отслеживать использование и понимать отчёты о затратах, особенно при работе с параллельными использованиями инструментов и многошаговыми диалогами. Полную документацию API см. в справочнике TypeScript SDK и справочнике Python SDK.
Поля total_cost_usd и costUSD являются оценками на стороне клиента, а не авторитетными данными для выставления счётов. SDK вычисляет их локально из таблицы цен, встроенной во время сборки, поэтому они могут отличаться от того, что вам фактически выставляется в счёт, когда:
  • изменяются цены
  • установленная версия SDK не распознаёт модель
  • применяются правила выставления счётов, которые клиент не может смоделировать
Используйте эти поля для получения информации о разработке и приблизительного бюджетирования. Для авторитетного выставления счётов используйте API использования и затрат или страницу использования в Claude Console. Не выставляйте счета конечным пользователям и не принимайте финансовые решения на основе этих полей.

Понимание использования токенов

SDK TypeScript и Python предоставляют одни и те же данные об использовании с разными названиями полей:
  • TypeScript предоставляет разбивку токенов по шагам для каждого сообщения помощника (message.message.id, message.message.usage), стоимость для каждой модели через modelUsage в результирующем сообщении и совокупный итог в результирующем сообщении.
  • Python предоставляет разбивку токенов по шагам для каждого сообщения помощника (message.usage, message.message_id), стоимость для каждой модели через model_usage в результирующем сообщении и накопленный итог в результирующем сообщении (total_cost_usd и словарь usage).
Оба SDK используют одну и ту же базовую модель затрат и предоставляют одинаковую детализацию. Разница заключается в названии полей и в том, где вложено использование по шагам. Отслеживание затрат зависит от понимания того, как SDK определяет область действия данных об использовании:
  • Вызов query(): одно вызывание функции query() SDK. Один вызов может включать несколько шагов (Claude отвечает, использует инструменты, получает результаты, отвечает снова). Каждый вызов создаёт одно сообщение result в конце.
  • Шаг: один цикл запроса/ответа в пределах вызова query(). Каждый шаг создаёт сообщения помощника с использованием токенов.
  • Сессия: серия вызовов query(), связанных идентификатором сессии (с использованием опции resume). Каждый вызов query() в пределах сессии сообщает о своих затратах независимо.
На следующей диаграмме показан поток сообщений от одного вызова query() с использованием токенов, сообщаемым на каждом шаге и совокупной оценкой в конце: Диаграмма, показывающая запрос, создающий два шага сообщений. Шаг 1 имеет четыре сообщения помощника с одинаковым ID и использованием (считать один раз), Шаг 2 имеет одно сообщение помощника с новым ID, и финальное результирующее сообщение показывает предполагаемый total_cost_usd.
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. Это доступно как в TypeScript (SDKResultMessage), так и в Python (ResultMessage). Если вы делаете несколько вызовов query() (например, в многошаговой сессии), каждый результат отражает только стоимость этого отдельного вызова. Если вам нужна только предполагаемая сумма, вы можете игнорировать использование по шагам и прочитать это единственное значение.

Получение общей стоимости запроса

Результирующее сообщение (TypeScript, Python) отмечает конец цикла агента для вызова query(). Оно включает total_cost_usd, совокупную предполагаемую стоимость всех шагов в этом вызове. Это работает как для успешных, так и для ошибочных результатов. Если вы используете сессии для создания нескольких вызовов query(), каждый результат отражает только стоимость этого отдельного вызова. Следующие примеры перебирают поток сообщений из вызова query() и выводят общую стоимость при поступлении сообщения result:
import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({ prompt: "Summarize this project" })) {
  if (message.type === "result") {
    console.log(`Total cost: $${message.total_cost_usd}`);
  }
}

Отслеживание использования по шагам и по моделям

Примеры в этом разделе используют названия полей TypeScript. В Python эквивалентные поля — это AssistantMessage.usage и AssistantMessage.message_id для использования по шагам, и ResultMessage.model_usage для разбивки по моделям.

Отслеживание использования по шагам

Каждое сообщение помощника содержит вложенное BetaMessage (доступное через message.message) с id и объектом usage с подсчётом токенов. Когда Claude использует инструменты параллельно, несколько сообщений имеют одинаковый id с идентичными данными об использовании. Отслеживайте, какие ID вы уже подсчитали, и пропускайте дубликаты, чтобы избежать завышенных итогов.
Параллельные вызовы инструментов создают несколько сообщений помощника, чьё вложенное BetaMessage имеет одинаковый id и идентичное использование. Всегда дедублируйте по ID, чтобы получить точные подсчёты токенов по шагам.
Следующий пример накапливает входные и выходные токены на всех шагах, считая каждый уникальный ID сообщения только один раз:
import { query } from "@anthropic-ai/claude-agent-sdk";

const seenIds = new Set<string>();
let totalInputTokens = 0;
let totalOutputTokens = 0;

for await (const message of query({ prompt: "Summarize this project" })) {
  if (message.type === "assistant") {
    const msgId = message.message.id;

    // Parallel tool calls share the same ID, only count once
    if (!seenIds.has(msgId)) {
      seenIds.add(msgId);
      totalInputTokens += message.message.usage.input_tokens;
      totalOutputTokens += message.message.usage.output_tokens;
    }
  }
}

console.log(`Steps: ${seenIds.size}`);
console.log(`Input tokens: ${totalInputTokens}`);
console.log(`Output tokens: ${totalOutputTokens}`);

Разбивка использования по моделям

Результирующее сообщение включает modelUsage, карту имени модели на подсчёты токенов и стоимость для каждой модели. Это полезно, когда вы запускаете несколько моделей (например, Haiku для подагентов и Opus для основного агента) и хотите увидеть, куда идут токены. Следующий пример запускает запрос и выводит разбивку стоимости и токенов для каждой используемой модели:
import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({ prompt: "Summarize this project" })) {
  if (message.type !== "result") continue;

  for (const [modelName, usage] of Object.entries(message.modelUsage)) {
    console.log(`${modelName}: $${usage.costUSD.toFixed(4)}`);
    console.log(`  Input tokens: ${usage.inputTokens}`);
    console.log(`  Output tokens: ${usage.outputTokens}`);
    console.log(`  Cache read: ${usage.cacheReadInputTokens}`);
    console.log(`  Cache creation: ${usage.cacheCreationInputTokens}`);
  }
}

Накопление затрат на несколько вызовов

Каждый вызов query() возвращает свой собственный total_cost_usd. SDK не предоставляет итог на уровне сессии, поэтому если ваше приложение делает несколько вызовов query() (например, в многошаговой сессии или для разных пользователей), накапливайте итоги самостоятельно. Следующие примеры запускают два вызова query() последовательно, добавляют total_cost_usd каждого вызова к текущему итогу и выводят как стоимость за вызов, так и совокупную стоимость:
import { query } from "@anthropic-ai/claude-agent-sdk";

// Track cumulative cost across multiple query() calls
let totalSpend = 0;

const prompts = [
  "Read the files in src/ and summarize the architecture",
  "List all exported functions in src/auth.ts"
];

for (const prompt of prompts) {
  for await (const message of query({ prompt })) {
    if (message.type === "result") {
      totalSpend += message.total_cost_usd;
      console.log(`This call: $${message.total_cost_usd}`);
    }
  }
}

console.log(`Total spend: $${totalSpend.toFixed(4)}`);

Обработка ошибок, кэширования и расхождений в токенах

Для точного отслеживания затрат учитывайте неудачные диалоги, цены на кэшированные токены и случайные несоответствия в отчётах.

Разрешение расхождений в выходных токенах

В редких случаях вы можете заметить разные значения output_tokens для сообщений с одинаковым ID. Когда это происходит:
  1. Используйте наибольшее значение: финальное сообщение в группе обычно содержит точный итог.
  2. Предпочитайте результирующее сообщение: total_cost_usd в результирующем сообщении отражает накопленную оценку SDK на всех шагах, поэтому оно более надёжно, чем суммирование значений по шагам самостоятельно. Это всё ещё оценка и может отличаться от вашего фактического счёта.
  3. Сообщайте о несоответствиях: подавайте проблемы в репозитории Claude Code на GitHub.

Отслеживание затрат на неудачные диалоги

Как успешные, так и ошибочные результирующие сообщения включают usage и total_cost_usd. Если диалог завершится неудачей на полпути, вы всё равно потребили токены до момента отказа. Всегда читайте данные о затратах из результирующего сообщения независимо от его subtype.

Отслеживание кэшированных токенов

Agent SDK автоматически использует кэширование подсказок для снижения затрат на повторяющееся содержимое. Вам не нужно самостоятельно настраивать кэширование. Объект использования включает два дополнительных поля для отслеживания кэша:
  • cache_creation_input_tokens: токены, используемые для создания новых записей кэша (взимаются по более высокой ставке, чем стандартные входные токены).
  • cache_read_input_tokens: токены, прочитанные из существующих записей кэша (взимаются по сниженной ставке).
Отслеживайте их отдельно от input_tokens, чтобы понять экономию от кэширования. В TypeScript эти поля типизированы на объекте Usage. В Python они появляются как ключи в словаре ResultMessage.usage (например, message.usage.get("cache_read_input_tokens", 0)).

Расширение TTL кэша подсказок до одного часа

Записи кэша, написанные SDK, используют TTL в 5 минут по умолчанию, когда вы аутентифицируетесь с помощью ключа API или запускаете на Amazon Bedrock, Google Cloud Vertex AI или Microsoft Foundry. Если ваша рабочая нагрузка запускает много коротких сессий против одной и той же системной подсказки и контекста с промежутками более 5 минут между ними, кэш истекает между сессиями и каждая новая сессия платит полную входную цену. Чтобы запросить TTL в 1 час на записи кэша, установите переменную окружения ENABLE_PROMPT_CACHING_1H. Вы можете экспортировать её в окружение вашей оболочки или контейнера, или передать её через options.env. Следующий пример включает TTL в 1 час для агента, работающего на Bedrock:
options = ClaudeAgentOptions(
    env={
        "CLAUDE_CODE_USE_BEDROCK": "1",
        "ENABLE_PROMPT_CACHING_1H": "1",
    },
)
Записи кэша с TTL в 1 час взимаются по более высокой ставке, чем записи в 5 минут, поэтому включение этого обменивает более высокую стоимость записи на больше чтений из кэша. Подробности см. в ценах на кэширование подсказок. Пользователи подписки Claude уже получают TTL в 1 час автоматически и не нужно устанавливать эту переменную.

Связанная документация