Настроить 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 Caching | docs.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‑ключа — симулируем:
- Установите LocalAI или используйте open‑source модель (например, llama.cpp) с поддержкой KV‑cache.
- Напишите враппер, который эмулирует подсчёт токенов и возвращает фейковые поля cache_creation_input_tokens и cache_read_input_tokens на основе размера префикса.
- Замерьте фактическое время ответа — оно будет меньше при повторном использовании префикса (реальный KV‑cache).
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Язык программирования | Python 3.10+ | Основной скрипт |
| SDK | anthropic (0.45+) | Взаимодействие с API Claude |
| Управление кэшем | functools.lru_cache, cachetools | Хранение префиксов в памяти |
| Замеры | time, asyncio | Время ответа, токены |
| Форматирование отчёта | pandas, matplotlib | Таблицы и графики затрат |
| Тестирование | pytest, unittest.mock | Проверка корректности кэша |
4. Этапы выполнения
Этап 1: Анализ архитектуры Prompt Caching (30 минут)
Действия
- Изучите документацию Anthropic: какие поля есть у
MessageParam, как указать cache_control для префикса. - Разберите пример из документации: создайте минимальный запрос, в котором
contentсодержит блок с cache_control = {"type": "ephemeral"}. - Зафиксируйте лимиты: максимальный размер кэша — 256 токенов (на самом деле 1024, но проверьте последние цифры); кэш живёт 5 минут с момента последнего cache‑read; кэш создаётся только для запросов с cache_control у префикса.
- Напишите короткую заметку в README.md с ключевыми правилами: при каждом новом префиксе (например, изменении system prompt) создаётся новый cache entry; при повторном использовании того же префикса — cache read, стоимость которого намного ниже.
Ожидаемый результат этапа Документ с принципами работы caching у Anthropic, список ограничений.
Этап 2: Подготовка тестового окружения и данных (1 час)
Действия
-
Установите Python‑пакеты: pip install anthropic pandas matplotlib
-
Создайте файл 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} -
Сформируйте набор из 50 пользовательских запросов (разной длины, первые 10 — уникальные, 10–50 — повторяющиеся). Сохраните в queries.json:
[ "Что такое энтропия?", "Объясни второй закон термодинамики", ... ] -
Напишите функцию
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 часа)
Действия
- Напишите класс
CachingAnthropic, который хранит в памяти словарь cache = {} с ключом = хэш префикса и значением = (время создания, текст префикса). - Реализуйте метод 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.
- После успешного ответа сохраните хэш и время.
- Перед отправкой проверьте, есть ли этот
- Обработайте ошибки API: если caching не поддерживается моделью, используйте fallback без кэша и логируйте предупреждение.
- Добавьте функцию
simulate_cache(), которая возвращает фиктивныеcache_read_input_tokens = 0.1 * total_input_tokens(для тестирования без ключа).
Ожидаемый результат этапа Работающий класс, который корректно управляет cache_control и подсчитывает экономию.
Этап 4: Прогон тестов и сбор метрик (1 час)
Действия
- Запустите цикл по 50 запросам (сначала без кэша — установите
no_cacheфлаг, затем с кэшем). - Для каждого запроса запишите:
input_tokenscache_creation_input_tokensилиcache_read_input_tokensoutput_tokens- Время ответа (сек)
- Рассчитайте стоимость по формуле 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 для модели)
- Без кэша:
- Постройте график:
cost per queryс кэшем и без, накопительная экономия.
Ожидаемый результат этапа Таблица и график, показывающие снижение стоимости более чем на 90%.
Этап 5: Написание отчёта и документирование (30 минут)
Действия
- Оформите результаты в файл
caching_report.mdсо структурой:- Методология: как считали cost.
- Результаты: таблица с метриками до/после, график.
- Выводы: достигнута ли экономия >90%, при каких условиях?
- Рекомендации: кэш эффективен для систем с длинным статичным промптом (агенты, RAG‑префиксы).
- Добавьте комментарии в коде о том, как адаптировать кэш для асинхронных вызовов (например,
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 на стороне сервера |
| 164 | Rate 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%.