Есть разговор, который, похоже, неизбежен, как только команда внедряет агентный инструмент для кодинга. «Я же написал это в CLAUDE.md — почему он всё равно так сделал?» Обычный ответ: файл разросся, и его уже никто не читает. Возможно, это правда, но настоящую проблему это упускает.
Настоящая проблема в том, что инструмент даёт несколько разных способов управлять им, и они не взаимозаменяемы. Memory-файл, skill, hook и subagent различаются тем, когда они загружаются, сколько контекста стоят, переживают ли compaction и — самое важное — являются ли они пожеланием или гарантией. Положите инструкцию не туда — и её либо проигнорируют, либо она будет сжигать контекст на каждом ходу, либо тихо исчезнет посреди длинной сессии.
Недавно Anthropic опубликовал короткую плотную статью ровно на эту тему: Steering Claude Code: skills, hooks, rules, subagents and more. Этот пост — мой инженерный синтез её и связанных статей про CLAUDE.md, hooks, skills и subagents, с моими собственными мнениями о том, где каждый механизм оправдывает своё место. Он парный к посту про AI-native SDLC, который смотрит на весь delivery-цикл издалека; здесь мы приближаемся к самому harness.
Один вопрос, который всё сортирует
Вопрос, который я задаю про любой кусок guidance:
Это знание, процедура, гарантия или отдельная работа?
- Знание — факты, которые агенту нужны почти всегда: команды сборки, структура каталогов, naming-конвенции. Это memory-файл.
- Процедура — многошаговое «как мы делаем X», которое нужно иногда: чек-лист релиза, рецепт миграции, security-ревью. Это skill.
- Гарантия — то, что должно произойти (или не должно произойти никогда) независимо от того, что решит модель: форматирование, блокировка записи в защищённые пути, отказ завершать работу, пока тесты падают. Это hook (плюс permissions).
- Отдельная работа — задача, чей промежуточный мусор вам не нужен в основном разговоре: прочитать сорок файлов ради ответа на один вопрос, непредвзятое ревью, анализ логов. Это subagent.
Большинство ошибок в управлении — это категориальные ошибки между этими четырьмя. Разберём по одному.
CLAUDE.md: всегда включённая карта
Файл памяти проекта загружается в начале каждой сессии и остаётся там. В этом его сила и его цена. Всё, что в нём есть, конкурирует за внимание на каждом ходу, включая ходы, где оно неактуально.
Туда относится то, что нужно толковому новичку в первый день и о чём он иначе спрашивал бы снова и снова: как собирать и тестировать, где что лежит, конвенции, неочевидные из кода, и проектные ловушки. Статья про CLAUDE.md формулирует это хорошо: каждая строка должна существовать потому, что она исправила реальную проблему, с которой вы действительно столкнулись, а не гипотетическую. Статья про steering даёт конкретный потолок: держите корневой файл короче 200 строк, назначьте ему владельца и ревьюйте изменения в нём как код.
Хороший корневой файл читается как лаконичная заметка для онбординга:
# CLAUDE.md
## Commands
- `npm run dev` — local server on :4321
- `npm run check` — lint + types + i18n parity. Must pass before commit.
## Layout
- App lives in `src/`, not the repo root. Content in `src/src/content/`.
## Conventions
- Every new UI string goes into all four locale files.
- Never construct canonical URLs from the request URL.
Что легко упустить:
- Файлы в подкаталогах ленивые. CLAUDE.md внутри подкаталога загружается, только когда агент читает файл из этого каталога. Это делает его дешёвым — и значит также, что после compaction он может выпасть, пока к каталогу снова не обратятся. В монорепо именно так каждая команда получает свои конвенции, не облагая налогом сессии всех остальных.
- Личным предпочтениям не место в файле проекта. Ваш любимый тон коммитов или причуды редактора идут в файл уровня пользователя. Файл проекта — для командных конвенций, специфичных для этой кодовой базы.
- Никаких секретов. Никогда. Он становится частью системного промпта; считайте его потенциально публичным.
Rules: CLAUDE.md со scope
Файлы правил в .claude/rules/ — мост между «загружается всегда» и «загружается, когда релевантно». Без scope правило ведёт себя как ещё больше CLAUDE.md. Добавьте поле paths — и оно загружается, только когда агент трогает подходящие файлы:
---
paths:
- "src/api/**"
---
All API handlers validate input with Zod before any processing.
Это правильный дом для сквозных ограничений, которые относятся к части кодовой базы — API-обработчикам, миграциям, сгенерированным клиентам — и были бы шумом везде остальном. Правило, специфичное для путей, но без path scope, — один из самых дешёвых для исправления антипаттернов.
Skills: процедуры по требованию
Skill — это папка с SKILL.md в корне — имя, описание и тело с инструкциями — плюс, опционально, скрипты, шаблоны и справочные файлы. Ключевой механизм — progressive disclosure: заранее в контексте лежат только имя и описание; тело загружается при вызове skill’а (slash-командой или потому, что агент сопоставил описание с задачей), а приложенные файлы загружаются, только если на них ссылаются инструкции. Статья-объяснялка про skills оценивает стоимость метаданных примерно в 100 токенов на skill, а полных инструкций — менее 5k токенов, поэтому можно держать много skills доступными, не перегружая окно.
---
name: release-checklist
description: Use when preparing a release or tagging a version. Bumps
the version, updates CHANGELOG, runs the full check suite, drafts notes.
---
1. Confirm the working tree is clean and on main.
2. Run `npm run check`; stop and report on any failure.
3. ...
Две вещи в этом файле важнее всего остального:
- Описание — это триггер. Это единственное, что агент видит, прежде чем решить, загружать ли skill. Пишите его как «что он делает и когда использовать», теми словами, которые люди действительно набирают. Расплывчатое описание означает, что skill либо не срабатывает никогда, либо срабатывает на всё.
- Тело — это процедура, а не эссе. Нумерованные шаги, явные условия остановки, ссылки на скрипты для всего детерминированного. Если шаг — «запусти вот эту точную команду», положите команду в скрипт, который вызывает skill, а не надейтесь, что модель восстановит её сама.
Эвристика из статьи про steering — та, которой я пользуюсь чаще всего: если вы нашли в CLAUDE.md 30-строчную процедуру, это skill, который ещё не извлекли. Она платит полную контекстную ренту на каждом ходу, чтобы пригодиться на нескольких.
Skills также комбинируются с коннекторами: MCP даёт агенту доступ к вашему issue tracker’у; skill говорит ему, как ваша команда делает triage.
Hooks: единственное, что действительно гарантировано
Вот строка, которую я бы подчеркнул во всей теме. Всё выше — CLAUDE.md, rules, skills — рекомендательное. Модель читает это и, как правило, следует. «Как правило» годится для конвенций. Не годится для «никогда не пиши в migrations/ без одобрения» или «всегда запускай форматтер».
Hooks — другого рода. Это обработчики, зарегистрированные в настройках и срабатывающие на события жизненного цикла: до запуска инструмента, после него, при старте сессии, когда агент пытается остановиться, перед compaction и так далее. Hooks типов command, HTTP и MCP-tool выполняются детерминированно: суждение модели не участвует. Хук PreToolUse, завершающийся с кодом 2, блокирует вызов инструмента, а его stderr подаётся обратно, чтобы агент понял почему.
Минимальный хук «форматировать после каждой правки» в .claude/settings.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/format.sh" }
]
}
]
}
}
Скрипт читает вход инструмента как JSON из stdin, достаёт путь к файлу и запускает ваш форматтер. Форматирование перестаёт быть тем, что агент может вспомнить; оно просто происходит.
Статья про steering формулирует правило прямо: инструкция — не ограждение. Если ваш CLAUDE.md говорит «всегда делай Y после X» — это hook. Если «никогда не делай Z» — это hook или permission-правило, а для политики на уровне организации — managed settings, которые отдельные пользователи не могут локально переопределить.
Несколько предостережений из руководства по hooks, которые я бы считал непреложными:
- Hooks работают с вашими пользовательскими правами. Это произвольный shell. Ревьюйте их как продакшен-код, берите переменные в кавычки, используйте абсолютные пути к скриптам и санитизируйте то, что приходит в stdin.
- Matchers чувствительны к регистру.
bashне совпадёт с инструментомBash. Это как раз тот баг, из-за которого ограждение молча не существует. - Не каждый hook детерминирован. Hooks типов prompt и agent используют суждение модели. Полезно, но не принимайте их за принуждение.
- Начните с одного. Руководство предлагает форматтер: низкий риск, мгновенная отдача.
Subagents: отдельный контекст для отдельной работы
Subagent — это изолированный экземпляр агента со своим окном контекста, своим системным промптом и своими правами на инструменты. Он стартует без истории вашего разговора, выполняет работу и возвращает только финальное сообщение. Эта изоляция — вся суть.
Кастомные subagents живут в .claude/agents/ (проект) или ~/.claude/agents/ (личные) как Markdown с frontmatter:
---
name: security-reviewer
description: Reviews a diff for security issues before commit. Use after
implementation, before opening a PR.
tools: Read, Grep, Glob
---
You are a security reviewer. You do not edit files. Report findings
by severity with file and line, and say explicitly if you found none.
Обратите внимание, что здесь делает работу: список инструментов только для чтения (он не может «услужливо» всё поправить) и описание, говорящее, когда делегировать, ведь именно это описание управляет автоматическим делегированием.
Статья про subagents предлагает правило, которое я нахожу по-настоящему полезным: если задача означает исследование десяти или более файлов, или у вас три и более независимых куска работы, это сильный сигнал делегировать. Другие сильные случаи — свежий взгляд (ревьюер, который никогда не видел ваших отладочных отступлений) и верификация перед коммитом.
Не менее полезно знать, когда не делегировать: последовательная работа, где каждому шагу нужен полный вывод предыдущего; параллельные правки одного и того же файла; мелкие задачи, где накладные расходы на делегирование перевешивают выгоду; и агенты, которым нужно разговаривать друг с другом. Каждый subagent сжигает свои токены — экономика токенов fan-out’а вполне реальна.
Разграничение skill и subagent в статье про steering — самое ясное из виденных мной: используйте subagent, когда промежуточные результаты засорили бы ваш разговор; используйте skill, когда хотите видеть и направлять каждый шаг.
Таблица решений
Вот всё целиком на одном экране. Колонки про загрузку и compaction взяты из статьи про steering; колонка «Для чего» — моя конденсация.
| Механизм | Загружается | После compaction | Рекомендация или принуждение | Для чего |
|---|---|---|---|---|
| Корневой CLAUDE.md | Старт сессии | Перечитывается | Рекомендация | Команды, структура, конвенции первого дня |
| CLAUDE.md в подкаталоге | Когда читается этот каталог | Теряется до следующего обращения | Рекомендация | Конвенции пакета или команды |
| Rule со scope по путям | Когда трогаются подходящие файлы | Подгружается заново | Рекомендация | Ограничения для части кодовой базы |
| Skill | Описание на старте, тело при вызове | Подгружается заново в рамках общего бюджета | Рекомендация | Процедуры, нужные иногда |
| Subagent | Описание на старте, тело при вызове | Возвращается только summary | Рекомендация (инструменты принудительны) | Изолированные, шумные или параллельные побочные задачи |
| Hook | На события жизненного цикла | Обходит compaction | Принуждение (типы command/HTTP/MCP) | Что обязано происходить и что не должно происходить никогда |
| Permissions / managed settings | Всегда | н/д | Принуждение | Жёсткие границы, политика всей организации |
Статья про steering также охватывает output styles и дописывание в системный промпт. Я бы считал оба редкими инструментами: кастомный output style заменяет стандартные инструкции для разработки ПО, если вы явно не сохраните их, а соблюдение дописанных инструкций падает по мере того, как вы навешиваете их всё больше. Если вы тянетесь к ним, чтобы решить проблему с coding-конвенцией, то почти всегда лучший дом для неё — один из механизмов выше.
Самые частые антипаттерны
Большинство из них — одна и та же ошибка, категориальная, в разных нарядах.
- Правила «никогда» в прозе. «Никогда не редактируй сгенерированные файлы» в CLAUDE.md — это надежда. Хук
PreToolUseна сгенерированном пути — это факт. - CLAUDE.md размером с роман. Процедуры, история, обоснования и каждый когда-либо усвоенный урок — всё загружается на каждом ходу. Вынесите процедуры в skills, path-специфичные куски в rules со scope и удалите всё, что больше не исправляет реальную проблему.
- Rules без scope. Правило про миграции базы данных, которое загружается, пока кто-то правит CSS.
- Subagent на всё. Статья про subagents прямо говорит, что слишком много кастомных агентов делает автоматическое делегирование менее надёжным; большинству команд хватает горстки хорошо ограниченных.
- Расплывчатое делегирование. «Изучи кодовую базу» — это не задача. «Найди каждое место вызова
X, выведи файл и строку, не редактируй» — задача. - Skills с расплывчатыми описаниями. Если описание не говорит когда, агент не может решить, загружать ли его.
- Личные предпочтения в командном файле. Теперь в сессиях у всех — вкус одного человека.
- Автоматизация до того, как паттерн ясен. Писать hooks и агентов для workflow, который никто ещё не выполнил руками хотя бы три раза. Начинайте в разговоре; кодифицируйте, когда знаете, что именно кодифицируете.
Где я бы был осторожен
- Это продуктовые детали, и они меняются. Названия файлов, событий, поля frontmatter и цифры по токенам здесь взяты из статей Anthropic на момент написания и изменятся. Паттерн — всегда включённая память, rules со scope, процедуры по требованию, детерминированные hooks, изолированные исполнители — вот долговечная часть. У других инструментов есть свои аналоги (файл
AGENTS.md, редакторские файлы правил и так далее); я бы сопоставлял категории, а не предполагал, что семантика совпадает один в один. - Рекомендательное — не бесполезное. «Skills советуют, hooks принуждают» можно переусвоить до «важны только hooks». Большая часть того, что делает агента хорошим на вашей кодовой базе, — это знание и процедура, которые могут быть только рекомендательными. Hooks — страховка, а не стратегия.
- Hooks — это код с вашими правами. Плохо написанный hook — новая поверхность атаки, а конфиг hook’а, добавленный коллегой, — это код, который вы вот-вот запустите. Ревьюйте соответственно.
- Ваш harness регрессирует. Каждая правка CLAUDE.md, skill’а или hook’а меняет поведение агента. Без какой-то формы evals на реальных задачах вы настраиваете по ощущениям. И всё это по-прежнему контекст-инжиниринг — механизмы лишь по-разному отвечают на вопрос, когда модель видит что.
Как бы я это внедрял
Если бы я с нуля настраивал команду, то в таком порядке:
- Сначала CLAUDE.md. Запустите
/init, затем жёстко сократите: команды, структура, неочевидные конвенции. Назначьте владельца. Рабочее правило: когда агент делает одну и ту же ошибку дважды, добавьте поправку — одной строкой. - Один hook. Форматтер на
PostToolUse. Затем блокировкаPreToolUseна пути, которых нельзя трогать без человека. Повысьте каждое предложение с «никогда» из CLAUDE.md до hook’а или permission. - Ограничьте scope тому, что относится лишь к части. Перенесите path-специфичные конвенции в rules с
paths, а конвенции пакетов — в файлы подкаталогов. - Извлеките первые skills. Ищите процедуры, которые вы постоянно вставляете или которые раздувают CLAUDE.md, — релиз, миграция, описание PR. Пишите точные описания. Два-три хороших skill лучше двадцати спекулятивных.
- Добавьте два-три subagent’а. Researcher только для чтения, reviewer только для чтения, может быть verifier, который запускает приложение и докладывает, не исправляя. Пользуйтесь ими в разговоре, прежде чем полагаться на автоматическое делегирование.
- Упакуйте и введите governance. Когда настройка стабильна, соберите skills, агентов и hooks в plugin, чтобы команда делилась одной версией, а политику, которая должна держаться, вынесите в managed settings.
Карьерный угол
Здесь вырисовывается тихий новый навык: проектирование harness. Это не написание промптов. Это ближе к platform engineering: решать, какое знание фоновое, какое по требованию, какое принудительное, а что выполняется в изоляции, и затем поддерживать эту конфигурацию отревьюенной, версионируемой и протестированной, как любой другой код. Те, кто в этом хорош, улучшают сессии с агентом у всех вокруг, а поскольку навык про категории, а не про синтаксис, он переносится на любой следующий инструмент.
Углубляясь
Если хотите попрактиковаться на реальной кодовой базе, Claude Code Mastery hands-on проходит ежедневный цикл и весь набор инструментов управления — memory-файлы, skills, hooks и subagents. AI-Native SDLC помещает этот harness в управляемый жизненный цикл delivery, с evals на самой конфигурации агента. Для upstream-дисциплины, благодаря которой всё это работает лучше, см. Spec-Driven Development Foundations и OpenSpec Mastery. А если хотите строить собственных агентов на тех же примитивах, следующий шаг — Claude Agent SDK.
Источники: Anthropic, Steering Claude Code: skills, hooks, rules, subagents and more; Using CLAUDE.md files; How to configure hooks; Skills explained; The complete guide to building skills for Claude; Subagents in Claude Code. Этот пост — независимый комментарий; детали продукта могли измениться с момента публикации, так что сверяйтесь с оригиналами. Связанное в этой серии: AI-native SDLC, контекст-инжиниринг, evals, Claude Code в продакшене.