Free-LLMs

Как снизить расходы на LLM API: токены, кэширование и маршрутизация моделей

Цена успешной задачи, кэш префикса, batch и роутер: как платить за LLM API меньше.

Cost
Расходы на LLM API
🤖
Мониторинг бесплатных моделей в Telegram Бот @freellms_bot присылает новые бесплатные модели и AI-акции.
→

Снизить расходы на LLM API можно тремя рычагами: платить меньше за каждый токен (кэш префикса, batch, дешёвая модель), отправлять меньше токенов (короткий контекст, ограничение вывода) и не оплачивать неудачные попытки (маршрутизация с эскалацией и проверка результата). Начинать нужно не с поиска самой дешёвой модели, а с метрики: цены успешной задачи. Разбираем, как её считать, что сегодня написано в документации OpenAI, Anthropic, Google и DeepSeek про кэширование, и как собрать роутер, который не ломает качество.

Считайте цену успешной задачи, а не запроса

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

цена_успешной_задачи = стоимость_запроса × попытки_на_задачу / доля_успеха

Здесь стоимость запроса считается по формуле input × цена_input + cached × цена_cached + output × цена_output, попытки на задачу включают повторы и шаги агента, а доля успеха измеряется на вашем наборе проверок. Пример на условных числах (это расчёт по формуле, а не замер):

ВариантСтоимость одной попыткиДоля успехаЦена успешной задачи
Дешёвая модель$0.00260%$0.002 / 0.6 = $0.0033
Сильная модель$0.01095%$0.010 / 0.95 = $0.0105
Дешёвая, при неудаче сильная (идеальная проверка)$0.002 + 0.4 × $0.010 = $0.0060.6 + 0.4 × 0.95 = 98%$0.006 / 0.98 = $0.0061

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

Из чего складывается счёт: input, cached, output

У большинства API три ценовые ветки. Input-токены: всё, что вы отправили. Cached-токены: часть input, совпавшая с ранее обработанным префиксом, она стоит дешевле. Output-токены: то, что сгенерировала модель, они дороже input, а у рассуждающих моделей включают токены размышлений. Отсюда практические выводы:

  • Длинный статичный префикс (системный промпт, инструкции, примеры, описания инструментов) нужно ставить в начало и не менять между запросами. Любое отличие внутри префикса сбрасывает кэш для всего, что идёт после него.
  • Переменную часть (вопрос пользователя, найденные фрагменты, время, идентификаторы) ставьте в конец.
  • Лимит max_tokens и просьба отвечать структурно и кратко режут самую дорогую ветку.

Prompt caching у четырёх провайдеров

Механики различаются, а скидки задаёт прайс конкретной модели. Ниже только то, что указано в документации на 25 октября 2026 года.

ПровайдерКак включаетсяМинимум для кэшаЧто в документации про цену и срок
OpenAIПо умолчанию для поддерживаемых моделей1024 токена для GPT-5.6 и новее, у старых моделей зависит от настроек запросаСкидка на кэшированный input до 95%. Для GPT-5.6 и новее запись в кэш на 30 минут стоит 1.25× обычного input, чтение 0.1× (на GPT-6.1 Sol 0.05×). Через Responses API можно выбрать минимальное время жизни 12 часов, запись тогда 2.5×
AnthropicПоле cache_control на верхнем уровне запроса (автоматически) или на блоках (до 4 брейкпоинтов)Зависит от модели: от 512 до 4096 токеновЗапись на 5 минут стоит +25% к input, на 1 час 2× input. Чтение 0.1× input, а для Opus 5.5 и Sonnet 5.5 0.05×, для Fable 5.1 и Mythos 5.1 0.025×. TTL продлевается при каждом попадании
Google GeminiНеявное кэширование включено по умолчанию для Gemini 2.5 и новее2048 токенов для Gemini 2.5, 4096 для Gemini 3.x и 4Экономия передаётся автоматически, в ответе есть total_cached_tokens. Явные кэши поддерживаются только на части моделей через generateContent; в Interactions API только неявные
DeepSeekПо умолчанию, кэш на дискеНе указан порог, кэш строится по границам запросов и фиксированным интервалам токеновВ ответе поля prompt_cache_hit_tokens и prompt_cache_miss_tokens. Кэш работает по принципу best-effort, гарантий попадания нет

Цены DeepSeek показывают масштаб эффекта: по прайсу для deepseek-flash (V4.1-Flash) входные токены с попаданием в кэш стоят $0.003 за миллион в непиковое время, а без попадания $0.15; вывод $0.6. В пиковое время все ставки удваиваются. Страница модели в каталоге: DeepSeek V4.1 Flash.

Расчёт для запроса с 6000 входных токенов, из которых 5000 статичный префикс, и 300 выходных, по тем же ценам, непиковое время:

  • Без кэша: 6000 × $0.15 / 1M + 300 × $0.6 / 1M = $0.0009 + $0.00018 = $0.00108.
  • С кэшем: 5000 × $0.003 / 1M + 1000 × $0.15 / 1M + $0.00018 = $0.000345.

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

Код: считаем стоимость по usage

Сначала научитесь видеть расходы. Скрипт ниже читает поле usage из ответа OpenAI-совместимого API и учитывает кэшированные токены, если провайдер их возвращает (у OpenAI это prompt_tokens_details.cached_tokens, у DeepSeek prompt_cache_hit_tokens):

from dataclasses import dataclass

@dataclass
class Price:
    input: float        # $ за 1M токенов
    cached: float       # $ за 1M кэшированных input-токенов
    output: float       # $ за 1M токенов вывода

def cached_tokens(usage: dict) -> int:
    details = usage.get("prompt_tokens_details") or {}
    return details.get("cached_tokens") or usage.get("prompt_cache_hit_tokens") or 0

def request_cost(usage: dict, p: Price) -> float:
    prompt = usage.get("prompt_tokens", 0)
    cached = min(cached_tokens(usage), prompt)
    out = usage.get("completion_tokens", 0)
    return ((prompt - cached) * p.input + cached * p.cached + out * p.output) / 1_000_000

def cost_per_success(cost_per_attempt: float, attempts: float, success_rate: float) -> float:
    if success_rate <= 0:
        return float("inf")
    return cost_per_attempt * attempts / success_rate

if __name__ == "__main__":
    flash = Price(input=0.15, cached=0.003, output=0.6)  # непиковые цены deepseek-flash
    usage = {"prompt_tokens": 6000, "prompt_cache_hit_tokens": 5000, "completion_tokens": 300}
    print(round(request_cost(usage, flash), 6))   # 0.000345
    print(round(cost_per_success(0.002, 1, 0.6), 4))  # 0.0033

Складывайте результат в лог вместе с именем модели, версией промпта и меткой задачи: без этого нельзя ответить, какая функция продукта съедает бюджет. Как устроить такой лог, показано в статье про LLMOps: версии промптов и мониторинг.

Сократите контекст до того, как платить за него

  • Не отправляйте историю целиком: оставьте последние N реплик, а старое сожмите в краткую сводку (одна дешёвая модель делает сводку раз в несколько шагов).
  • В RAG ограничивайте число фрагментов и их длину; плохо нарезанные документы раздувают контекст без пользы.
  • Описания инструментов агента занимают токены в каждом запросе. Держите только нужные для текущего шага и ставьте их в кэшируемый префикс.
  • У рассуждающих моделей ограничивайте бюджет размышлений там, где это поддерживается. Токены размышлений тарифицируются как вывод.

Batch: когда результат не нужен сразу

Для массовых задач (разметка, классификация, суммаризация архива, оценка датасета) есть пакетные API. По документации OpenAI Batch API даёт 50% скидки относительно синхронных запросов, отдельные лимиты и окно выполнения до 24 часов; один пакет вмещает до 50 000 запросов. У Anthropic Message Batches тарифицируются по 50% от стандартных цен, большинство пакетов завершается в течение часа, но срок истекает через 24 часа. Если задача не интерактивная, это самая простая экономия, не требующая менять промпты.

Маршрутизация: дешёвая модель, затем эскалация

Идея роутера: отправить задачу на дешёвую модель, автоматически проверить результат и только при провале перейти к более сильной. Ключевое слово здесь «автоматически проверить»: без дешёвой проверки (парсинг JSON, схема, регулярное выражение, юнит-тест, сверка с источником) роутер превращается в лотерею. Пример на OpenAI-совместимом клиенте, где в TIERS можно подставить любые модели и base_url:

import json, os
from openai import OpenAI

TIERS = [
    {"name": "cheap",  "base_url": "https://api.deepseek.com", "key_env": "DEEPSEEK_API_KEY", "model": "deepseek-flash"},
    {"name": "strong", "base_url": "https://openrouter.ai/api/v1", "key_env": "OPENROUTER_API_KEY", "model": "z-ai/glm-5.2"},
]

def valid(text: str) -> bool:
    """Дешёвая проверка: это JSON с нужными полями."""
    try:
        data = json.loads(text)
        return isinstance(data.get("category"), str) and isinstance(data.get("confidence"), (int, float))
    except (ValueError, AttributeError):
        return False

def route(messages: list[dict], max_tokens: int = 300) -> dict:
    last_error = None
    for tier in TIERS:
        client = OpenAI(base_url=tier["base_url"], api_key=os.environ[tier["key_env"]])
        try:
            r = client.chat.completions.create(
                model=tier["model"], messages=messages, max_tokens=max_tokens, temperature=0,
            )
        except Exception as exc:   # 429, 5xx, таймаут: идём на следующий уровень
            last_error = exc
            continue
        text = r.choices[0].message.content or ""
        if valid(text):
            return {"tier": tier["name"], "text": text, "usage": r.usage.model_dump()}
    raise RuntimeError(f"Все уровни не справились: {last_error}")

Что важно в реальной системе: ведите долю эскалаций (если дешёвый уровень проходит проверку реже 50-60% запросов, он не окупается), логируйте уровень, на котором получен ответ, и ограничивайте число уровней двумя-тремя. Для агентов, где дешёвые модели берут рутинные шаги, см. маленькие LLM в агенте. Цены и модели разных провайдеров сравнивайте на странице провайдеров.

Бесплатные API: что можно вынести на них

Бесплатные уровни полезны для прототипов, разметки небольших датасетов и дешёвого уровня роутера, но у них есть потолки:

  • OpenRouter: для моделей с суффиксом :free действуют дневные и минутные лимиты, они зависят от того, пополняли ли вы счёт; разбор в статье лимиты OpenRouter.
  • Groq: лимиты заданы на модель по запросам и токенам в минуту и в день. В таблице лимитов для openai/gpt-oss-120b указано 30 запросов в минуту, 1000 в день, 8K токенов в минуту и 200K в день; актуальные значения для вашего аккаунта показывает страница Limits.
  • Gemini: лимиты считаются на проект, а не на ключ, суточная квота сбрасывается в полночь по тихоокеанскому времени, и бесплатный доступ есть не у всех моделей, это видно в прайсе (у одной из моделей линейки указано, что free tier недоступен).

Практическое правило: бесплатный уровень ставьте в начало роутера на ненагруженных задачах и всегда держите платный резерв на ответ 429. Общий обзор вариантов есть в гайде по бесплатным LLM API. Конфиденциальные данные через бесплатные эндпоинты без проверки политики данных провайдера не отправляйте.

Как проверить, что оптимизация не сломала качество

  1. До изменений соберите набор из 50-200 реальных задач с критерием успеха и зафиксируйте базовую долю успеха и цену успешной задачи.
  2. Меняйте одну вещь за раз: кэш (качество не меняется, проверяйте только долю попаданий), сокращение контекста, замену модели, роутер.
  3. После каждого изменения прогоняйте тот же набор несколько раз: выход LLM недетерминирован, и одна пробежка не отличает улучшение от шума.
  4. Смотрите не только среднее, но и худшие случаи.
  5. В продакшене сравнивайте долю эскалаций, долю ручных исправлений и жалоб до и после, а изменения выкатывайте на часть трафика.

Итого

Порядок действий: сначала измерить цену успешной задачи и разложить расходы на input, cached и output; затем включить кэш, выстроив промпт как стабильный префикс и переменный хвост; вынести фоновые задачи в batch; сократить контекст; и лишь потом внедрять маршрутизацию с проверкой результата. После каждого шага сверяйтесь с набором проверок, а не с прайс-листом.

FL
Редакция Free-LLMsКоманда каталога бесплатных LLM API. Проверяем лимиты провайдеров и тестируем модели и инструменты руками.

Читайте также