Привет, Хабр! Меня зовут Сергей Нотевский, я AI Platform Lead в Битрикс24.Мы строим AI-платформу на self-hosted инференсе - vLLM, свои модели, своя оптимизация.Привет, Хабр! Меня зовут Сергей Нотевский, я AI Platform Lead в Битрикс24.Мы строим AI-платформу на self-hosted инференсе - vLLM, свои модели, своя оптимизация.

Погоди переезжать на дешёвую модель: считаем effective cost с учётом кэша

2026/03/10 13:00
16м. чтение
Для обратной связи или замечаний по поводу данного контента, свяжитесь с нами по адресу [email protected]

Привет, Хабр! Меня зовут Сергей Нотевский, я AI Platform Lead в Битрикс24.

Мы строим AI-платформу на self-hosted инференсе - vLLM, свои модели, своя оптимизация. Кэш - одна из ключевых метрик: hit rate напрямую влияет на нагрузку GPU и latency для пользователя. И как следствие - на количество ресурсов которые нам требуются.

В сообществе часто пишут о том что KV-cache hit rate - один из главных приоритетов при оптимизации стоимости. Manus в той-самой статье про context engineering и своего агента, TikTok в кейсе про оптимизацию AI-агента для тестирования, AiSDR в статье про перестройку шаблонов генерации писем.
Стало интересно стало: а как это считается у MaaS-провайдеров? Я знаком со скидкой за кэш токены, но никогда не садился детально разбирать экономику кэша у OpenAI, Anthropic, Gemini, DeepSeek - с цифрами, сценариями, сравнением.

Сел считать. Первый же результат удивил: два запроса к одной и той же модели с одним и тем же объёмом токенов - разница в цене в 3 раза. Зависит только от того, попали ли токены в кэш.

Про то как KV-кэш устроен внутри - уже хорошо написано на Хабре, ссылки в конце. Здесь только про деньги и токены: как считать реальную стоимость и почему прайс-лист для этого не подходит только прайс-лист.


TL;DR

  • Прайс часто показывает только стоимость input и output токенов. Реальная стоимость зависит ещё от того, какая доля промпта повторяется между запросами (S), сколько токенов в ответе (O) и как часто кэш срабатывает (h, hit rate). Без этих трёх параметров сравнение провайдеров бессмысленно.

  • При переезде на другого провайдера архитектура кэша меняется. То что давало 90% hit rate может давать 40–50% без переработки промптов - из-за разной логики кэширования: OpenAI кэширует только префикс, Anthropic требует явной разметки, Gemini implicit вообще не гарантирует хит.

  • Перед миграцией: посчитайте текущий effective cost, потом новый - с hit rate 30%.


Быстро про механику - только то, что нужно для расчётов

При каждом запросе к LLM модель обрабатывает весь входной промпт заново - это фаза prefill (вычисление KV-пар для каждого входного токена). Если часть промпта из запроса в запрос не меняется (системный промпт, RAG-контекст, tool definitions), провайдер может сохранять результаты её обработки в KV-кэше. При следующем запросе берёт оттуда.

Токены с cache hit стоят в 4–10 раз дешевле - отсюда и расхождение между тем что написано в прайсе и тем что приходит в счёте.


Одна формула, которая нужна для сравнения

C = S \cdot [(1-h) \cdot P_{miss} + h \cdot P_{hit}] + D \cdot P_{miss} + O \cdot P_{out}

Где:

  • S - токены повторяющейся части входа (system prompt, tool definitions, память, уже загруженный контекст и другие блоки, которые переиспользуются между вызовами без изменений)

  • D - токены динамики (пользовательский запрос, переменные)

  • O - токены output

  • h - cache hit rate (0–1): доля запросов, в которых статическая часть попала в кэш

  • P_miss, P_hit, P_out - цены провайдера

Важно для Anthropic: в формуле выше P_miss используется и для cache miss, и для динамики. У провайдеров с write surcharge (Anthropic) первый запрос на запись в кэш стоит дороже: P_write = P_miss × 1.25 для 5-минутного TTL. Точнее, первое слагаемое для таких провайдеров выглядит так:

S \cdot [(1-h) \cdot P_{write} + h \cdot P_{hit}]

Во всех расчётах ниже это учтено. Если подставляете свои цифры - не забудьте про множитель.

Прайс-лист в основном показывает только P_miss и P_out. Без S, O и h - бесполезен для сравнения.

Практическое замечание про hit rate: в логах вы обычно видите cached_tokens / total_input_tokens. У Anthropic total_input_tokens - это сумма cache_read_input_tokens + cache_creation_input_tokens + input_tokens.

Формула одна, но P_hit и P_miss берутся не из воздуха — у провайдеров принципиально разные схемы кэширования, и от схемы зависит за что вы платите.


Три «контракта кэширования»

Провайдеры работают по разным схемам.

Auto, без наценки за запись

OpenAI (GPT-5 mini, GPT-5.2, GPT-5.4), Gemini 2.5, DeepSeek V3.2

Кэш включается сам, за запись не доплачиваете. При miss - обычная цена, при hit - дешевле. Для нерегулярного трафика безопаснее всего: нет риска переплатить за write, который никогда не прочитают.

Explicit, наценка за запись

Anthropic (Claude Haiku 3.5, Sonnet 4, Opus 4.1)

Вы явно размечаете что кэшировать через cache_control.

Anthropic позволяет ставить точки кэширования не только на весь запрос целиком, но и на отдельные стабильные блоки промпта - например, на system prompt, tool definitions или RAG-блок. Ниже я буду называть такие точки per-block breakpoints. Это важно: в отличие от префиксного кэша, здесь можно кэшировать не только непрерывное начало запроса, но и отдельные куски запроса, если они стабильно повторяются.

За 5-минутный TTL (время жизни кэша) +25% к цене input. За 1-часовой TTL ×2 к цене input. Зато скидка при hit - 90%.

С февраля 2026 Anthropic также поддерживает автоматический кэш: один cache_control на уровне запроса, без ручной разметки блоков - система сама управляет точками кэширования по мере роста диалога. Для простых случаев этого достаточно. Per-block breakpoints дают больше контроля - например, кэшировать какой-то блок отдельно от system prompt.
Break-even для 5-минутного TTL (k=1.25):

h_{min} = \frac{P_{miss} \cdot (k-1)}{P_{miss} \cdot k - P_{hit}}

Для Claude Sonnet 4 ($3/M miss, $0.30/M hit):

h_{min} = \frac{3 \cdot 0.25}{3 \cdot 1.25 - 0.30} = \frac{0.75}{3.45} \approx 22\%

Кэш Anthropic окупается при hit rate > 22%. Не окупается только при абсолютно уникальных запросах каждый раз с новым контекстом.

А если через агрегатор - OpenRouter и подобные?

Многие используют OpenRouter как единую точку доступа к разным моделям. Кэш там работает - механика и цены те же что у провайдеров напрямую. Но есть детали которые влияют на стоимость.

OpenRouter использует sticky routing: повторные запросы он старается направлять на тот же бэкенд, где уже лежит прогретый кэш.
Под «одним и тем же диалогом» здесь понимается conversation, который определяется по хэшу первого system-сообщения и первого пользовательского сообщения.
Но это best-effort, а не гарантия. Если нужный бэкенд недоступен, запрос уйдёт на другой сервер - без прогретого кэша. В этот момент hit rate обнуляется, и префикс придется прогревать заново.
Самое неприятное, что такое может произойти в плохой момент: при росте нагрузки или деградации провайдера, когда кэш особенно нужен.

С Anthropic через OpenRouter есть отдельный нюанс.
Top-level cache_control работает только тогда, когда запрос идёт напрямую в Anthropic. Если OpenRouter может отправить его через Bedrock или Vertex, такой режим кэша там не поддерживается - и эти маршруты просто исключаются.
Per-block breakpoints в этом смысле надёжнее: они поддерживаются шире и не так жёстко завязаны на прямую маршрутизацию в Anthropic.
Практический вывод неприятный: можно думать, что кэш у вас включён, а в реальности запрос уходит по маршруту, где эта схема вообще не работает.

Для экспериментов и нерегулярного трафика разница с прямым API несущественна. Для продакшена где кэш закрывает UX-требования по TTFT - аргумент ходить напрямую.


Три сценария, которые показывают, почему прайс врёт

Ниже - cost-only сценарии. Они сравнивают экономику токенов при заданном hit rate, без поправки на качество модели. Сравнивать Flash-Lite с флагманской моделью напрямую бессмысленно - это разные весовые категории. Поэтому сценарий 1 оставлен как чистый пример на одной модели, а в сценариях 2 и 3 модели сгруппированы по приблизительно сопоставимому ценовому классу: важно не "кто абсолютно дешевле", а как кэш и структура промпта меняют стоимость внутри одного класса.

Во всех сценариях ниже для Anthropic учтён write surcharge за 5-минутный TTL: cache write считается по цене input ×1.25, cache read - по discounted rate.

Сценарий 1: та же модель - цена отличается в 3 раза

Вот тот самый пример из введения. RAG-агент с append-only контекстом (новые данные дописываются в конец, старые не удаляются): 10 000 токенов повторяющейся части промпта, 200 токенов запрос, 300 токенов ответ, 2 000 запросов/день.

Вариант

Hit rate

Итого/день

DeepSeek V3.2 — timestamp в system prompt

30%

$4.45

DeepSeek V3.2 — кэш настроен правильно

90%

$1.43

Claude Haiku 3.5 — кэш настроен правильно

90%

$6.16

Смотрите на первые две строки. Одна и та же модель, один и тот же объём токенов - разница больше чем в 3 раза. Всё решает hit rate, а hit rate решает структура промпта.

Реальный кейс: команда Manus перешла с $3/MTok на $0.30/MTok на Claude Sonnet - снижение стоимости инференса в 10 раз. Три практики: append-only контекст, sort_keys=True при сериализации tool definitions, инструменты в промпте всегда. Ничего сложного - только стабильный префикс.

Сценарий 2: короткий output меняет всю картину

Классификация документов: 8 000 токенов повторяющейся части промпта, 200 токенов запрос, 20 токенов ответ, 5 000 запросов/день, hit rate 90%.

Низкий ценовой класс

Модель

Cache miss

Cache read

Динамика

Output

Итого/день

Gemini 2.5 Flash-Lite

$0.40

$0.36

$0.10

$0.04

$0.90

DeepSeek V3.2

$1.12

$1.01

$0.28

$0.04

$2.45

GPT-5 mini

$1.00

$0.90

$0.25

$0.20

$2.35

Средний ценовой класс

Модель

Cache miss

Cache read

Динамика

Output

Итого/день

Gemini 2.5 Flash

$1.20

$1.08

$0.30

$0.25

$2.83

Claude Haiku 3.5

$4.00

$2.88

$0.80

$0.40

$8.08

GPT-5.2

$7.00

$6.30

$1.75

$1.40

$16.45

Флагманский класс

Модель

Cache miss

Cache read

Динамика

Output

Итого/день

GPT-5.4

$10.00

$9.00

$2.50

$1.50

$23.00

Claude Sonnet 4

$15.00

$10.80

$3.00

$1.50

$30.30

При коротком output цена ответа перестаёт быть главным фактором - начинает решать стоимость input и cache read. В низком ценовом классе Flash-Lite с cache hit $0.01/M выигрывает у DeepSeek и GPT-5 mini за счёт самой дешёвой стоимости кэшируемого input. В среднем классе Gemini 2.5 Flash дешевле Claude Haiku 3.5 и GPT-5.2 потому, что при 20 токенах ответа базовая цена input оказывается важнее output. Во флагманском классе GPT-5.4 дешевле Claude Sonnet 4 прежде всего за счёт отсутствия write surcharge.

Сценарий 3: большой контекст

AI-агент с базой знаний: 50 000 токенов повторяющейся части промпта, 500 токенов запрос, 500 токенов ответ, 1 000 запросов/день, hit rate 95%.

Низкий ценовой класс

Модель

Cache miss

Cache read

Динамика

Output

Итого/день

Gemini 2.5 Flash-Lite

$0.25

$0.48

$0.05

$0.20

$0.98

DeepSeek V3.2

$0.70

$1.33

$0.14

$0.21

$2.38

GPT-5 mini

$0.62

$1.19

$0.12

$1.00

$2.94

Средний ценовой класс

Модель

Cache miss

Cache read

Динамика

Output

Итого/день

Gemini 2.5 Flash

$0.75

$1.43

$0.15

$1.25

$3.58

Claude Haiku 3.5

$2.50

$3.80

$0.40

$2.00

$8.70

GPT-5.2

$4.38

$8.31

$0.88

$7.00

$20.57

Флагманский класс

Модель

Cache miss

Cache read

Динамика

Output

Итого/день

GPT-5.4

$6.25

$11.88

$1.25

$7.50

$26.88

Claude Sonnet 4

$9.38

$14.25

$1.50

$7.50

$32.63

При 50k повторяющегося контекста input и cache read начинают доминировать вместе с output. В низком ценовом классе Flash-Lite остаётся самым дешёвым вариантом, DeepSeek - вторым, GPT-5 mini - третьим: разницу здесь делает прежде всего цена cache read. В среднем классе Gemini 2.5 Flash существенно дешевле Claude Haiku 3.5 и GPT-5.2 за счёт дешёвого input и output одновременно. Во флагманском классе GPT-5.4 дешевле Claude Sonnet 4, но оба остаются на другом уровне стоимости по сравнению со средним классом.


Как снять S, D, O из собственных логов

Подставлять в формулу круглые числа из головы - плохая идея. Ниже пример для Anthropic API (поля для остальных провайдеров - в FAQ):

# Anthropic — из usage каждого ответа S_approx = response.usage.cache_read_input_tokens # статика в кэше D_approx = response.usage.input_tokens # динамика (не кэшировалась) O = response.usage.output_tokens total_input = S_approx + response.usage.cache_creation_input_tokens + D_approx h = S_approx / total_input if total_input > 0 else 0

На выборке из 1 000 запросов возьмите медиану cache_read_input_tokens — это ваш реальный S при стабильном промпте. Если медиана близка к нулю — кэш не работает, смотрите антипаттерны ниже.


Скрытый налог миграции

Сам кэш прогревается быстро - первый же батч запросов заполнит его. Это не проблема.

Проблема в другом: у каждого провайдера своя архитектура кэширования, и промпт который давал 90% hit rate на одном стеке может давать 40% на другом без переработки.

OpenAI кэширует только непрерывный префикс с начала промпта. Официально задокументировано: "cache hits are only possible for exact prefix matches". Практически это означает: если у вас структура [system prompt] → [user query] → [RAG блок], то RAG блок в конце не попадёт в кэш никогда — он идёт после динамической части. На Anthropic с explicit cache_control вы могли пометить RAG-блок отдельной точкой кэширования (per-block breakpoint) и кэшировать его независимо. При переезде на OpenAI эта логика ломается и её надо переписывать.

Gemini implicit - это best-effort, но не гарантия. В официальных доках написано "to increase the chances of a cache hit" — именно так, не "гарантирует хит". На практике это подтверждается: в Google AI Developer Forum есть треды где люди получали 25 хитов из 100 при "идентичном промпте", 0 хитов на Flash-Lite при формально выполненном пороге в 1024 токена, "random 40–60%" на Vertex при префиксе 9k+ токенов. Если закладывать в расчёт 90% hit rate на Gemini implicit - есть реальный шанс получить 40% в продакшене и не сразу понять почему.

У Anthropic дефолтный TTL - 5 минут. При нерегулярном трафике (утренний пик, ночной простой) кэш тухнет каждую ночь и вы платите за write заново каждое утро. У OpenAI сложнее: in-memory кэш живёт 5–10 минут бездействия (иногда до часа), но на моделях gpt-5 и gpt-5.2, а также gpt-4.1 доступен extended retention до 24 часов - это принципиально другой разговор для нерегулярного трафика. У DeepSeek - диск, живёт дольше всех без дополнительных настроек.

Перед миграцией: посчитайте текущий effective cost с реальным hit rate, потом новый - с hit rate 40–50% вместо текущего. Структура промптов под новую архитектуру кэша может потребовать переработки - это не час работы, заложите время.


TTFT (Time to First Token): почему при 50k токенов кэш важнее денег (ну или почти важнее)

Prefill-фаза блокирующая - пользователь стоит и ждёт, пока модель прочитает весь контекст перед первым токеном ответа. Cache hit пропускает эту фазу для статичной части целиком. При 50k токенов это разница между 0.8 с и 12 с до первого слова.

Длина статики

TTFT без кэша

TTFT с кэшем

Снижение

4 000 токенов

~1.2 с

~0.4 с

−67%

10 000 токенов

~2.8 с

~0.5 с

−82%

50 000 токенов

~12 с

~0.8 с

−93%

Источник: данные Anthropic и кейс Caylent + Bedrock (опубликован в блоге AWS, 2025)

RAG-агент с 30k контекста и требованием TTFT < 1 с - без кэша это недостижимо физически на большинстве провайдеров, плати хоть больше, хоть меньше.


Три антипаттерна, которые убивают hit rate полностью

Полный список - тема отдельной статьи. Три самых частых, и первый встречается буквально везде:

Временные метки в системном промпте

# hit rate = 0 - каждый запрос уникален system = f"Сегодня: {datetime.now()}. Ты помощник..." # правильно - время в user-сообщение user = f"[Время: {datetime.now()}] {user_query}"

Специфичные пользовательские данные в начале system prompt

Это менее очевидно. Кажется что "Ты помогаешь {user.name} из {user.company}" - нормальная такая персонализация. Но это делает каждый системный промпт уникальным. В таком случае cache hit между запросами разным пользователей невозможен физически.

# плохо system = f"Ты помогаешь {user.name} из {user.company}..." # всё про пользователя - в user-сообщение system = "Ты корпоративный ассистент..." user = f"[Контекст: {user.name}, {user.company}] {query}"

Нестабильная JSON-сериализация tool definitions

Один символ разницы в префиксе - кэш сбрасывается. Это не только про timestamp. У Pydantic и dataclasses порядок ключей при сериализации может меняться между версиями. Обнаруживается не сразу - hit rate просто чуть ниже ожидаемого, и непонятно почему.

json.dumps(tool_params) # порядок не гарантирован json.dumps(tool_params, sort_keys=True) # правильно

Перед каждым деплоем стоит проверять хэш промпта - если изменился, кэш сбросится:

import hashlib, json def prompt_hash(system: str, tools: list) -> str: content = json.dumps({"system": system, "tools": tools}, sort_keys=True) return hashlib.sha256(content.encode()).hexdigest()


Справочник: актуальные цены кэширования (март 2026)

Провайдер / Модель

Тип кэша

Input miss

Input hit

Output

Мин. токенов

TTL

GPT-5 mini

Авто

$0.25/M

$0.025/M (−90%)

$2/M

1 024

5-10 мин / до 1 ч

GPT-5.2

Авто

$1.75/M

$0.175/M (−90%)

$14/M

1 024

5-10 мин / до 1 ч*

GPT-5.4

Авто

$2.50/M

$0.25/M (−90%)

$15/M

1 024

5-10 мин / до 1 ч

Claude Opus 4.1

Явный

$15.00/M

$1.50/M (−90%)

$75/M

1 024

5 мин / 1 ч

Claude Sonnet 4

Явный

$3.00/M

$0.30/M (−90%)

$15/M

1 024

5 мин / 1 ч

Claude Haiku 3.5

Явный

$0.80/M

$0.08/M (−90%)

$4/M

2 048

5 мин / 1 ч

Gemini 2.5 Pro

Авто + явный

$1.25/M

$0.125/M (−90%)

$10/M

2 048

до 1 ч

Gemini 2.5 Flash

Авто + явный

$0.30/M

$0.03/M (−90%)

$2.50/M

1 024

до 1 ч

Gemini 2.5 Flash-Lite

Авто + явный

$0.10/M

$0.01/M (−90%)

$0.40/M

1 024

до 1 ч

DeepSeek V3.2

Авто (disk)

$0.28/M

$0.028/M (−90%)

$0.42/M

~64

Авто

vLLM (self-hosted)

Авто (APC)

compute

~16

LRU

Что не видно из таблицы:

У Haiku 3.5 минимальный порог - 2 048 токенов, вдвое больше чем у Sonnet/Opus. Системный промпт меньше 2k - кэш не работает вообще.

Write surcharge у Anthropic зависит от TTL: за 5-минутный +25%, за 1-часовой ×2. Если трафик нерегулярный и кэш тухнет раньше чем окупится write - считайте TTL отдельно.

У OpenAI стандартный in-memory кэш живёт 5-10 минут бездействия, иногда до часа. Для части моделей (например, gpt-5 и gpt-5.2) доступен extended retention до 24 часов - в таблице выше для сравнимости указан стандартный режим, кроме пометки *.

У Gemini два режима. Implicit (авто) не гарантирует hit - провайдер сам решает что кэшировать. Explicit требует создания cache-объекта и имеет отдельную storage price. В таблице только стоимость использования; для длинных TTL добавьте storage. Отдельная деталь: минимальные пороги у Gemini нестабильны между версиями документации - официальный блог и актуальный doc-гайд дают разные числа для одних и тех же моделей. Правильнее проверять по фактическим логам.

DeepSeek хранит KV-кэш на диске за счёт компактного MLA-формата - в отличие от западных провайдеров где кэш живёт в GPU-памяти. На практике это значит что кэш не вытесняется так быстро при высокой нагрузке. Плюс минимальный порог около 64 токенов - кэшируется практически любой промпт.


FAQ

Кэш - это хранение моих данных у провайдера?

Нет. KV-кэш хранит тензоры промежуточных вычислений - не текст промпта, а результат его обработки моделью. Изоляция по API-ключу у Anthropic, по аккаунту у OpenAI. Для compliance - документация провайдера, там это прописано явно.

Высокий hit rate, но счёт не уменьшился. Почему?

Скорее всего output съедает всё. Возьмите любые 100 запросов из логов и посчитайте долю output_tokens в суммарном cost. Если больше 60% - кэш на входящие запросы не поможет: GPT-5.2 с $14/M output будет дорогим при любом hit rate. В этом случае смотреть надо на output price, а не на скидку кэша.

Что важнее - скидка на read или отсутствие наценки на write?

Зависит от паттерна трафика. Постоянный трафик, кэш не тухнет - берёте максимальную скидку на read, сейчас все топовые провайдеры дают −90%. Пиковый с паузами, TTL 5 минут - кэш тухнет, вы платите за write снова и снова, смотрите на OpenAI/Gemini/DeepSeek без write surcharge.

Как проверить что кэш вообще работает?

OpenAI: usage.prompt_tokens_details.cached_tokens Anthropic: cache_read_input_tokens (+ cache_creation_input_tokens) Google: usage_metadata.cached_tokens DeepSeek: prompt_cache_hit_tokens OpenRouter: usage.prompt_tokens_details.cached_tokens + usage.prompt_tokens_details.cache_write_tokens + поле cache_discount в ответе (сколько сэкономили на этом запросе)

cached_tokens / total_input_tokens - hit rate. Для RAG и агентов целевой показатель выше 70%. Ниже 50% - смотрите антипаттерны выше, там почти наверняка один из трёх.


Итог

Когда я начал считать, думал что всё очевидно: есть прайс, есть скидка на кэш, дальше включаем математику. Но оказалось что без S, O и h это нормально не посчитать. Gemini Flash-Lite с $0.01/M за cache read побеждает DeepSeek в двух из трёх сценариев - кто бы подумал глядя на прайс.


По механике кэша — как устроено внутри:

  • Как работает кэширование промптов - PagedAttention и автоматическое кэширование префикса - OTUS, январь 2026

Источники по поведению кэша в продакшене:

  • OpenAI: Prompt Caching guide - официальная документация

  • Google: Context caching - Gemini API docs

  • Implicit caching inconsistencies - реальные кейсы из Google AI Developer Forum


В tg-канале @sergeinotevskii иногда выкладываю расчёты, но чаще про инженерные практики и инсайты построения AI платформы.

Источник

Возможности рынка
Логотип NodeAI
NodeAI Курс (GPU)
$0.02811
$0.02811$0.02811
+3.80%
USD
График цены NodeAI (GPU) в реальном времени
Отказ от ответственности: Статьи, размещенные на этом веб-сайте, взяты из общедоступных источников и предоставляются исключительно в информационных целях. Они не обязательно отражают точку зрения MEXC. Все права принадлежат первоисточникам. Если вы считаете, что какой-либо контент нарушает права третьих лиц, пожалуйста, обратитесь по адресу [email protected] для его удаления. MEXC не дает никаких гарантий в отношении точности, полноты или своевременности контента и не несет ответственности за любые действия, предпринятые на основе предоставленной информации. Контент не является финансовой, юридической или иной профессиональной консультацией и не должен рассматриваться как рекомендация или одобрение со стороны MEXC.