Субагенты Claude Code: когда экономят контекст, а когда мешают

Автор: Обновлено

Что такое субагент в Claude Code?

Субагент в Claude Code - отдельный экземпляр Claude со своим окном контекста, системным промптом и набором инструментов, которому основной разговор поручает задачу. Он не видит историю разговора и возвращает только итоговый ответ. Это выгодно, когда промежуточной работы много, а результат короткий, и невыгодно, когда задача короткая или зависит от контекста текущего разговора.

TL;DR

  • -По 535 завершённым субагентам автора: на пике медианный субагент держит ~117 тыс. токенов контекста, а в основной разговор возвращает ~1 500 символов. Выгода изоляции в этой разнице.
  • -У запуска есть цена: медианный стартовый контекст субагента в той же конфигурации ~58 тыс. токенов. Задачи на 1–3 вызова инструментов не окупаются: ~55 тыс. токенов на старте ради ответа в ~1 100 символов.
  • -В контролируемом эксперименте (Claude Code 2.1.318, n=3 на вариант) узкий список tools снизил стартовый контекст на 78,5%, omitClaudeMd на 12,8%, вместе на 91,8%, до ~4,7 тыс. токенов. Размер результата не изменился.
  • -Модель субагента выбирается по цепочке: параметр вызова, поле model во frontmatter, CLAUDE_CODE_SUBAGENT_MODEL, модель основного разговора. Переменная окружения перебивает frontmatter только с CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1.
  • -89% запусков у автора приходятся на встроенный general-purpose. Файл агента нужен ради ограничений инструментов, модели и повторяемости, а не ради самого факта делегирования.

В транскриптах субагентов Claude Code на машине автора медианный субагент на пике держит около 117 тыс. токенов контекста, а в основной разговор возвращает около 1 500 символов. Субагент - отдельный экземпляр Claude со своим окном контекста, системным промптом и инструментами: он делает работу в стороне и отдаёт только итог. Ради разницы между пиком и итогом его и запускают.

У той же медианы есть вторая цифра: ещё до первого действия субагент занимает около 58 тыс. токенов. Это цена запуска, и на короткой задаче она съедает всю выгоду. Документация Claude Code описывает механику субагентов подробно, но не говорит, сколько стоит старт и когда он окупается.

Статья о том, как решить, нужен ли субагент в конкретной задаче. В основе: документация по субагентам (сверено с Claude Code 2.1.318), агрегаты по 648 транскриптам субагентов автора и контролируемый эксперимент из 18 запусков. Выборка одного пользователя с тяжёлой конфигурацией, поэтому вместе с цифрами даны ограничения и скрипт, чтобы повторить замер у себя. Справка по всем полям файла агента уже есть в статье Claude Code Skills и Agents, здесь она не повторяется.

Что именно изолирует субагент

Обычный (не fork) субагент стартует со свежим окном контекста. Он не продолжает разговор, а получает задачу, которую сформулировал основной агент, и собирает нужный контекст сам.

Что субагент получает на старте, а чего не видит

ПолучаетНе получает
Собственный системный промпт (тело файла агента)Историю основного разговора
Сообщение-задачу от основного агентаФайлы, которые основной агент уже прочитал
CLAUDE.md пользователя, проекта и локальный (кроме Explore и Plan; отключается через omitClaudeMd)Skills, вызванные в основном разговоре
Снимок git status (кроме Explore и Plan)Auto memory основного разговора
Skills из поля skills (полное содержимое)Output style основной сессии
Схемы разрешённых инструментов, включая MCP

Из правой колонки следует главное ограничение: всё, что основной агент знает из разговора, субагент получит, только если это попало в текст задачи. Встроенные Explore и Plan по документации стартуют без CLAUDE.md и git status, чтобы исследование было быстрым и дешёвым.

Что возвращается в основной разговор

Возвращается только финальный ответ субагента. Промежуточные вызовы инструментов, прочитанные файлы и рассуждения остаются в его транскрипте. С версии 2.1.277 результат приходит под заголовком, который помечает его как вывод субагента, с отступом. По CHANGELOG это сделано, чтобы текст из результата не выдавал себя за инструкции сессии.

Документация прямо оговаривает две вещи. Первая: результаты накапливаются в основном контексте, и много субагентов с подробными ответами занимают заметное место. Вторая: каждый субагент отправляет собственные запросы, и они идут в те же лимиты использования, что и основной разговор.

Субагент, fork и skill

SkillСубагентFork
КонтекстТекущий разговор целикомСвежий, только задачаКопия всего разговора
Системный промпт и инструментыОсновной сессииИз файла агентаОсновной сессии
МодельОсновной сессии или из поля skillИз цепочки выбора (см. ниже)Основной сессии
Кэш промптаОбщийОтдельныйОбщий с основной сессией
Что попадает в основной контекстВсёТолько итоговый ответТолько итоговый ответ

Fork появился как способ отдать побочную задачу без пересказа контекста: он видит то же, что основная сессия, но его вызовы инструментов в основной разговор не попадают. Запустить fork вручную можно командой /subtask <задача>. Режим fork включён по умолчанию с версии 2.1.302, отключается переменной CLAUDE_CODE_FORK_SUBAGENT=0. Fork не может запускать другие forks. Поскольку системный промпт и инструменты у него те же, первый запрос использует кэш основной сессии, и документация называет fork более дешёвым вариантом для задач, которым нужен тот же контекст. Skill с полем context: fork тоже выполняется в отдельном субагенте.

Что показали замеры

Цифры ниже из двух источников. Первый: агрегаты по реальным транскриптам субагентов автора за весь период, который они хранятся. Второй: эксперимент E2 с одним и тем же тривиальным заданием в разных конфигурациях агента. Содержимое задач не анализировалось и не публикуется, только размеры.

Метод и выборка

Claude Code пишет транскрипт каждого субагента в ~/.claude/projects/<проект>/<сессия>/subagents/agent-<id>.jsonl. В каждом ассистентском сообщении есть поле usage. Размер контекста хода считался как input_tokens + cache_read_input_tokens + cache_creation_input_tokens.

  • Стартовый контекст: размер на первом ходе (системный промпт, CLAUDE.md, схемы инструментов, описания, задача).
  • Пик: максимальный размер по ходам.
  • Результат: длина последнего текстового сообщения субагента в символах.

Пересчёт 6 ноября 2026 года, срез по транскриптам, созданным до 15:00: 648 транскриптов, из них 535 завершённых с ответом. Выборка живая: к вечеру того же дня новые тяжёлые запуски сдвинули медиану старта до ~62 тыс., поэтому при повторе скриптом ниже цифры будут немного другими. Записи с моделью <synthetic> (заглушки при ошибках API) исключены. По типам (все 648 транскриптов): general-purpose 577 запусков (89%), кастомные агенты 44 (~7%), агент плагина для передачи задачи внешнему CLI 19 (3%), Explore 8 (1%).

Сумма токенов по ходам как метрика не годится: одни и те же 58 тыс. стартового контекста считаются на каждом ходу заново. Около 91% входных токенов в этих транскриптах приходится на чтение из кэша, поэтому цена хода в деньгах заметно ниже номинальной. Здесь измеряется размер контекста, а не счёт.

Выгода: пик против результата

Показатель (535 субагентов)Медианаp10p90
Стартовый контекст, токенов~58 тыс.~17 тыс.~82 тыс.
Пик контекста, токенов~117 тыс.~44 тыс.~238 тыс.
Результат, символов~1 500~100~6 300
Вызовов инструментов18455

Медианный субагент на пике держит ~117 тыс. токенов, а в основной разговор приходит ответ на ~1 500 символов, то есть несколько сотен токенов. Разница в сотни раз. Без субагента большая часть этого объёма (содержимое прочитанных файлов, вывод команд) легла бы в основной контекст и оставалась бы там до компакции.

Отсюда простая проверка для любой задачи: если ответ по размеру сопоставим с проделанной работой, изоляция ничего не дала.

Цена: стартовый контекст

Медиана старта ~58 тыс. токенов, p10 ~17 тыс. Это контекст, который субагент занимает до первого действия. В конфигурации автора туда входят большой глобальный CLAUDE.md с правилами, схемы инструментов нескольких десятков MCP-серверов, описания агентов и skills, git status.

Распределение неровное: около пятой части запусков стартует с 10–20 тыс. токенов, основная масса с 40–90 тыс. Из-за этого медиана старта чувствительна к фильтрации. Если не исключить заглушки <synthetic>, она поднимается до ~65 тыс., хотя пик и результат почти не меняются. При повторении замера такие записи лучше отбрасывать явно.

Короткие задачи не окупаются

ГруппаЗапусковСтартовый контекстПикРезультат
≤3 вызовов инструментов34~55 тыс.~55 тыс.~1 100 символов
≥15 вызовов инструментов~315~66 тыс.~156 тыс.~1 900 символов

В коротких задачах контекст почти не растёт после старта: субагент поднимает ~55 тыс. токенов ради ответа на ~1 100 символов. Основной разговор сделал бы те же 1–3 вызова в уже собранном контексте. В длинных задачах соотношение обратное: ~156 тыс. токенов работы сворачиваются в ~1 900 символов. Граница между ними зависит от стартовой цены в конкретной конфигурации, и её можно снизить.

Что снижает стартовую цену

Эксперимент E2 проверял три рычага: поле omitClaudeMd, узкий список tools и запуск сессии без MCP-серверов. Условия: Claude Code 2.1.318, модель sonnet (в транскриптах claude-sonnet-5-5), временный проект без собственного CLAUDE.md, четыре проектных агента, задача «прочитать файл из одной строки и вернуть её». Каждый вариант запускался 3 раза через claude -p, метрика: стартовый контекст субагента по первому ходу его транскрипта.

Вариант агентаСтартовый контекст, медианаИзменение
Без ограничений (baseline)56 882база
omitClaudeMd: true49 594−12,8%
tools: Read, Grep12 232−78,5%
tools: Read, Grep + omitClaudeMd: true4 667−91,8%
Baseline, сессия без MCP-серверов41 639−26,8%
tools + omitClaudeMd, сессия без MCP-серверов4 6670% к тому же варианту с MCP

Сильнее всего действует поле tools. Allowlist убирает из контекста субагента схемы всех остальных инструментов, включая MCP, и в этой конфигурации это ~44,6 тыс. токенов. omitClaudeMd дал ~7,3 тыс.: в тестовом каталоге был только глобальный CLAUDE.md, с проектным файлом выгода будет больше. Рычаги складываются почти аддитивно, и остаток ~4,7 тыс. токенов можно считать полом для этой версии: системный промпт субагента, две схемы инструментов, тело агента.

Запуск сессии без MCP (--strict-mcp-config с пустым конфигом) сократил стартовый контекст основной сессии на 22,6% (69 767 → 53 993) и субагента без ограничений на 26,8%. Агенту с узким tools отключение MCP ничего не добавило: MCP-схемы у него и так отсечены. Во всех вариантах субагент вернул один и тот же ответ в 39 символов: рычаги меняют цену запуска, а не то, что приходит в основной разговор.

Ограничения эксперимента E2

Эти условия нужно учитывать, прежде чем переносить цифры на свою конфигурацию:

  • Одна машина, один пользователь, одна версия Claude Code, одна модель, один день.
  • Конфигурация очень тяжёлая: около 65 MCP-серверов (436 инструментов в сессии), глобальные правила на ~7 тыс. токенов, около 50 агентов и большой список skills. Baseline 57 тыс. токенов для лёгкой конфигурации нетипичен, и абсолютная экономия у читателя будет меньше. Переносить стоит соотношения между рычагами, а не числа.
  • Задача тривиальная, n=3 на вариант. Разброс внутри варианта мал (до ~2%), но это оценки порядка величины, а не доверительные интервалы.
  • Не измерялись качество результата на реальных задачах, рост контекста по ходам, время и влияние tools на способность агента выполнить задачу. Агенту, которому нужны Bash или Edit, узкий allowlist из двух инструментов не подойдёт.

Как повторить замер у себя

Скрипт читает только поля usage и длину ответов, содержимое транскриптов не выводит. Формат jsonl недокументирован и может меняться между версиями.

import glob, json, os, statistics as st

KEYS = ("input_tokens", "cache_read_input_tokens", "cache_creation_input_tokens")
rows = []
for path in glob.glob(os.path.expanduser("~/.claude/projects/*/*/subagents/agent-*.jsonl")):
    first = peak = None
    result, tools = "", 0
    for line in open(path, errors="ignore"):
        try:
            rec = json.loads(line)
        except ValueError:
            continue
        msg = rec.get("message")
        if rec.get("type") != "assistant" or not isinstance(msg, dict) or msg.get("model") == "<synthetic>":
            continue  # служебные записи и заглушки ошибок
        ctx = sum((msg.get("usage") or {}).get(k) or 0 for k in KEYS)
        first = ctx if first is None else first
        peak = max(peak or 0, ctx)
        for c in msg.get("content") or []:
            tools += c.get("type") == "tool_use"
            if c.get("type") == "text" and c.get("text", "").strip():
                result = c["text"]
    if peak and result:
        rows.append((first, peak, len(result), tools))

med = lambda i, rs=rows: st.median(r[i] for r in rs)
print(f"n={len(rows)} старт={med(0):.0f} пик={med(1):.0f} результат={med(2):.0f} симв.")
short = [r for r in rows if r[3] <= 3]
print(f"<=3 вызовов: n={len(short)} старт={med(0, short):.0f} результат={med(2, short):.0f} симв.")

Если стартовый контекст выходит заметно ниже 58 тыс., граница окупаемости у вас сдвинута в пользу субагентов. Claude Code удаляет транскрипты субагентов по истечении срока cleanupPeriodDays (по умолчанию 30 дней), поэтому без изменения настройки выборка охватывает примерно последний месяц.

Когда субагент нужен

Документация рекомендует субагента для задач с объёмным выводом, который не понадобится снова, для принудительных ограничений инструментов и прав и для самодостаточной работы, которая возвращает сводку. Замеры добавляют к этому порог: задача должна быть длиннее нескольких вызовов.

Объёмный поиск и чтение

Типичный случай: найти все места, где используется функция, прочитать логи, пройтись по десяткам файлов и вернуть короткий список. Для поиска по кодовой базе есть встроенный Explore: он только читает (Write и Edit запрещены), работает с уровнями тщательности quick, medium и very thorough и стартует без CLAUDE.md. Если поиск переходит в действия, подходит general-purpose.

Признак подходящей задачи: ответ можно описать заранее в нескольких строках («список файлов и строк», «три причины ошибки»), а путь к нему потребует десятков вызовов.

Ограничения по конструкции

Субагент с tools: Read, Grep, Glob физически не может ничего изменить, и это надёжнее, чем просьба в промпте. Ревью-агент без Write и Edit или исследователь с доступом только к чтению и веб-поиску выигрывают дважды: права ограничены, а стартовый контекст меньше из-за короткого списка инструментов. Поле disallowedTools работает как denylist и применяется раньше tools. Некоторые инструменты у субагентов отсутствуют всегда, даже если их перечислить: AskUserQuestion, EnterPlanMode, ExitPlanMode (кроме permissionMode: plan), ScheduleWakeup, WaitForMcpServers, Workflow, EndConversation, а на пределе вложенности и сам Agent.

Независимые задачи параллельно

По документации в одной сессии одновременно работают до 20 субагентов (CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS меняет лимит). Субагенты, запущенные из основного разговора без дополнительных настроек, стартуют в фоне: основной агент продолжает работу, результат приходит сообщением позже. Параллельность имеет смысл, когда задачи не зависят друг от друга: три независимых исследования, проверки разных модулей. Каждый запуск платит свою стартовую цену, поэтому десять мелких параллельных задач обойдутся дороже, чем кажется.

Изоляция правок в worktree

isolation: worktree запускает субагента во временном git worktree, и его правки не затрагивают рабочую копию. Документация уточняет деталь, которую легко пропустить: worktree по умолчанию ответвляется от основной ветки репозитория, а не от текущего HEAD родительской сессии. Если субагент должен работать поверх незакоммиченных или свежих изменений, это нужно учитывать.

Когда субагент мешает

Короткие и точечные задачи

Исправить опечатку, прочитать один файл, проверить значение в конфиге. Замер выше показывает, что такие задачи в тяжёлой конфигурации стоят ~55 тыс. токенов старта ради ответа в ~1 000 символов. Документация называет основной разговор подходящим местом для быстрых точечных правок и задач, чувствительных к задержке: новому субагенту нужно время, чтобы собрать контекст.

Работа, которой нужна история разговора

Если задача опирается на то, что обсуждалось последние полчаса (решения, отвергнутые варианты, уточнения), обычный субагент начнёт с нуля. Пересказ в тексте задачи теряет детали. Здесь есть три варианта: продолжить в основном разговоре, запустить fork, который видит всю историю, или для вопроса по уже обсуждённому использовать /btw. По документации /btw отвечает без доступа к инструментам и не добавляет ответ в историю.

Итеративная работа с частыми уточнениями тоже плохо ложится на субагента: каждый раунд правок проходит через пересказ, а не через общий контекст.

Когда есть дешёвый индексированный поиск

Если в проекте подключён индекс кода (например, граф символов через MCP-инструмент), ответ на вопрос «где определено и кто вызывает» получается одним-двумя запросами к индексу. Субагент, который будет искать то же самое чтением файлов, добавит стартовую цену и десятки вызовов. В глобальных правилах автора для таких проектов прямо записано: исследование кода делает основной разговор через индекс, а не Explore. Замеров этого сравнения нет, это правило из практики, а не результат эксперимента.

Накопление результатов и ошибки пересказа

Ответ субагента - это сводка, а сводка может ошибаться: пропустить файл, неверно обобщить, уверенно назвать непроверенное. Основной агент видит только итог и проверить его без повторной работы не может. Для решений, от которых много зависит, стоит просить в ответе ссылки на файлы и строки, чтобы выборочно проверить их.

Второй эффект: при многих запусках результаты копятся в основном контексте. Десять субагентов по 6 тыс. символов ответа (p90 из замеров) уже заметны в окне, и сюда добавляются формулировки задач.

Фон и вложенность

Фоновые субагенты работают с урезанным набором встроенных инструментов; MCP-инструменты сохраняются. Запросы разрешений всплывают в основной сессии с именем субагента, который спрашивает, и при нескольких параллельных запусках это отвлекает. С версии 2.1.318 shell-команда фонового субагента сама уходит в фон через 3 минуты, чтобы не истёк кэш промпта.

Субагенты могут запускать своих субагентов до трёх уровней под основным разговором (CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH, значение 1 отключает вложенность). Каждый уровень платит свою стартовую цену и пересказывает задачу, поэтому глубокая вложенность умножает и стоимость, и риск искажения.

Дерево решения: субагент, fork или основной разговор

СитуацияГде выполнятьПочему
1–3 вызова, точечная правкаОсновной разговорСтарт субагента дороже самой работы
Итерации с уточнениями, общий большой контекстОсновной разговорСубагент не видит историю
Вопрос по уже обсуждённому/btwБез инструментов, не засоряет историю
Побочная задача, которой нужен весь контекстFork (/subtask)Видит историю, делит кэш, возвращает только итог
Десятки чтений и поисков, короткий ответExplore или general-purposeИзоляция окупается
Нужны жёсткие ограничения правКастомный агент с toolsОграничение по конструкции, меньше старт
Правки, которые не должны задеть рабочую копиюАгент с isolation: worktreeОтдельная ветка и каталог
Несколько независимых задачПараллельные субагентыДо 20 одновременно, каждый со своим окном
Долгая работа, не помещается в одно окноОтдельные сессии, фоновые агенты или agent teamsТак рекомендует документация
Есть индекс кодаОсновной разговор с индексомПоиск дешевле, чем чтение файлов субагентом

Большинство случаев решают два вопроса. Первый: сколько вызовов инструментов понадобится. Если их один-три, субагент вряд ли окупится. Второй: нужна ли задаче история разговора. Если нужна, остаются fork и основной разговор.

Как выбирается модель субагента

Порядок разрешения

По документации модель субагента определяется в таком порядке:

  1. Параметр model, который Claude передаёт в конкретном вызове Agent.
  2. Поле model во frontmatter агента.
  3. Переменная окружения CLAUDE_CODE_SUBAGENT_MODEL.
  4. Модель основного разговора.

Допустимые значения поля: sonnet, opus, haiku, fable, полный ID (например, claude-opus-5-5) или inherit, то есть модель основного разговора. При подключении к Anthropic API алиасы opus, sonnet и haiku указывают на Opus 5.5, Sonnet 5.5 и Haiku 5.5, а fable на Fable 5.1. У облачных провайдеров соответствие может быть другим.

Частая ошибка: считать, что CLAUDE_CODE_SUBAGENT_MODEL перебивает всё. Так было в старых версиях; сейчас это значение по умолчанию, и frontmatter или параметр вызова его перекрывают. Чтобы поставить одну модель всем субагентам, нужно добавить CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1 (с версии 2.1.257). У встроенных агентов свои правила: Plan наследует модель основного разговора, Explore тоже, но если основной разговор идёт на Fable, при подписке Claude, аккаунте Console или LLM-шлюзе Explore переходит на модель за алиасом opus.

Политика выбора и чего замеры не показывают

В правилах автора модель агентов задана политикой: поиск и сбор информации на Sonnet, анализ, планирование и решения на Opus, Haiku для агентов не используется. Это рабочее соглашение, а не вывод из замеров.

Транскрипты такого вывода и не позволяют сделать. В них смесь моделей нескольких поколений, причину выбора (frontmatter, параметр вызова, переменная, наследование) по транскрипту не восстановить, а качество ответов не измерялось. Парных сравнений «одна задача на двух моделях» не было, поэтому утверждать, что Sonnet справляется с теми же задачами не хуже Opus, по этим данным нельзя. Цены и различия моделей разобраны в статье Claude Opus vs Sonnet.

Effort и thinking

Субагенты наследуют настройку extended thinking основного разговора. Уровень усилия задаётся полем effort во frontmatter (low, medium, high, xhigh, max), параметром вызова или переменной CLAUDE_CODE_SUBAGENT_EFFORT, которая действует, когда больше ничто не задаёт уровень. Для исследовательского агента с узкой задачей разумно начать с меньшего уровня и поднимать его, если ответы получаются поверхностными.

Формат файла агента: поля, которые влияют на цену

Агент хранится как markdown-файл с YAML-frontmatter в .claude/agents/ (проект) или ~/.claude/agents/ (пользователь); базовая настройка Claude Code описана в полном гайде. Пример read-only ревьюера с полями, которые влияют на цену и поведение:

---
name: code-reviewer
description: Reviews a diff for bugs and security issues. Use after a feature is implemented. Read-only; for writing tests use test-writer.
tools: Read, Grep, Glob
model: sonnet
maxTurns: 20
---

Review the changes you are pointed to. Report issues by priority
with file:line references. Do not propose rewrites of unrelated code.
ПолеЧто даётКогда задавать
toolsAllowlist инструментов; без поля наследуются всеПочти всегда: и права, и стартовый контекст
modelМодель агента (см. выше)Когда агент должен работать не на модели сессии
maxTurnsЛимит ходов; по достижении результат помечается частичнымАудиторы и исследователи, склонные уходить вширь
omitClaudeMdСтарт без CLAUDE.md (с 2.1.271); managed-политика всё равно загружаетсяАгентам, которым правила проекта не нужны
isolationworktree: временный git worktreeАгентам, которые правят код параллельно с вами
autoCompactWindowРанняя компакция субагента, 100 000–1 000 000 токеновАгентам, читающим длинные логи

Значение autoCompactWindow пишется целым числом: по документации 200k во frontmatter читается как 200 и игнорируется как выходящее за диапазон. Остальные поля (permissionMode, memory, skills, mcpServers, hooks, background, color) описаны в справочной статье по skills и agents.

Описание агента как роутер

Claude решает, кому делегировать, по полю description. Описания всех агентов лежат в контексте основного разговора постоянно, и по документации, если их суммарный объём (без встроенных) превышает 15 000 токенов, Claude Code показывает предупреждение при старте.

Что работает

В каталоге автора встречаются два паттерна, которые упрощают выбор агента:

  1. Триггер в начале. «Use after completing a logical unit of code» или «Use when…» с перечнем ситуаций.
  2. Граница с соседом в конце. Фраза вида «для reference-паттернов используй команду /mcp-server» или «для тест-кода есть агент test-writer» снимает конфликт выбора между похожими агентами, командами и skills.

Добавка «use proactively» по документации повышает шанс автоматического делегирования.

Антипаттерны

  • Длинные описания с примерами. В каталоге есть агенты с описаниями по 900–1 000 символов с блоками «Example: User says… use this agent». Такое описание оплачивается в каждом запросе, даже когда агент не нужен.
  • Двуязычные описания. Работают, но удлиняют текст, который лежит в контексте постоянно.
  • Устаревшие имена в tools. У агента, написанного под старую версию, в списке могут остаться инструменты, которых уже нет или которые у субагентов вырезаются (AskUserQuestion). Что Claude Code делает с частично неразрешёнными именами, автор на живом запуске не проверял; список стоит сверять с текущим перечнем инструментов.

Почему агент не вызывается

  • Файл пропущен. Без description или с невалидным YAML агент не загружается, причина пишется в debug-лог. Файл без name считается документацией.
  • Опечатка в поле. Неизвестные поля молча игнорируются. В claude --debug (с 2.1.296) такие поля видны по строке does not recognize or apply.
  • Описание не выделяет агента. Если два агента описаны похоже, Claude может выбрать соседа или обойтись general-purpose.
  • Нужен гарантированный запуск. Упоминание @agent-<имя> в запросе или выбор из списка через @ запускает конкретного агента; формулировку задачи для него всё равно пишет Claude.

При одинаковых именах побеждает определение с более высоким приоритетом: managed settings, затем флаг --agents, затем .claude/agents/ проекта, ~/.claude/agents/ пользователя и в конце агенты плагинов.

Сколько агентов нужно

В пользовательском каталоге автора 33 файла агентов. Около 10 из них написаны автором, остальные пришли со сторонним пакетом. При этом 89% всех запусков приходятся на встроенный general-purpose, а все кастомные агенты вместе дают ~7%. Чаще других запускаются исследовательский агент с набором инструментов только для чтения и веб-поиска и read-only ревьюер.

Число файлов агентов о пользе ничего не говорит. Файл агента нужен, когда он что-то фиксирует: узкий набор инструментов, модель, лимит ходов, формат ответа. Для разового делегирования хватает general-purpose с хорошо сформулированной задачей. Начинать разумно с 2–3 агентов под повторяющиеся роли с явными границами между ними, а не каталог «на все случаи», описания которого постоянно занимают контекст.

Хуки и наблюдаемость

Для контроля субагентов есть события SubagentStart и SubagentStop с matcher по имени агента. SubagentStop получает путь к транскрипту субагента и его последнее сообщение, этого хватает, чтобы логировать запуски или проверять формат ответа. Хуки можно объявить и во frontmatter агента: они работают, пока агент активен, а Stop в этом случае превращается в SubagentStop. Подробно события и формат хуков разобраны в статье о хуках Claude Code.

Модель каждого запущенного субагента показывает /tasks. Для разбора постфактум остаются транскрипты в subagents/ и файлы .meta.json рядом с ними, где записан тип агента.

CLAUDE.md входит в стартовый контекст субагента, поэтому его размер влияет и на цену делегирования. Как держать CLAUDE.md коротким, разобрано в гайде по CLAUDE.md, а общая логика управления окном описана в статье о context engineering.

С чего начать

  1. Прогоните скрипт замера на своих транскриптах и узнайте свою стартовую цену субагента. От неё зависит, с какой длины задачи делегирование окупается.
  2. Не делегируйте задачи на 1–3 вызова и работу, которой нужна история разговора. Для второго случая есть fork и /btw.
  3. Задавайте tools каждому кастомному агенту. В эксперименте на тяжёлой конфигурации это самый сильный рычаг: −78,5% стартового контекста, плюс ограничение прав по конструкции.
  4. Добавьте omitClaudeMd: true агентам, которым правила проекта не нужны, и уберите из сессии MCP-серверы, которые не используются.
  5. Пишите описания коротко: триггер в начале, граница с соседями в конце, без блоков с примерами. Модель задавайте явно во frontmatter и помните, что CLAUDE_CODE_SUBAGENT_MODEL без _FORCE=1 её не перебивает.

Часто задаваемые вопросы

Экономит ли субагент токены в Claude Code?
Субагент экономит место в контексте основного разговора. Токены он тратит собственные, и они идут в те же лимиты использования, плюс у каждого запуска есть стартовая цена: системный промпт, CLAUDE.md, схемы инструментов. Выгода появляется, когда промежуточной работы много (десятки вызовов инструментов), а ответ короткий.
Видит ли субагент мой разговор и CLAUDE.md?
Обычный субагент историю разговора не видит: он получает свой системный промпт, сообщение-задачу, CLAUDE.md, снимок git status и предзагруженные skills. Встроенные Explore и Plan стартуют без CLAUDE.md и git status. Кастомному агенту CLAUDE.md можно отключить полем omitClaudeMd: true. Историю целиком видит только fork.
Как выбрать модель субагента в Claude Code?
Модель задают полем model во frontmatter: sonnet, opus, haiku, fable, полный ID или inherit. Параметр model в вызове Agent перебивает frontmatter, а CLAUDE_CODE_SUBAGENT_MODEL работает как значение по умолчанию. Чтобы одна модель стояла у всех субагентов, нужен ещё CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1.
Сколько субагентов можно запустить параллельно?
По документации по умолчанию до 20 одновременно в одной сессии; лимит меняет переменная CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS. Вложенность по умолчанию до трёх уровней под основным разговором, её задаёт CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH (значение 1 отключает вложенность).
Чем субагент отличается от skill и от fork?
Skill выполняется в текущем контексте, вместе с историей разговора. Субагент стартует с чистым контекстом и возвращает только ответ. Fork - субагент, который наследует весь разговор, системный промпт, инструменты и модель основной сессии и делит с ней кэш промпта; наружу тоже возвращает только результат.
Почему Claude не вызывает мой агент?
Частые причины: файл пропущен из-за отсутствующего description или невалидного YAML, опечатка в имени поля (неизвестные поля молча игнорируются) или описание не отличает агента от соседей. Причины пропуска видны в claude --debug. Запуск можно гарантировать упоминанием @agent-<имя> в запросе.
Как уменьшить стартовый контекст субагента?
Самый сильный рычаг - узкий список tools: allowlist убирает из контекста схемы остальных инструментов, включая MCP. Дальше omitClaudeMd: true и меньше MCP-серверов в сессии. В эксперименте автора tools и omitClaudeMd вместе сократили старт на 91,8%, но в лёгкой конфигурации абсолютная экономия будет меньше.