Как снизить расходы на токены: Batch API, caching, routing и чистка контекста

Расходы на LLM API растут не только потому, что модель дорогая.

Часто проблема проще: продукт каждый раз отправляет модели слишком много лишнего. Системный промпт раздувается. История диалога тянется целиком. В запрос попадают лишние фрагменты базы знаний. Ответы получаются длиннее, чем нужно. Все задачи идут в одну сильную модель, даже если половину из них могла бы обработать более дешёвая.

Формально всё работает.

14 мин чтения2 969 словВнедрение ИИ
Александр Колотов
Александр Колотов
Автор CompanionAI
Как снизить расходы на токены: Batch API, caching, routing и чистка контекста

По факту счёт растёт, а команда начинает искать виноватого в прайсах. Хотя виноватый часто сидит в архитектуре запроса и делает вид, что он “временное решение”.

Если вы уже разобрались, что такое входные, выходные и кэшированные токены, следующий вопрос практический: как снизить расходы без поломки качества.

Ответ короткий: не резать всё подряд.

Ответ нормальный: считать дорогие сценарии, использовать Batch API для несрочных задач, проектировать запросы под кэширование, маршрутизировать задачи между моделями и не отправлять модели весь цифровой чердак.

Почему счёт за LLM API растёт даже на нормальной модели

Один и тот же AI-сервис может стоить по-разному при одинаковой модели.

Разница возникает не в названии модели, а в том, что именно вы ей отправляете и что просите вернуть.

Дорогими становятся привычки:

Что делает продуктПочему это дорого
Отправляет всю историю диалогакаждый следующий запрос становится тяжелее
Добавляет все инструкции “на всякий случай”модель читает дубли и лишние правила
Передаёт много фрагментов базы знанийрастёт input и появляется шум
Использует сильную модель для всех задачпростые операции стоят как сложные
Просит подробный ответ по умолчаниюрастёт output
Не отделяет срочные задачи от несрочныхтеряется возможность batch-обработки
Не держит стабильный префикс промптахуже работает кэширование

Если AI-бот отвечает на вопрос клиента, ему не всегда нужно перечитывать все правила компании, всю историю переписки и половину базы знаний.

Иногда ему нужен один статус, три факта и короткий ответ.

Но если архитектура устроена лениво, модель получает всё подряд. Модель не спорит. Она читает. Потом выставляется счёт.

Не всякая стоимость плохая

Оптимизация расходов не означает, что любой запрос должен стать максимально дешёвым.

Есть нормальные расходы. Например: сложная аналитика, проверка важного ответа, работа с юридически чувствительным текстом, финальная валидация результата перед отправкой клиенту.

Там экономия любой ценой может стоить дороже, чем сами токены.

А есть мусорные расходы. Их и нужно искать первыми.

Тип расходаПримерЧто делать
Оправданныйсильная модель проверяет важный ответоставить и считать стоимость
Мусорныйодно правило повторяется в системном промпте и базе знанийубрать дубли
Мусорныйвся история диалога отправляется каждый раззаменить summary
Спорныйвсе задачи идут в самую дорогую модельразделить сценарии
Спорныймодель всегда пишет длинные ответызадать формат и лимит

Цель не в том, чтобы удешевить всё подряд.

Цель — убрать переплату, которая не улучшает результат.

Сначала найдите самые дорогие сценарии

Нельзя нормально оптимизировать то, что вы не считаете.

Если в продукте виден только общий месячный счёт за API, команда работает вслепую. Счёт вырос — неприятно. Почему вырос — непонятно. Кто виноват — модель, пользователи, длинные документы или “ну оно само”.

Минимально нужно логировать:

МетрикаЗачем нужна
модельпонять, где используется дорогая модель
тип сценарияотделить чат, RAG, отчёты, классификацию
input tokensувидеть тяжёлый входной контекст
output tokensнайти слишком длинные ответы
cached tokensпонять, работает ли кэширование
стоимость запросасчитать экономику сценария
latencyвидеть влияние на скорость
ошибки и повторыпроверять, не сломалась ли точность

Средняя стоимость запроса часто обманывает.

Она может выглядеть терпимо, пока небольшая доля тяжёлых запросов съедает основную часть бюджета.

Например, 80% обращений — короткие FAQ. Они стоят недорого. Но 20% запросов идут через RAG по длинным документам, тащат много фрагментов базы знаний и каждый раз возвращают подробный ответ. Если смотреть только среднее значение, проблема будет замазана.

Считать лучше по сценариям:

  • чат;
  • поиск по базе знаний;
  • суммаризация документов;
  • классификация обращений;
  • генерация отчётов;
  • массовая обработка данных;
  • внутренний ассистент;
  • проверка результата.

После этого видно, где перерасход: во входном контексте, в output, в выборе модели, в повторяющихся инструкциях или в отсутствии batch-обработки.


Batch API: когда можно платить меньше за несрочные задачи

Batch API нужен для задач, где результат не нужен пользователю прямо сейчас.

Это не волшебная кнопка “сделать дешевле весь AI-продукт”. Это способ дешевле обработать большой объём запросов асинхронно.

У OpenAI Batch API предназначен для асинхронной обработки запросов и даёт 50% скидку относительно синхронных API; текущее окно обработки — до 24 часов. Источник: platform.openai.com.

У Gemini Batch API тоже рассчитан на крупные несрочные задачи, обрабатывает запросы асинхронно и стоит 50% от стандартной интерактивной стоимости для эквивалентной модели. Источник: Google AI for Developers.

Batch API подходит для:

  • массовой классификации обращений;
  • ночной обработки архивов;
  • подготовки черновиков;
  • embeddings;
  • проверки карточек товаров;
  • суммаризации массива документов;
  • анализа старых диалогов поддержки;
  • пакетной модерации;
  • подготовки данных для отчёта.

Batch API не подходит для:

  • живого чата;
  • клиентской поддержки в реальном времени;
  • ответа в интерфейсе, где пользователь ждёт результат;
  • проверки статуса заказа;
  • сценария “нажал кнопку — получил ответ”.
ЗадачаBatch подходит?Почему
Классификация 10 000 обращенийДарезультат не нужен мгновенно
Ответ клиенту в чатеНетпользователь ждёт сейчас
Ночная обработка документовДаможно выполнить асинхронно
Поиск статуса заказаНетнужен быстрый ответ
Подготовка черновиков описанийДаможно обработать пачкой
Подсказка менеджеру во время звонкаНетважна задержка

Простой критерий такой: если пользователь не смотрит на экран и не ждёт ответ прямо сейчас, задачу можно рассмотреть для batch-обработки.

Если ждёт — не надо превращать интерфейс в медитацию на спиннер. Пользователь пришёл за результатом, а не за практикой терпения.

Кэширование: как не платить заново за повторяющийся контекст

Во многих AI-продуктах часть запроса повторяется постоянно.

Например:

  • системный промпт;
  • роль ассистента;
  • правила ответа;
  • описание компании;
  • схема данных;
  • примеры;
  • инструкции безопасности;
  • структура JSON;
  • одни и те же документы;
  • одинаковые tool definitions.

Если эти части каждый раз одинаковые, провайдер может обработать их дешевле и быстрее через кэширование.

У OpenAI prompt caching работает автоматически на современных моделях. В официальной документации указано, что он может снижать latency до 80%, а стоимость input-токенов — до 90%. Cache hits возможны для точного совпадения префикса, поэтому статичные инструкции и примеры лучше держать в начале запроса, а переменные данные — в конце. Источник: platform.openai.com.

Ключевое слово — точного.

Кэширование работает не потому, что промпты “примерно похожи по смыслу”. Для кэша важна стабильность структуры и повторяющихся блоков.

Что повторяетсяКак сделатьЧто мешает
Системный промптдержать стабильнымпереписывать при каждом запросе
Правила ответавынести в постоянный блоквставлять в разном порядке
Схема JSONфиксировать структуруменять поля без причины
Примерыхранить в одном местекаждый раз генерировать заново
Документыкэшировать крупные повторяющиеся блокисмешивать с динамическими данными
Пользовательский контекстставить после статичного блокавставлять в начало запроса

Хорошая структура запроса:

  1. Постоянная системная инструкция
  2. Постоянные правила ответа
  3. Постоянная схема данных
  4. Постоянные примеры
  5. Переменный пользовательский запрос
  6. Переменные данные из CRM, базы знаний или истории

Плохая структура:

  1. Сегодняшний пользовательский запрос
  2. Немного системных правил
  3. Случайный фрагмент базы знаний
  4. Ещё кусок инструкции
  5. История диалога
  6. Ещё одно правило, которое забыли вставить выше

Второй вариант может работать. Но кэширование будет срабатывать хуже. Иногда не будет вообще.

Промпт не нужно каждый раз украшать новыми словами “для естественности”. Машина красоту не оценит. Счёт выставит.

У OpenAI, Claude и Gemini кэширование считается по-разному

Нельзя один раз прочитать документацию OpenAI и решить, что у всех провайдеров caching устроен одинаково.

ПровайдерКак устроено кэшированиеЧто важно
OpenAIprompt caching работает автоматически для повторяющихся префиксовстатичный контент лучше ставить в начало запроса
Anthropic Claudeотдельно учитываются cache writes и cache reads, есть TTL 5 минут и 1 часнужно считать экономику записи и чтения кэша
Geminiесть implicit caching и explicit caching, explicit caching учитывает TTL и хранениедля гарантированной экономии нужен explicit caching

У Anthropic prompt caching управляется через cache control: в документации отдельно описаны cache creation, cache read и TTL 5 минут или 1 час. Источник: Claude API Docs.

У Gemini есть implicit caching и explicit caching. Explicit caching позволяет вручную кэшировать контент, выбирать TTL и получать гарантированную экономию при повторном использовании; стоимость зависит от числа кэшируемых токенов, срока хранения и обычных input/output-расходов. Источник: Google AI for Developers.

Принцип общий: повторяющийся контекст можно сделать дешевле.

Экономика разная.

Перед внедрением кэширования нужно смотреть документацию конкретного провайдера и считать свою нагрузку. Иначе можно красиво “оптимизировать” в презентации и неприятно удивиться в биллинге.

Маршрутизация моделей: не каждый запрос должен идти в дорогую модель

Во многих продуктах все запросы по умолчанию отправляют в одну сильную модель.

Так проще. Но не всегда разумно.

Не каждая задача требует самой дорогой модели. Классификация обращения, извлечение e-mail из текста, проверка формата JSON, нормализация названия компании, короткий служебный ответ — это не всегда работа для тяжёлой модели.

Простые задачи можно отдавать более дешёвой модели:

  • классификация;
  • извлечение полей;
  • проверка формата;
  • нормализация текста;
  • короткая суммаризация;
  • определение языка;
  • выбор сценария;
  • простые служебные ответы.

Сложные задачи лучше оставлять сильной модели:

  • аналитика;
  • неоднозначные запросы;
  • многошаговые рассуждения;
  • ответы с высокой ценой ошибки;
  • работа с конфликтующими данными;
  • финальная проверка результата;
  • юридически или финансово чувствительные формулировки.

Пример маршрута для AI-бота поддержки:

Запрос пользователя → дешёвая модель определяет тип обращения → система выбирает сценарий → простые вопросы закрываются дешёвой моделью → сложные или рискованные вопросы уходят в сильную модель → результат проверяется по формату → пользователь получает ответ.

Это и есть маршрутизация моделей, или routing.

Смысл не в том, чтобы заменить сильную модель слабой. Смысл в том, чтобы не заставлять сильную модель делать всю подсобную работу.

Плохой routing опасен. Если система неверно определяет сложность задачи, дешёвая модель начнёт отвечать там, где нужна точность.

На графике расходов всё станет лучше.

В продукте — хуже.

А пользователю всё равно, что вы сэкономили на токенах. Он видит неправильный ответ.

Чистка контекста: как снизить input без потери смысла

Контекст — это не склад.

Но во многих AI-продуктах его используют именно так. В запрос отправляют всё, что может пригодиться: инструкцию, старую инструкцию, новую инструкцию, FAQ, документы, историю, комментарии менеджера, фрагменты базы знаний и “ещё вот это, чтобы наверняка”.

Наверняка получается дорого.

Чистка контекста снижает input-токены. То есть уменьшает объём текста, который модель должна прочитать перед ответом.

Первое, что нужно сделать, — убрать дубли.

Если одно и то же правило есть в системном промпте, базе знаний и дополнительной инструкции, модель читает его несколько раз. Польза сомнительная. Стоимость реальная.

Второе — отделить постоянное от переменного.

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

Третье — не отправлять всю базу знаний.

Если у вас RAG-сценарий, задача retrieval-части — найти релевантные фрагменты. Не нужно скармливать модели весь справочник “для надёжности”. Это повышает стоимость и может ухудшить ответ: чем больше лишнего текста, тем выше шанс, что модель зацепится не за тот фрагмент.

Практический минимум:

Что сделатьЗачем
Оставить постоянные инструкции в одном местеубрать дубли
Разделить постоянное и переменноеулучшить структуру запроса
Ограничить число фрагментов базы знанийснизить input
Ранжировать фрагменты по релевантностиубрать шум
Не отправлять устаревшие данныеснизить риск ошибки
Сокращать длинные документы до нужных частейне платить за лишнее
Убрать данные “на всякий случай”не раздувать контекст

Лучше 3–5 релевантных фрагментов, чем 15 случайных кусков, которые раздувают запрос и мешают ответу.

Суммаризация истории вместо бесконечного диалога

В чат-ботах и AI-ассистентах история диалога быстро становится дорогой.

Первые сообщения стоят немного. Потом пользователь уточняет. Потом меняет задачу. Потом возвращается к старому вопросу. Потом добавляет ограничение. Потом просит “учесть всё выше”.

Если каждый раз отправлять всю переписку, каждый следующий запрос становится дороже предыдущего.

В какой-то момент пользователь пишет одну строку, а модель перечитывает роман в трёх томах.

Решение — summary истории.

Не нужно удалять историю вслепую. Нужно сжимать её до рабочего состояния:

  • Цель клиента
  • Важные факты
  • Ограничения
  • Принятые решения
  • Текущий статус
  • Открытые вопросы
  • Следующий шаг

Что хранить в summary:

  • что хочет пользователь;
  • какие факты уже известны;
  • какие ограничения важны;
  • что уже согласовано;
  • какой сейчас статус;
  • какой следующий шаг;
  • что нельзя забыть.

Когда обновлять summary:

  • после смены задачи;
  • после подтверждения условий;
  • после изменения статуса;
  • после передачи менеджеру;
  • после загрузки важного документа;
  • после завершения этапа.

Так ассистент сохраняет смысл, но не тащит в каждый запрос всю переписку.

Это особенно важно для клиентской поддержки, личных кабинетов, CRM-ассистентов и внутренних AI-сервисов. Там длинный контекст — обычная история. И дорогая, если её не контролировать.

Ограничение ответа: как не платить за лишний output

Команды часто смотрят на input-токены и забывают про output.

А ответ модели тоже стоит денег. Иногда output-токены дороже input-токенов. Поэтому фраза “ответь подробно” в массовом продукте может стать маленьким финансовым преступлением.

Без злого умысла, зато регулярно.

Не каждый ответ должен быть длинным.

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

Если менеджер просит подсказку по лиду, ему не нужен эссеистический разбор. Ему нужны 3 факта и рекомендация.

Если API ждёт структурированные данные, ему не нужна вежливая прелюдия: “Конечно, вот JSON”. Ему нужен JSON.

Примеры ограничений:

  • Ответь в 3 пунктах.
  • Верни только JSON.
  • Дай статус и следующий шаг.
  • Не добавляй пояснения, если данных достаточно.
  • Сформулируй ответ не длиннее 500 знаков.
  • Сначала вывод, потом детали.

Хороший промпт задаёт не только задачу, но и формат результата.

Плохо:

Проанализируй обращение клиента и дай ответ.

Лучше:

Проанализируй обращение клиента. Верни:

  1. тип обращения;
  2. срочность;
  3. краткий ответ клиенту до 400 знаков;
  4. нужно ли передать менеджеру: да/нет.

Модель не обязана угадывать, насколько длинный ответ вам нужен. Если не задать формат, она часто выберет безопасную многословность.

Безопасную для себя. Платную для вас.

Пример до и после: как один AI-бот стал дешевле без потери смысла

Представим AI-бота поддержки.

Он отвечает клиентам по базе знаний, смотрит историю обращения и иногда передаёт диалог менеджеру.

Было

В каждый запрос отправлялось:

  • длинный системный промпт;
  • все правила ответа;
  • вся история переписки;
  • 8 фрагментов базы знаний;
  • дополнительная инструкция для текущего сценария;
  • просьба “ответить подробно и дружелюбно”.

Все запросы шли в одну сильную модель.

Несрочная аналитика старых обращений выполнялась через обычный синхронный API.

Стало

Системный промпт сделали стабильным.

Постоянные правила вынесли в один блок.

Историю диалога заменили summary.

Для RAG стали передавать 3–5 релевантных фрагментов вместо 8–12.

Ответ ограничили форматом: краткий ответ, статус, следующий шаг.

Простую классификацию обращений отдали более дешёвой модели.

Сложные ответы и спорные случаи оставили сильной модели.

Анализ старых обращений перевели в batch-обработку.

Что изменилось

БылоСталоЭффект
вся история в каждом запросеsummary историименьше input-токенов
много фрагментов базы знанийтолько релевантные фрагментыменьше шума и стоимости
одна дорогая модель для всегоrouting моделейдешевле простые операции
подробный ответ по умолчаниюформат и лимит ответаменьше output-токенов
синхронная массовая обработкаBatch APIниже стоимость несрочных задач
нестабильный промптстабильный префиксвыше шанс на caching

Здесь нет одного чудо-приёма.

Экономия складывается из нескольких решений. В этом и смысл: расходы на токены редко снижаются одной правкой. Обычно это аудит архитектуры.

Где экономия ломает качество

Оптимизация может навредить.

Если просто резать всё подряд, продукт станет дешевле и хуже. Это не победа. Это скидка на собственную ошибку.

Четыре частые проблемы.

Первая — слишком короткий контекст.

Модель не видит нужных данных и отвечает общими словами. Пользователь задаёт уточняющий вопрос. Потом ещё один. В итоге экономия исчезает, потому что запросов становится больше.

Вторая — слишком дешёвая модель.

Она может нормально классифицировать простые обращения, но ошибаться в сложных. Особенно там, где нужны нюансы, логика, длинный контекст или высокая точность.

Третья — слишком жёсткие лимиты ответа.

Краткость хороша, пока она не превращается в обрубок. Если пользователю нужно объяснение, а он получает сухую строку, качество падает.

Четвёртая — слепое удаление истории.

Ассистент теряет договорённости, статус клиента и важные ограничения. Снаружи это выглядит так, будто компания ничего не помнит.

Проверять качество после оптимизации нужно не на ощущениях, а по метрикам:

  • доля повторных вопросов;
  • доля эскалаций к человеку;
  • ошибки классификации;
  • ручные правки менеджеров;
  • жалобы пользователей;
  • падение точности ответов;
  • рост времени решения задачи.

Если запрос стал дешевле, но пользователь чаще переспрашивает, вы не сэкономили. Вы перенесли стоимость в другой столбец.

Бухгалтерия такое любит. Продукт — нет.

Чек-лист аудита расходов на токены

Перед тем как переписывать промпты, проверьте систему.

  • Логируются ли input, output и cached tokens?
  • Видна ли стоимость по каждому сценарию?
  • Есть ли список самых дорогих типов запросов?
  • Отделены ли чат, RAG, суммаризация, классификация и отчёты?
  • Используется ли Batch API для несрочных массовых задач?
  • Стабильны ли повторяющиеся части промпта?
  • Разделены ли постоянный и переменный контекст?
  • Проверено ли, срабатывает ли caching?
  • Используется ли routing моделей?
  • Не отправляется ли вся история диалога в каждый запрос?
  • Есть ли summary для длинных диалогов?
  • Ограничены ли формат и длина ответа?
  • Проверяется ли качество после оптимизации?

Если на половину вопросов ответ “не знаем”, проблема не только в стоимости токенов.

Проблема в том, что AI-функция уже работает, но её эксплуатацией никто толком не управляет.

Вывод: расходы на токены снижают архитектурой

Сократить промпт полезно. Но этого мало.

Настоящая экономия появляется, когда команда управляет всей цепочкой:

  1. какой сценарий запускается;
  2. какая модель используется;
  3. какой контекст попадает в запрос;
  4. что можно кэшировать;
  5. что можно обработать пакетно;
  6. как ограничить ответ;
  7. как хранить историю;
  8. где нельзя экономить без потери качества.
Токены — это не только техническая единица текста. Это себестоимость AI-функции.

Если продукт не считает токены, он не управляет расходами.

Если продукт отправляет модели всё подряд, он платит за всё подряд.

Если продукт разделяет сценарии, чистит контекст, использует caching, batch-обработку и routing, расходы становятся управляемыми.

Не магически низкими.

Управляемыми.

А это уже нормальная инженерная история, а не надежда на то, что следующий счёт будет добрее.