Кэш ответов X-Zukko-Cache: когда запрос бесплатный
Одинаковый запрос от одного пользователя можно не оплачивать второй раз. Разбираем, как включается кэш и как проверить, сработал ли он.
5 мин · · Обновлено · API · экономия
Если один и тот же запрос от одного и того же пользователя повторяется — в тестах, в CI, при повторных запусках одного и того же промпта в разработке — платить за него второй раз бессмысленно. Для этого случая есть встроенный кэш ответов.
Когда запрос кэшируется
Кэширование срабатывает в двух случаях:
- запрос содержит заголовок
X-Zukko-Cache: true— основной и универсальный способ, работает для любой модели; - запрос отправлен с
"temperature": 0— только для моделей, которые принимают такое значение. Модели Claude (claude-opus-5-5,claude-sonnet-5) могут отклонитьtemperature, отличный от 1, иtop_pниже 0.99 с ошибкой 400, поэтому для них не передавайтеtemperature/top_p, а используйте заголовок.
В обоих случаях одинаковые запросы одного и того же пользователя кэшируются — для чата время жизни кэша до 7 суток. Повторный идентичный запрос в это окно возвращается мгновенно и бесплатно. Работает кэш для POST /v1/chat/completions, /v1/messages и /v1/responses.
curl https://api.zukko.pro/v1/chat/completions \
-H "Authorization: Bearer fetch_ваш_ключ" \
-H "Content-Type: application/json" \
-H "X-Zukko-Cache: true" \
-d '{
"model": "claude-sonnet-5",
"messages": [{"role": "user", "content": "Объясни разницу между 401 и 403"}]
}'Второй вызов с точно таким же телом от того же ключа/аккаунта попадёт в кэш.
Как проверить, что сработало
Ответ приходит с заголовком X-Zukko-Cache: hit, если запрос был обслужен из кэша. Если заголовка нет или он отсутствует — запрос дошёл до модели и был оплачен как обычно.
import requests
resp = requests.post(
"https://api.zukko.pro/v1/chat/completions",
headers={
"Authorization": "Bearer fetch_ваш_ключ",
"X-Zukko-Cache": "true",
},
json={
"model": "claude-sonnet-5",
"messages": [{"role": "user", "content": "Объясни разницу между 401 и 403"}],
},
)
print("cache:", resp.headers.get("X-Zukko-Cache", "miss"))
print("cost micros:", resp.headers.get("X-Zukko-Cost-Micros"))
print("balance micros:", resp.headers.get("X-Fetch-Balance-Cents")) # несмотря на название — микродолларыЗаголовок X-Zukko-Cost-Micros показывает стоимость запроса в микродолларах (1 000 000 = $1); X-Fetch-Balance-Cents, несмотря на название, тоже в микродолларах. При попадании в кэш стоимость должна быть нулевой или отсутствовать — удобно проверять оба заголовка вместе, а не полагаться на один X-Zukko-Cache. Попадания в кэш не пишутся в /v1/usage.
Почему temperature: 0 тоже включает кэш (для моделей, которые его принимают)
temperature: 0 означает детерминированный, максимально предсказуемый вывод — при одинаковом вводе модель и так стремится вернуть один и тот же ответ. Раз результат и без кэша почти не меняется от запроса к запросу, кэшировать его безопасно по смыслу: пользователь получает тот же ответ, что получил бы при обычном вызове, только быстрее и бесплатно.
Если вам нужна вариативность ответов (creative-writing промпты, чат с случайностью), не выставляйте temperature: 0 только ради экономии — вы получите одинаковые ответы там, где хотели разные. В этом случае используйте X-Zukko-Cache: true осознанно, только на тех промптах, где повтор ответа — ожидаемое и желаемое поведение.
Где это реально экономит
CI и автотесты. Пайплайн, который на каждый пуш гоняет один и тот же тестовый промпт к модели (например, проверка, что интеграция вообще отвечает), может гонять его хоть на каждый коммит — если тело запроса не меняется, оплата будет только за первый прогон в пределах окна кэша.
Повторные запуски при разработке. Отладка промпта локально часто означает десятки перезапусков одного и того же кода с одним и тем же вводом, пока не поправишь остальную логику приложения. Пока сам промпт не меняется, каждый перезапуск после первого — бесплатный.
Демо и презентации. Если демо-сценарий заранее известен и повторяется дословно, первый прогон оплачивается, все последующие в течение недели — нет.
Что не кэшируется
Кэш привязан к пользователю (аккаунту/ключу) и к точному телу запроса. Это не общий кэш «одинаковый промпт от кого угодно» — если два разных клиента отправят одинаковый текст, каждый получит собственную оплаченную генерацию, если только это не один и тот же ключ. Кэш срабатывает только при полном совпадении тела запроса — не на «почти одинаковых» запросах и не на общем префиксе. Малейшее отличие в теле запроса — другой system-промпт, другой порядок сообщений, лишний пробел в тексте, другое значение max_tokens — это уже другой запрос, кэш не сработает, спишется полная стоимость (поля metadata, user и stream_options на сравнение не влияют).
Генерация изображений через Zukko сейчас временно недоступна, так что всё сказанное относится к текстовым запросам.
Кэш и Idempotency-Key — не одно и то же
Их легко перепутать, потому что оба защищают от лишней оплаты. Разница в том, от чего именно: Idempotency-Key защищает от повторной оплаты одного и того же запроса при ретрае после сбоя (сеть оборвалась, клиент не дождался ответа). Кэш через X-Zukko-Cache — про намеренно повторяющиеся запросы, которые вы отправляете снова и снова осознанно, потому что вход не меняется. Первый — про надёжность, второй — про экономию на предсказуемой нагрузке. Их можно использовать одновременно в одном запросе, они не конфликтуют.
Практический пример: тестовый набор промптов
Если у вас есть набор из, скажем, двадцати эталонных промптов для регрессионного тестирования качества ответов модели после смены версии, и вы гоняете их каждую ночь одним и тем же CI-джобом, добавление X-Zukko-Cache: true ко всем запросам, кроме первого прогона после реального изменения промптов, превращает большинство ночных прогонов в бесплатные. Оплата случится только тогда, когда текст промпта или системный промпт действительно изменится — то есть именно тогда, когда результат стоит проверить заново.
Итог
Кэш — это не отдельная настройка в кабинете, а два способа пометить конкретный запрос как кэшируемый: заголовок X-Zukko-Cache: true (основной, для любой модели) или temperature: 0 (только у моделей, которые его принимают, — не у Claude). Проверяйте X-Zukko-Cache: hit в ответе, чтобы убедиться, что сработало, и X-Zukko-Cost-Micros, чтобы увидеть реальную стоимость (или её отсутствие) конкретного вызова.
zukko
Платите в 25×
меньше
за Claude Code & ChatGPT
Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.
Похожие статьи
- Агенты opencode: как настроить роли, модели и инструментыСвой агент в opencode — это роль, модель и список разрешений. Показываем конфиг и пример, где рутину делает дешёвая модель, а код правит сильная.
- Plan mode в Claude Code: сначала план, потом правки в кодеВ plan mode Claude Code читает код и предлагает план, но ничего не правит, пока вы не согласитесь. Как включить, использовать и во сколько это обходится.
- Купить токены нейросети: как устроен баланс в долларах и что на него взять«Токены» в шлюзе — это не пакет, а баланс в долларах. Разбираем, что с него списывается, и считаем, на сколько запросов хватит $5.
- Оплата нейросетей без комиссии: бывает ли так и как посчитать переплатуКомиссия при пополнении есть почти всегда. Показываем, из чего она складывается, считаем её для СБП и карты и даём формулу «сколько рублей нужно на N долларов».