Есть встреча, которая убивает больше агентных проектов, чем любой баг когда-либо. Она случается примерно через два месяца после запуска, и ведёт её не инжиниринг. Финансы открывают дашборд, показывают на строку, которая выросла в 8 раз при росте использования в 2 раза, и задают вопрос, на который никто в комнате не может ответить: «За что именно мы платим?»
Инженеры не некомпетентны — система работает. Но никто не проектировал её стоимостное поведение, поэтому стоимостное поведение спроектировало себя само. Этот пост называет дисциплину, которая предотвращает ту встречу: token economics. Это шестая опора в арке, которую я пишу, — после контекст-инжиниринга, spec-driven development, evals, OpenSpec и durable execution — и именно она решает, продолжат ли остальные пять работать в продакшене.
Что такое token economics?
Token economics — это инженерная дисциплина отношения к стоимости LLM как к спроектированному свойству системы, а не обнаруженному. Она покрывает четыре решения: сколько каждому запросу разрешено стоить (бюджетирование), за какую работу вы отказываетесь платить дважды (кэширование), какая работа может подождать более дешёвой обработки (батчинг) и какая модель заслуживает каждый запрос (routing). Команды, принимающие эти решения явно, отгружают агентов с предсказуемым unit cost; команды, которые нет, узнают свои unit costs из инвойса.
Слово «economics» в этом определении делает реальную работу. Это не урезание затрат — это их моделирование: знать маржинальную стоимость ещё одного пользователя, ещё одной фичи, ещё одного шага агента до того, как спросят финансы.
Никто не проектировал её стоимостное поведение, поэтому стоимостное поведение спроектировало себя само. Эта фраза описывает почти любую агентную систему, которую выключают на втором квартале.
Рычагов шесть, и их стоит знать как набор, потому что у каждого есть режим отказа, проявляющийся как сюрприз по затратам, а не как ошибка:
| Рычаг | Что он делает | Типичный эффект | Как он оборачивается против вас |
|---|---|---|---|
| Бюджет на запрос | Ограничивает, сколько может потратить один прогон, с принуждением в рантайме | Превращает «можем добавить шаг верификации?» из дебата в арифметику | Размерен по средним, поэтому прогоны из длинного хвоста умирают у потолка вместо того, чтобы дойти до конца |
| Prompt caching | Прекращает перекупать стабильный prefix на каждом шаге | Крупный срез оплачиваемых входных токенов, вообще без размена качества | Промпт, собранный в меняющемся порядке, промахивается молча — полная цена, никакой ошибки |
| Batch-обработка | Уносит работу, которую никто не ждёт, в дисконтированный async | Крутая скидка на evals, бэкфиллы и суммаризацию | Применена к тому, чего пользователь ждёт, и теперь фича кажется сломанной |
| Routing моделей | Отправляет каждый шаг самой дешёвой модели, чей выход вы можете проверить | Большинство шагов дешевеет; токены концентрируются там, где связывает качество | Сделан без evals, поэтому вы оптимизируете вслепую и отгружаете регрессию качества |
| Checkpointing | Позволяет упавшему прогону возобновиться вместо рестарта | Ретраи прекращают перекупать всю историю разговора | Checkpoint’ы слишком крупные, поэтому вы всё равно переигрываете большую часть прогона |
| Вытеснение контекста | Выбрасывает то, что следующему шагу доказуемо не нужно | Прекращает квадратичный рост затрат с длиной прогона | Вытесняет то единственное ограничение, которое агенту нужно было продолжать соблюдать |
Почему затраты агентов взрываются, когда затраты запросов — нет?
Потому что агенты умножают. Чат-фича стоит примерно один вызов модели на действие пользователя — линейно, скучно, безопасно. Агент делает шаги, и каждый шаг может нести накопленный контекст всех шагов до него. Стоимость прогона — это не стоимость-шага × шаги; это ближе к стоимость-шага × шаги², потому что контекстное окно растёт по мере удлинения прогона. Добавьте ретраи, tool-результаты, вываленные в контекст дословно, и планировщик, который «подумает об этом ещё разок», — и 8-кратный сюрприз по затратам при 2-кратном использовании перестаёт быть загадкой.
Вот почему token economics неотделима от контекст-инжиниринга. Каждое контекст-инженерное решение — что ретривить, что суммаризировать, что вытеснять — это ещё и решение о покупке. Неряшливая контекст-стратегия — не просто проблема качества; это постоянное поручение покупать одни и те же токены снова и снова.
Связь с durable execution столь же прямая: агент, который умеет возобновляться вместо рестарта, не перекупает собственную историю после каждого сбоя. В терминах затрат checkpointing — это дисконтная программа. Архитектуры retry-from-zero платят полную цену за ту же работу N раз и называют это надёжностью.
Как на самом деле должен выглядеть токен-бюджет?
Настоящий токен-бюджет — это потолок на запрос с владельцем и точкой принуждения, а не месячный итог на дашборде. Рабочая форма: каждая фича декларирует ожидаемую стоимость на запрос и жёсткий максимум, система принуждает максимум в рантайме (агент, упёршийся в потолок, останавливается и репортит — ровно как таймаут), и у числа есть именованный владелец. Месячные итоги обнаруживают проблемы; потолки на запрос их предотвращают.
Бюджеты меняют инженерные разговоры так, как дашборды не меняют никогда. «Можем добавить агенту шаг верификации?» перестаёт быть философским дебатом о качестве и становится арифметикой: шаг стоит ~4k токенов на прогон, в бюджете 3k запаса, значит либо шаг становится дешевле, либо что-то другое. Это продуктивный спор. Команды ведут его до отгрузки, а не после инвойса.
Бюджет также должен быть видим там же, где живёт спека. Если вы практикуете spec-driven development, потолок стоимости принадлежит спеке рядом с поведенческими требованиями — «отвечает за 30 секунд, стоит меньше X за прогон» — потому что требование, которое никто не записал, — это требование, которого у системы нет.
Что на самом деле покупает кэширование?
Prompt caching — самый высокорычажный инструмент затрат в стеке, потому что агентные нагрузки экстраординарно повторяемы: системный промпт, схемы инструментов и долгоживущий контекст идентичны между шагами и часто между пользователями. Кэш-осознанный дизайн запросов — стабильный префикс сначала, волатильный контент в конце — рутинно срезает оплачиваемый объём токенов агентной системы вдвое и больше, вообще без размена качества. Это самое близкое к бесплатным деньгам в AI-инжиниринге.
Но кэширование окупается, только если запросы построены кэшируемыми, а это архитектурное решение, не флаг. Промпт, собираемый в разном порядке на каждый запрос, тихо побеждает кэш — вы платите полную цену, и ничего не падает с ошибкой. Это место, где разница между «однажды прочитал API-доки» и «реально знает платформу» проявляется прямо в инвойсе; механика (cache breakpoints, дизайн префикса, TTL и то, как верифицировать, что вы получаете cache-хиты) — ровно то, что дриллит курс по Claude API, потому что верифицированная экономия бьёт предполагаемую.
Как спроектировать запрос, который реально кэшируется
Правило легко сформулировать и легко нарушить: всё стабильное идёт первым, всё волатильное — последним. Системные инструкции, tool schemas и долгоживущий проектный контекст образуют prefix; текущее сообщение пользователя, отритривленные чанки для этого запроса и состояние конкретного шага идут после. В момент, когда один меняющийся токен появляется рано, всё после него становится некэшируемым — кэш матчится по префиксам, а не по контенту, который он узнаёт позже.
Самострел, который я видел чаще всего, — timestamp. Кто-то добавляет полезную строку Current time: … ближе к верху системного промпта, и весь prefix меняется на каждом единичном вызове. Промпт всё ещё работает. Evals всё ещё проходят. Счёт тихо удваивается, и нигде нет падения, которое можно было бы расследовать. То же касается имени пользователя, request ID или случайно упорядоченного набора tool-определений, собранного из хеш-мапы, — всё, что меняется от вызова к вызову, принадлежит месту после стабильного блока или не принадлежит нигде.
Время жизни кэша тоже важно. Кэшированные префиксы истекают, поэтому низкотрафиковая фича может заплатить за запись кэша и ни разу не прочитать его до истечения; высокотрафиковая амортизирует запись по тысячам вызовов. Вот почему кэширование выигрывает так решительно именно на агентных циклах — один прогон делает много вызовов в быстрой последовательности против почти идентичного prefix.
Как верифицировать экономию вместо того, чтобы её предполагать
Логируйте кэшированные и некэшированные входные токены как отдельные поля, всегда. Дашборд, показывающий одно слитое число «входные токены», не может сказать вам, работает ли кэширование, и команды рутинно верят, что получают скидку, которую перестали получать недели назад. Когда разделение записано, производная метрика, которая вам реально нужна, — cache-hit ratio на фичу, а алерт, который вам нужен, — падение этого отношения, потому что ломает кэширование никогда не деплой с подписью «сломать кэш», а безобидный рефакторинг, поменявший порядок сборки промпта. Этот алерт — разница между «узнать за один вечер» и «узнать на квартальном ревью».
Батчинг — тихий сиблинг кэширования: любая работа, которой не нужен ответ за секунды — ночная суммаризация, бэкфиллы, eval-сьюты, — может идти через batch-обработку с крутой скидкой. Проектный вопрос прост: какие из ваших нагрузок тайно асинхронны. По моему опыту, их больше, чем признаёт архитектура, и evals — канонический пример: комплексный сьют, гоняемый ночью по batch-ценам, стоит дешевле тонкого, гоняемого синхронно в панике после инцидента.
Когда запрос должна брать модель поменьше?
Роутьте по верифицируемости, а не по вайбам: используйте наименьшую модель, чей выход вы можете проверить, и берегите фронтирную модель для шагов, где ошибаться дорого, а проверять трудно. Классификация, экстракция, форматирование, суммаризация-для-хранения — у них верифицируемые выходы, и они терпят более дешёвую модель, подпёртую валидацией. Планирование, выбор инструмента в открытых ситуациях и финальный пользовательский синтез обычно заслуживают большую модель. Хорошо отроученный агент часто гонит большинство своих шагов на малых моделях, тратя большинство своих токенов там, где качество реально связывает.
Routing — это ещё и место, где evals перестают быть опциональными. Без регрессионного сьюта каждое изменение роутинга — прыжок веры, и команды либо никогда не оптимизируют (дорого), либо оптимизируют вслепую (хуже). С настоящим eval-харнессом «перенести экстракцию на малую модель» — это эксперимент на полдня с pass/fail-ответом. Eval-сьют — то, что делает оптимизацию затрат безопасной; это снова та самая троица: спека говорит, что должно держаться, evals верифицируют, что всё ещё держится, а token economics решает, сколько это может стоить.
Паттерн, который бьёт обе крайности, — эскалация вместо назначения: гоните шаг на малой модели, валидируйте выход механически и ретрайте на фронтирной модели только тогда, когда validation падает. Если дешёвая модель права в восьмидесяти процентах случаев, а validation надёжна, вы платите цены малой модели четыре раза из пяти и всё равно получаете корректность фронтирной модели — экономика лучше, чем роутить всё вниз, и качество лучше, чем роутить всё вверх.
Конкретная форма, из support-triage агента, над которым я работал: классифицировать входящий запрос (малая модель, выход — одна из фиксированного набора меток, тривиально проверяемо), отритривить релевантную историю (вообще без модели — это запрос к базе, который команды рутинно отдают LLM без всякой причины), составить черновик ответа (mid-tier), затем финально проверить политику и тон до того, как это дойдёт до человека (фронтирная). Четыре шага, три разные модели, один шаг вообще без модели. Большинство шагов идут дёшево; большинство токенов садится на те два, которые важны.
Антипаттерн, который стоит назвать: routing по тарифу клиента вместо routing по задаче. Платящим клиентам не нужна модель побольше, им нужен корректный ответ — и дешёвая модель с validation часто выдаёт его надёжнее, чем дорогая модель без неё. Роутьте по верифицируемости, дайте evals решать и держите страницу с ценами вне архитектуры.
Для мультиагентных систем добавьте одно правило: суб-агенты не наследуют модель оркестратора по умолчанию. Каждая роль получает самую дешёвую модель, которая проходит evals этой роли, — разница между флотом, который масштабируется, и флотом, который выключают, — обычно это правило, применённое рано. Строить агентов с пер-ролевым выбором модели и инструментированием затрат с первого дня — базовый паттерн курса по Agent SDK, ровно по этой причине.
Как сделать затраты видимыми раньше, чем это сделают финансы?
Инструментируйте стоимость на запрос, на фичу и на шаг агента с первого деплоя — так же, как вы относитесь к latency. Логируйте токены на входе и выходе (кэшированные и некэшированные отдельно, иначе обманете сами себя), тегируйте по фиче и шагу, алертите на выбросы по отдельным запросам, а не на месячные итоги. Один медленный запрос не ждёт месячного инфраструктурного ревью; один агентный прогон с 50-кратной стоимостью тоже не должен.
Пяти полей на вызов модели достаточно, чтобы ответить почти на любой вопрос, который вам потом зададут: фича, шаг, модель, входные токены, разделённые на кэшированные и некэшированные, и выходные токены. Всё полезное выводится из них — стоимость на прогон, стоимость на фичу, cache-hit ratio, распределение, которое говорит вам, размерен ли ваш бюджетный потолок под среднее или под хвост. Команды, пропускающие тег шага, — это те, кто знает, что их агент дорогой, но не может сказать, который из его восьми шагов за это отвечает, а это превращает фикс на полдня в неделю догадок.
Дальше два алерта, и удержитесь от добавления новых. Первый — выброс по стоимости отдельного запроса: один прогон, перешедший некоторое кратное своего бюджета, потому что именно так снаружи выглядит разбежавшийся цикл. Второй — падение cache-hit ratio на фичу, потому что именно так тихое удвоение о себе объявляет. Алерты на месячные итоги ощущаются ответственно и почти бесполезны: к моменту, когда месячное число становится тревожным, деньги потрачены, а причина — четыре деплоя назад.
Репортинговый артефакт, который меняет политику, — кривая unit cost: стоимость на успешную задачу во времени. Она перефреймит финансовую встречу из «почему растёт счёт» (угроза) в «unit cost упал на 40%, пока использование удвоилось» (круг почёта). Те же числа, противоположная встреча — и команда, которая владеет своими unit costs, получает право продолжать экспериментировать, потому что руководство доверяет: за счётчиком следят.
Дисциплина, сжатая
Дайте каждому запросу бюджет с владельцем. Стройте промпты кэшируемыми и верифицируйте хиты. Батчьте всё, что тайно асинхронно. Роутьте по верифицируемости с evals как страховочной сеткой. Делайте checkpoint’ы, чтобы ретраи не перекупали историю. Инструментируйте unit cost с первого дня и репортите его до того, как спросят. Ничего из этого не экзотика — это та же кривая зрелости, которую инфраструктурные затраты прошли декаду назад, сжатая в один год. Команды, которые её интернализируют, получают право гонять амбициозные агентные системы; команды, которые нет, получают ту встречу. Архитектурные паттерны RAG-и-агентов все предполагают эту дисциплину под собой — а если хотите версию всей арки как операционной модели, основы spec-driven development — то место, где шесть дисциплин собираются в один воркфлоу.