Механизм skills появился как способ расширить возможности ИИ-агентов без переобучения модели: разработчик описывает, что агент должен делать в конкретной ситуации, и агент сам решает, когда применить эту инструкцию. Звучит удобно — но на практике агент регулярно активирует не тот skill, пропускает нужный или запускает несколько конкурирующих одновременно.

Каждый skill состоит из двух частей. YAML frontmatter — это заголовок: название, описание и опционально список разрешённых инструментов. Тело skill — основная инструкция: пошаговые действия, условия выхода, референсная документация. Когда агент получает запрос, он читает frontmatter всех доступных skills и на основе этого контекста решает, какой из них применить. Для LLM-модели описание skill и текст пользовательского промпта — принципиально одинаковые входные данные, и модель выбирает следующий шаг исходя из всего контекста сразу.

На вероятность активации skill можно влиять двумя способами. Первый — на этапе обучения модели: в Anthropic и других компаниях активность использования skills теперь входит в метрики качества. Второй — через промпт: исследователи из Anthropic публиковали пример инструкции, которая буквально мотивирует агента использовать инструменты как можно чаще и исследовать кодовую базу перед тем, как что-то менять. Такой текст можно добавить в CLAUDE.md, AGENTS.md или через hook — как это реализовано в Spring Agent Toolkit.

Слова MUST, CRITICAL, MANDATORY в описании skill заставляют агента активировать его почти при любом запросе.

Главная практическая проблема — «неэкологичные» skills. Достаточно добавить в YAML frontmatter слова MUST, CRITICAL или MANDATORY, и агент начнёт активировать skill при любом запросе, независимо от контекста. Это легко проверить экспериментально: skill с описанием «MUST USE with any prompt» и телом «Tell user: Hello world!» будет срабатывать на любую задачу и останавливать выполнение. Если таких skills несколько, агент начинает вести себя непредсказуемо.

Аналогичная проблема возникает со слишком широкими описаниями. Разработчик хочет, чтобы skill про Event Listener активировался при добавлении нового слушателя, но агент его игнорирует. После нескольких итераций описание превращается в «используй, когда работаешь со Spring Boot» — и теперь skill активируется для любой задачи в Spring Boot-проекте. Широкие формулировки сами по себе не запрещены: если skill действительно покрывает большую область и содержит внутреннюю маршрутизацию через sub-agents, широкое описание оправдано. Проблема возникает, когда широкое описание не соответствует реальному содержанию skill.

Вторая точка уязвимости — момент активации в процессе выполнения задачи. Агент теоретически может подгрузить новый skill перед каждым следующим шагом, но на практике чем дальше от исходного промпта, тем реже это происходит. При работе в режиме планирования агент ещё реже проверяет доступные skills — зато в этом режиме нужный skill можно явно указать прямо в плане. Кроме того, один skill может напрямую вызывать другой — это позволяет выстраивать цепочки без участия пользователя.

В Spring Agent Toolkit часть skills намеренно не является «экологичными» — они знают о соседних skills и проходят тестирование на совместимость. Это показывает, что управление набором skills — отдельная инженерная задача, а не просто написание инструкций.