
При повторном запросе к языковой модели можно избежать лишнего обращения к API — если вход действительно совпадает с тем, для которого был сохранён ответ. Проверять только текст вопроса недостаточно: системная инструкция, версия модели, история диалога, инструменты и права пользователя тоже могут изменить результат.
В этой статье речь о прикладном кэше: приложение сохраняет готовый ответ и возвращает его при безопасном совпадении. Это отдельный механизм от prompt caching провайдера, который может повторно использовать часть входного контекста, но обычно не заменяет сам вызов модели.
Сначала выберите сценарий
Кэш ответа подходит для повторяющихся запросов, если результат допустимо показать повторно и контекст не успел измениться. Например, он может быть полезен для типового объяснения неизменной функции продукта. Проверка актуального остатка товара — другой случай: такой результат должен отражать текущее состояние системы.
Prompt caching у провайдера решает иную задачу: повторно использует обработанную часть запроса, например длинный общий префикс. Он может повлиять на стоимость или задержку, но поведение зависит от конкретного API и модели. Сверяйтесь с документацией провайдера и измеряйте этот эффект отдельно от кэша готовых ответов.
Перед реализацией ответьте на два вопроса:
- Нужно ли при повторе полностью избежать нового вызова модели? Рассматривайте прикладной кэш.
- Нужно ли эффективнее обрабатывать длинные неизменные инструкции? Проверьте prompt caching у используемого провайдера.
Какие поля включить в ключ
Ключ должен меняться вместе с любым параметром, способным повлиять на содержание или допустимость ответа. Практичный подход — сформировать объект из значимых полей, стабильно сериализовать его и вычислить хеш. Например:
json
{
«provider»: «example-provider»,
«model»: «model-version»,
«system»: «Инструкция поддержки»,
«messages»: [
{«role»: «user», «content»: «Как отменить заказ?»}
],
«temperature»: 0,
«max_tokens»: 500,
«tools»: [],
«response_schema»: null,
«locale»: «ru-RU»,
«tenant_id»: «tenant-42»,
«prompt_version»: «support-v7»
}
Значения в примере условные. В рабочей системе указывайте фактическую версию модели, настройки генерации и контекст приложения. Набор полей зависит от API: включайте используемые параметры, которые могут менять результат.
| Поле | Почему оно важно | Что проверить |
|---|---|---|
| Провайдер и модель | Разные модели могут отвечать по-разному | Учитывается ли версия, а не только изменяемый псевдоним |
| Сообщения и инструкция | Содержание и порядок диалога задают контекст | Сохраняются ли роли и последовательность |
| Параметры и схема ответа | Настройки и формат могут изменить результат | Включены ли активные параметры и схема |
| Инструменты | Их описание влияет на выбор действия | Меняется ли ключ при обновлении списка функций |
| Пользователь и данные | Права и персональный контекст влияют на допустимый ответ | Разделены ли записи между пользователями и арендаторами |
Если ответ зависит от пользователя или организации, изолируйте кэш соответствующим идентификатором и всё равно проверяйте авторизацию при чтении записи. Само разделение ключей не является проверкой прав.
Стабильная сериализация без потери смысла
Один и тот же объект может превратиться в разные строки JSON из-за порядка полей или особенностей представления чисел. В таком случае хеши разойдутся, хотя запросы эквивалентны. Используйте сериализацию с фиксированным порядком полей, единым форматом кодировки и явным представлением отсутствующих значений.
Нормализуйте только то, что точно не меняет смысл. Удаление пробелов в тексте иногда портит код, форматированный документ или цитату. Стабильный порядок полей конфигурации обычно безопаснее такой нормализации.
Для ключа применяйте криптографический хеш, например SHA-256. Не используйте в качестве имени записи открытый текст запроса: он может содержать персональные данные, а длинные значения неудобны для хранилища. Хеш скрывает исходную строку в имени ключа, но не защищает сохранённый ответ от несанкционированного доступа.
Когда совпадение входа не означает свежий ответ
Даже точное совпадение запроса не гарантирует, что старый ответ остаётся актуальным. Модель могла получить внешние данные, которых нет в тексте вопроса: состояние заказа, результаты поиска, содержимое базы знаний или сведения о правах.
Для RAG-сценария учитывайте идентификаторы и версии документов либо индекса. Иначе один и тот же вопрос после обновления базы может получить прежний ответ. Если контекст нельзя надёжно версионировать, ограничьте срок хранения или не кэшируйте такой сценарий.
Не возвращайте запись из кэша вместо повторного выполнения действия, которое обязано проверить актуальное состояние или изменить данные. Например, кэш текста о наличии товара не подходит для подтверждения текущего остатка, а результат операции записи нельзя выдавать как обычный повторяемый ответ без проверки её статуса.
Особенно тщательно проверяйте запросы, связанные с персональными данными, правами доступа, меняющимися источниками и побочными эффектами.
TTL и инвалидация
TTL — срок, по истечении которого запись считается устаревшей и перестаёт выдаваться. Универсального значения для LLM нет: оно зависит от изменчивости контекста и последствий ошибки. Объяснение неизменной функции может оставаться пригодным дольше, чем ответ по регулярно обновляемому каталогу.
Определите срок по двум критериям: как быстро меняются исходные данные и какой ущерб нанесёт устаревший ответ. Если версии данных доступны, добавьте их в ключ. Также предусмотрите явную инвалидацию при обновлении системной инструкции, схемы ответа, индекса или бизнес-правил.
HTTP-директива Cache-Control описывает правила свежести HTTP-ответов, но сама по себе не определяет, какие поля запроса к модели важны для совпадения. Логику кэша LLM нужно задавать на уровне приложения, с учётом его данных и правил доступа.
Проверки перед запуском
Составьте небольшой тестовый набор с повторяющимися запросами и вариантами, где меняется только один существенный параметр. Проверьте следующее:
Одинаковые входы после сериализации дают один ключ.
Изменение модели, системной инструкции, схемы или инструмента даёт другой ключ.
3. Разные пользователи не получают один персонализированный ответ.
4. Обновление документа или контекста не возвращает прежний результат.
5. Истёкшая запись не выдаётся, а ручная инвалидация срабатывает.
6. При недоступности хранилища приложение соблюдает заранее выбранное безопасное поведение.
Для каждого теста фиксируйте причину попадания или промаха и число фактических вызовов модели. Затем наблюдайте за долей попаданий, задержкой, расходами на запросы и случаями, когда проверка контекста запретила выдачу. Высокая доля попаданий сама по себе не доказывает безопасность: важны тесты на ложные совпадения и устаревшие данные.
Что хранить и как ограничить доступ
Храните минимально необходимое: ответ, время создания, срок истечения и метаданные, нужные для проверки совместимости. Не сохраняйте полный диалог в открытом виде, если он не нужен для работы кэша. Установите контроль доступа к хранилищу, правила удаления записей и порядок обработки данных в резервных копиях и журналах.
Для диагностики обычно достаточно хеша ключа, версии модели и инструкции, результата попадания и времени. Не записывайте в журнал секреты или весь пользовательский текст только ради отладки. Проверьте также, что ответ не попадает в общий кэш, если он содержит данные конкретного человека.
Кэш — вспомогательное хранилище, а не источник истины. Продумайте, что произойдёт при его недоступности, ошибке чтения или повреждённой записи. В рекомендациях AWS по проектированию кэшей отдельно рассматриваются стратегии заполнения и обработки отказов; эти вопросы важны и для прикладного кэша ответов.
Практический порядок внедрения
Начните с одного сценария, где запросы действительно повторяются, а цена устаревания невелика. До включения кэша составьте список полей ключа, определите границы пользовательской изоляции и задайте правило удаления записи при изменении данных.
Затем проведите тесты на совпадение, изменение контекста, истечение TTL и отказ хранилища. Сравните экономию повторных вызовов с затратами на хранение и поддержку инвалидации. Если запросы почти всегда уникальны или результат зависит от состояния в реальном времени, прикладной кэш ответа может не окупиться.
Для дополнительной проверки сверяйтесь с первичной документацией: AWS Builders’ Library о стратегиях и рисках кэширования, справкой MDN по HTTP Cache-Control, руководствами OpenAI и Anthropic по prompt caching и документацией Redis по кэшированию. Эти материалы описывают разные уровни системы, поэтому не считайте механизм провайдера заменой проверок ключа и доступа в приложении.










