Кэширование контекста в LLM: как сократить расходы на суммаризацию
Почему второй запуск одного и того же суммаризатора иногда оказывается почти вдвое дешевле первого, а иногда выходит дороже? В этом вопросе самое важное — не просто «включить кэш», а понять, какая часть запроса действительно повторяется.

Кэширование контекста в LLM для суммаризации позволяет повторно использовать уже вычисленные состояния модели, сокращая расходы на входные токены и время ожидания первых слов ответа.
Хорошая новость: в подходящих сценариях экономия на чтении кэша достигает 90%, а задержка до первого токена для длинных промптов у Anthropic может снижаться на 85%. Но эти цифры относятся к повторному использованию неизменяемого префикса. Если каждый запрос отличается с первого символа, ничего не изменится. Придётся платить и считать всё заново.
Что именно LLM сохраняет в кэше
На пальцах процесс выглядит так:
1. Системный промпт, инструкция, примеры и исходный текст превращаются в токены.
2. Трансформер вычисляет для них механизм внимания и сохраняет тензоры Key и Value.
3. При следующем похожем запросе эти вычисления для неизменного префикса используются повторно.
4. Модель заново обрабатывает изменившуюся часть запроса и генерирует новый ответ.
Кэш хранит результаты вычисления внимания для неизменного префикса. Текст готового ответа остаётся за пределами этого механизма. Если сервис должен вернуть полностью идентичную сумму, для этой задачи обычно используют отдельный подход: semantic caching или exact-match caching в Redis. Там сравниваются запросы и при точном совпадении возвращается сохранённый результат.
Это принципиальное различие. Prompt caching помогает повторно выполнить вычислительную часть запроса, а semantic caching пропускает генерацию целиком. Для новостного дайджеста оба подхода могут быть полезны, только экономия достигается разными путями.
Отсюда ещё одно ограничение: скидка распространяется на входные токены кэшированного префикса. Выходные токены суммаризации оплачиваются по обычному тарифу. Если модель генерирует длинный разбор с цитатами и пересказом, сэкономленные деньги на входе не превратятся в скидку на весь готовый текст.
Кэширование контекста — это способ не повторять тяжёлые вычисления над неизменной частью запроса.
Сколько реально экономит: Anthropic, OpenAI и Gemini
Провайдеры подходят к кэшированию по-разному, хотя принцип остаётся общим: повторное чтение дешёвого префикса оплачивается дешевле первого обращения.
| Провайдер | Как включается | Порог префикса | Скидка и дополнительные условия | Срок жизни кэша |
|---|---|---|---|---|
| Anthropic | Явно, через параметр cache_control | От 1024 токенов | Чтение стоит 0,1 от базовой цены ввода, то есть скидка до 90%; запись в 5-минутный кэш стоит 1,25 от базовой цены | 5 минут или 1 час |
| OpenAI | Автоматически, без ручной настройки | От 1024 токенов | Скидка 50% на повторные входные токены при срабатывании автоматического кэша | От 30 минут |
| Google Gemini | Через Context Caching | 2048 или 4096 токенов в зависимости от модели; также доступен фиксированный кэшируемый объект | Скидка до 75–90%; при фиксированном объекте добавляется плата за хранение в течение часа | Зависит от выбранного механизма |
У Anthropic кэширование появилось в августе 2024 года, автоматическое кэширование в OpenAI API — в октябре 2024-го. Почти за два года подход фактически стал стандартным для систем, где один и тот же объём входного контекста используется много раз.
У Anthropic максимальная скидка выглядит особенно привлекательно, но у неё есть условие: запись в пятиминутный кэш оплачивается по множителю 1,25. Для сервиса с большим числом повторных обращений это быстро окупается. Для единственного короткого запроса та же настройка увеличивает расходы на 25%.
OpenAI выглядит проще: кэш включается автоматически, а повторный вход получает 50-процентную скидку. Здесь не приходится вручную расставлять breakpoints или думать, куда именно поставить cache_control. Однако автоматический режим не гарантирует попадание: если префикс изменился или истекло время жизни, запрос снова оплачивается как обычный.
У Gemini скидка может достигать 90%, но условия зависят от модели и способа кэширования. Длинный префикс можно кэшировать непосредственно в контексте либо заранее сохранить как фиксированный объект. Во втором случае к цене входа добавляется почасовая плата за хранение.
Отдельно про скорость: для длинных промптов у Anthropic задержка до первого токена, то есть TTFT, может снижаться до 85%. Это особенно заметно в новостных пайплайнах, где модель получает большой корпус статей и затем генерирует краткий дайджест. Экономия времени и денег идут здесь вместе, хотя TTFT и полная длительность ответа — разные показатели.
Где суммаризатор выигрывает сильнее всего
Кэш раскрывается именно на повторяемой части запроса, и обычный объём текста тут ничего не гарантирует. Для информационного дайджеста обычно выигрывают три сценария.
1. Длинная редакционная инструкция и примеры. У суммаризатора есть постоянная «начинка»: правила отбора новостей, стиль изложения, схема анонса, ограничения по длине, несколько готовых примеров. Эта часть меняется редко, а модель вынуждена обрабатывать её при каждом запуске. Если поставить инструкцию и примеры в начало запроса, а саму новость — после них, тяжёлая префиксная часть вычисляется повторно.
2. Один большой документ с несколькими формулировками задачи. Из исходника требуется сделать короткий анонс, подробный пересказ, список тегов и отдельную проверку фактов. Принцип тот же: неизменяемый исходный текст располагается раньше, а формулировка конкретного задания добавляется в хвост. Тело документа используется повторно, а каждый вариант суммаризации генерируется отдельно.
3. Пакетная обработка одной и той же основы. Когда через модель прогоняют большой корпус с несколькими типами срезов, выгоднее группировать запросы по общему префиксу, чем случайно перемешивать длинные документы и меняющиеся команды. Так больше запросов попадает в один кэш и реже истекает его время жизни.
Представьте ежедневный выпуск новостей. Редакционные правила, шаблон рубрики и пять примеров машинного пересказа остаются неизменными, а тело каждой статьи меняется. В таком пайплайне кэшировать имеет смысл именно постоянный префикс. Сам материал новости остаётся динамическим и рассчитывается отдельно.
Если же каждая статья приходит только один раз, а инструкция состоит из двух коротких предложений, экономия может не появиться. Кэширование хорошо работает с повторяемым объёмом. Сам факт обработки большого текста ещё ничего не гарантирует.
Самая ценная часть для кэша — та, которая чаще всего повторяется дословно и стоит дороже обычного текста.
Ещё один полезный сценарий возникает, когда один корпус используют несколько внутренних сервисов. Редакционный дайджест, архивная карточка и краткая новостная лента могут иметь разные форматы, но общий исходник. При правильном порядке токенов модель повторно использует дорогую обработку документа, а различия сводятся к короткому хвосту запроса.
Почему кэш сбрасывается из-за даты и ID
Здесь скрывается самый неприятный подводный камень суммаризаторов: кэширование префикса строго позиционное. Совпадение первого токена запускает поиск сохранённого состояния, совпадение второго продолжает его, и так до первого различия.
Если в начало запроса вставлена текущая дата, номер сессии или идентификатор пользователя, изменение этой строки обрывает совпадение. Дальнейшие инструкции и примеры снова приходится вычислять, хотя сами они не менялись.
Поэтому запрос лучше разложить на две части:
- Стабильный префикс — системная инструкция, правила, примеры, справочники или крупный исходный документ.
- Переменный суффикс — текст конкретной новости, дата, ID сессии, пользовательский вопрос и формат ответа.
Для ежедневного выпуска это может выглядеть так: сначала идут неизменные правила и few-shot примеры, затем материал статьи, а в конце находится задание «сделай краткий анонс» и служебные параметры запроса. При следующем запуске начало совпадает, поэтому модель использует сохранённые KV-состояния.
Если изменился один символ в начале длинного префикса, несовпадение проходит через все последующие токены. Чем раньше находится переменная величина, тем больше хвоста запроса приходится считать заново. Поэтому дату не стоит ставить перед редакционным руководством, а ID пользователя — перед общим корпусом.
Отдельная головная боль — форматирование. Пробел, изменённый перенос строки или новая версия системной инструкции тоже меняют последовательность токенов. На уровне API это выглядит как другой префикс, даже если смысл для человека остался прежним.
Версионирование инструкций лучше продумать заранее. Если добавляете новый абзац в конец постоянного руководства, старый префикс можно оставить нетронутым и кэшировать отдельно. Если меняете начало, придётся создавать новую ветку кэша.
Считаем окупаемость: когда кэш снижает расходы
Давайте посмотрим на цифры без магических «до 90%». Пусть C — обычная стоимость входных токенов одного и того же префикса. Расчёт предполагает, что кэш срабатывает, срок жизни не истёк, а выходные токены во всех вариантах одинаковы.
| Сценарий | Без кэша | С кэшем | Изменение |
|---|---|---|---|
| Anthropic, 1 обращение | C | 1,25C | На 25% дороже |
| Anthropic, 2 обращения | 2C | 1,35C | На 32,5% дешевле |
| Anthropic, 10 обращений | 10C | 2,15C | На 78,5% дешевле |
| OpenAI, 2 обращения | 2C | 1,5C | На 25% дешевле |
| OpenAI, 10 обращений | 10C | 5,5C | На 45% дешевле |
Для Anthropic формула выглядит так: одна запись стоит 1,25C, каждый последующий cache read — 0,1C. Поэтому десять обращений обходятся в 1,25C + 9 × 0,1C = 2,15C вместо 10C. Порог окупаемости находится примерно после 1,4 обращения к общему префиксу, а на дискретных запросах уже второй вызов даёт экономию.
Расчёт относится к пятиминутному кэшу Anthropic. Для часового варианта действует другой тариф, поэтому переносить множитель 1,25 без проверки не стоит.
В модели OpenAI первый вход оплачивается полностью, а последующие получают скидку 50%. Если автоматический кэш срабатывает десять раз подряд, входные токены обходятся в C + 9 × 0,5C = 5,5C. Это уже 45% экономии без необходимости вручную управлять параметрами кэша.
Для Gemini при скидке 75–90% десять обращений дают примерно 3,25C–1,9C вместо 10C, то есть экономию около 67,5–81%. Здесь я считаю только входные токены по указанной скидке. При использовании фиксированного кэшируемого объекта к результату добавляется почасовая плата за хранение.
Три обстоятельства чаще всего превращают кэширование в дорогое украшение:
1. Запрос одноразовый и короткий. Ручная запись в кэш Anthropic увеличивает цену вызова на 25%.
2. Префикс не достигает минимального порога. Для OpenAI и Anthropic это 1024 токена, для моделей Gemini — 2048 или 4096 в зависимости от модели.
3. Кэш не переживает паузу или вытесняется с оборудования. Стандартные TTL ограничены, а внутренние алгоритмы вытеснения OpenAI и Google публично не раскрыты. Гарантированного hit rate в продакшене нет.
Как настроить кэширование без инженерной сатаны
Я бы начала с одного честного вопроса: какая часть нашего промпта действительно повторяется слово в слово? Часто ответ находится не там, где команда изначально искала.
1. Разделите запрос на стабильную и переменную части. Отдельно выпишите инструкции, примеры, справочники, исходный корпус и то, что меняется для каждой статьи.
2. Поставьте повторяемый блок в начало. Дату, ID, пользовательский текст и конкретное задание перенесите в хвост. Если один документ обрабатывается несколькими способами, оставьте его перед разными формулировками задания.
3. Проверьте минимальный порог. Короткий префикс не запустит экономию ни у OpenAI, ни у Gemini. Иногда корпус выгоднее объединить с инструкцией, иногда — разбить запросы настолько, чтобы повторяемая часть стала длиннее.
4. Учитывайте способ включения. В Anthropic нужно явно отметить кэшируемый блок через cache_control; OpenAI выполняет кэширование автоматически; у Gemini есть пороговый и объектный режимы.
5. Группируйте запросы по времени жизни. Обращения к пятиминутному кэшу лучше отправлять пачками. Если между новостями проходит больше пяти минут, можно использовать часовой TTL Anthropic или подходящий объектный кэш Gemini.
6. Измеряйте попадания и стоимость. Считайте cache hit rate, расходы на входные токены, число записей и TTFT. Без этих чисел легко оптимизировать не тот участок пайплайна.
7. Отделяйте повторный ввод от повторного ответа. Если один и тот же запрос с неизменными параметрами должен возвращать готовый текст без вызова LLM, semantic caching или точный Redis-кеш подходят лучше. Prompt caching остаётся полезен, когда меняются инструкции, формат ответа или сам генерируемый текст.
Мой простой лайфхак: возьмите реальный запрос из продакшена, закройте изменяемый хвост и посмотрите, сколько одинаковых токенов осталось в начале. Если это большой стабильный блок, кэширование уже почти настроено — нужно лишь перестать вставлять в его середину изменчивую дату.
Если вы выпускаете регулярный дайджест, начните с кэширования редакционного руководства и примеров, затем измерьте экономию. Для корпуса, из которого готовится несколько срезов, попробуйте кэшировать исходный документ. Кэширование контекста зарабатывает на повторении, поэтому сначала найдите именно то, что повторяется, и только потом переключайте настройки провайдера.