中文翻译暂不可用,显示俄语原文。

Настроить prompt caching (Anthropic style)

ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить prompt caching (Anthropic style)

1. Цель задачи

Спроектировать и реализовать систему prompt caching для серии запросов к LLM (Anthropic), которые используют общий префикс (например, системный промпт или длинный контекст). Основной фокус — снижение затрат на повторную обработку общего префикса, типичного для multi‑turn диалогов, пакетной обработки или streaming‑агентов.

Ключевой результат Демонстрация снижения стоимости генераций не менее чем на 90% (cost per token) за счёт кэширования общего префикса при сохранении качества ответов на уровне без кэша.


2. Исходные данные

Перед началом необходимо иметь:

Что нужноОткуда взять
API‑ключ Anthropic (Claude)console.anthropic.com
Документация по Prompt Cachingdocs.anthropic.com/en/docs/build-with-claude/prompt-caching
Тестовый набор запросов с общим префиксомСформировать самостоятельно (например, 50 вопросов с одним system prompt длиной ~5k токенов)
Инструмент для расчёта стоимости токеновAnthropic API возвращает usage.cache_creation_input_tokens, usage.cache_read_input_tokens, usage.input_tokens
Дополнительные зависимостиPython 3.10+, anthropic SDK (pip install anthropic), pandas, matplotlib (для отчёта)

Если нет реального API‑ключа — симулируем:

  1. Установите LocalAI или используйте open‑source модель (например, llama.cpp) с поддержкой KV‑cache.
  2. Напишите враппер, который эмулирует подсчёт токенов и возвращает фейковые поля cache_creation_input_tokens и cache_read_input_tokens на основе размера префикса.
  3. Замерьте фактическое время ответа — оно будет меньше при повторном использовании префикса (реальный KV‑cache).

3. Технологический стек

КомпонентИнструментыНазначение
Язык программированияPython 3.10+Основной скрипт
SDKanthropic (0.45+)Взаимодействие с API Claude
Управление кэшемfunctools.lru_cache, cachetoolsХранение префиксов в памяти
Замерыtime, asyncioВремя ответа, токены
Форматирование отчётаpandas, matplotlibТаблицы и графики затрат
Тестированиеpytest, unittest.mockПроверка корректности кэша

4. Этапы выполнения

Этап 1: Анализ архитектуры Prompt Caching (30 минут)

Действия

  1. Изучите документацию Anthropic: какие поля есть у MessageParam, как указать cache_control для префикса.
  2. Разберите пример из документации: создайте минимальный запрос, в котором content содержит блок с cache_control = {"type": "ephemeral"}.
  3. Зафиксируйте лимиты: максимальный размер кэша — 256 токенов (на самом деле 1024, но проверьте последние цифры); кэш живёт 5 минут с момента последнего cache‑read; кэш создаётся только для запросов с cache_control у префикса.
  4. Напишите короткую заметку в README.md с ключевыми правилами: при каждом новом префиксе (например, изменении system prompt) создаётся новый cache entry; при повторном использовании того же префикса — cache read, стоимость которого намного ниже.

Ожидаемый результат этапа Документ с принципами работы caching у Anthropic, список ограничений.

Этап 2: Подготовка тестового окружения и данных (1 час)

Действия

  1. Установите Python‑пакеты: pip install anthropic pandas matplotlib

  2. Создайте файл config.py:

    import os
    CLIENT = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
    MODEL = "claude-3-5-sonnet-20241022"  # поддерживает caching
    SYSTEM_PROMPT = "Ты — эксперт по ... (очень длинный текст, ~5000 токенов)"
    GENERATION_KWARGS = {"model": MODEL, "max_tokens": 512}
    
  3. Сформируйте набор из 50 пользовательских запросов (разной длины, первые 10 — уникальные, 10–50 — повторяющиеся). Сохраните в queries.json:

    [
      "Что такое энтропия?",
      "Объясни второй закон термодинамики",
      ...
    ]
    
  4. Напишите функцию build_messages(system_prompt, user_query):

    def build_messages(system, query):
        return [
            {"role": "user", "content": [
                {"type": "text", "text": system, "cache_control": {"type": "ephemeral"}},
                {"type": "text", "text": query}
            ]}
        ]
    

Ожидаемый результат этапа Конфигурация, тестовые данные и функция построения сообщений с cache_control.

Этап 3: Реализация кэширующего враппера (2 часа)

Действия

  1. Напишите класс CachingAnthropic, который хранит в памяти словарь cache = {} с ключом = хэш префикса и значением = (время создания, текст префикса).
  2. Реализуйте метод generate(prefix_hash, messages):
    • Перед отправкой проверьте, есть ли этот prefix_hash в кэше и не истёк ли TTL (4 минуты 30 секунд).
    • Если кэш актуален: отправляйте запрос, но не указывайте cache_control для префикса (будет cache read). Зафиксируйте usage.cache_read_input_tokens.
    • Если кэш отсутствует или протух: отправляйте запрос с cache_control у префикса (создаст cache entry). Зафиксируйте usage.cache_creation_input_tokens.
    • После успешного ответа сохраните хэш и время.
  3. Обработайте ошибки API: если caching не поддерживается моделью, используйте fallback без кэша и логируйте предупреждение.
  4. Добавьте функцию simulate_cache(), которая возвращает фиктивные cache_read_input_tokens = 0.1 * total_input_tokens (для тестирования без ключа).

Ожидаемый результат этапа Работающий класс, который корректно управляет cache_control и подсчитывает экономию.

Этап 4: Прогон тестов и сбор метрик (1 час)

Действия

  1. Запустите цикл по 50 запросам (сначала без кэша — установите no_cache флаг, затем с кэшем).
  2. Для каждого запроса запишите:
    • input_tokens
    • cache_creation_input_tokens или cache_read_input_tokens
    • output_tokens
    • Время ответа (сек)
  3. Рассчитайте стоимость по формуле Anthropic:
    • Без кэша: cost = input_tokens * price_per_input + output_tokens * price_per_output
    • С кэшем: cost = cache_creation_input_tokens * price_per_cache_create + cache_read_input_tokens * price_per_cache_read + output_tokens * price_per_output (цену берите из pricing для модели)
  4. Постройте график: cost per query с кэшем и без, накопительная экономия.

Ожидаемый результат этапа Таблица и график, показывающие снижение стоимости более чем на 90%.

Этап 5: Написание отчёта и документирование (30 минут)

Действия

  1. Оформите результаты в файл caching_report.md со структурой:
    • Методология: как считали cost.
    • Результаты: таблица с метриками до/после, график.
    • Выводы: достигнута ли экономия >90%, при каких условиях?
    • Рекомендации: кэш эффективен для систем с длинным статичным промптом (агенты, RAG‑префиксы).
  2. Добавьте комментарии в коде о том, как адаптировать кэш для асинхронных вызовов (например, asyncio + aiocache).

Ожидаемый результат этапа Готовый отчёт и чистый репозиторий с кодом.


5. Критерии приемки (Definition of Done)

  • Реализована функция создания сообщений с cache_control для префикса.
  • Кэш корректно распознаёт повторное использование того же префикса (хэш + TTL).
  • При первом запросе с новым префиксом фиксируется cache_creation_input_tokens.
  • При повторном запросе с тем же префиксом фиксируется cache_read_input_tokens и стоимость снижена.
  • Измеренная стоимость (cost per query) сократилась минимум на 90% для набора из 50 запросов.
  • Все ошибки API (лимит кэша, неподдерживаемая модель) обработаны и не приводят к падению.
  • Написан отчёт в формате Markdown с таблицами и графиками.
  • Код покрыт юнит‑тестами (минимум: тест на кэширование, тест на TTL, тест на fallback).

6. Ожидаемый результат

Основной артефакт Папка anthropic_caching/ со следующей структурой:

caching_demo/
├── config.py               # Ключ, модель, system промпт
├── queries.json             # 50 запросов
├── caching_client.py        # Класс CachingAnthropic
├── run_experiment.py        # Основной скрипт: запуск с кэшем и без, сбор метрик
├── tests/
│   ├── test_caching.py      # Юнит-тесты
│   └── __init__.py
├── caching_report.md        # Отчёт со сравнением
└── figures/
    ├── cost_per_query.png
    └── cumulative_savings.png

Содержание отчёта

  • Итоговая таблица: средний cost на запрос без кэша vs с кэшем.
  • Процент экономии (должен быть ≥90%).
  • График накопленной стоимости для серии запросов.
  • Замечания: TTL, количество запросов в пуле, влияние размера префикса.

Опциональные результаты

  • Реализация асинхронной версии (asyncio + aiocache).
  • Сравнение с обычным KV‑cache на локальной модели (llama.cpp).

7. Возможные сложности и их решение

СложностьРешение
API возвращает ошибку prompt_caching_not_supported для моделиПроверить поддерживаемые модели (Claude 3.5 Sonnet, Claude 4 и т.д.) или использовать fallback без кэша.
Кэш сбрасывается из-за 5-минутного TTLУменьшить количество запросов или использовать пакетную отправку с минимальной задержкой между ними.
Токены кэширования не видны в ответе (может быть устаревшая версия SDK)Обновить anthropic до последней версии (pip install --upgrade anthropic).
Нет реального API ключаИспользовать симуляцию (описана в Этапе 2) и эмулировать цены.
Изменение префикса на ходу (разные system prompt)Сделать ключ кэша = хэш всего префикса; при изменении — новый cache creation.

8. Бюджет времени (оценка)

ЭтапВремя
Этап 1: Анализ30 мин
Этап 2: Подготовка1 час
Этап 3: Реализация2 часа
Этап 4: Прогон тестов1 час
Этап 5: Отчёт30 мин
Итого5 часов

Примечание Для первого выполнения задачи может потребоваться до 8 часов из‑за отладки кэша и изучения документации.


9. Связанные вопросы из базы знаний

ВопросТема
12Основы токенизации и стоимость запросов к LLM
45Оптимизация промптов: общий префикс
88Архитектура system prompt в мульти-агентных системах
132Кэширование KV‑cache на стороне сервера
164Rate limiting и retry при работе с API
205Измерение задержек и стоимости LLM вызовов
267Использование cache_control в Anthropic
310Сравнение API провайдеров (Anthropic vs OpenAI)
389Балансировка нагрузки и распределённый кэш
451Анализ чувствительности качества ответов при кэшировании

10. Чек-лист самопроверки

  • Я прочитал документацию Anthropic по prompt caching и понимаю разницу между cache_creation и cache_read.
  • Я подготовил корректный набор запросов: первые 10 — разные префиксы, остальные 40 — повтор одного префикса.
  • Я убедился, что в cache_control указан "ephemeral", а не другое значение.
  • Я измерил стоимость как в симулированном режиме, так и (если есть ключ) на реальных вызовах.
  • В итоговом отчёте приведены численные значения экономии и график, подтверждающий ≥90%.