К содержимому
ErgonLab
← Блог
Гайд · Claude Code
· 7 мин

Skills vs Agents vs Hooks — что когда выбирать

Три похожих инструмента Claude Code решают разные задачи. Разбираю на пальцах с решающим деревом и примерами из реальной работы.

Почему все три выглядят одинаково

Когда я объяснял клиенту (по обучению Claude Code) разницу между skills, agents и hooks на второй сессии, он честно сказал: «выглядит одинаково — какой-то markdown, какие-то инструкции, какая разница?»

Разница большая. И если её не уловить, через месяц у тебя будет CLAUDE.md на 800 строк, в котором написано «каждый раз когда я коммичу, запусти линтер» — и оно почему-то не работает.

Я через эту путаницу прошёл сам. На SkandiKlubb и ErgonLab у меня сейчас работают все три механизма одновременно, и каждый занимается своим. Расскажу, как я для себя это разделил.

Решающее дерево за три вопроса

Когда мне приходит задача автоматизировать что-то в Claude Code, я задаю себе три вопроса по порядку:

  1. Это реакция на событие? (например — файл сохранён, команда выполнена, сессия закончилась) → нужен hook.
  2. Это повторяющаяся команда, которую я зову по имени? (например — /commit, /deploy, /review) → нужен skill.
  3. Это большая многошаговая работа, которая должна жить в своём контексте? (например — написать модуль, прогнать ревью кода, сделать исследование) → нужен subagent.

Всё. Если ни одно — значит это просто инструкция в CLAUDE.md.

Hooks: реакция без AI-мышления

Hook — это триггер «когда произошло X — выполни Y». Никакого AI, никакого размышления, просто скрипт.

У меня на ErgonLab сейчас крутятся такие хуки:

  • На сохранение .py — автоматический black.
  • На сохранение .tsxprettier.
  • На команды вроде rm -rf, git push --force — предупреждение и подтверждение.
  • На конвертацию .excalidraw файлов — автоматический экспорт в PNG.

Это не задачи для AI. Это «делай N всегда, когда случается M». Если запихнуть это в CLAUDE.md правилом «каждый раз когда я меняю .py, запусти black» — оно будет работать через раз, потому что Claude забывает или интерпретирует по-своему. Хук в settings.json работает всегда.

Признак, что нужен хук, а не правило в CLAUDE.md:

  • Действие детерминированное (не нужно «подумать»).
  • Триггер — конкретное событие.
  • Если пропустить — будет плохо (security, форматирование, валидация).

Skills: переиспользуемые сценарии под имена

Skill — это «когда я говорю слэш-команду X, выполни такой-то протокол». В отличие от хука, тут AI участвует — он читает SKILL.md, понимает контекст, применяет логику.

Мои живые skills:

  • /commit — смотрит git status + git diff, формулирует сообщение по конвенции (feat/fix/docs), ставит co-author, делает коммит.
  • /deploy — коммитит, пушит, ребилдит, копирует через rsync, перезапускает PM2.
  • /review — Playwright скриншоты ключевых страниц на 375px и 1280px.
  • /ergonlab-post — генерирует пост для канала с автоматическим подбором эмодзи из моих кастомных паков.
  • /session-save — сохраняет контекст в MEMORY.md по моему шаблону.

Раньше я каждое из этого набивал руками или копировал из старых чатов. Сейчас — одна команда.

Признак, что нужен skill:

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

НЕ нужен skill, если:

  • Делал один раз и больше не повторится.
  • Это часть большой задачи, а не самостоятельный кусок.

Subagents: многошаговая работа в своём контексте

Вот тут начинается интересное. Subagent — это специализированный исполнитель со своим набором инструкций и своим контекстным окном. Ты ему отправляешь задачу, он её делает где-то у себя, возвращает сжатый результат.

Главная фишка — не засоряет основной контекст. Если я в основном чате обсуждаю архитектуру с собой и параллельно нужно прогнать большое исследование рынка — я не хочу, чтобы в моём контексте оказались 50К токенов выдач WebSearch. Я отправляю это в web-researcher, он возвращает сводку на 500 слов.

Мои рабочие агенты:

  • backend-specialist — пишет бэкенд, работает с API и БД. На нём собран клиентский бот и SkandiKlubb.
  • frontend-specialist — UI, компоненты, адаптив. Сайт ErgonLab почти весь через него.
  • quality-guardian — код-ревью перед коммитом. Запускаю в фоне через run_in_background.
  • test-writer — генерация тестов.
  • web-researcher — конкурентный анализ. Все исследования по рынку (Avito, MCP, Replicate) собраны через него.
  • db-admin — схемы, миграции, оптимизация.

Признак, что нужен subagent:

  • Задача займёт больше 20% контекста.
  • Результат можно сжать (отчёт, список, готовый код).
  • Это самостоятельная единица работы — её можно делать отдельно от того, что я делаю прямо сейчас.

Когда они работают вместе

Самое полезное — когда три уровня собираются в одну цепочку.

Пример из работы над сайтом HealthCompanion: я пишу код компонента → срабатывает hook на сохранение, который форматирует prettier → я говорю /review-code (это skill), который запускает агента quality-guardian (subagent) → агент в своём контексте читает diff, проверяет SOLID/DRY, безопасность, возвращает короткий отчёт.

Я в основном чате получаю «всё ок» или список из 3 проблем. Никаких 2000 строк рассуждений в моём контексте.

Другой пример — /commit skill:

  1. Я говорю /commit.
  2. Skill читает CLAUDE.md проекта (там конвенция коммитов).
  3. Читает git status + git diff.
  4. Формулирует сообщение.
  5. После коммита срабатывает hook на post-commit (обновление статусов в дашборде).

Каждый слой делает своё, никто не дублирует.

Главный антипаттерн новичков

Самая частая ошибка, которую я сам совершал в первые месяцы — пытаться вместить hook-задачу в CLAUDE.md правило.

Выглядит это так:

## Правила
- Каждый раз, когда я меняю .py файл, запускай black
- После каждого коммита делай git push
- Если в diff есть console.log — удали

Это не сработает. Точнее, сработает в 70% случаев, а в оставшихся 30 — нет. Потому что AI читает CLAUDE.md как контекст, а не как императив. Он может забыть, отложить, решить, что в этом конкретном случае не нужно.

Если действие должно происходить всегда — это хук в settings.json. Точка.

Похожая ошибка с обратной стороны — пытаться сделать skill из того, что должно быть агентом. Например, skill «прогони полное код-ревью с проверкой 12 пунктов». Skill в основном контексте съест 30К токенов, и я потом сижу с раздутым окном. Это работа для агента.

Короткий чек-лист

Когда не уверен, куда положить логику — спроси:

  1. «Хочу ли я, чтобы это случилось без моей команды?» → да = hook.
  2. «Я зову это по имени и оно делает примерно одно и то же?» → да = skill.
  3. «Это работа, у которой свой контекст и которую можно делать параллельно с тем, что я обсуждаю?» → да = subagent.
  4. Ничего из этого? → просто запись в CLAUDE.md.

И обратное правило: не клади в CLAUDE.md «когда X — делай Y». CLAUDE.md — это про «что есть», а не «что делать в ответ на событие». Для второго есть отдельные слои.

Что сделать прямо сейчас

  1. Открой свой CLAUDE.md. Найди все правила в формате «каждый раз когда…», «после каждого…», «при сохранении…». Это кандидаты в хуки.
  2. Открой историю последней недели — какие три команды ты повторил больше пяти раз? Это кандидаты в skills.
  3. Найди задачу, на которой у тебя сейчас раздувается контекст до 60-70%. Это место для агента.

Дальше — по одному инструменту в неделю. Через месяц система собирается сама.

Соседние посты

Читать дальше

← Предыдущий
Subagents — параллельная работа без переполнения контекста
Следующий →
/loop dynamic — событийная автоматизация в одном окне
Все материалы
Принимаю заказы

Понравилось?
Обсудим задачу?

Напишите коротко — ответим в течение дня.

Написать в Telegram
@ergonlab_bot