CLAUDE.md — как написать файл, который Claude Code реально слушается
CLAUDE.md — как написать файл, который Claude Code реально слушается
Claude Code — штука мощная, но без памяти. Каждая новая сессия — чистый лист: он не помнит ваш стек, конвенции, любимые команды. CLAUDE.md решает эту проблему — файл загружается автоматически в начале каждого разговора и даёт Claude контекст, который он не может вытащить из кода сам.
Проблема в том, что большинство CLAUDE.md файлов не работают. Claude их читает, но не следует. По данным SFEIR Institute, файлы до 200 строк показывают compliance rate выше 92%, а после 400 строк — всего 71%. Разница между «Claude делает как надо» и «Claude делает как хочет» — в том, как вы пишете этот файл.
TL;DR: Claude Code следует примерно 150 инструкциям — а системный промпт уже забирает ~50. На ваш CLAUDE.md остаётся 100-150 правил. Пишите коротко, императивами, используйте progressive disclosure через
@importsи.claude/rules/. Ниже — 6 конкретных правил с примерами.
Правило 1: Меньше — значит лучше
Фронтирные LLM стабильно следуют ~150-200 инструкциям. У Claude Code системный промпт уже содержит ~50 инструкций — значит ваш CLAUDE.md конкурирует за оставшиеся слоты.
Что происходит при перегрузке:
- До 200 строк — compliance rate 92%+
- 200-400 строк — начинается деградация, особенно правила из середины файла
- 400+ строк — правила игнорируются молча, compliance падает до 71%
Причём деградация затрагивает все инструкции равномерно, не только новые. LLM смещают внимание к началу и концу промпта — середина теряется. Борис Черни, создатель Claude Code, рекомендует постоянно ревизировать файл: удалять устаревшее, объединять дубли, затачивать формулировки.
Хороший ориентир — 60-150 строк. CLAUDE.md команды HumanLayer, которые написали подробный гайд по теме, — всего ~60 строк.
Правило 2: Императивы, а не описания
Claude Code интерпретирует императивы как обязательные инструкции, а описания — как информацию к сведению. Разница огромная:
# ❌ Описание (Claude может проигнорировать) The project uses functional components and ES modules. We prefer named exports over default exports. # ✅ Императив (Claude выполняет) - Use functional components, not class components - Use ES modules (import/export), not CommonJS (require) - Use named exports, not default exports
Каждая строчка должна отвечать на вопрос: «Если убрать это правило, Claude начнёт делать ошибки?» Если нет — удаляйте. По рекомендациям официальной документации, не стоит писать то, что Claude и так знает (стандартные конвенции языка) или может вывести из кода (структура проекта, если она типовая).
Правило 3: Структура WHY / WHAT / HOW
Вместо хаотичного списка правил используйте фреймворк из гайда HumanLayer:
# MyProject One-sentence: SaaS billing dashboard on Next.js 15 + Stripe. ## WHAT — стек и структура - Runtime: Node 22, package manager: bun - Framework: Next.js 15 (App Router) - DB: PostgreSQL via Drizzle ORM - Tests: Vitest + Playwright ## HOW — как работать - Run tests: `bun test` - Run single test: `bun test path/to/file` - Typecheck: `bun run typecheck` - Lint before commit: `bun run lint:fix` ## Conventions - Use functional components with TypeScript - Prefer server components, use 'use client' only when needed - API routes return `NextResponse.json()` - Error handling: throw custom AppError, catch in middleware ## Gotchas - Stripe webhooks require raw body — don't use JSON middleware on /api/webhooks - Drizzle migrations: `bun run db:push`, NOT `db:migrate` (push for dev)
Обратите внимание: никаких абзацев текста, никаких объяснений «почему мы выбрали Next.js». Только то, что Claude нужно прямо сейчас, чтобы не наломать дров.
Правило 4: Progressive disclosure через @imports
Главная ошибка — пытаться впихнуть всё в один файл. Официальная документация Claude Code поддерживает @path/to/file синтаксис для импортов:
# CLAUDE.md See @README.md for project overview. See @docs/api-conventions.md for API design rules. See @docs/git-workflow.md for branch and commit conventions. ## Core rules - Use bun, not npm - Run `bun test` before committing - Prefer server components
Claude загрузит импортированные файлы только если они релевантны текущей задаче. Импорты поддерживают рекурсию до 5 уровней вложенности и работают с относительными и абсолютными путями.
Ещё мощнее — .claude/rules/ директория. Файлы из неё загружаются автоматически, а через paths в YAML frontmatter можно привязать правила к конкретным файлам:
# .claude/rules/api-routes.md --- paths: - "src/api/**/*.ts" --- - All API endpoints must validate input with Zod - Return standardized error format: { error: string, code: number } - Include OpenAPI comments for documentation
Эти правила активируются только когда Claude работает с файлами из src/api/. Правила для React-компонентов не засоряют контекст при работе с API — и наоборот. Структура для среднего проекта:
.claude/
├── CLAUDE.md # 60-100 строк, ядро
└── rules/
├── frontend/
│ ├── react.md # React-конвенции
│ └── styles.md # CSS/Tailwind правила
├── backend/
│ ├── api.md # API endpoints
│ └── database.md # Drizzle/Prisma правила
└── testing.md # Тестовые конвенции
Правило 5: Иерархия памяти — 6 уровней
Claude Code загружает CLAUDE.md файлы из нескольких мест, и у каждого своя роль:
- Managed policy (
/Library/Application Support/ClaudeCode/CLAUDE.md) — корпоративные стандарты от IT, высший приоритет - Project memory (
./CLAUDE.mdили./.claude/CLAUDE.md) — общие правила проекта, расшарены через git - Project rules (
./.claude/rules/*.md) — модульные правила по темам - User memory (
~/.claude/CLAUDE.md) — ваши личные предпочтения для всех проектов - Project local (
./CLAUDE.local.md) — личные настройки для конкретного проекта (auto-добавляется в.gitignore) - Auto memory (
~/.claude/projects/<project>/memory/) — заметки, которые Claude пишет сам
Более специфичные файлы перекрывают общие. CLAUDE.local.md идеален для вещей вроде «мой sandbox URL» или «мои тестовые данные» — того, что не нужно коммитить.
Отдельно про auto memory: Claude сам записывает паттерны, решения дебаггинга и архитектурные заметки в ~/.claude/projects/<project>/memory/MEMORY.md. Первые 200 строк этого файла загружаются в каждую сессию. Если хотите, чтобы Claude запомнил что-то конкретное, просто скажите: "remember that we use pnpm, not npm".
Правило 6: Проверяйте, что Claude действительно следует правилам
Самый неприятный gotcha: Claude не всегда автоматически обращается к CLAUDE.md при выполнении задач. По наблюдениям Maxitect, Claude может прочитать файл в начале сессии и «забыть» через 2-5 промптов — особенно когда контекст забивается кодом и выводом команд.
Что помогает:
- Добавьте
IMPORTANTилиYOU MUSTк критичным правилам — официальная документация подтверждает, что усиление формулировок повышает adherence - Для правил без исключений используйте hooks вместо CLAUDE.md — hook на PostToolUse запустит линтер после каждого редактирования файла, а не «когда Claude вспомнит»
- Периодически проверяйте:
"What specific standards from CLAUDE.md apply to this code?" - Совет от Бориса Черни: после каждого исправления говорите
"Update your CLAUDE.md so you don't make that mistake again"— Claude неплохо справляется с написанием правил для самого себя
Подводные камни
CLAUDE.md раздувается незаметно. Вы добавляете правило за правилом после каждой ошибки — и через месяц файл весит 500 строк, а Claude игнорирует половину. По баг-репортам на GitHub, это самая частая причина жалоб «Claude не следует инструкциям». Решение: ревизия раз в 1-2 недели, безжалостное удаление.
Auto-generated CLAUDE.md через /init — ловушка. Команда /init анализирует кодовую базу и генерирует стартовый файл. Звучит удобно, но HumanLayer предупреждает: автогенерация создаёт раздутый файл с очевидностями, которые Claude и так знает. CLAUDE.md — самый важный рычаг настройки агента, его стоит писать вручную. Если используете /init, сразу сократите результат в 3-4 раза.
Правила для линтинга в CLAUDE.md — антипаттерн. Код-стиль и форматирование — работа для детерминистических инструментов (Biome, ESLint, Prettier). Как формулирует HumanLayer: «Never send an LLM to do a linter's job». Вместо правила «Use 2-space indentation» настройте hook, который запускает prettier --write после каждого файлового изменения.
Claude.md в поддиректориях загружается не сразу. Файлы из дочерних директорий подгружаются on-demand — только когда Claude работает с файлами из этих папок. Если вы ожидаете, что src/api/CLAUDE.md будет действовать с начала сессии — он не будет. Правила, нужные всегда, должны быть в корневом файле.
Первое одобрение @imports — или никогда. При первом запуске Claude Code показывает диалог одобрения для внешних импортов. Если вы нажали «Decline», диалог больше не появится, и импорты останутся отключёнными навсегда для этого проекта. Из документации — это one-time decision.
Вердикт
Из всех настроек Claude Code — CLAUDE.md даёт самый большой эффект при минимальных усилиях. Но только если файл короткий (60-150 строк), написан императивами, и тяжёлая работа вынесена в .claude/rules/ с привязкой к путям. Честная оценка: compliance rate 92%+ для коротких файлов — отличный результат, но не 100%. Для критических правил без исключений используйте hooks, а не CLAUDE.md.
Как попробовать
-
Создайте
CLAUDE.mdв корне проекта. Начните с 5 пунктов: стек, команды для тестов/билда, 2-3 конвенции, которые Claude нарушает чаще всего -
Запустите Claude Code и дайте задачу. Проверьте:
"What rules from CLAUDE.md apply here?" -
Вынесите специфичные правила в
.claude/rules/:
mkdir -p .claude/rules
# .claude/rules/react.md --- paths: - "src/components/**/*.tsx" --- - Use functional components with TypeScript - Extract hooks into custom hooks when reused 2+ times - Props interface name = ComponentNameProps
- Добавьте
CLAUDE.local.mdдля личных настроек (auto-добавится в.gitignore):
- My test DB: postgresql://localhost:5432/mydb_dev - Sandbox URL: http://localhost:3000
- Закоммитьте
CLAUDE.mdи.claude/rules/в git — файл накапливает ценность со временем, когда вся команда его дополняет