Я неделю писал subagent для Claude Code - Claude его игнорировал. Виновата одна строка

Я неделю писал 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.

--- name: code-reviewer description: | [ЧАСТЬ 1 - результат] Expert code review specialist. Finds bugs, security issues, and bad patterns in modified files. Returns prioritized list with severity and concrete fix. [ЧАСТЬ 2 - явный триггер активности] Use proactively immediately after writing or editing code. Use when user asks: "ревьюй PR", "проверь код", "найди баги в этом файле", "что не так с моим коммитом", "посмотри последние изменения". [ЧАСТЬ 3 - явное «когда НЕ применять»] Do not invoke for: README edits, commit message rewrites, documentation changes, frontmatter changes - those go to doc-maintainer. tools: Read, Glob, Grep, Bash model: sonnet --- Ты - code-reviewer. Когда тебя вызывают, читаешь diff последнего коммита через `git diff HEAD~1`, прогоняешь по чек-листу из 8 пунктов (см. ниже), возвращаешь структурированный отчёт. [чек-лист и формат отчёта - 50 строк]

Разбираю, что делает каждая часть.

Часть 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 лежат в пяти местах, у каждого свой приоритет:

  1. Enterprise managed settings - правила организации, перекрывают всё. Если ты внутри компании с настроенным Claude Code - твои личные subagents с тем же именем игнорируются.
  2. Сессия - CLI-флаг --agents с JSON. Применяется только к текущему окну. Дальше по силе.
  3. Project - .claude/agents/[имя].md внутри корня проекта. Применяется только в этом проекте.
  4. Personal - ~/.claude/agents/[имя].md в домашней папке. Применяется во всех твоих проектах.
  5. 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». Возвращает приоритизированный список багов с фиксами.

description: Expert code review specialist. Finds bugs, security issues, and bad patterns in modified files. Use proactively immediately after writing or editing code. Triggers: "ревьюй PR", "проверь код", "найди баги в коммите". Do not invoke for README/docs edits.

security-auditor (sonnet, effort: high). Триггерится при изменении auth/permissions/cron-job/SQL. Возвращает severity-ранжированный список уязвимостей.

description: Security audit specialist for auth, permissions, cron, SQL. Use immediately after editing files in /api/auth/, /api/cron/, or files matching prisma migrations. Returns CVSS-style severity list with fix steps. Do not invoke for frontend-only changes.

docs-researcher (haiku!). Триггерится фразами «что нового», «какой changelog», «найди в документации». Возвращает выжимку 10-15 строк со ссылками.

description: Documentation researcher. Reads 20-50 sources, summarizes into 10-15 lines with links. Use proactively when user asks "что нового в X", "найди changelog для Y", "research про Z". Use haiku model for cost control. Do not invoke for code changes.

refactor-suggester (opus, effort: max). Триггерится при намеренной просьбе «отрефактори». Возвращает план refactor с шагами и оценкой риска. Код сам не пишет: пишешь ты вручную или другой агент после ревью плана.

description: Refactor planner. Returns step-by-step refactor plan with risk assessment, never writes code itself. Use when user explicitly asks "отрефактори X", "перепиши Y под архитектуру Z". Do not invoke for small fixes - those go to code-reviewer.

doc-maintainer (sonnet, tools: Read, Edit). Триггерится изменениями в *.md или фразой «обнови документацию». Возвращает diff README/CHANGELOG.

description: Documentation maintainer. Updates README, CHANGELOG, and markdown docs when code changes. Use immediately after merging PR or when user says "обнови README", "напиши CHANGELOG". Do not invoke for code or test changes.

Положи эти 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»?

1 комментарий