В моей предыдущей статье мы обсуждали концепцию кэширования промптов — что это такое, как это работает и как это может сэкономить вам много денег и времени при запуске приложений с искусственным интеллектом при высокой нагрузке. Сегодня я проведу вас через реализацию кэширования промптов, используя API OpenAI, и обсудим некоторые типичные ошибки.
Краткое напоминание о кэшировании промптов
Перед началом давайте кратко вспомним, что именно представляет собой кэширование промптов. Кэширование промптов — это функциональность, предоставляемая сервисами API передовых языковых моделей, такими как OpenAI API или Claude API, которая позволяет кэшировать и повторно использовать части входных данных модели, которые повторяются часто. Такие повторяющиеся части могут быть системными промптами или инструкциями, которые передаются модели каждый раз при запуске приложения с искусственным интеллектом, наряду с любым другим переменным контентом, например запросом пользователя или информацией из базы знаний. Чтобы попасть в кэш при кэшировании промптов, повторяющиеся части промпта должны находиться в его начале, а именно — это префикс промпта. Кроме того, для активации кэширования промптов этот префикс должен превышать определённый порог (например, для OpenAI префикс должен содержать более 1024 токенов, в то время как Claude имеет разные минимальные длины кэша для разных моделей). При условии, что эти два требования выполнены — повторяющиеся токены как префикс, превышающие пороговый размер, определённый сервисом API и моделью — кэширование может быть активировано для достижения экономии масштаба при запуске приложений с искусственным интеллектом.
В отличие от кэширования в других компонентах RAG или других приложений с искусственным интеллектом, кэширование промптов работает на уровне токенов, во внутренних процедурах модели. В частности, вывод LLM происходит в два этапа:
- Предварительное заполнение — модель учитывает пользовательский промпт для генерации первого токена, и
- Декодирование — модель рекурсивно генерирует токены выходных данных один за другим
Короче говоря, кэширование промптов сохраняет вычисления, которые происходят на этапе предварительного заполнения, поэтому модели не нужно пересчитывать их, когда тот же префикс появляется снова. Любые вычисления, происходящие на этапе итераций декодирования, даже если они повторяются, не будут кэшированы.
Для остальной части этой статьи я буду сосредоточен исключительно на использовании кэширования промптов в OpenAI API.
Что насчёт OpenAI API?
В OpenAI API кэширование промптов было первоначально представлено 1 октября 2024 года. Первоначально оно предоставляло скидку 50% на кэшированные токены, но в настоящее время эта скидка доходит до 90%. Кроме того, используя кэш промптов OpenAI, можно достичь дополнительной экономии по задержке до 80%.
Когда кэширование промптов активировано, сервис API пытается попасть в кэш для отправленного запроса, маршрутизируя отправленный промпт на соответствующую машину, где должен существовать соответствующий кэш. Это называется маршрутизацией кэша, и для этого сервис API обычно использует хэш первых 256 токенов промпта.
Кроме того, их API также позволяет явно определить параметр prompt_cache_key в запросе API к модели. Это единый ключ, определяющий, к какому кэшу мы обращаемся, с целью дальнейшего увеличения вероятности маршрутизации вашего промпта на правильную машину и попадания в кэш.
Кроме того, OpenAI API предоставляет два различных типа кэширования в отношении продолжительности, определяемые параметром prompt_cache_retention. Это:
- Кэширование промптов в памяти: это по сути тип кэширования по умолчанию, доступный для всех моделей, для которых доступно кэширование промптов. При кэшировании в памяти кэшированные данные остаются активными в течение 5–10 минут между запросами.
- Расширенное кэширование промптов: доступно для определённых моделей. Расширённое кэширование позволяет сохранять данные в кэше дольше и до максимум 24 часов.
Что касается стоимости всего этого, OpenAI взимает одинаковую плату за входной токен (некэшированный), независимо от того, активировано ли кэширование промптов или нет. Если вы успешно попадёте в кэш, вам будут выставлены счета за кэшированные токены по значительно сниженной цене со скидкой до 90%. Кроме того, цена за входной токен остаётся одинаковой как для кэширования в памяти, так и для расширенного кэширования.
Кэширование промптов на практике
Теперь давайте посмотрим, как кэширование промптов на самом деле работает с простым примером на Python, используя сервис API OpenAI. Более конкретно, мы будем рассматривать реальный сценарий, где длинный системный промпт (префикс) повторно используется в нескольких запросах. Если вы здесь, то я предполагаю, что у вас уже есть ваш ключ API OpenAI на месте и вы установили необходимые библиотеки. Итак, первое, что нужно сделать — это импортировать библиотеку OpenAI, а также time для захвата задержки, и инициализировать экземпляр клиента OpenAI:
from openai import OpenAI
import time
client = OpenAI(api_key="your_api_key_here")
затем мы можем определить наш префикс (токены, которые будут повторяться и которые мы хотим кэшировать):
long_prefix = """
You are a highly knowledgeable assistant specialized in machine learning.
Answer questions with detailed, structured explanations, including examples when relevant.
""" * 200
Обратите внимание, что мы искусственно увеличиваем длину (умножаем на 200), чтобы убедиться, что порог кэширования в 1024 токена соблюдается. Затем мы также устанавливаем таймер для измерения нашей экономии задержки, и мы наконец готовы сделать наш вызов:
start = time.time()
response1 = client.responses.create(
model="gpt-4.1-mini",
input=long_prefix + "What is overfitting in machine learning?"
)
end = time.time()
print("First response time:", round(end - start, 2), "seconds")
print(response1.output[0].content[0].text)
Чего мы можем ожидать отсюда? Для моделей gpt-4o и новее кэширование промптов активировано по умолчанию, и поскольку наши 4616 входных токенов хорошо превышают пороговое значение префикса в 1024 токена, мы в порядке. Таким образом, этот запрос сначала проверяет, является ли вход попаданием в кэш (это не так, поскольку это первый раз, когда мы делаем запрос с этим префиксом), и поскольку это не так, он обрабатывает весь вход и затем кэширует его. В следующий раз, когда мы отправим вход, который совпадает с начальными токенами кэшированного ввода в некоторой степени, мы получим попадание в кэш. Давайте проверим это на практике, сделав второй запрос с тем же префиксом:
start = time.time()
response2 = client.responses.create(
model="gpt-4.1-mini",
input=long_prefix + "What is regularization?"
)
end = time.time()
print("Second response time:", round(end - start, 2), "seconds")
print(response2.output[0].content[0].text)
Действительно! Второй запрос выполняется значительно быстрее (23,31 против 15,37 секунд). Это потому, что модель уже произвела вычисления для кэшированного префикса и должна только обработать с нуля новую часть — «What is regularization?» (Что такое регуляризация?). В результате, используя кэширование промптов, мы получаем значительно меньшую задержку и сниженную стоимость, поскольку кэшированные токены дисконтированы.
Ещё одна вещь, упомянутая в документации OpenAI, о которой мы уже говорили — это параметр prompt_cache_key. В частности, согласно документации, мы можем явно определить ключ кэша промпта при составлении запроса и таким образом определить запросы, которые должны использовать один и тот же кэш. Тем не менее, я попытался включить его в мой пример, соответственно отрегулировав параметры запроса, но не добился особых успехов:
response1 = client.responses.create(
prompt_cache_key = 'prompt_cache_test1',
model="gpt-5.1",
input=long_prefix + "What is overfitting in machine learning?"
)