# Prompt caching: платим за повтор копейки

Курс: Claude API для разработчиков — https://zero2claude.ru/learn/api
Канонический URL: https://zero2claude.ru/learn/api/3-2-prompt-caching

Prompt caching удешевляет повторы: ставь cache_control на стабильный префикс запроса и проверяй экономию по cache_read_input_tokens.

Если в каждом запросе ты гонишь один и тот же большой кусок — инструкцию боту, каталог товаров, правила возврата — платить за него полную цену каждый раз глупо. **Prompt caching** позволяет закэшировать этот префикс: первый раз платишь чуть дороже (запись ~1.25×), а дальше читаешь из кэша почти бесплатно (~0.1× от цены входа).

## Главное правило: кэш — это префикс

Запрос склеивается в фиксированном порядке: `tools` → `system` → `messages`. Кэш работает по совпадению с начала. **Любое изменение в префиксе сбрасывает кэш для всего, что идёт после.** Поэтому стабильное (инструкция бота, каталог) — в начало, изменчивое (вопрос клиента) — в конец.

Ставишь `cache_control` на последний стабильный блок:

```python
resp = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    system=[
        {
            "type": "text",
            "text": BIG_INSTRUKCIYA_I_KATALOG,
            "cache_control": {"type": "ephemeral"},
        }
    ],
    messages=[{"role": "user", "content": "Где мой заказ 4821?"}],
)
```

## Как проверить, что сработало

Смотри в `usage` ответа:

```
"usage": {
  "input_tokens": 18,
  "cache_creation_input_tokens": 2360,
  "cache_read_input_tokens": 0
}
```

Первый запрос пишет кэш — растёт `cache_creation_input_tokens`. На втором с тем же префиксом должно появиться `cache_read_input_tokens` > 0 — значит, читаем из кэша и экономим.

Если `cache_read_input_tokens` упорно ноль — в префиксе что-то меняется на каждом запросе. Частые виновники: дата/время или `datetime.now()` в system, случайный id, несортированный JSON. Вынеси изменчивое в конец `messages`.

Кэш живёт около 5 минут и привязан к модели — сменил модель, и первый запрос снова пишет кэш заново.
