Context Caching: Технология кэширования для снижения затрат

45 минут Урок 17

Введение: Парадокс огромного контекста

Добро пожаловать на урок, который может сэкономить вашему проекту тысячи долларов. Мы уже обсудили возможности Gemini работать с гигантскими контекстными окнами (до 1-2 миллионов токенов). Это открывает невероятные возможности: вы можете загрузить в модель целые книги, юридические кодексы или кодовую базу крупного проекта.

Но здесь возникает две фундаментальные проблемы:

  1. Стоимость (Cost): Каждый раз, когда вы отправляете запрос к модели, вы платите за весь входной контекст. Если вы загрузили книгу на 500,000 токенов и задали 10 вопросов, вы заплатите за обработку 500,000 токенов 10 раз. Это 5 миллионов токенов на входе.
  2. Задержка (Latency): Модели нужно время, чтобы «прочитать» и обработать этот контекст перед генерацией ответа. Повторная обработка одних и тех же данных — это пустая трата вычислительного времени.

Context Caching (Кэширование контекста) — это решение, которое позволяет сохранить (закешировать) токены входных данных на серверах Google. Вместо того чтобы пересчитывать их при каждом запросе, модель обращается к уже обработанным данным.

Как это работает: Архитектура и Экономика

Давайте разберем механику. Когда вы используете Context Caching, процесс разделяется на три этапа оплаты и обработки:

  • 1. Создание кэша (Write): Вы платите за первичную обработку токенов. Это стоит примерно так же, как обычный входящий запрос (или чуть дешевле, в зависимости от тарифа).
  • 2. Хранение (Storage): Вы платите почасовую ставку за хранение этих данных в активной памяти сервера.
  • 3. Использование (Read): Когда вы задаете вопросы к кэшированному контенту, вы платите за входные токены значительно меньше (скидка может достигать 90% и более по сравнению с обычным вводом), так как модели не нужно заново «понимать» текст.

Правило большого пальца: Кэширование становится выгодным, если вы планируете обратиться к одному и тому же контексту большое количество раз (обычно от 5-10 запросов и выше, в зависимости от длины контекста и времени жизни кэша).

python
import os
import time
import google.generativeai as genai
from google.generativeai import caching

# Настройка API ключа
# Убедитесь, что ваш ключ поддерживает платные функции, так как кэширование обычно недоступно на бесплатном уровне
genai.configure(api_key=os.environ['GOOGLE_API_KEY'])

# 1. Подготовка данных
# Допустим, у нас есть PDF файл с технической документацией
# Загружаем файл в File API
document_path = 'large_technical_manual.pdf'
print(f"Загрузка файла {document_path}...")

my_file = genai.upload_file(path=document_path)

# Ждем завершения обработки файла на стороне Google
while my_file.state.name == "PROCESSING":
    print(".", end="")
    time.sleep(2)
    my_file = genai.get_file(my_file.name)

print(f"\nФайл готов: {my_file.uri}")

Создание и использование кэша

Теперь, когда файл загружен, мы не будем просто скармливать его модели напрямую. Мы создадим объект CachedContent.

Обратите внимание на параметр ttl (Time To Live). По умолчанию кэш живет недолго (обычно 1 час), чтобы вы не платили за забытые данные. Вы должны явно указать, как долго данные должны храниться.

Важный нюанс: Кэшированный контент привязывается к конкретной модели (например, gemini-1.5-pro-001). Вы не можете создать кэш для Pro и использовать его с Flash.

python
import datetime

# 2. Создание кэша
# Мы хотим, чтобы кэш жил 2 часа
cache_ttl = datetime.timedelta(hours=2)

cache = caching.CachedContent.create(
    model='models/gemini-1.5-flash-001',
    display_name='manual_cache_v1', # Удобное имя для отладки
    system_instruction='Ты эксперт по технической поддержке на основе данного мануала.',
    contents=[my_file],
    ttl=cache_ttl
)

print(f"Кэш создан: {cache.name}")
print(f"Истекает: {cache.expire_time}")

# 3. Подключение модели к кэшу
# ВАЖНО: Мы создаем экземпляр модели, передавая cache в конструктор
model = genai.GenerativeModel.from_cached_content(cached_content=cache)

# 4. Использование
# Теперь все запросы к этой переменной model будут иметь доступ к PDF
response = model.generate_content("Как сбросить настройки устройства до заводских?")
print(response.text)

# Можно вести диалог
chat = model.start_chat()
response2 = chat.send_message("А если это не поможет, что делать?")
print(response2.text)

Управление жизненным циклом (Lifecycle Management)

В продакшн-среде крайне важно следить за состоянием кэша. Если TTL истечет, ваше приложение получит ошибку 404 Not Found при попытке обратиться к кэшу. С другой стороны, «зомби-кэши» (которые вам больше не нужны, но они висят в памяти) будут тратить бюджет.

Методы управления:

  • update(): Позволяет продлить время жизни (TTL). Содержимое кэша изменить нельзя! Если данные изменились, нужно создавать новый кэш.
  • delete(): Явное удаление кэша, когда сессия пользователя завершена.
  • list(): Просмотр всех активных кэшей (полезно для скриптов очистки).

python
# Продление жизни кэша (если пользователь все еще активен)
new_ttl = datetime.timedelta(hours=1)
cache.update(ttl=new_ttl)
print(f"Жизнь кэша продлена. Новое время истечения: {cache.expire_time}")

# Явное удаление после завершения работы
# Всегда делайте это в блоке finally или при завершении сессии
cache.delete()
print("Кэш удален для экономии средств.")

# Пример листинга (админская панель)
print("Активные кэши:")
for c in caching.CachedContent.list():
    print(f"- {c.name} (Model: {c.model}) Exp: {c.expire_time}")

Лучшие практики и Антипаттерны

Чтобы технология работала на вас, а не против вас, следуйте этим рекомендациям:

✅ Когда использовать:

  • Чат-боты с базой знаний: Загружаете FAQ компании в кэш и держите его активным в рабочие часы.
  • Анализ длинных документов: Пользователь загрузил 100-страничный отчет и хочет задать ему 20 вопросов.
  • Few-Shot Prompting: Если у вас есть огромный набор примеров (десятки тысяч токенов), обучающих модель стилю ответа.

❌ Когда НЕ использовать:

  • Разовые запросы: Если вы загружаете контекст, задаете 1 вопрос и уходите. Вы заплатите за создание кэша, но не получите выгоды от дешевых чтений.
  • Динамичный контент: Данные, которые меняются каждую минуту. Кэш в Gemini неизменяем (immutable). Вам придется пересоздавать его постоянно, что дорого.

Упражнение

Создайте систему 'Личный Библиотекарь'. Задача:<br>1. Создайте текстовый файл `library_context.txt` (можно программно), содержащий описание вымышленного мира из 3-4 абзацев.<br>2. Загрузите его и создайте кэш с TTL 10 минут для модели `gemini-1.5-flash-001`.<br>3. Инициализируйте чат-сессию с использованием этого кэша.<br>4. Задайте модели вопрос о деталях этого мира.<br>5. Выведите в консоль имя кэша и время его истечения.<br>6. В конце скрипта удалите кэш.

Вопрос

Представьте, что вы разрабатываете бота для анализа юридических договоров. Пользователь загружает договор на 100,000 токенов. Что из перечисленного является наиболее экономически эффективной стратегией использования Context Caching?