Перейти к основному содержимому

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

Продвинутый

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

What you'll learn
  • Ментальная модель: точка разрыва кэша после стабильного префикса, переиспользуемого между вызовами
  • Как пометить точку разрыва в Python и TypeScript с помощью cache_control
  • Единственный инвариант, который всё решает, — префикс должен быть побайтово идентичным
  • Как читать поля usage, чтобы убедиться, что вы действительно попадаете в кэш
  • Где кэширование окупается больше всего и как сочетать его с пакетной обработкой и подбором размера модели

Как это работает (ментальная модель)

Вы помечаете точку разрыва кэша (cache breakpoint) после стабильного префикса. При первом вызове он обрабатывается и кэшируется; последующие вызовы, использующие тот же самый префикс, попадают в кэш и платят за него значительно меньше.

Словарь кэширования
Нажмите Enter или пробел, чтобы перевернуть карточку. Используйте стрелки влево и вправо для перехода между карточками.Показан термин.
1 / 4

Пометьте точку разрыва (copy-paste)

Добавьте cache_control к последнему стабильному блоку — здесь это большой системный промпт. Реплика пользователя идёт после него и свободно меняется; кэшируется всё вплоть до помеченного блока включительно.

Guided walkthrough1 of 4
  1. Найдите большой неизменный фрагмент — длинный системный промпт, объёмный документ или каталог инструментов, переиспользуемый во многих запросах.
import anthropic

client = anthropic.Anthropic()

message = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
system=[
{
"type": "text",
"text": LARGE_STABLE_PROMPT, # long, unchanging — the cached prefix
"cache_control": {"type": "ephemeral"},
}
],
messages=[{"role": "user", "content": "Summarize the key points."}], # varies per call
)

print(message.usage.cache_read_input_tokens) # > 0 means you got a hit

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

Инвариант, который всё решает

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

Размещайте всё стабильное в начале, а всё переменное — в конце, и держите префикс действительно постоянным.

Убедитесь, что это действительно работает

Не полагайтесь на предположения — считайте данные обратно из поля usage в ответе:

  • cache_creation_input_tokens — токены, записанные в кэш в этом вызове (первый запрос).
  • cache_read_input_tokens — токены, отданные из кэша (ваша экономия).
  • input_tokens — некэшированный остаток, тарифицируемый по полной цене.

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

Где это окупается больше всего

  • Длинные системные промпты, переиспользуемые между пользователями.
  • RAG / вопросы-ответы по документам, где один и тот же исходный текст запрашивается многократно.
  • Агенты с фиксированным каталогом инструментов и инструкциями на протяжении многих ходов.

Сочетайте кэширование с пакетной обработкой (batching) для офлайн-нагрузок и с подбором подходящего размера модели (Выбор модели) для максимальной совокупной экономии — см. Затраты и задержка.

Проверьте себя

0/3
  1. Что требуется от кэшированного префикса для попадания в кэш?
  2. Какое поле usage сообщает, что токены были отданы из кэша (ваша экономия)?
  3. Где должно располагаться переменное содержимое каждого вызова относительно точки разрыва кэша?
Key takeaways
  • Помечайте точку разрыва кэша после стабильного префикса; первый вызов записывает его, последующие считывают его обратно дёшево.
  • Для попадания в кэш нужен побайтово идентичный префикс — держите стабильное содержимое в начале, а переменное — в конце.
  • Незаметные инвалидаторы в начале промпта (метки времени, имена, переупорядоченные инструменты) тихо обнуляют долю попаданий.
  • Проверяйте через usage: cache_read_input_tokens > 0 означает попадание; ноль на повторяющихся запросах означает, что работает инвалидатор.
  • Кэширование окупается больше всего на переиспользуемых системных промптах, RAG и агентах; сочетайте его с пакетной обработкой и подбором размера модели.

Далее