Глава 11 · Экономика
Стоимость цикла и почему prompt caching меняет всё
Каждый поворот agentic loop — это новый HTTP-запрос со всем предыдущим контекстом. Без кеша агент тратит в десять раз больше, чем мог бы, и платит за одни и те же системные токены столько раз, сколько раз провернулся цикл.
Из чего складывается счёт
Anthropic считает по двум типам токенов: input (всё, что вы шлёте: tools, system, messages) и output (то, что модель сгенерировала в ответе, включая thinking- и tool_use-блоки). Output обычно дороже input в 4–5 раз — это базовая асимметрия, на которой держится всё остальное. Цены на момент написания (за миллион токенов, тариф «standard», без Batch-скидки):
| Модель | Input | Output | Cache write · 5m | Cache write · 1h | Cache 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 съедает один из четырёх слотов. Во-вторых, кеширование уважает иерархию префикса — tools → system → messages: изменение на верхнем уровне инвалидирует всё, что ниже. В-третьих, минимальная длина кешируемого префикса — 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».
Что ломает кеш
Кеш — это хеш префикса. Любое изменение в префиксе меняет хеш и обнуляет всё, что от него зависит. Самые распространённые источники инвалидации, в порядке частоты:
- Любое изменение
tools— переименование инструмента, добавление поля в JSON Schema, перестановка инструментов в массиве, любое подключение нового MCP-сервера. Это инвалидирует кеш на всех трёх уровнях (tools+system+messages): нужно перегенерировать всё. - Изменение system-промпта — timestamps, динамически подставляемая дата, A/B-переменная в начале. Всё ниже
systemтеряет валидность. - Нестабильная сериализация tool-аргументов — Swift и Go рандомизируют порядок ключей в JSON, и каждый запрос получает новый хеш «как будто ничего не менялось». Anthropic явно предупреждает в best practices: гарантируйте детерминированный порядок ключей.
- Subagents и любые «forks» — каждый subagent (см. главу 7) стартует с новым system + tool-палитрой, значит новый префикс, значит cold cache. Это одна из неочевидных стоимостей dispatch'а: вы экономите контекст у main-агента, но платите write-rate за инициализацию каждой ветки.
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»Источники главы
- [ant] Prompt Caching — Anthropic Docs (механика, breakpoints, TTL, hierarchy
tools → system → messages, инвалидация, usage-поля) - [ant] Pricing — Anthropic Docs (базовые ставки Opus / Sonnet / Haiku, Batch API discount)
- [man] Context Engineering for AI Agents — Manus (Peak Ji) (KV-cache как ключевая метрика, 100:1 input/output ratio, append-only context)
- [cli] Конспект: Cost Tracking (имплементация:
calculateUSDCost, OTel-счётчики,maxBudgetUsd, восстановление стоимости при resume) - [cli] Конспект: Anthropic API distill (Prompt caching + Batch API section, кумулятивная семантика
usageв streaming)