Экономия на повторных запросах: кэш через X-Zukko-Cache и temperature:0

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

4 мин · · Обновлено · API · экономия

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

Когда включается кэш

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

Заголовок X-Zukko-Cache: true. Основной способ: работает с любой моделью и независимо от температуры — явный заголовок форсирует кэширование, даже если вы не трогаете temperature.

temperature: 0 в теле запроса. Тоже включает кэш: при нулевой температуре модель и так должна давать детерминированный (или почти детерминированный) ответ на одинаковый вход. Но работает это только у моделей, которые принимают такой параметр. claude-sonnet-5 и claude-opus-5-5 могут отклонить temperature, отличную от 1 (и top_p меньше 0.99), ошибкой 400 — с моделями Claude temperature и top_p не передавайте и включайте кэш заголовком.

bash
curl https://api.zukko.pro/v1/chat/completions \
  -H "Authorization: Bearer fetch_ваш_ключ" \
  -H "X-Zukko-Cache: true" \
  -H "Content-Type: application/json" \
  -d '{"model":"claude-sonnet-5","messages":[{"role":"user","content":"Переведи слово table на русский"}]}'

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

Как понять, что ответ пришёл из кэша

Ответ содержит заголовок X-Zukko-Cache, со значением hit при попадании в кэш:

bash
curl -i https://api.zukko.pro/v1/chat/completions \
  -H "Authorization: Bearer fetch_ваш_ключ" \
  -H "X-Zukko-Cache: true" \
  -H "Content-Type: application/json" \
  -d '{"model":"claude-sonnet-5","messages":[{"role":"user","content":"Что такое HTTP 404?"}]}' \
  | grep -i x-zukko-cache

Кэшированный ответ возвращается мгновенно и бесплатно — заголовок X-Zukko-Cost-Micros в этом случае будет нулевым или отсутствовать, потому что списания не происходит. В истории /v1/usage попадания в кэш тоже не появляются.

Где это реально экономит

Повторные тесты промпта. При отладке системного промпта разработчик обычно гоняет один и тот же входной текст десятки раз, меняя только инструкцию модели в системной роли. Если тестовый ввод не меняется и кэш включён заголовком X-Zukko-Cache: true, все повторные прогоны с идентичным телом запроса не будут стоить ничего после первого.

Классификация одинаковых значений. Если сервис классифицирует поток данных, где значения повторяются (например, одинаковые названия категорий товаров, одинаковые статусы), кэш убирает дублирующие вызовы модели для уже виденных значений — при условии, что промпт вокруг значения тоже не меняется.

Демо и CI-тесты. В автотестах, где сценарий фиксирован и запускается при каждом пуше, заголовок X-Zukko-Cache: true даёт бесплатные повторные прогоны, пока кэш не истёк, а у моделей, которые принимают temperature: 0, она добавляет ещё и детерминированность (важно для проверки регрессий).

Что кэш не делает

Кэш срабатывает только при полном совпадении запроса — модели, температуры, сообщений и прочих параметров тела. Малейшее изменение (лишний пробел в промпте, другой max_tokens, добавленное системное сообщение) — это уже другой запрос, и кэш на него не распространяется. Это не семантическое кэширование по смыслу, а точное совпадение по телу запроса.

Кэш также не заменяет Idempotency-Key. Это разные механизмы: Idempotency-Key защищает от повторного списания при ретрае одного и того же запроса в течение 24 часов (полезно при сетевых обрывах), а кэш ответов — это отдельная функция про переиспользование результата на срок до 7 суток при совпадении тела. Их можно использовать одновременно, но путать не стоит: идемпотентность — про надёжность, кэш — про повторяемость и экономию.

bash
curl https://api.zukko.pro/v1/chat/completions \
  -H "Authorization: Bearer fetch_ваш_ключ" \
  -H "Idempotency-Key: batch-42-item-7" \
  -H "X-Zukko-Cache: true" \
  -H "Content-Type: application/json" \
  -d '{"model":"glm-5.3-flash","messages":[{"role":"user","content":"Классифицируй: iPhone 15 Pro"}]}'

В этом примере оба механизма работают вместе: X-Zukko-Cache: true открывает дорогу к кэшу при повторе запроса, а Idempotency-Key защищает конкретно этот вызов от повторного списания при сетевом сбое.

Проверка стоимости до и после кэша

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

bash
import requests

url = "https://api.zukko.pro/v1/chat/completions"
headers = {"Authorization": "Bearer fetch_ваш_ключ", "Content-Type": "application/json", "X-Zukko-Cache": "true"}
body = {
    "model": "claude-sonnet-5",  # для Claude temperature не передаём
    "messages": [{"role": "user", "content": "Сколько будет 17 * 24?"}],
}

first = requests.post(url, headers=headers, json=body)
second = requests.post(url, headers=headers, json=body)

print("first cache:", first.headers.get("X-Zukko-Cache"), "cost:", first.headers.get("X-Zukko-Cost-Micros"))
print("second cache:", second.headers.get("X-Zukko-Cache"), "cost:", second.headers.get("X-Zukko-Cost-Micros"))

Первый вызов идёт к модели и списывает деньги, второй — при одинаковом теле и заголовке X-Zukko-Cache: true — должен вернуться с X-Zukko-Cache: hit и нулевой стоимостью.

Когда кэш не подходит

Если задача требует разнообразия ответов на один и тот же вход — генерация вариантов текста, творческие задачи, где повторный запрос должен звучать иначе каждый раз — кэш и temperature: 0 противоречат самой цели запроса. В таких сценариях кэш стоит явно не включать (не ставить X-Zukko-Cache: true и не занулять температуру), иначе пользователь будет получать один и тот же вариант вместо нового.

Итог

Кэш ответов — это бесплатный способ убрать повторные расходы на одинаковые запросы, но он требует осознанного выбора. Основной способ — явный заголовок X-Zukko-Cache: true: он работает с любой моделью. temperature: 0 — альтернатива там, где детерминированность и так нужна, но только для моделей, которые принимают этот параметр (не для Claude). Проверка через X-Zukko-Cache: hit в ответе — самый быстрый способ убедиться, что экономия действительно работает, а не просто предполагается.

zukko

Платите в 25×
меньше

за Claude Code & ChatGPT

Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.