Я неделю писал subagent для Claude Code - Claude его игнорировал. Виновата одна строка
Завёл я в проекте subagent под код-ревью. Положил файл в .claude/agents/code-reviewer.md, описал что делает, дал ему tools: Read, Glob, Grep. Открываю чат, прошу: «Проверь мой последний коммит, найди уязвимости и плохие паттерны». Claude кивает, лезет читать файлы основным контекстом, тратит токены, выдаёт отчёт. Subagent при этом молчит. Я не вижу ни вызова, ни делегирования, как будто файла нет.
Я думал у меня кривой markdown. Перепроверил - валидный. Думал tools мало - добавил Bash, Edit, Write. Не помогло. Перенёс файл из .claude/agents/ в ~/.claude/agents/, потом обратно. Никакой реакции. Потерял неделю на угадывание, пока не залез в исходники Claude Code и не нашёл одну строку в документации Anthropic, которая решает 90% случаев «subagent молчит». Эта статья - о ней. И ещё о пяти ошибках, которые я успел сделать рядом, пока разбирался.
1. Почему Claude по умолчанию игнорирует твоего subagent и тянет всё в основной чат
Базовая модель работы Claude Code такая. Ты пишешь запрос. Главный чат смотрит, есть ли в окружении subagents, читает их description, и решает сам, делегировать или сделать в текущем контексте. Это работает как автомат с порогом срабатывания. Если триггер слабый, автомат не вызывается.
Главный порог - сила формулировки description. Если description написан в стиле «Helper for code review», Claude в 7 случаях из 10 не делегирует. Потому что фраза слишком общая. Под неё подходит любая задача с кодом - значит, никакая. Claude не любит делегировать по слабому сигналу: лучше сам сделает в своём контексте, чем разбудит специалиста, который потом вернёт не то.
Второй порог - явный сигнал «использовать активно». По дефолту Claude склоняется к «оставлю себе» при любой неоднозначности. Чтобы он склонился в сторону вызова, в description должна быть фраза-маркер. В документации Anthropic это сказано прямо.
<Quote author="Claude Code Documentation" source="https://code.claude.com/docs/en/sub-agents"> Claude автоматически делегирует задачи на основе описания задачи в твоём запросе, поля description в конфиге subagent и текущего контекста. Чтобы подтолкнуть проактивное делегирование, добавь в description у subagent фразы вроде 'use proactively'. </Quote>
То есть Claude по умолчанию ленив. Это паттерн поведения, заложенный в системный промпт Claude Code, и фикс на стороне продукта тут не появится. Хочешь, чтобы subagent работал, явно скажи модели «зови меня». Без этой строки описание остаётся вежливым намёком, который автомат проглатывает мимо.
Третий порог - уникальность триггера. Если у тебя в проекте лежат три subagent с похожими описаниями («код-ревью», «security-аудит», «качество кода»), Claude растеряется и сделает сам. Один subagent на одну зону ответственности, формулировки в кавычках в description должны не пересекаться.
2. Формула description из 3 частей, которая заставит Claude делегировать с первой попытки
Это первый артефакт статьи. Скопируй шаблон, замени плейсхолдеры в квадратных скобках, положи в .claude/agents/[имя].md. Через 30 секунд после перезапуска сессии Claude начнёт активно вызывать subagent.
Разбираю, что делает каждая часть.
Часть 1 - формулировка результата. Слабая формулировка: «анализирует код». Сильная: «находит уязвимости и возвращает список с severity». Claude матчит твою задачу против результата, который обещает агент. «Найди мне баги» совпадает с «находит баги в коде» на уровне глагола.
Часть 2 - две группы фраз-триггеров. Первая - «use proactively immediately after». Это магическая фраза для Anthropic, она снижает порог делегирования. Вторая - реальные формулировки из твоих чатов в кавычках. Не выдумывай - возьми историю переписки, выпиши, как ты на самом деле просишь ревью. У всех формулировки разные: одни говорят «ревьюй», другие «check code», третьи «глянь PR». Чем ближе формулировки в description к твоим реальным запросам, тем выше шанс матча.
Часть 3 - явное отключение. Без неё у двух subagent с похожим радиусом ответственности всегда конфликт: каждый «может подойти», Claude выбирает рандомно или делает сам. Запиши, на что этот subagent не должен реагировать.
3. Магическая фраза «use proactively», и почему Anthropic её прячет
Anthropic в документации даёт эту рекомендацию одной строкой, без выделения и без примеров. Это создаёт ложное впечатление, что это «маленький лайфхак». В реальности это самая важная строка во всей конфигурации subagent. У меня code-reviewer лежит в ~/.claude/agents/ около года. До того, как я добавил в description «use proactively», делегирование шло одно из трёх-четырёх. После того, как добавил, Claude стал вызывать его почти каждый раз, когда я правил код.
Почему фразу прячут. Anthropic не хочет, чтобы каждый разработчик лепил «use proactively» подряд в три subagent. Если все агенты помечены как proactive, Claude растеряется и снова станет делегировать рандомно. То есть фраза - острый инструмент: ставь её ровно туда, где проактивность критична. Для research-агента - да, нужно. Для code-reviewer после каждого Edit - да, нужно. Для редкого ad-hoc генератора отчётов раз в месяц - не нужно, пусть Claude вызывает по явной команде @agent-reporter.
Альтернативная формулировка та же по силе: «use immediately after writing code». Она работает, когда триггер привязан к конкретному событию. Например:
- use immediately after writing or editing code - для security-аудитора.
- use immediately after running tests - для test-failure-analyzer.
- use immediately after generating migration file - для миграционного валидатора.
Если ты можешь описать момент, в который subagent должен включиться, используй паттерн «use immediately after [событие]». Это работает точнее, чем общее «use proactively».
4. Главная путаница 2026: subagent vs skill - что выбрать на самом деле
90% случаев, когда я видел вопрос «сделал subagent, но Claude его не вызывает» в Telegram-чатах и на Hacker News, заканчивались одним и тем же. Человек писал subagent там, где должен был написать skill. Это не одна и та же сущность, и не «skill побольше». Это разные механизмы расширения с разными зонами применения.
Чтобы решить, что выбрать - прогони задачу через 4 вопроса. Это второй артефакт статьи.
Вопрос 1: это знание, которое должно быть всегда? Например, «у нас RU-локализация, не используй длинное тире», «коммитим через conventional commits», «не трогай файл .env». Положи в CLAUDE.md - туда грузится постоянное знание, оно доступно главному чату каждую сессию без триггера.
Вопрос 2: это методология с триггером, которую сейчас ты делаешь руками? Например, «каждый понедельник я пишу отчёт по продажам - открываю Notion, копирую цифры из аналитики, форматирую». У этого процесса есть чёткий запуск (фраза «отчёт за неделю») и чёткий результат (структурированный markdown). Делай skill. Skill = рецепт. Подгружается по триггеру в твой основной контекст и руководит главным чатом.
Вопрос 3: задача съест весь контекст основного чата или её можно делать в параллель? Например, «глубокий research по 30 источникам», «security-аудит пока ты пишешь новую фичу», «прогон 100 файлов миграции через линтер». Это работа, которая не нужна тебе в основном чате - тебе нужен только итог. Делай subagent. Subagent живёт в своём контексте, ест свои токены, возвращает summary.
Вопрос 4: нужна автоматическая реакция на событие в Claude Code? Например, «после каждого Edit запускать линтер», «перед каждым Bash-вызовом проверять команду на безопасность». Это hook. Hooks встраиваются в lifecycle Claude Code, не требуют ни триггера, ни делегирования.
Я веду эту таблицу в своём CLAUDE.md уже полгода. Каждый раз, когда возникает мысль «надо чтобы Claude умел X», прогоняю через 4 вопроса. Из 30+ таких ситуаций subagent оказался правильным выбором только в 7 случаях. Остальные 23 - это CLAUDE.md, skills или hooks.
Если хочется глубже разобраться, чем skill отличается от subagent и как собрать собственную библиотеку навыков под Claude Code, я разбирал это в отдельном гайде про Skills в Claude Code.
5. Где живут subagents и кто кого перекрывает - 5 уровней и одна ловушка
Когда subagent перестаёт вызываться после того, как только что работал, в 7 случаях из 10 виновата иерархия. Subagent с тем же именем перекрылся файлом из другого scope.
В Claude Code subagents лежат в пяти местах, у каждого свой приоритет:
- Enterprise managed settings - правила организации, перекрывают всё. Если ты внутри компании с настроенным Claude Code - твои личные subagents с тем же именем игнорируются.
- Сессия - CLI-флаг --agents с JSON. Применяется только к текущему окну. Дальше по силе.
- Project - .claude/agents/[имя].md внутри корня проекта. Применяется только в этом проекте.
- Personal - ~/.claude/agents/[имя].md в домашней папке. Применяется во всех твоих проектах.
- Plugin - subagents, которые приходят с подключённым плагином. Самый слабый приоритет.
Ловушка такая. Ты создал personal-агента ~/.claude/agents/code-reviewer.md. Он работал. Потом ты внутри проекта поставил плагин, в котором есть свой code-reviewer. И личный начал перекрываться плагином? Нет. Плагин слабее personal, личный остаётся главным. Но если ты потом в этом же проекте сделал .claude/agents/code-reviewer.md (например, чтобы переопределить промпт под этот проект) - проект перекроет personal. И в других проектах personal-агент продолжит работать, а в этом перехватится project-агентом.
Самая частая ошибка - не помнить, что project перекрывает personal. Открываешь проект, удивляешься, что subagent стал отвечать иначе, лезешь править personal. А надо было смотреть на .claude/agents/ внутри проекта - там лежит «более свежая» версия, о которой ты забыл.
Второй болезненный момент - подгрузка. Subagents читаются один раз при старте сессии. Если ты поправил файл агента руками на диске - изменения не подхватятся, пока ты не перезапустишь Claude Code. Через интерактивный UI /agents правки применяются мгновенно, потому что UI пишет на диск и одновременно обновляет in-memory кэш. Через текстовый редактор - нет.
6. 16 полей frontmatter, на которых я экономил токены и сжигал их зря
Минимальный subagent - 9 строк, два обязательных поля: name и description. Всё остальное - 14 опциональных полей. Поначалу я их игнорировал, оставлял всё по дефолту. И сжигал Sonnet там, где должен был работать Haiku.
Вот критичные поля, ради которых стоит лезть в frontmatter.
model: haiku - главное поле для экономии. Если у тебя research-агент, который читает 50 страниц документации и возвращает 10 строк выжимки - запускай его на Haiku. Экономия примерно 4-5 раз против Opus. У меня есть subagent docs-researcher, который читает changelog'и AI-моделей и собирает что нового. На Haiku он тратит 200-300 токенов за прогон. На Opus - 1200-1500. За месяц это десятки тысяч сэкономленных токенов.
tools: Read, Glob, Grep - белый список. Без него subagent наследует все инструменты основного чата. Когда у тебя security-аудитор имеет доступ к Bash и Edit, риск, что он что-то «починит сам» - реальный. Закрой ему всё кроме чтения.
disallowedTools: WebFetch - чёрный список. Применяется раньше белого. Полезно, когда хочешь сказать «всё кроме одного» - проще запретить одно, чем перечислять все остальные.
isolation: worktree - запускать subagent в отдельной git-копии проекта. Спасает, когда subagent делает потенциально опасные правки: рефакторинг, миграция, массовое переименование. Claude Code создаёт временный worktree, subagent работает там, возвращает diff, ты ревьюишь и накатываешь руками.
effort: high - уровень reasoning. Для security-аудита и архитектурных решений ставь high. Для routine-задач типа форматирования - low или дефолт. Это влияет на качество ответа и расход токенов одновременно.
background: true - всегда запускать subagent в фоне. Полезно для тяжёлых задач, которые не блокируют основной чат. Я держу так e2e-test-runner - он гонит Playwright в фоне, пока я пишу следующий H2.
Поле memory: project я сначала не понимал зачем нужно. Потом завёл research-агента, который собирает мне свежие новости про вайб-кодинг каждый день. Без памяти он каждый раз начинал с нуля, дублировал источники, выдавал противоречивые саммари. С memory: project у него появилась папка .claude/memory/<agent-name>/, куда он сам пишет «что уже видел». На второй неделе он стал умнее основного чата на эту тему - просто потому, что у него история есть, а у chat-сессии нет.
7. 5 готовых ролей за 30 минут: формулировки description, которые работают
Третий артефакт статьи. Это пять description, которые я уже год обкатываю в боевых условиях. Можешь забрать, подставить свои внутренние ссылки, сложить в ~/.claude/agents/.
code-reviewer (sonnet, 800 знаков). Триггерится после git commit или явной фразы «проверь PR». Возвращает приоритизированный список багов с фиксами.
security-auditor (sonnet, effort: high). Триггерится при изменении auth/permissions/cron-job/SQL. Возвращает severity-ранжированный список уязвимостей.
docs-researcher (haiku!). Триггерится фразами «что нового», «какой changelog», «найди в документации». Возвращает выжимку 10-15 строк со ссылками.
refactor-suggester (opus, effort: max). Триггерится при намеренной просьбе «отрефактори». Возвращает план refactor с шагами и оценкой риска. Код сам не пишет: пишешь ты вручную или другой агент после ревью плана.
doc-maintainer (sonnet, tools: Read, Edit). Триггерится изменениями в *.md или фразой «обнови документацию». Возвращает diff README/CHANGELOG.
Положи эти 5 файлов в ~/.claude/agents/. Перезапусти сессию. У тебя появятся 5 специалистов, которых Claude будет реально вызывать, а не игнорировать. На 5 ролей я потратил 30 минут - 6 минут на каждую, плюс пара итераций тюнинга description в первый день.
Если нужен пошаговый разбор всех 16 полей frontmatter, иерархии scope и Multi-agent v2 от Anthropic - это в моём полном гайде про Claude Code subagents.
8. 7 антипаттернов, на которых я уже спалился
Антипаттерн 1 - subagent без tools-белого списка. Когда tools не указаны, subagent наследует всё. Security-аудитор с правом писать в файлы - это бомба замедленного действия. Всегда явно перечисляй tools, или хотя бы блокируй опасные через disallowedTools.
Антипаттерн 2 - subagent на Opus там, где Haiku справится. Каждый раз, когда видишь себе мысль «пусть будет Opus, на всякий случай» - проверь: эта задача правда требует reasoning топового уровня, или это типовая работа с текстом? Research, summary, документация, простая классификация - Haiku справляется. Сэкономишь в 4-5 раз.
Антипаттерн 3 - два subagent с пересекающимся description. У меня раз были bug-finder и code-reviewer с почти одинаковыми триггерами. Claude чередовал их рандомно, иногда вообще делал сам. Слил в один.
Антипаттерн 4 - забыл про «do not invoke». Без явного отрицательного триггера subagent ловит ложные срабатывания. Code-reviewer прибегал на правки в CHANGELOG.md. Добавил do not invoke for README/docs edits - перестал.
Антипаттерн 5 - description в стиле «AI assistant for X». Слишком общо. Claude матчит описание на конкретные фразы из запроса пользователя. Пиши description как ответ на вопрос «когда меня позвать?». Конкретные триггеры в кавычках всегда работают лучше абстрактных ролевых формулировок.
Антипаттерн 6 - не задан формат возврата в системном промпте. Subagent возвращает «эссе» вместо структурированного списка. Я в каждом промпте теперь явно прописываю формат: «Возвращай в виде markdown-таблицы с колонками severity / file / fix». Без этого summary тонет в воде.
Антипаттерн 7 - попытка сделать subagent, который порождает subagent. Не получится. В Claude Code запрещена вложенность - subagents не могут спавнить других subagents. В документации это сформулировано как защита от бесконечной рекурсии. Если задача правда нужна в три уровня - перепроектируй так, чтобы каждый subagent делал плоскую работу.
Что я бы сделал на твоём месте - Выводы
Если у тебя сейчас лежит subagent, которого Claude игнорирует - открой его файл и смотри только на одну строку. Description. 90% случаев молчания лечится там.
- Перепиши description по формуле 3 частей. Результат + явные триггеры в кавычках + явное «do not invoke».
- Добавь «use proactively» или «use immediately after [событие]». Без этой фразы Claude склоняется к «сделаю сам».
- Проверь, не лежит ли в проекте .claude/agents/[имя].md, который перекрывает personal. Project бьёт personal, personal бьёт plugin.
- Перепрогон через 4 вопроса: может быть, ты пишешь subagent там, где должен быть skill или просто запись в CLAUDE.md. Это самая частая ошибка.
- Закрой tools белым списком. Не давай subagent больше, чем нужно. И ставь model: haiku везде, где задача не требует reasoning топа.
И один тейк из практики. Промпт ты пишешь один раз за сессию. Description пишешь в каждом агенте. От его силы зависит, есть ли у тебя в проекте команда из 5 специалистов или 5 файлов, которые лежат и занимают место в .claude/.
А ты как пишешь description для своих subagents - даёшь короткое «assistant for X» или прописываешь все триггеры в кавычках? И какой формат у тебя сработал лучше: «use proactively» или «use immediately after»?