Кэширование промптов

Платите меньше за повторяющиеся префиксы запросов

KodikRouter — прозрачный шлюз. Никаких специальных заголовков не требуется: кэширование управляется телом запроса, как в нативных SDK от OpenAI / Anthropic / Google. Мы пробрасываем поля cache_control и любые расширения на блоках контента без изменений, а в ответе считаем корректную стоимость с учётом скидки кэша.

Два режима

ImplicitGPT-5/4.1/4o, Grok, DeepSeek, Gemini 2.5 Pro/Flash, Moonshot, Groq KimiНичего — просто держите префикс сообщений стабильнымУправляется провайдером (~5–10 мин)
ExplicitAnthropic Claude, Gemini explicit, Alibaba QwenДобавьте cache_control в блоки контента5 мин по умолчанию или 1 ч
Режим выбирает сама модель — вы не переключаете его руками. Любую форму cache_control мы передаём провайдеру дословно.

Implicit caching

Держите начало messages одинаковым между запросами. Попадание в кэш зависит от минимальной длины префикса, модели, TTL и попадания к тому же провайдеру. Для GPT-4o проверяйте префикс от 1024 токенов. Нулевой cached_tokens для короткого запроса ожидаем и не доказывает ошибку. Факт попадания подтверждается полем prompt_tokens_details.cached_tokens, а не повторением текста. Для сравнения фиксируйте модель, провайдера и точное тело запроса; служебные инструкции маскирования при наличии плейсхолдеров тоже входят во входные токены.

json
{
  "model": "openai/gpt-4.1",
  "messages": [
    { "role": "system",  "content": "<длинный стабильный system prompt>" },
    { "role": "user",    "content": "Что такое TypeScript?" }
  ]
}

Минимальный размер промпта

OpenAI1024 токена
Gemini Flash1024 токена
Gemini Pro4096 токенов

Запросы короче порога не кэшируются — это аппаратное ограничение провайдеров, не KodikRouter.

Explicit caching: cache_control

Для Anthropic, Gemini explicit и Qwen используйте структурированный формат сообщений (массив блоков типизированного контента вместо строки) и расставьте контрольные точки кэша.

Anthropic — auto-cache для чата (рекомендуется)

Верхнеуровневый cache_control в запросе говорит Anthropic автоматически продвигать точку кэширования по мере роста диалога — лучший вариант для чатов.

json
{
  "model": "anthropic/claude-sonnet-4.6",
  "cache_control": { "type": "ephemeral" },
  "messages": [
    {
      "role": "system",
      "content": [
        { "type": "text", "text": "<очень длинный стабильный system prompt>" }
      ]
    },
    {
      "role": "user",
      "content": [
        { "type": "text", "text": "Опиши изменения в проекте за неделю." }
      ]
    }
  ]
}

Anthropic — точечный breakpoint

Если нужен ручной контроль, ставьте cache_control на конкретный блок. Максимум 4 точки на запрос.

json
{
  "model": "anthropic/claude-sonnet-4.6",
  "messages": [
    {
      "role": "system",
      "content": [
        {
          "type": "text",
          "text": "<длинная стабильная инструкция, ≥1024 токенов>",
          "cache_control": { "type": "ephemeral" }
        }
      ]
    },
    {
      "role": "user",
      "content": [
        { "type": "text", "text": "Краткий вопрос к этому контексту." }
      ]
    }
  ]
}

1-часовой TTL

По умолчанию кэш живёт 5 минут. Для долгих сессий укажите ttl: "1h" — запись в кэш стоит 2x от входа, зато повторное чтение остаётся дешёвым весь час.

json
{
  "type": "text",
  "text": "<длинная инструкция>",
  "cache_control": { "type": "ephemeral", "ttl": "1h" }
}

Gemini и Qwen

Тот же синтаксис: cache_control: { "type": "ephemeral" } на блоке контента. Gemini уважает только последний breakpoint в запросе — ставьте его в конец префикса, который хотите закэшировать.

Что делает KodikRouter

cache_control (top-level)
object
Пробрасывается провайдеру без изменений.
cache_control (на блоке контента)
object
Пробрасывается провайдеру без изменений.
ttl: "1h"
string
Пробрасывается провайдеру без изменений.

Мы не валидируем и не переписываем cache_control — sticky-маршрутизация до того же узла с прогретым кэшем делается шлюзом автоматически по хэшу промпта. Мы только корректно тарифицируем ответ с учётом скидки.

Чтение информации из ответа

В каждом ответе (стриминг и не-стриминг) есть блок usage:

prompt_tokens
number
Полный размер промпта (включая cached + cache_write).
prompt_tokens_details.cached_tokens
number
Сколько токенов прочитано из кэша (дешёвый сегмент).
prompt_tokens_details.cache_write_tokens
number
Сколько токенов записано в кэш (дорогой сегмент у Anthropic / Gemini explicit).
cost
number
Стоимость, переданная провайдером, в USD до конвертации в рубли и наценки KodikRouter, если провайдер передаёт это поле.
Не складывайте поля токенов
cached_tokens и cache_write_tokens — это подмножества prompt_tokens, а не отдельные категории. «Свежие» токены = prompt_tokens − cached_tokens − cache_write_tokens.

В стриминговых ответах блок usage приходит в последнем SSE-чанке (с finish_reason).

Стоимость

Цены в каталоге — ориентировочные. Провайдеры могут менять тарифы, включая кэш и длинный контекст. При наличии положительной стоимости от провайдера (usage.cost) для чата используется она; иначе стоимость рассчитывается по каталогу с раздельным учётом fresh / cached / cache-write. База в USD умножается на курс и наценку KodikRouter.

В журнале запросов cost_rub_exact — списание в рублях с шестью знаками после запятой, provider_cost_usd — база в долларах до конвертации и наценки. Поле cost_usd в API журнала — устаревший псевдоним суммы в рублях; он сохранён для совместимости и не означает доллары. Для сверки используйте явно обозначенные валютные поля.

GET /v1/fx/usd-rub возвращает курс effective_rate_rub без наценки и отдельное поле pricing_markup_pct. Рублёвые цены на сайте включают оба. Новые записи содержат billing_details с применёнными параметрами и идентификаторами из ответа провайдера. Версия модели доступна только если она явно передана; название модели или изменение курса сами по себе версию не подтверждают.

Полная выгрузка: GET /v1/usage/export.json?from=2026-10-19&to=2026-10-19. Даты — в UTC, обе границы включены. Для списка используйте limit=200&offset=0, затем увеличивайте offset на 200. Параметры page и days не поддерживаются. Выгрузка не ограничена размером страницы.

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