lenec ru

← все посты

Как считать стоимость запросов к Claude и не разориться на проде

16K

Однажды утром мне пришёл скрин счёта от Anthropic и я аккуратно отложил кружку с кофе. За месяц мы выкатили в прод небольшую LLM-фичу — суммаризацию заявок поддержки. Расход — больше, чем зарплата мидл-разработчика. Не потому что фича плохая, а потому что считать стоимость никто не сел заранее.

Этот текст — про то, как я после того случая считаю расходы на Claude перед запуском. Без хитрой математики, на пальцах, чтобы можно было прикинуть на салфетке за пять минут.

Из чего складывается счёт

Anthropic берёт деньги за токены. Токен — это не символ и не слово, это кусок текста, на который токенайзер разбил твою строку. Для русского языка токены примерно в 1.5–2 раза "толще", чем для английского. Грубое правило, которым я пользуюсь: 1 русский символ ≈ 0.5 токена. Английский — около 0.25 токена за символ.

Считают раздельно две вещи:

  • Input — всё, что ты отправил модели. Системный промпт, история диалога, описание инструментов, новый запрос пользователя. Дешевле.
  • Output — то, что модель сгенерировала в ответ. Дороже, обычно в 5 раз.

На начало 2026 у Sonnet 4.5 цена примерно $3 за миллион input-токенов и $15 за миллион output. У Opus 4 — $15 и $75. У Haiku 4.5 — $1 и $5. Цены меняются, перед расчётом всегда смотри актуальные на странице моделей Anthropic. Но соотношение input/output ≈ 1:5 держится давно.

Базовая формула

Стоимость одного запроса считается так:

cost = (input_tokens / 1_000_000) * input_price
     + (output_tokens / 1_000_000) * output_price;

Если умеешь оценивать, сколько у тебя в среднем уходит токенов на запрос и сколько ответ — умножаешь на ожидаемое число запросов в день и получаешь дневной расход. Дальше на 30 — месячный.

Простой пример. У меня бот отвечает на сообщения в чат-поддержке. На один разговор уходит примерно 3000 input-токенов (промпт + история + контекст из базы) и 500 output. Sonnet:

const inputCost = (3000 / 1_000_000) * 3;   // $0.009
const outputCost = (500 / 1_000_000) * 15;   // $0.0075
const perRequest = inputCost + outputCost;   // $0.0165

1.65 цента за разговор. Если в день 1000 разговоров — $16.5 в день, $495 в месяц. Это нормально. А вот если внезапно 50000 — это уже $24750 в месяц, и пора думать.

Где утекают токены

На моей практике львиная доля счёта — это input, а не output. Причина банальная: разработчики любят пихать в системный промпт всё подряд.

Реальный пример. Был промпт на 4000 токенов: правила бренда, примеры ответов, описание тегов, FAQ компании. Каждый из 5000 разговоров в день начинался с него. Это 4000 × 5000 = 20 миллионов токенов в день только на промпт. На Sonnet — $60 в день, $1800 в месяц только за то, что одни и те же инструкции отправляются туда-сюда.

Второе место — история диалога. Если ты держишь весь чат в памяти и шлёшь его при каждом сообщении, к 20-му сообщению у тебя в input уже 20 копий первых 19 ответов модели. Растёт квадратично, удивляться нечему.

Как реально посчитать токены

Anthropic возвращает в ответе точные цифры:

const res = await client.messages.create({...});
console.log(res.usage);
// { input_tokens: 2843, output_tokens: 412,
//   cache_creation_input_tokens: 0, cache_read_input_tokens: 0 }

Я в каждом проде логирую usage в нашу метрику и графану. По запросу видно, кто из эндпоинтов сколько жжёт. Без этого расследовать счёт вслепую — мука.

До запуска можно прикинуть через эндпоинт /v1/messages/count_tokens:

const count = await client.messages.countTokens({
  model: "claude-sonnet-4-5",
  system: systemPrompt,
  messages: [{ role: "user", content: userMessage }],
});
console.log(count.input_tokens);

Полезно, когда сравниваешь два варианта промпта или прикидываешь, влезешь ли в контекст.

Кэширование промптов — главное оружие

Вернёмся к тому толстому промпту на 4000 токенов. У Anthropic есть prompt caching: ты помечаешь стабильную часть запроса флагом cache_control, и при повторных запросах эта часть идёт по тарифу cache_read. Cache_read стоит примерно в 10 раз дешевле обычного input. Cache_write — на 25% дороже, но он один раз на 5 минут.

const res = await client.messages.create({
  model: "claude-sonnet-4-5",
  max_tokens: 1024,
  system: [
    {
      type: "text",
      text: bigSystemPrompt,
      cache_control: { type: "ephemeral" },
    },
  ],
  messages: [{ role: "user", content: userQuery }],
});

На том проекте включение кэша срезало input-расход на 78%. Не потому что мы пишем меньше токенов, а потому что цена за миллион упала с $3 до $0.30 для тех, что в кэше.

Что важно понимать про кэш:

  • Минимум 1024 токена для кэширования (для Sonnet/Opus). Меньшие куски не кэшируются.
  • Время жизни — 5 минут с момента последнего обращения. Если поток запросов плотный — живёт долго. Если запрос раз в полчаса — каждый раз будет cache_write.
  • Любое изменение в кэшированном префиксе инвалидирует кэш. Поставь дату в системный промпт — и кэш рассыпался.
  • Кэшировать можно не только system, но и tools, и часть messages. Я обычно кэширую: system + tools + первые сообщения с few-shot примерами.

Что ещё снижает счёт

Перевод на Haiku где можно. Haiku 4.5 примерно в 3 раза дешевле Sonnet и для простых задач — классификация, извлечение данных, короткие ответы — справляется. У меня роутер в боте: первый запрос идёт в Haiku с промптом "определи тип задачи", и только сложные кейсы уходят в Sonnet. Экономия на дешёвых задачах — 2–3 раза по счёту.

Ограничение max_tokens в ответе. Это потолок, а не цель. Если ставишь 4096, а модель отвечает в 200 — заплатишь за 200. Но контролируемое ограничение дисциплинирует промпт: "ответ не длиннее 100 слов" в инструкции часто работает.

Резка истории. Не таскай весь диалог. Я обычно держу system, последние N сообщений и сжатый summary всего, что было раньше. Summary прогоняешь раз в N сообщений отдельным дешёвым вызовом Haiku.

Batch API — если задача не риалтайм. Anthropic даёт скидку 50% на батчи: ты загружаешь пачку до 100k запросов, забираешь результат через какое-то время (обычно минуты, потолок — 24 часа). Идеально для офлайн-аналитики, переразметки, классификации старых данных.

Как я выставляю лимиты

В консоли Anthropic есть spend limits на ключ. У меня на каждый сервис — свой ключ со своим лимитом. Прод-бот — $50 в день. Дев-окружение — $5. Эксперименты — $10. Это не от жадности, это от защиты: один багующий цикл, который дёргает API в while(true), может за час сжечь сильно больше, чем нужно.

Плюс на бэкенде я делаю свои лимиты по userId — пользователь не должен суммарно за день потратить больше N центов. Если бот общедоступный — без этого тебя за час положат на лопатки.

Маленький чеклист перед прод-запуском

  • Посчитал ожидаемый input/output на один запрос через countTokens.
  • Прикинул траты на 100x от ожидаемого трафика — не пугает?
  • Стабильную часть промпта обернул в cache_control.
  • Задачу можно решить на Haiku — пробую сначала Haiku.
  • Историю диалога режу или суммаризирую.
  • На ключе стоит spend limit.
  • В коде логирую usage в метрику.
  • Есть алерт на превышение дневного бюджета.

Ничего сложного, но если пройти этот список перед запуском — счёт через месяц не удивит.

Комментарии 0

  • Будьте первым, кто оставит комментарий.

Войдите, чтобы оставить комментарий.