Глава 11 · Экономика

Стоимость цикла и почему prompt caching меняет всё

Каждый поворот agentic loop — это новый HTTP-запрос со всем предыдущим контекстом. Без кеша агент тратит в десять раз больше, чем мог бы, и платит за одни и те же системные токены столько раз, сколько раз провернулся цикл.

Из чего складывается счёт

Anthropic считает по двум типам токенов: input (всё, что вы шлёте: tools, system, messages) и output (то, что модель сгенерировала в ответе, включая thinking- и tool_use-блоки). Output обычно дороже input в 4–5 раз — это базовая асимметрия, на которой держится всё остальное. Цены на момент написания (за миллион токенов, тариф «standard», без Batch-скидки):

МодельInputOutputCache write · 5mCache write · 1hCache read
Claude Opus 4.1 / 4$15$75$18.75$30$1.50
Claude Sonnet 4.5 / 4.6$3$15$3.75$6$0.30
Claude Haiku 4.5$1$5$1.25$2$0.10

Запомните три множителя: cache write 5m = ×1.25 от input, cache write 1h = ×2, cache read = ×0.1. Эти числа стабильны между моделями — меняется только база. Вся экономика этой главы выводится из этих трёх чисел.

Почему агент дорогой

Чат — это один запрос на одну реплику. Агент — это цикл, в котором каждый поворот = ещё один вызов Messages API. И каждый такой вызов отправляет в API весь прошлый messages заново: API stateless, никакой «сессии» на стороне Anthropic нет, контекст живёт только у вас в памяти harness'а. На двадцати итерациях ваш system-prompt и tools-схемы летят в API двадцать раз. Каждый tool_result, который модель когда-то увидела, она увидит ещё на каждой следующей итерации до конца сессии.

Формула проще, чем кажется. Пусть S — токены system+tools, H — прирост истории за итерацию, N — число поворотов. Без кеша суммарный input-биллинг = N·S + H·N(N+1)/2. Рост квадратичный по истории: десять итераций по 1500 токенов истории и 8k системного промпта дают уже 162.5k input-токенов, двадцать итераций — 475k. Это «налог на агента»: контекст прокатывается через API столько раз, сколько раз вы провернули цикл.

Prompt caching: механика

Prompt caching позволяет «возобновлять с заданного префикса»: Anthropic хранит prefix-хеш и KV-state по нему, и если вы шлёте тот же префикс ещё раз — модель не обрабатывает его заново, а тянет уже посчитанное представление. Включается это через маркер cache_control: {"type": "ephemeral"} — либо на конкретном content-блоке (explicit), либо одним полем на верхнем уровне запроса (automatic caching, тогда система сама ставит breakpoint на последний кешируемый блок и двигает его вперёд от запроса к запросу).

Ключевые ограничения. Во-первых, максимум 4 cache_control breakpoint'а на запрос: automatic caching съедает один из четырёх слотов. Во-вторых, кеширование уважает иерархию префикса — toolssystemmessages: изменение на верхнем уровне инвалидирует всё, что ниже. В-третьих, минимальная длина кешируемого префикса — 1024 токена для Sonnet 4.5 / Opus 4.1, 2048 для Sonnet 4.6, 4096 для Opus 4.5–4.7 и Haiku 4.5: всё короче кешируется молча-впустую. В-четвёртых, lookback при поиске уже записанной cache-entry — окно в 20 блоков назад от breakpoint'а.

TTL и тарифы

У ephemeral-кеша два tier'а времени жизни: дефолтный 5 минут и опциональный 1 час (cache_control: {"type": "ephemeral", "ttl": "1h"}). 5-минутный write стоит ×1.25 от input rate, часовой — ×2. Cache read в обоих случаях — ×0.1. TTL сбрасывается при каждом cache hit: пока вы попадаете в кеш, он живёт.

Практическое правило: 5m покрывает интерактивные итерации (пользователь отвечает за секунды-минуты, цикл крутится непрерывно), 1h оправдан для долгих сессий с паузами — кодовая сессия с обедом посередине, многошаговый сценарий по чек-листу, агент, дописывающий PR в фоне. Часовой кеш дороже на запись, но дешевле, чем заплатить полный input rate после того, как 5-минутка истекла. Эти множители стакаются с Batch API (−50% к input и output), что даёт ещё один пласт оптимизации для бэкграунд-задач — об этом в конце главы.

Cache hit / miss: мониторинг

Каждый ответ Messages API в поле usage возвращает три счётчика: cache_creation_input_tokens (записанное в кеш на этом запросе), cache_read_input_tokens (прочитанное из кеша) и input_tokens (то, что осталось после последнего breakpoint и обработано как обычный uncached input). Формула суммы — total_input = cache_read + cache_creation + input. Для streaming-режима усложнение одно: usage в message_delta приходит кумулятивно для cached-полей, поэтому код accounting'а должен брать последнее значение, а не суммировать дельты.

Hit rate считается как cache_read / (cache_read + cache_creation + input). Для production-агента целевая цифра — 90%+. У claude-cli в cost-tracker.ts крутятся четыре OTel-счётчика (inputTokens, outputTokens, cacheCreationInputTokens, cacheReadInputTokens) ровно ради этой метрики: без неё нельзя ни прайсинг отдебажить, ни понять, что ваш агент «дороже среднего, потому что у вас постоянно меняются tools».

Что ломает кеш

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

Manus в своём context-engineering постулирует это как первый принцип архитектуры: maintain stable prompt prefixes — single-token differences invalidate cache, плюс append-only context (никогда не редактировать прошлые сообщения, только дописывать в конец). Если вы хоть раз думали «давайте я просто перепишу system после i-той итерации» — теперь у вас перед глазами счёт за это решение.

Manus и KV-cache 100 : 1

Peak Ji формулирует это прямее, чем кто бы то ни было: «KV-cache hit rate represents the single most critical metric for production AI agents, directly affecting both latency and cost». В операции типового агента input-to-output ratio сильно перекошен — у Manus примерно 100 : 1: на каждый сгенерированный токен приходится сотня прочитанных. Каждая итерация цикла принимает решение на основе ВСЕГО предыдущего контекста, выполняет действие, и observation от среды дописывается к контексту для следующей итерации. Это значит: типовая «дорогая» часть запроса — не output модели, а гигантский префикс, который снова и снова летит в API.

Для такого workload caching — не оптимизация, а условие существования. Без кеша Sonnet 4.5 на 50 tool calls по 4k токенов истории каждый = 3 · (8k·50 + 4k·50·51/2) / 1M = ~$1.55 за одну задачу. С каэшированием тот же сценарий — около 10–15 центов. На миллионах задач это разница между «бизнес-модель работает» и «не работает».

Batch API: +50% сверху

Если ваш агент не интерактивный — ночной чекап репозиториев, ETL-агент, классификатор резюме, регрессии тестов — посмотрите на Batch API. Это асинхронный канал: вы кладёте N запросов в один JSONL, получаете batch_id, через до 24 часов забираете результаты. Скидка — 50% и на input, и на output, и она стакается с prompt caching: если 90% вашего input — это cache reads, вы платите 0.5 · 0.1 = 0.05× input rate за эту часть. Ограничения тоже стоит знать: размер пакета — до 256 MB, fast mode недоступен, Zero Data Retention не работает. Это не путь для каждого агента, но для бэкграунд-сценариев один Batch + caching спокойно даёт 15–30× экономию относительно «тупого» streaming.

"

The KV-cache hit rate represents the single most critical metric for production AI agents, directly affecting both latency and cost. <…> Identical prefix contexts leverage KV-caching, drastically reducing time-to-first-token and inference costs.

— Yichao "Peak" Ji · Manus, «Context Engineering for AI Agents»

Источники главы