Оптимизация стоимости инференса: prompt caching, маршрутизация и контроль выхода
Затраты на LLM-инференс уменьшаются на 60-90% с правильными техниками. Prompt caching, маршрутизация моделей, контроль выхода, батчинг и несколько менее известных паттернов. Числа, паттерны и продакшен-дисциплина, отличающие хорошо организованный инференс от неуправляемого счёта.
К середине 2026 года самая частая архитектурная ошибка ИИ, которую мы видим в продакшене, — переплата за инференс. Команды выкатывают LLM-функции, видят, что они работают, потом получают пятизначные ежемесячные счета, растущие с использованием. Часть функций становится убыточной. Часть компаний режет функции, которые были бы жизнеспособны при лучшей дисциплине по затратам.
Числа однозначны: большинство счетов за LLM на 60-90% больше, чем нужно. Экономия — не от одной волшебной техники, а от стека сложенных оптимизаций, каждая из которых умеренна по отдельности, но вместе они трансформируют картину.
В статье — техники, числа и продакшен-дисциплина. Считаем, что базовую маршрутизацию моделей вы уже сделали (это разобрано в другой статье); идём глубже.
Стек затрат
Затраты на LLM складываются из:
- Входные токены. То, что вы шлёте в модель. Включают system-промпт, контекст, пользовательский запрос.
- Выходные токены. То, что модель возвращает. Обычно в 3-10 раз дороже входа.
- Reasoning-токены. У reasoning-моделей — внутренние «думательные» токены. Часто такие же дорогие, как выход.
- Вызовы инструментов. При tool-calling каждое описание инструмента — входные токены.
- Retry. Неудавшиеся вызовы тоже стоят.
Оптимизация работает на каждом уровне.
Техника 1: Prompt caching
Самый большой рычаг. Большинство современных провайдеров кэшируют повторяющиеся префиксы входа — вы платите полную цену за первый раз и значительно меньше за последующие вызовы с тем же префиксом.
Цены (типично):
- Anthropic: кэшированный вход ~10% от обычной цены.
- OpenAI: автоматически для совпадения префиксов, ~50% от обычной (зависит от модели).
- Google: явный cached content, варьируется.
Как работает: первый вызов модели с конкретным префиксом — обычная цена. Последующие вызовы в окне кэша (обычно 5-60 минут, зависит от провайдера) переиспользуют кэшированное представление.
Практическая реализация:
Стройте промпты так, чтобы статический контент шёл первым, динамический — последним:
[CACHED: 10K tokens]
- System prompt
- Tool descriptions
- User's static profile
- Knowledge base snippets unlikely to change per call
[NOT CACHED: 1K tokens]
- Conversation history (changes each turn)
- Current user queryПервые 10K токенов кэшируются после первого вызова. Последующие вызовы платят ~10% за них и полную цену за 1K.
Пример экономии:
Без кэширования:
- 11K входных токенов × €3/миллион = €0.033 за вызов.
- 100K вызовов/день = €3,300/день.
С кэшированием (90% входа кэшировано):
- 1K по полной цене + 10K кэшированных по 10%:
- 1K × €3/миллион + 10K × €0.30/миллион = €0.003 + €0.003 = €0.006 за вызов.
- 100K вызовов/день = €600/день.
Экономия 82%. Реальные числа, реальные системы.
Дисциплина реализации:
- Идентифицировать статические vs динамические части промптов.
- Размещать статическое первым.
- Использовать маркеры кэша там, где провайдер поддерживает (Anthropic), для явного контроля.
- Тестировать попадания в кэш — ваша observability должна показывать cache hit rate. Если он низкий — структура промпта не та.
Это оптимизация с самым высоким ROI. Внедрите её прежде всего.
Техника 2: маршрутизация моделей
Подробно разобрано в другом месте. Кратко: разные запросы — разным моделям по сложности.
- 60% запросов — маленьким моделям.
- 30% — среднему классу.
- 10% — флагману.
Типичная экономия: 60-80% против использования флагмана на всё.
В сочетании с кэшированием — 90%+ экономии против наивного бэйзлайна.
Техника 3: контроль длины выхода
Выходные токены доминируют в стоимости для большинства кейсов. Они в 3-10 раз дороже входных; определяются моделью и промптом; часто длиннее, чем нужно.
Стратегии:
Явные инструкции по длине.
Respond in at most 100 words.Модели разумно этому следуют. Значимо режут стоимость выхода.
Структурированный выход.
Когда видимый пользователю ответ — короткие структурированные данные (JSON с конкретными полями), выход ограничен. Нет риска ненужной болтливости.
Параметр `max_tokens`.
Поставьте его. Не оставляйте по умолчанию. Если 200 токенов достаточно — поставьте max в 250 (небольшой буфер). Модель не может выйти за.
Ограничения формата.
«Только списком» или «один абзац» дают более короткие выходы, чем свободная форма.
Списки против прозы.
Списки обычно вдвое короче прозы с той же информацией.
Без преамбулы.
«Пропускайте вводные фразы. Сразу к ответу.» Модели часто начинают с «Great question...» или «Let me explain...» — потраченные впустую токены.
Пример экономии:
Процесс саммаризации. Выход по умолчанию: 500 токенов. С ограничением: 200 токенов.
- 500 токенов × €10/миллион = €0.005 за вызов.
- 200 токенов × €10/миллион = €0.002 за вызов.
Экономия 60% на выходе. Менее впечатляюще, чем 90% у кэширования, но на самой большой статье.
Техника 4: сэмплирование выхода и ранний останов
В некоторых кейсах вам нужен не полный вывод LLM — а решение или классификация.
Logprobs для классификации.
response = openai.chat.completions.create(
model="gpt-5-mini",
messages=[{"role": "user", "content": prompt}],
logprobs=True,
top_logprobs=5,
max_tokens=1
)
# Read logprobs of first token to determine likely categoryВы просите модель выдать один токен (категорию). Стоимость — один проход по входу + 1 выходной токен. Быстрее, дешевле, часто не хуже длинных ответов.
Logit bias.
Для выходов с известным множеством — смещайте logit'ы в сторону валидных опций.
import tiktoken
enc = tiktoken.encoding_for_model("gpt-4o-mini")
# logit_bias keys are token IDs (as strings), not words.
bias = {str(enc.encode(w)[0]): 100 for w in (" yes", " no", " maybe")}
response = openai.chat.completions.create(
model="gpt-4o-mini",
messages=[...],
logit_bias=bias,
max_tokens=1,
)Загоняет модель в правильный тип выхода. Дёшево и надёжно для классификации.
Техника 5: батчинг
Когда обрабатываете много объектов — батчите.
Асинхронный батчинг на уровне API.
Большинство провайдеров поддерживают async или batch API, обрабатывающие несколько запросов по сниженной цене.
- OpenAI Batch API: -50%, SLA 24 часа.
- Anthropic Message Batches: -50%, SLA 24 часа.
Если у вас есть отложенная работа без требования к реалтайму — гоните через batch. Вдвое дешевле.
Батчинг внутри промпта.
Обрабатывайте несколько объектов в одном LLM-вызове, где можно.
Вместо:
[10 separate calls, each classifying one ticket]Делайте:
[1 call, classifying 10 tickets in one prompt]У единого вызова больше входа (10 объектов), но один комплект фиксированных накладных (system-промпт, описания инструментов). Суммарно токенов меньше, чем у 10 отдельных вызовов.
Оговорка: качество может падать при слишком многих объектах на промпт. Найдите свой максимум. Обычно 5-20 объектов в промпте — норм.
Техника 6: меньшие модели на узкие задачи
Помимо стандартной маршрутизации — задумайтесь, действительно ли задаче нужна большая модель.
Классификация: GPT-5 Nano (€0.05/M токенов) часто не хуже GPT-5 (€2/M) для простой классификации. Экономия в 40x.
Извлечение: модели среднего класса справляются со структурированным извлечением. Берегите флагман для случаев, где они валятся.
Перевод: специализированные модели перевода или мелкие LLM справляются с большинством случаев.
Эмбеддинги: используйте модели, заточенные под эмбеддинги, а не универсальные LLM.
Паттерн: идентифицируйте свои «простые, узкие» нагрузки. Маршрутизируйте их в самую маленькую модель, которая делает работу адекватно. Берегите флагман для сложной работы с суждением.
Техника 7: дообученные маленькие модели
Для очень высокообъёмных узких задач — дообучайте маленькую модель.
Пример: 100K запросов классификации в день.
- GPT-5 без модификаций: €30/день в API-затратах.
- Дообученная 8B модель на выделенном инференсе: €5-10/день в инференсе плюс единоразовая стоимость дообучения.
При достаточном объёме дообученные маленькие модели быстро окупаются. Математика зависит от вашего объёма.
Это разобрано в статье о fine-tuning. Принцип: когда сходятся масштаб и узость, fine-tuning — рычаг по затратам.
Техника 8: предварительная фильтрация
Для многошаговых LLM-флоу дешёвая фильтрация ловит очевидные случаи до дорогой обработки.
Пример: классификация обращений в поддержку + ответ.
Дешёвая префильтрация:
- «Это реальный вопрос в поддержку или спам/мусор?» (классификация в один токен на малой модели.)
- «Это известный FAQ?» (Эмбеддинговый поиск; дёшево.)
Только запросы, прошедшие фильтр, доходят до дорогой генерации ответа.
Экономия: если 30% входящих запросов — мусор или FAQ-абельные, это минус 30% от ваших дорогих вызовов.
Префильтр дёшев (€0.0001 за вызов) по сравнению с генерацией ответа (€0.05 за вызов). Лёгкий ROI.
Техника 9: кэширование сверх prompt caching
Помимо кэширования промптов на стороне провайдера — кэширование на уровне приложения:
Кэширование ответов. Тот же запрос, тот же контекст, тот же ответ. Кэшируем и возвращаем без вызова модели.
def cached_call(prompt, model, ttl=3600):
cache_key = hash(prompt + model)
cached = redis.get(cache_key)
if cached:
return cached
response = call_llm(prompt, model)
redis.set(cache_key, response, ttl=ttl)
return responseДля идемпотентных запросов это полностью устраняет дубли вызовов.
Кэширование эмбеддингов. Вычисленные эмбеддинги кэшируются.
Кэширование результатов retrieval. Результаты поиска по запросу кэшируются на короткие промежутки.
Кэширование результатов инструментов. Результаты вызова инструментов кэшируются, если данные под ними не часто меняются.
Уровни кэширования складываются. На каждом слое вы экономите вызовы.
Техника 10: спекулятивное выполнение
Для латентно-чувствительных флоу, где можно предсказать следующие шаги, — спекулятивно вызывайте заранее.
Пример: агент поддержки. Вы знаете, что после описания проблемы клиентом следующий шаг обычно «резюмировать обращение». Запустите эту суммаризацию параллельно с показом подтверждения пользователю.
Если предсказание верное — ответ готов к моменту, когда нужен. Если нет — потратили один вызов впустую.
Это скорее оптимизация латентности, чем затрат, но для некоторых флоу значимо улучшает UX.
Техника 11: арбитраж провайдеров
Разные провайдеры берут по-разному за похожие модели. Пользуйтесь.
Open-source модели на дешёвых inference-провайдерах.
Llama 4 70B на Together AI: ~€0.30/M входных, €0.50/M выходных. Эквивалент по качеству у Anthropic Claude 4 Sonnet: ~€2/M входных, €15/M выходных.
Для задач, где Llama 4 70B достаточно, вы экономите в 5-30 раз.
Та же модель у разных провайдеров.
Некоторые открытые модели хостятся у нескольких провайдеров с разной ценой. Ходите по магазинам.
Self-hosting в масштабе.
При достаточном объёме (скажем, €10K+/месяц на конкретной модели) self-hosting становится дешевле API-вызовов. Требует операционных мощностей.
Арбитраж провайдеров требует сложности. Мультипровайдерная маршрутизация с фолбэком. Тесты качества под вариант каждого провайдера. В масштабе стоит того.
Техника 12: ускорение инференса
Для self-hosted — оптимизация самого слоя инференса.
vLLM, TGI, SGLang. Оптимизированные inference-серверы. 2-10x пропускной способности против наивных реализаций.
Квантизация. Запуск моделей в меньшей точности (4-bit, 8-bit). 2-4x пропускной способности, лёгкая потеря качества.
Flash Attention, paged attention. Архитектурные оптимизации, включённые в современных серверах.
Continuous batching. Серверы, батчующие запросы в полёте для лучшей утилизации GPU.
Для команд на self-hosting в масштабе — важно. Для команд на API — это забота провайдера.
Техника 13: стриминг
Стриминг не уменьшает число токенов, но улучшает UX, что влияет на восприятие cost-effectiveness.
Для длинных выходов пользователи видят, как контент появляется сразу. Они могут читать по ходу генерации. Ощущается заметно быстрее, чем ожидание полного ответа.
Для агентов стриминг промежуточных шагов даёт пользователю видимость прогресса.
Реализация: каждое современное API поддерживает стриминг. Используйте на пользовательских флоу.
Техника 14: бюджетные ограждения
Сверх оптимизации — принуждайте жёсткие бюджеты, чтобы предотвратить разгон затрат.
Бюджет на запрос. Максимум токенов на запрос. Превышение — стоп.
Бюджет на пользователя. Дневной или месячный потолок стоимости на пользователя. Throttling на подходе к нему.
Бюджет на функцию. У каждой функции свой бюджет. Авто-отключение на 10x от среднедневного.
Глобальный бюджет. Общий дневной/месячный лимит. На подходе к нему — приостановка некритичной работы.
Это напрямую денег не экономит, но предотвращает катастрофы. Один баг или атака без ограждений может быстро раздуть счёт.
Проработанный пример: реальное снижение затрат
Команда с продакшен AI поддержки имела счёт €12,000/месяц. Шесть месяцев спустя, с применёнными техниками, — €1,800/месяц, снижение на 85%.
Изменения:
- Prompt caching. Перестроены промпты под максимизацию статического префикса. ~70% входа теперь кэшируется. Экономия ~30%.
- Маршрутизация моделей. Классификация и сортировка тикетов переведены с Claude Sonnet на Claude Haiku. Экономия ~15%.
- Контроль длины выхода. Ответы ограничены 250 словами против прежних 800-1500. Экономия ~25%.
- Предварительная фильтрация. Дешёвая классификация ловит FAQ-абельные тикеты, выдаваемые из кэша. ~20% тикетов вычеркнуто из дорогого флоу. Экономия ~10%.
- Кэширование ответов для FAQ. Идентичные вопросы возвращают кэшированные ответы. Экономия ~5%.
Сложение в процентах больше суммы частей: каждая экономия применяется к оставшейся стоимости.
Качество: по каждой замеренной метрике (удовлетворённость клиента, корректность ответа, доля разрешения) качество не изменилось или чуть улучшилось.
Операционные затраты: ~80 инженерных часов за 3 месяца. ROI: окупилось за 2 недели.
Распространённые ошибки
Несколько паттернов, которые мы видим:
Ошибка 1: отсутствие отслеживания затрат. У команды нет видимости, сколько стоит каждая функция, пользователь, вызов. Без измерения оптимизация невозможна.
Ошибка 2: оптимизация не того. Потратили недели на снижение входных токенов на 5%, когда выходные занимали 80% счёта. Сначала меряйте; потом оптимизируйте крупнейшие.
Ошибка 3: регрессии качества. Резку затрат выкатили без мониторинга качества. Сэкономили деньги, потеряли пользователей. Всегда сочетайте работу над затратами с eval-сьютами.
Ошибка 4: чрезмерная маршрутизация. Агрессивная маршрутизация в маленькие модели на задачи, которые они на деле не тянут. Фальшивая экономия.
Ошибка 5: загрязнение кэша. Кэш забивается редкими запросами. Большинство записей используются один раз. Доминируют промахи. Нужна другая стратегия кэширования.
Ошибка 6: игнорирование batch API. Реалтайм там, где сошёл бы batch. Скидка в 50% валялась на столе.
Ошибка 7: переусложнение. Строят сложную оптимизацию поверх фич, которые всё равно нерентабельны. Иногда правильный ответ — «убить фичу».
Ошибка 8: нет бюджетных ограждений. Один баг даёт разгон. Катастрофа вместо лёгкого неудобства.
Культурная часть
Дисциплина по затратам частично культурна. Команды, у которых получается:
- Относятся к стоимости как к метрике, а не как к послемыслю.
- Имеют ответственного (часто на стыке инженерии и финансов).
- Смотрят затраты в недельных метриках.
- Расследуют скачки сразу.
- Ставят бюджеты по фичам; алертят на пробой порогов.
- Делают компромиссы явно (стоимость vs качество vs латентность).
Команды, у которых не получается:
- Относятся к стоимости как к чужой проблеме.
- Обнаруживают счёт в конце месяца.
- Реагируют на скачки постфактум.
- Не имеют понятия о бюджете.
- Пропускают разговор о компромиссах; оптимизируют по одной оси.
Культурное изменение труднее технического. Но именно оно делает технические изменения устойчивыми.
Траектория цен
Пара слов о большом тренде.
Затраты на LLM-инференс падают в 5-10 раз ежегодно. Модель, стоящая €5/M токенов сегодня, скорее всего, будет €0.50-€1/M через год.
Это значит:
- Некоторые оптимизации со временем значат меньше (абсолютная цена и так падает).
- Часть нагрузок, нерентабельных сейчас, станут рентабельными.
- Стройте на длинную: чистая архитектура > выжимать каждый цент сейчас.
При этом: даже с падающими ценами оптимизация важна. Неэффективные системы транжирят на любой цене. И конкурентное преимущество часто за командами, у которых эффективные операции при меньшей цене.
90-дневный план оптимизации затрат
Для команды, начинающей с «у нас есть AI-фича, затраты выше ожидаемых»:
Недели 1-2: измеряем.
- Инструментуем стоимость на вызов.
- Строим дашборды по фичам и пользователям.
- Идентифицируем крупнейших участников затрат.
Недели 3-4: быстрые победы.
- Включаем prompt caching там, где поддерживается.
- Перестраиваем 3 самых частых промпта под максимум cache hit rate.
- Ставим max_tokens на всех вызовах.
- Внедряем бюджетные алерты.
Недели 5-6: маршрутизация.
- Идентифицируем простые задачи, идущие на флагман.
- Строим роутер для 3-5 самых вызываемых эндпоинтов.
- Тестируем на регрессии качества.
Недели 7-8: выход и кэширование.
- Ограничиваем длины выхода там, где не видны пользователю.
- Добавляем application-level кэш ответов для распространённых запросов.
- Добавляем префильтры для самых высокообъёмных флоу.
Недели 9-10: продвинутое.
- Batch API для не-реалтайм работы.
- Оцениваем альтернативы провайдеров.
- Кэш эмбеддингов, кэш retrieval.
Недели 11-12: устойчивость.
- Бюджетные ограждения на каждой фиче.
- Cost-дашборды в регулярный обзор команды.
- Документация паттернов для будущих фич.
К концу 90 дней: реалистично снижение затрат на 50-80%. Качество отмониторено. Дисциплина внедрена.
Главный вывод
Стоимость LLM сокращаема — обычно на 60-90% — без потери качества. Техники хорошо известны: кэширование, маршрутизация, контроль выхода, батчинг, префильтрация, кэширование ответов, выбор модели, бюджетные ограждения.
По отдельности каждая экономит умеренно. Вместе они складываются в драматическую экономию.
Команды, которые делают это правильно, превращают убыточные AI-фичи в прибыльные. Команды, которые не делают, в итоге режут фичи, которые могли быть жизнеспособны.
Сначала меряйте. Оптимизируйте крупнейших участников. Поддерживайте мониторинг качества. Встройте дисциплину по затратам в регулярную работу команды.
Результат: AI-фичи, масштабирующиеся экономически, а не только технически. Это и делает AI устойчивой частью продукта, а не разовым заголовком при запуске.