Что такое prompt caching у провайдеров (Anthropic, Google) и как его использовать?

Краткий тезис

Prompt caching — это механизм, при котором API провайдера сохраняет промежуточные вычисления (KV-кэш) для повторяющихся префиксов промпта. Это позволяет значительно снизить задержку (latency) и стоимость (cost) при многократном использовании одинаковых начальных частей запроса, таких как системные промпты, few-shot примеры или общая база знаний. Anthropic (Claude) и Google (Gemini) предлагают разные реализации, но общая идея — кэшировать ключи и значения внимания (KV-cache) для shared prefix]], чтобы не пересчитывать их каждый раз.


1. Термин: KV-кэш (Key-Value cache)

В трансформерных LLM каждый слой внимания вычисляет ключи (K) и значения (V) для каждого токена. При генерации ответа токены обрабатываются последовательно, и для каждого нового токена нужно вычислить внимание ко всем предыдущим токенам. Если каждый раз пересчитывать K и V для всего контекста — это дорого. Поэтому модели хранят KV-кэш — матрицы K и V для уже обработанных токенов. При добавлении нового токена вычисляются только его K и V, а старые берутся из кэша.

Prompt caching расширяет эту идею на уровень API: если вы отправляете запрос с длинным префиксом (например, системный промпт + несколько примеров), провайдер может сохранить KV-кэш для этого префикса. При следующем запросе с тем же префиксом (но другим суффиксом, например, новым вопросом пользователя) кэш переиспользуется, и модель начинает генерацию сразу с нового токена, минуя повторное вычисление префикса.


2. Реализация у Anthropic (Claude)

Anthropic предоставляет prompt caching для моделей Claude (Claude 3.5 Sonnet, Claude 3 Opus и др.) через API.

Как работает

  • Вы помечаете часть промпта как cacheable (кэшируемую) с помощью специального заголовка или параметра.
  • Anthropic сохраняет KV-кэш для этой части на некоторое время (обычно 5–10 минут с момента последнего использования).
  • При повторном запросе с тем же cacheable префиксом вы получаете скидку на стоимость (до 90% снижения cost) и ускорение (latency падает в 2–3 раза).

Пример использования (Python с Anthropic SDK):

import anthropic

client = anthropic.Anthropic()

# Первый запрос — создаём кэш для системного промпта
response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    system=[
        {
            "type": "text",
            "text": "Вы — эксперт по RAG. Отвечайте кратко и по делу.",
            "cache_control": {"type": "ephemeral"}  # помечаем как кэшируемый
        }
    ],
    messages=[{"role": "user", "content": "Что такое RAG?"}]
)

# Второй запрос — используем тот же системный промпт (кэш уже есть)
response2 = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    system=[
        {
            "type": "text",
            "text": "Вы — эксперт по RAG. Отвечайте кратко и по делу.",
            "cache_control": {"type": "ephemeral"}
        }
    ],
    messages=[{"role": "user", "content": "Как работает chunking?"}]
)

Важно Кэш привязан к точному тексту префикса. Любое изменение (даже пробел) инвалидирует кэш.

Ценообразование

  • Запись кэша (первый раз) стоит немного дороже обычного токена.
  • Чтение из кэша (последующие разы) стоит значительно дешевле (до 90% экономии).
  • Подробные тарифы: Anthropic публикует цены на странице документации.

3. Реализация у Google (Gemini)

Google Gemini API также поддерживает context caching (аналог prompt caching).

Как работает

  • Вы создаёте кэшированный контекст через отдельный endpoint или параметр в запросе.
  • Кэш хранится до 1 часа (по умолчанию) и может быть продлён.
  • При запросе вы ссылаетесь на идентификатор кэша.

Пример (Python с Google Generative AI SDK):

import google.generativeai as genai

genai.configure(api_key="YOUR_API_KEY")

# Создаём кэш для системного промпта и базы знаний
cache = genai.caching.CachedContent.create(
    model='models/gemini-1.5-pro-001',
    system_instruction="Вы — помощник по документации.",
    contents=[
        genai.Content(role="user", parts=[genai.Part.from_text("Вот база знаний: ...")])
    ],
    ttl=datetime.timedelta(hours=1)
)

# Используем кэш в запросе
model = genai.GenerativeModel.from_cached_content(cached_content=cache)
response = model.generate_content("Как настроить RAG?")

Особенности Gemini

  • Можно кэшировать не только system prompt, но и целые сообщения (например, историю диалога или документы).
  • TTL (time-to-live) настраивается.
  • Кэш считается отдельным ресурсом, за его хранение взимается плата (но дешевле, чем повторный расчёт).

4. Сравнение Anthropic vs Google

ПараметрAnthropic (Claude)Google (Gemini)
НазваниеPrompt cachingContext caching
Способ указанияПараметр cache_control в system или messagesОтдельный ресурс CachedContent
Время жизни кэша~5–10 мин с последнего использованияНастраиваемое (по умолчанию 1 час)
Снижение costДо 90% на чтенииДо 75% (зависит от размера)
Снижение latencyВ 2–3 разаВ 2–4 раза
Что можно кэшироватьSystem prompt, сообщения (с версии API 2024-10-22)System instruction, contents (история, документы)
ИнвалидацияЛюбое изменение текста префиксаИзменение содержимого или TTL
APIЕдиный endpoint messagesОтдельный endpoint для создания/использования кэша

5. Стратегии использования prompt caching

5.1 Структурированные системные промпты

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

system_prompt = """
Ты — AI-ассистент для технической поддержки.
Правила:
- Отвечай только на основе предоставленных документов.
- Если ответа нет в документах, скажи "Не знаю".
- Формат: краткий ответ, затем цитата из документа.
"""

5.2 Few-shot examples как cache_prefix

Если вы передаёте несколько примеров (вопрос-ответ) в начале промпта, их можно кэшировать. При смене реального вопроса кэш остаётся валидным.

5.3 Common knowledge base как постоянный cache

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

5.4 Многошаговые агентные сценарии

В agentic RAG агент может делать несколько вызовов LLM в рамках одного диалога. Если системный промпт и история общих инструкций кэшированы, каждый следующий шаг будет быстрее.


6. Важные нюансы и ограничения

  • Инвалидация при изменении Любое изменение кэшируемого текста (даже лишний пробел) делает кэш недействительным. Нужно строго контролировать версионирование промптов.
  • Размер кэша Ограничен (у Anthropic — до 200K токенов, у Google — до 1M токенов). Слишком большой кэш может не поместиться.
  • Консистентность Если модель обновляется (новая версия), старый кэш может стать невалидным. Провайдеры обычно автоматически инвалидируют кэш при обновлении модели.
  • Безопасность Кэш хранится на стороне провайдера. Не кэшируйте конфиденциальные данные, если нет гарантий изоляции.
  • Региональность Кэш может быть привязан к региону дата-центра. При смене региона кэш не работает.

7. Когда не стоит использовать prompt caching

  • Короткие промпты (< 100 токенов) — выигрыш минимален, а накладные расходы на управление кэшем могут перевесить.
  • Уникальные запросы — если каждый запрос имеет совершенно разный префикс, кэш никогда не попадёт.
  • Динамические системные промпты — если системный промпт часто меняется (например, зависит от пользователя), кэш будет постоянно инвалидироваться.
  • Очень большие кэши — если размер кэша接近 лимит, стоимость хранения может быть выше экономии.

8. Практические советы по оптимизации

  1. Разделяйте статическую и динамическую части промпта. Всё, что одинаково для многих запросов (инструкции, формат, правила), выносите в кэшируемый префикс. Всё, что меняется (конкретный вопрос, динамический контекст), — в некэшируемый суффикс.
  2. Используйте один кэш для всех запросов одной сессии. Если у вас чат-бот, кэшируйте системный промпт один раз при старте сессии.
  3. Мониторьте hit rate кэша Провайдеры предоставляют метрики (например, в Anthropic — заголовки x-llm-cache-hit). Если hit rate низкий — пересмотрите стратегию.
  4. Версионируйте промпты При изменении системного промпта меняйте его хэш или версию, чтобы не использовать старый кэш.
  5. Комбинируйте с другими оптимизациями prompt caching + speculative decoding + batching дают максимальный эффект.

Пет-проект для закрепления

Задача Реализовать RAG-чат-бота с поддержкой prompt caching для снижения затрат.

Инструменты Python, Anthropic SDK (или Google Generative AI SDK), FastAPI, Redis (для хранения идентификаторов кэша).

Шаги:

  1. Создайте FastAPI-приложение с эндпоинтом /chat.
  2. При старте приложения сгенерируйте системный промпт (например, «Ты — помощник по документации. Отвечай на русском. Используй контекст: ...»).
  3. При первом запросе отправьте его с cache_control (Anthropic) или создайте CachedContent (Google). Сохраните идентификатор кэша в Redis.
  4. При последующих запросах используйте сохранённый идентификатор кэша.
  5. Добавьте endpoint /invalidate_cache для принудительной инвалидации при обновлении документов.
  6. Измерьте latency и cost до и после внедрения кэша (используйте логи API).

Ожидаемый результат Рабочий чат-бот, который при повторных запросах с тем же системным промптом отвечает в 2–3 раза быстрее и тратит на 70–90% меньше токенов.


Связь с другими вопросами

ВопросТема
7Как уменьшить latency RAG-системы?
10Что такое Self-RAG и когда его использовать?
20Как оптимизировать стоимость LLM-запросов?
30Что такое speculative decoding?
45Как работает KV-кэш в трансформерах?
50Как проектировать системные промпты для RAG?

Навигация