Настройка
Хуки Claude Code: правила, которые агент не может пропустить
Скопируй страницу и вставь в Claude или GPT — разберёт под твою задачу.
Ты записал в CLAUDE.md «всегда запускай тесты перед коммитом». Неделю агент слушался, а сегодня закоммитил без тестов — и даже не заметил. Это не поломка: CLAUDE.md — просьба, а любая просьба к модели выполняется с вероятностью, не с гарантией. Когда правило важное настолько, что «почти всегда» не устраивает, нужен другой механизм — хук. Хук не просит, а срабатывает: это команда, которую Claude Code выполняет сам на определённом событии, хочет того модель или нет. Ниже — как они устроены, куда их писать и три хука, с которых стоит начать.
Короткий ответ
Хук — это shell-команда, привязанная к событию в работе Claude Code: агент собрался выполнить инструмент, закончил правку, завершил ответ. Наступило событие — команда выполнилась автоматически. В отличие от правила в CLAUDE.md, хук нельзя «забыть» или проигнорировать: это не текст для модели, а механика самого Claude Code.
Настраиваются хуки в файле настроек — .claude/settings.json в проекте (или ~/.claude/settings.json глобально), а посмотреть и отредактировать их можно командой прямо в сессии:
/hooks
Простейший пример — звуковое уведомление, когда агент закончил работу и ждёт тебя:
{
"hooks": {
"Stop": [
{
"hooks": [
{ "type": "command", "command": "afplay /System/Library/Sounds/Glass.aiff" }
]
}
]
}
}
Запустил долгую задачу, ушёл за кофе — сигнал скажет, когда агент освободился.
Что понадобится
- Установленный Claude Code (команда
claudeработает в терминале). - Понимание, что хук — это НАСТОЯЩАЯ команда в твоей системе. Она выполнится с твоими правами. Это сила и риск одновременно — про риск ниже отдельно.
- Пять минут и один сценарий, который тебя реально достал: «агент опять сделал X». С него и начнём.
Чем хук отличается от правила в CLAUDE.md
Это главный вопрос, и на нём держится всё. CLAUDE.md читает модель. Она старается следовать правилам — и в основном следует. Но модель работает с вниманием, а внимание размывается: длинная сессия, распухший контекст, двадцать правил, из которых половина «важные», — и вот твоё «всегда» превратилось в «обычно».
Хук модель не читает. Его выполняет сам Claude Code — программа, а не нейросеть. Наступило событие — команда выполнилась. Сессия может быть какой угодно длинной, контекст каким угодно грязным: на срабатывание хука это не влияет никак.
Отсюда простое правило разделения:
- Пожелания и стиль — в CLAUDE.md: «комментарии по-русски», «объясняй коротко», «предпочитай такой-то подход». Если один раз из ста агент отступит — не страшно.
- Гарантии — в хуки: «этот файл не трогать никогда», «после каждой правки — автоформат», «завершил ход — просигналь». Здесь «один раз из ста» недопустим.
Ключевая мысль: CLAUDE.md — это инструктаж сотруднику, хук — это турникет на проходной. Инструктаж можно прослушать вполуха. Через турникет вполуха не пройдёшь.
На каких событиях срабатывают хуки
Событий у Claude Code больше десятка — полный список всегда в официальной доке, он пополняется. Вот ключевые, которыми ты реально будешь пользоваться:
- SessionStart — старт сессии. Подгрузить окружение, напомнить агенту состояние дел.
- UserPromptSubmit — когда ты отправил сообщение. Можно дописать контекст к запросу — или заблокировать сам запрос, не дав ему уйти в модель.
- PreToolUse — перед тем, как агент выполнит инструмент (запустит команду, отредактирует файл). Здесь живут запреты: хук проверяет, что агент собрался сделать, и может заблокировать действие.
- PostToolUse — после того, как инструмент отработал. Место для автоматики вслед: форматирование после правки, запуск линтера. Важный нюанс — событие срабатывает уже ПОСЛЕ выполнения, отменить сделанное оно не может.
- Stop — агент закончил ход и ждёт тебя. Уведомления, финальные проверки — вплоть до того, чтобы заставить агента продолжить работу.
- SubagentStop — субагент завершил свою подзадачу. То же, что Stop, но для параллельного агента.
- PreCompact — перед тем, как Claude Code сожмёт контекст. Момент сохранить важное, пока история не ужалась.
- Notification — агент шлёт уведомление (например, ждёт твоего решения). Удобно перекинуть в свой канал оповещений.
Не все события умеют блокировать. Останавливать ход могут четыре: PreToolUse (заблокировать вызов инструмента), UserPromptSubmit (не пропустить твой запрос), Stop и SubagentStop (заставить агента не останавливаться, а работать дальше). Остальные — реагируют на событие, но не отменяют его.
Как хук блокирует: коды выхода
Управляет всем код выхода команды хука — то самое число, которое процесс возвращает, завершившись. Правило короткое:
- Код 0 — всё в порядке, продолжаем. Хук отработал, действие агента идёт своим чередом.
- Код 2 на PreToolUse — вызов инструмента БЛОКИРУЕТСЯ. Агент не выполнит команду или правку, а текст ошибки хука увидит как объяснение — и поменяет план. Так запрет становится физическим, а не словесным.
- Код 2 на Stop — наоборот, заставляет агента ПРОДОЛЖИТЬ работу. Он собрался закончить ход, а хук говорит «рано» — и агент возвращается к делу. Тем же кодом на PreToolUse ты действие останавливаешь, а на Stop — не даёшь остановиться. Смысл кода зависит от события.
Отсюда и вся сила механизма: одно число решает, пройдёт действие или нет, — и решает не модель, а команда, которую написал ты.
Структура в settings.json и матчеры
В файле настроек хуки лежат под ключом hooks. Каждое событие — это массив блоков, у каждого блока свой матчер (какие случаи ловить) и список команд:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "python3 .claude/guard.py" }
]
}
]
}
}
Матчер работает по-разному в зависимости от события. Для инструментальных событий (PreToolUse, PostToolUse) он фильтрует по ИМЕНИ ИНСТРУМЕНТА: Bash — только команды в терминале, Edit|Write — правки и создание файлов, mcp__.* — любой инструмент из MCP-сервера. Для SessionStart матчер ловит не инструмент, а то, КАК стартовала сессия: startup (обычный запуск), resume (продолжение), clear (после /clear), compact (после сжатия). У событий без вариантов (например, Stop) матчер можно опустить — хук ловит их всегда.
Три хука, с которых стоит начать
1. Защита файлов, которые нельзя трогать. У каждого проекта есть зона «руки прочь»: конфиг прода, папка с данными, .env. Хук на PreToolUse проверяет путь файла в действии агента и блокирует правку кодом 2, если путь в запретном списке. Правило в CLAUDE.md агент может забыть — этот хук не забудет ни разу.
2. Автоформат после каждой правки. Хук на PostToolUse запускает форматтер (prettier, black — что у тебя) на файле, который агент только что изменил. Код всегда в едином стиле, и в диффах не мелькает мусор из пробелов. Агент даже не тратит на это внимание — формат происходит «за кадром».
3. Сигнал о завершении. Хук на Stop из «Короткого ответа» выше. Звучит несерьёзно, а по факту меняет режим работы: перестаёшь сидеть и смотреть на терминал, спокойно занимаешься другим — агент сам позовёт.
С этих трёх видно общий паттерн: хук снимает с тебя роль надзирателя. Не «следить, чтобы агент не трогал конфиг», а «он физически не может его тронуть».
Как добавить хук
Самый простой путь — команда /hooks прямо в сессии: она показывает настроенные хуки и помогает добавить новый по шагам. Второй путь — руками в settings.json по структуре выше: событие → матчер → команда.
Где держать:
.claude/settings.jsonв проекте — хуки этого проекта, едут в git вместе с командой.~/.claude/settings.json— твои личные, работают во всех проектах.
После правки настроек перезапусти сессию — как и всё в Claude Code, хуки подхватываются на старте.
Безопасность: хук — это код с твоими правами
Тут без обиняков. Хук — произвольная shell-команда, которая выполняется автоматически, без подтверждения, с правами твоего пользователя. Это значит две вещи.
Первая: не копируй чужие хуки не глядя. Конфиг с хуками из интернета — это чужой код, который будет запускаться у тебя при каждом событии. Прочитай команду и пойми, что она делает, прежде чем вставлять.
Вторая: помни, что хуки проекта лежат в .claude/settings.json и приезжают с репозиторием. Открыл чужой проект — посмотри, какие там хуки, до того как запускать в нём Claude Code.
Внимание: сила хука в том, что он выполняется всегда и без вопросов. Ровно поэтому единственный фильтр — твоя голова на этапе настройки. Пиши хуки сам, чужие — читай построчно.
Частые ошибки
| Симптом | Причина | Что сделать |
|---|---|---|
| Хук добавил, а он не срабатывает | Настройки подхватываются на старте сессии | Перезапусти Claude Code, проверь /hooks |
| Хук срабатывает на всё подряд | Матчер слишком широкий | Сузь матчер до нужного инструмента: Bash, Edit|Write, а не пусто |
| Ждал, что PostToolUse отменит правку, — не отменил | Событие срабатывает уже после выполнения инструмента | Для запрета бери PreToolUse с кодом 2 — он ловит действие ДО выполнения |
| Агент «упирается» и не может работать | Блокирующий хук на PreToolUse режет лишнее | Посмотри текст ошибки хука, ослабь условие или сузь матчер |
| Всё дублируется в CLAUDE.md и хуках | Непонимание разделения | Стиль и пожелания — в CLAUDE.md, гарантии — в хуки |
FAQ
Чем хук лучше правила в CLAUDE.md?
Он не лучше — он про другое. Правило выполняется моделью с высокой вероятностью, хук выполняется программой со стопроцентной. Важное настолько, что сбой недопустим, — переноси из текста в хук.
Хуки — это только для программистов?
Нет. Самые полезные хуки бытовые: сигнал о завершении, запрет трогать папку, автосохранение. Одна команда в конфиге — не программирование, а настройка. Собрать хук помогает и сам агент через /hooks.
Может ли хук сломать мне систему?
Хук выполняет ровно ту команду, которую ты в него записал, с твоими правами. Сам по себе — нет. Бездумно скопированный чужой — может. Отсюда правило: свои пиши, чужие читай.
Что выбрать: хук или скилл?
Скилл — это процедура, которую агент выполняет, когда ты его просишь. Хук — автоматика, которая срабатывает сама на событии. «Как делать задачу» — скилл, «что происходит всегда» — хук.
Итог
Хук — это shell-команда на событии Claude Code: SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, Stop и другие; полный список — в доке. В отличие от правил в CLAUDE.md, хук выполняется не моделью, а самой программой — его нельзя забыть или проигнорировать. Настраивается в settings.json (событие → матчер → команда) или через /hooks. Блокировать умеют PreToolUse, UserPromptSubmit, Stop и SubagentStop, а решает всё код выхода: 2 на PreToolUse режет действие, 2 на Stop, наоборот, гонит агента работать дальше. Начни с трёх хуков: защита запретных файлов, автоформат после правок, сигнал о завершении. И помни про природу инструмента: хук — код с твоими правами, поэтому свои — пиши, чужие — читай построчно.
Хуки держат агента в рамках, пока он работает один. А как заставить работать НЕСКОЛЬКИХ агентов и когда это вообще нужно — тема про субагентов, следующий уровень той же лестницы.