> · 8 мин

CLAUDE.md — как написать файл, который Claude Code реально слушается

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.

Как попробовать

  1. Создайте CLAUDE.md в корне проекта. Начните с 5 пунктов: стек, команды для тестов/билда, 2-3 конвенции, которые Claude нарушает чаще всего

  2. Запустите Claude Code и дайте задачу. Проверьте: "What rules from CLAUDE.md apply here?"

  3. Вынесите специфичные правила в .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
  1. Добавьте CLAUDE.local.md для личных настроек (auto-добавится в .gitignore):
- My test DB: postgresql://localhost:5432/mydb_dev
- Sandbox URL: http://localhost:3000
  1. Закоммитьте CLAUDE.md и .claude/rules/ в git — файл накапливает ценность со временем, когда вся команда его дополняет
$ ls ./related/

Похожие статьи

subscribe.sh

$ cat /dev/blog/updates

> Свежие заметки о программировании,

> DevOps и AI — прямо в мессенджер

./subscribe