Токены Claude Code в команде агентов: почему дороже всех тот, кто ждёт
В команде агентов Claude Code больше всех токенов тратит ведущий: каждое его пробуждение перечитывает весь контекст. В замерах supertick одно пробуждение стоило 2,18 млн входных токенов, больше всех кодеров за прогон. Лечится event loop: ожидание переносят в скрипт или cron, а модель будят только по событию.
Почему в команде агентов Claude Code больше всех токенов тратит ведущий, который ждёт, и как event loop в скрипте и cron режут расход: замеры supertick и мой конвейер.

В статье · 9 разделовразвернутьсвернуть
Токены Claude Code в команде агентов уходят не туда, где идёт работа. Больше всех тратит ведущий (team lead), хотя половину времени он просто ждёт: каждое его пробуждение перечитывает весь контекст заново. Event loop - это когда ожидание живёт в дешёвом скрипте вне модели, а ведущий просыпается только по событию, которое требует решения.
Я сам гоняю пачку агентов на сервере через cron-обёртки и долго не думал, сколько стоит "подождать". А потом прочитал разбор на Хабре от автора плагина supertick (25.10.2026), полез в его замеры и понял, что у меня тот же принцип, только в профиль. Ниже цифры, механика и как это повторить у себя.
Почему ведущий агент съедает больше всех токенов в Claude Code?
Ведущий агент в Claude Code дорогой не из-за работы, а из-за пробуждений. Каждый раз, когда тиммейт пишет сообщение или задача закрывается, ведущий делает новый вызов модели и платит за весь свой контекст. При контексте в сотни тысяч токенов и десятках пробуждений за прогон это миллионы входных токенов на ровном месте.
Как это устроено по документации. В agent teams ведущий - это обычная сессия Claude Code, а тиммейты - отдельные инстансы, каждый со своим окном контекста. Сообщения доставляются автоматически, опрашивать никого не надо, и когда тиммейт закончил, ведущему прилетает уведомление. Звучит экономно. Но уведомление - это и есть пробуждение: новый ход модели с полным контекстом ведущего на входе.
Документация сама честно пишет, что команды "use significantly more tokens than a single session" и что расход растёт линейно с числом активных тиммейтов. Но где именно он растёт, видно только по замерам.
Сколько стоит одно пробуждение ведущего: замеры supertick
Одно пробуждение ведущего в замерах supertick стоило 2,18 млн входных токенов в версии 0.13.1 и 0.93 млн в версии 0.14.0 (оба прогона 24.09.2026). Пересылка одного письма через ведущего при контексте 437 тыс. токенов обошлась в $0,38 по ценам API. Почти весь вход - чтение кэша, но его объём съедает экономию.
Цифры из docs/measurements.md репозитория supertick:
| Показатель (прогоны 24.09.2026) | 0.13.1, ведущий в ожидании | 0.14.0, ожидание в скрипте |
|---|---|---|
| Длительность | 63 мин | 141 мин (без простоя ~95) |
| Пробуждений ведущего | 35 | 50 |
| Входных токенов у ведущего, всего | 76,27 млн | 46,59 млн |
| Из них чтение кэша | 75,92 млн | 46,15 млн |
| Выходных токенов | 228 тыс. | 151 тыс. |
| Входных токенов на пробуждение | 2,18 млн | 0,93 млн |
| Контекст ведущего на старте | ~600 тыс. | ~150 тыс. |
Важная оговорка автора: сравнение нечистое. Контекст на старте разный, а вторая пачка задач выросла из SIMPLE в MEDIUM. Так что "в 2,3 раза дешевле на пробуждение" - это ориентир, а не чистый A/B.
А теперь то, ради чего я полез в таблицу. В той же первой пачке субагенты за весь прогон съели: ревьюер 78 тыс., пять кодеров от 49 до 108 тыс., остальные проверки ещё около 177 тыс. Я сложил - выходит примерно 0,62 млн токенов на всех исполнителей. Ведущий за одно пробуждение - 2,18 млн. То есть один "проснулся, глянул почту, уснул" стоит дороже, чем вся команда кодеров за прогон.
Да, кэш-чтение дешёвое. Пересчитал грубо: если считать кэш по 0,1 от базовой цены входа, а субагентов вообще без скидки, ведущий всё равно выходит примерно в 12-13 раз дороже всех исполнителей вместе. Отсюда и ответ на вопрос из заголовка: самый дорогой агент - тот, что ждёт.
Что такое event loop для агентов Claude Code?
Event loop для агентов - это цикл в обычном скрипте, который сам проверяет состояние команды (файлы, почту, статусы задач) и будит модель только при событии, требующем решения. Пока цикл крутится, токены не тратятся: sleep в bash бесплатный, а ход модели нет.
В supertick это сделано так (README, v1.1.1):
supervisor-tick.pyодин раз читает файлы прогона, раскладывает возможные действия по приоритетам P0-P4 и пишет снимок вstate/supervisor.json;supervisor-wait.shповторяет тик раз в 20 секунд и завершается, когда появилось действие P1 или выше (порог задаёт--wake-on), либо по таймауту--max, по умолчанию час;- ведущий засыпает на этом фоновом скрипте, а не на собственном ходе.
Что будит ведущего, тоже прописано явно. P0 - письмо 2 минуты висит недоставленным, тиммейт молчит два интервала проверки без правок файлов, движок упал. P1 - кодер отчитался DONE, а приёмка не начата; готов отчёт приёмки; висит вопрос без ответа. P2-P4 - "спи дальше". Например, если тиммейт гоняет pytest или jest, это статус busy, а не ложная тревога.
Мне больше всего понравилась одна деталь: ведущий читает не отчёт кодера, а одну строку вида ACCEPT: task #N - PASS. Автор формулирует это как "DONE is a claim, not a result". Чем меньше ведущий читает, тем меньше у него контекст, тем дешевле каждое следующее пробуждение.
Как вынести ожидание из модели в дешёвый скрипт?
Ожидание выносится из модели в три шага: состояние команды лежит в файлах, скрипт проверяет эти файлы по таймеру и решает, нужно ли будить модель, а модель на пробуждении получает короткую выжимку вместо сырых логов. В Claude Code для этого есть фоновый Bash и Monitor, снаружи - обычный cron.
Состояние - в файлы
Задачи, письма, статусы и отчёты лежат на диске, а не в голове ведущего. После сжатия контекста он восстанавливается по файлам и одному тику.Тик - в скрипт
Скрипт без модели читает файлы и сортирует события по важности. Никаких LLM внутри, только правила.Порог пробуждения
Модель будится только на событии, где нужно решение. Всё остальное копится до следующего пробуждения пачкой.Короткий вход
На пробуждении модель получает выжимку в пару строк, а не сырые логи тиммейтов.
Чем это сделать в самом Claude Code (по справочнику инструментов, октябрь 2026):
- Запустить скрипт ожидания через Bash с
run_in_background: true. Модель продолжает работу или заканчивает ход, а когда команда завершится, сессия получит уведомление. В интерактивной сессии лимита времени у фоновой команды нет, вclaude -pпо умолчанию 10 минут, максимум 2 часа. - Если нужно реагировать на поток событий, а не на одно, - Monitor: он запускает скрипт в фоне и отдаёт модели каждую строку вывода. Дедлайн у него 5 минут по умолчанию, максимум 30.
- Скрипт должен печатать только то, на что нужна реакция. Строка в выводе Monitor - это уже пробуждение, так что "всё ок, жду" в stdout ровно та ошибка, от которой мы уходим.
- Если не нужна живая сессия вообще - выносите ожидание за пределы Claude Code, в cron. Об этом ниже, у меня так работает весь конвейер.
Как я сделал: cron-обёртки, которые не будят модель зря
У меня на сервере крутится конвейер статей и постов: 9 cron-обёрток вызывают claude -p со своим скиллом. Ни одна из них не держит модель в ожидании. Обёртка сама проверяет базу, и если работы нет, выходит, не потратив ни токена.
Сквозной пример - обработка правок по комментам автора. Крон дёргает обёртку каждые 15 минут, вот её начало дословно:
# Этап B: обработка комментов-правок (cron, каждые 15 мин).
source "$(dirname "$0")/lib.sh"
bp_init
with_lock edits
mkdir -p data/tmp
LOG=cron/edits.log
IDS=$(bpdb drafts-list --status editing --ids-only 2>>"$LOG") || {
alert "❌ blog-edit: bp_db drafts-list упал
$(tail -c 500 "$LOG")"; exit 1; }
[ "$IDS" = "[]" ] && exit 0Вся "экономия токенов" тут - одна последняя строка. Пустой список черновиков на правку - выход. Claude запускается только в цикле ниже, на каждый id отдельно.
Что это дало в цифрах. В логе правок 10 запусков модели: первый 13.07.2026, последний 05.10.2026. За эти 84 дня крон тикнул примерно 8 000 раз (96 раз в сутки). Модель понадобилась примерно в 0,1% тиков. Будь это ведущий агент, который "ждёт комментов" внутри своего хода, он бы проснулся 8 000 раз ради 10 событий.
Бот-собеседник в Threads устроен так же, только крон каждые 2 минуты, то есть 720 тиков в сутки. Скрипт сначала собирает новые реплики под постами, и если их нет, печатает IDLE нечего и выходит. Обёртка даже не пишет эти строки в лог (grep -v '^IDLE'), иначе лог распух бы от тишины.
Из грабель, на которые я наступил. В обёртке правок долго не было бэкоффа на алерты: застрявший черновик слал мне в телеграм до 96 сообщений в сутки, потому что крон честно пробовал каждые 15 минут. Пришлось завести файл-маркер и алертить не чаще раза в 6 часов. Ровно та же логика, что у supertick с приоритетами: не каждое событие стоит пробуждения, даже если "пробуждается" не модель, а я.
Про то, как я вообще перенёс фоновые задачи на cron вместо облачных рутин, писал отдельно: Routines в Claude Code против парка cron-обёрток.
Почему пауза дольше 5 минут бьёт по лимитам Claude Code
Кэш промпта в Anthropic API по умолчанию живёт 5 минут и продлевается при каждом чтении. Если ведущий спит дольше, следующее пробуждение не читает контекст из кэша, а пишет его заново. На Opus 5.5 запись в 5-минутный кэш стоит 1,25 от базовой цены входа, а чтение 0,05 - разница в 25 раз.
Это следует из документации по prompt caching (цены проверены 30.10.2026): для Opus 5.5 база $4 за млн входных токенов, запись в 5-минутный кэш $5, в часовой $8, чтение $0,20. У моделей с множителем 0,1 на чтение (Opus 5, Sonnet 5) разрыв 12,5 раза.
И вот тут event loop надо настраивать с головой. Если скрипт будит ведущего раз в час, каждое пробуждение - холодный кэш на весь контекст. Документация agent teams отдельно предупреждает: у in-process тиммейтов кэш по умолчанию 5 минут даже на подписке, а продлить до часа можно настройкой subagentPromptCacheTtl: "1h" (запись тогда стоит вдвое дороже базы).
Мой вывод, которого в разборе supertick нет: event loop экономит, только если пробуждения либо частые (кэш тёплый), либо с маленьким контекстом. Самая дорогая середина - большой контекст и пробуждения раз в 10-30 минут: каждый раз полная запись кэша. В такой зоне лучше не ждать вообще, а закончить ход ведущего и поднять новую короткую сессию по событию. Как у меня с cron: каждый claude -p стартует с чистого листа, без накопленной истории, и ему пофиг, остыл кэш прошлого запуска или нет.
Когда команда агентов и event loop не нужны
Команда агентов не нужна, если задача последовательная, правки идут в одни и те же файлы или работа не трогает деньги и безопасность. В таких случаях одна сессия Claude Code дешевле и быстрее, а event loop нужен только там, где реально есть параллельные исполнители и долгое ожидание между их шагами.
Это не только моё мнение. Сам supertick при сложности ниже COMPLEX предлагает одну сессию вместо команды и в README ставит это правилом: команда оправдана для задач, которые трогают деньги или безопасность. Документация Claude Code говорит то же: для последовательных задач и правок одного файла одна сессия или субагенты эффективнее.
Мои границы такие:
- меньше 3 параллельных задач - не собирайте команду, раздайте работу субагентам или моделям подешевле, как в статье про Haiku и Sonnet вместо Opus на исполнителях;
- ведущий ждёт меньше пары минут между событиями - event loop не окупит своей сложности, кэш и так тёплый;
- контекст ведущего меньше ~100 тыс. токенов - пробуждения дешёвые, оптимизируйте сначала что-то другое;
- задача в headless (
claude -p) - тиммейтов там вообще нет, Claude не спавнит команду в неинтерактивном режиме, так что ожидание сразу выносите в cron или в обёртку.
И отдельно: не путайте ожидание с размножением. Если лимит улетает потому, что субагенты плодят субагентов, event loop не поможет, нужен потолок на фан-аут. Разбирал это в статье про одну фразу, которая сожгла 20% недельного лимита.
Как посчитать, сколько тратит ведущий у вас
Посчитать расход ведущего можно по журналу сессии: каждое пробуждение - это запись пользователя без tool_result, а токены считаются один раз на message.id. Делите входные токены ведущего на число пробуждений - получите цену ожидания. Больше миллиона на пробуждение - пора выносить ожидание в скрипт.
Методику я взял у supertick как есть, она простая и честная. Дальше смотрите на две цифры: долю кэш-чтения во входе (у supertick 99,5%) и размер контекста ведущего на середине прогона. Если доля кэша высокая, а пробуждений много, вы платите за то, что ведущий каждый раз перечитывает одну и ту же историю. Если доля кэша падает - у вас паузы длиннее TTL, и это ещё дороже.
А чтобы считать не токены, а стоимость задачи целиком, у меня есть отдельный разбор: как считать реальную стоимость прогона агента.
Такие дела. Самый дорогой сотрудник в команде агентов не тот, кто пишет код, а тот, кто сидит и ждёт письма. С людьми, кстати, иногда так же :)
Частые вопросы
Тратит ли Claude Code токены, пока агент просто ждёт?
Пока агент ничего не делает, токены не идут. Но каждое пробуждение по сообщению тиммейта или уведомлению - новый вызов модели с полным контекстом. Поэтому ожидание оплачивается в момент, когда агент просыпается, и тем дороже, чем больше его контекст.
Можно ли использовать agent teams в claude -p и по крону?
Нет. По документации Claude Code в неинтерактивном режиме с флагом -p тиммейты не спавнятся, а именованный субагент работает как обычный субагент. Для фоновых задач по расписанию удобнее cron-обёртка, которая запускает claude -p только когда есть работа.
Почему лимиты подписки Claude Code улетают быстрее после пауз?
Кэш промпта живёт 5 минут. Если сессия молчит дольше, следующий запрос записывает контекст в кэш заново, а запись на Opus 5.5 в 25 раз дороже чтения. Частые паузы по 10-30 минут на большом контексте съедают лимит быстрее, чем непрерывная работа.
Как готовился материал: черновик собран моим AI-конвейером по темам и заметкам из практики, факты сверены с первоисточниками, финальный текст я прочитал, поправил и утвердил перед публикацией. Обложку к статье тоже рисует нейросеть. Про сам конвейер — в разделе обо мне.
