Агент на базе LLM не помнит предыдущий шаг. Вызывая инструмент и получая результат, он снова отправляет модели весь контекст: определения функций, developer prompt с правилами, все прошлые вызовы и их результаты. Модель предсказывает следующий токен только по тому, что пришло в запросе, внутренней памяти между запросами у неё нет. Разбор Amazon для ML-инженеров называет это основной статьёй расходов в агентных сценариях.
Арифметика простая. К 20-му ходу кодинг-сессии модель заново читает ходы с 1-го по 19-й, и за каждый из этих токенов платит пользователь. Prompt caching прерывает цикл: сервис сохраняет входной промпт, куда входят инструкции, инструменты и контент, и переиспользует его в следующем запросе по доле обычной цены входных токенов.
Дальше по порядку: что именно уходит в промпт агента, какие блоки реально кэшируются, чем отличаются режимы implicit и explicit, как выглядит рабочая структура промпта и по каким метрикам проверять эффект.
Почему агент платит за один и тот же контекст на каждом шаге
Расход растёт не из-за «сложных размышлений» модели, а из-за механики доставки контекста. Каждый шаг агента — это новый независимый запрос. Всё, что было в предыдущем, нужно повторить, иначе модель потеряет нить задачи. В длинных агентных сессиях, особенно в кодинге, где история набирает вес быстро, это главный источник стоимости.
Что именно уходит в промпт на каждом шаге агента
- Список инструментов — определения каждой функции, которую агент может вызвать. Меняется при выпуске новой версии агента.
- Инструкции (developer prompt) — правила, персона, политики, примеры. Тоже меняется при релизе.
- История — всё, что случилось в сессии: задача, вызовы инструментов, результаты. Растёт каждый ход.
- Новый ход — последний результат инструмента или сообщение пользователя. Может отличаться при каждом вызове.
Дальше всё решает стабильность блока.
| Блок промпта | Как часто меняется | Смысл для кэширования |
|---|---|---|
| Список инструментов | При релизе агента | Стабильный префикс, главный кандидат на кэш |
| Инструкции | При релизе | Кэшируется вместе с tools как единый префикс |
| История | Каждый ход, но только в конец | Растёт монотонно, поэтому переиспользуется до последнего хода |
| Новый ход | Каждый вызов | Кэшировать бессмысленно: точного совпадения не будет |
Вывод: стабильные блоки в начале промпта — первые кандидаты на кэш, растущая история — второй. Новый ход кэшировать нечего, он по определению уникален.
Prefill и KV-векторы: что на самом деле сохраняет кэш
Читая промпт, модель выполняет prefill: обрабатывает каждый входной токен и строит key-value векторы (KV). Они формируют рабочее состояние модели и появляются до того, как она выдаст первый токен ответа. Prompt caching сохраняет это состояние, в котором есть system prompt, инструменты, контент и история.
Когда следующий запрос начинается с тех же входных токенов, сервис загружает сохранённое состояние вместо повторного расчёта и обрабатывает только новую часть payload. Экономия берётся из вычисления, которое не пришлось делать. Конкретных замеров задержки в исходном материале нет, акцент там на цене входных токенов, но логика понятна: меньше prefill — быстрее ответ на первом токене.
Отсюда главное следствие для проектирования промпта. Кэш сопоставляет префикс по точному тексту, а не по смыслу. Любая правка в начале промпта, будь то переформулировка инструкции, другой порядок инструментов или подставленная дата, ломает переиспользование, и вся история пересчитывается заново.
Implicit и explicit: два режима prompt caching на Amazon Bedrock
Режимов два. В implicit Amazon Bedrock сам выбирает, где заканчивается переиспользуемый префикс, по мере роста диалога. В explicit код вручную отмечает эту границу через prompt_cache_breakpoint. Оба подхода можно использовать вместе. Подробности про cachePoint в Converse API, тарифы на запись и чтение кэша и пороги токенов есть в отдельном разборе prompt caching в Amazon Bedrock.
Implicit: когда границу выбирает Bedrock
Режим для быстрого старта. Диалог растёт, изменяемый хвост дописывается, а сервис сам определяет, какой кусок префикса имеет смысл держать в кэше. Кода меньше, ручной поддержки тоже. Плата за это — меньше контроля: граница задаётся не вами, поэтому предсказуемость попадания ниже, а поведение сложнее связать с конкретной строкой в промпте. Подходит, когда структура промпта стабильна и хочется увидеть эффект без переписывания обвязки.
Explicit и prompt_cache_breakpoint: ручная граница префикса
Здесь вы сами решаете, что попадёт в кэш. Рабочий паттерн: поставить prompt_cache_breakpoint после общих блоков, то есть после tools и instructions. Тогда они кэшируются как единый стабильный префикс, а меняющаяся история идёт после границы. Принцип простой: до breakpoint всё должно быть максимально неизменным, после — что угодно, хоть новый результат инструмента на каждом ходу. Точный синтаксис параметра и правила размещения смотрите в документации Bedrock, в исходном материале примеров кода нет.
Комбинация режимов
Explicit фиксирует общий стабильный префикс из tools и instructions, implicit подхватывает рост истории дальше по диалогу. Логика такая: короткая ручная разметка там, где важна стабильность, и автоматика там, где промпт растёт сам. Как именно ведут себя режимы в связке, в доступном фрагменте источника не раскрыто, поэтому проверяйте на своём workload по метрикам, а не по предположениям.
Практические паттерны кэширования для агентов
Кэширование истории и результатов инструментов
История — самый быстрорастущий блок, и именно она делает поздние ходы дорогими. Кэш состояния до последнего хода позволяет не пересчитывать прошлые вызовы и результаты, а доплачивать только за новый фрагмент. Ограничение известно: правка инструкции в начале сбрасывает префикс и обнуляет эффект. Держите стабильные блоки до breakpoint, изменяемое — после. Как ловить такие сбросы в локальных обвязках, разобрано в материале про поиск проблем инвалидации кэша префиллов.
Новые инструменты через additional_tools без инвалидации каталога
Проблема очевидна: список инструментов стоит в начале промпта. Добавили функцию в произвольное место каталога, получили другой префикс и промах по кэшу на всей истории. Паттерн additional_tools описан как способ подключать инструменты, не ломая начальный каталог. Назначение понятно, детали (куда именно попадают дополнительные определения и действуют ли на них те же пороги) сверяйте с документацией Bedrock и проверяйте по cache_write_tokens. Похожая логика привязки инструментов к навыкам и её влияние на кэш промпта разобраны в статье про Deep Agents.
Профили инструментов под разные роли
Разные наборы инструментов — это разные префиксы, а значит разные кэшируемые цепочки. Когда в одном промпте смешаны роли с пересекающимися, но не совпадающими каталогами функций, префикс меняется от вызова к вызову, и кэш почти не попадает. Практика: группировать агентов по стабильному набору tools и instructions, у каждого профиля свой префикс и свой ключ кэша. Планировщик, исполнитель и ревьюер с разными инструментами должны жить в разных профилях.
Прогрев общего префикса перед запуском суб-агентов
Если несколько суб-агентов работают с одним и тем же префиксом из tools и instructions, первый вызов прогревает кэш, а следующие читают готовое состояние вместо нового prefill. Условие жёсткое: префикс должен совпадать, а модель, аккаунт и регион — быть одними и теми же. Выгода зависит от того, как часто суб-агенты запускаются в пределах TTL. Веер из десяти агентов, стартующих подряд, отработает заметно дешевле веера, растянутого на часы.
Переиспользование кэша между сессиями при стабильном prompt_cache_key
Стабильный prompt_cache_key позволяет подхватить кэш в новой сессии, если префикс не изменился. Ограничение — TTL от 30 минут: если между запусками прошло больше, состояние не доживёт и prefill пойдёт заново. Держите ключ неизменным для одного набора tools и instructions и меняйте его только тогда, когда префикс меняется осознанно. Случайный или привязанный к сессии ключ обнуляет весь смысл схемы.
Требования и ограничения, без которых кэш не сработает
Условия, при которых кэширование префикса вообще включается:
- Минимум 1024 токена в кэшируемом префиксе. Короткий стабильный блок не даёт эффекта: кэшировать нечего.
- TTL от 30 минут. После паузы состояние теряется и следующая сессия платит полную цену prefill.
- Совпадение модели, аккаунта и региона. Смена модели или региона обнуляет переиспользование.
- Точное совпадение начальных токенов. Любая правка в начале промпта ломает попадание.
Эти значения приведены как ориентир из описания механизма. Прямого подтверждения цифр в исходном материале Amazon, который лёг в основу разбора, нет, поэтому сверяйте порог и TTL с актуальной документацией Bedrock: они могут отличаться для разных моделей.
Кому кэширование не даст выгоды
- Короткие промпты: стабильная часть меньше порога в 1024 токена.
- Нестабильное начало промпта: динамические инструкции, текущая дата в system prompt, случайный порядок инструментов.
- Редкие вызовы с паузами больше TTL: состояние не успевает переиспользоваться.
- Частая смена модели или региона: каждая смена означает новый кэш с нуля.
Порядок действий здесь один: сначала измерить, потом настраивать. Если стабильный префикс занимает 300 токенов, никакая разметка breakpoint экономию не создаст.
Как проверить, что кэш работает: cached_tokens, cache_write_tokens и CloudWatch
Смотреть нужно на два поля в ответе. cached_tokens показывают, сколько входных токенов пришло из кэша. cache_write_tokens показывают, сколько записано в кэш при создании состояния. По их соотношению видно, что происходит на самом деле, без догадок.
- cached_tokens растут при стабильном префиксе: попадание есть.
- cache_write_tokens есть, а cached_tokens на следующем вызове нулевые: префикс каждый раз разный.
- Оба показателя нулевые: префикс короче порога или кэширование не включено.
Метрики CloudWatch и мониторинг во времени
Разовая проверка ловит грубые ошибки, динамику показывают метрики CloudWatch. Смотрите долю кэшированных токенов по мере правок промпта и релизов агента. Резкое падение доли сразу после обновления — почти всегда признак того, что префикс перестал быть стабильным: переставили инструменты, добавили дату в инструкцию, поменяли порядок блоков. Конкретный набор метрик сверяйте с документацией, в исходном материале перечислены только эти показатели.
Как оценить экономию на своём workload
Считайте по своим данным: типичную длину стабильного префикса (tools плюс instructions), среднюю длину истории к концу сессии, число вызовов на сессию, длительность сессий относительно TTL и частоту изменений префикса. Кэширование окупается там, где префикс длинный, стабильный и вызывается часто в пределах TTL. Чужие оценки экономии переносить на свой агент бессмысленно: они зависят от структуры промпта и паттерна вызовов.
Что в итоге делать: порядок шагов
- Выделите стабильный префикс из tools и instructions и посчитайте его длину. Меньше 1024 токенов — расширяйте стабильную часть или откажитесь от затеи.
- Начните с implicit, если нужен быстрый результат, или сразу переходите к explicit, если важна предсказуемость.
- Поставьте prompt_cache_breakpoint после стабильных блоков. История и новый ход должны идти после границы.
- Уберите из начала промпта всё изменяемое: даты, идентификаторы сессий, рандомизированный порядок инструментов.
- Подключайте новые инструменты через additional_tools, чтобы не ломать начальный каталог.
- Разведите профили инструментов по ролям: у каждого профиля свой стабильный префикс и свой ключ кэша.
- Прогрейте общий префикс одним вызовом перед веером суб-агентов, если они работают с одинаковыми tools и instructions.
- Держите стабильный prompt_cache_key для повторного использования кэша между сессиями и меняйте его только вместе с префиксом.
- Проверяйте cached_tokens и cache_write_tokens после каждого релиза, следите за динамикой в CloudWatch.
- Посчитайте экономию на своём workload до и после изменений, а не полагайтесь на общие оценки.
Ограничения остаются: TTL от 30 минут, привязка к модели, аккаунту и региону, чувствительность к любой правке в начале промпта. Кэширование окупается дисциплиной структуры промпта: стабильный префикс, аккуратная граница и регулярная проверка метрик. Начните с одного агента, замерьте cached_tokens до и после разметки breakpoint, и решение о раскатке на остальные профили принимайте по цифрам.