English version

Автор: abavyka

Він згадувався в кожному пості: правила, що переживають compact, версії стеку проти галюцинацій, команди перевірки.

Що це

CLAUDE.md — звичайний markdown з інструкціями, які ти, або команда пише самостійно. Claude Code читає його на старті кожної сесії. На відміну від auto memory, де нотатки веде сам Claude, тут усе руками: команди збірки, конвенції, «завжди роби X».

Це контекст, а не конфіг. Вміст приходить як повідомлення після system prompt, і Claude намагається його виконувати, але гарантії нема. Якщо щось треба заборонити жорстко — це хуки або permissions, не CLAUDE.md.

Де лежить

  • Managed policy — для всієї організації, кладе IT (на macOS /Library/Application Support/ClaudeCode/CLAUDE.md)
  • ~/.claude/CLAUDE.md — глобальний, для всіх проєктів
  • ./CLAUDE.md або ./.claude/CLAUDE.md — проєктний, комітиться і шариться з командою
  • ./CLAUDE.local.md — твій особистий для цього проєкту, кладеться в .gitignore

Вони не перекривають один одного, а склеюються. Порядок — від кореня файлової системи до папки, де запустив Claude, і в кожній папці CLAUDE.local.md йде після CLAUDE.md. Виходить, що файл з папки, де ти запустив Claude, потрапляє в контекст останнім, після всіх файлів з папок вище. CLAUDE.md у підпапках вантажаться не на старті, а коли Claude вперше полізе у файли тієї підпапки.

Перевірити, що реально завантажилось: /context, список Memory files.

Що писати, а що ні

Дока радить додавати в CLAUDE.md, коли:

  • Claude вдруге робить ту саму помилку
  • на рев’ю ловиш те, що він мав знати про цей код
  • пишеш у чат те саме виправлення, що й минулої сесії
  • новому розрабу в команді знадобився б той самий контекст

Писати конкретно, так щоб можна було перевірити: «запускай npm test перед комітом» замість «тестуй зміни». Групувати під заголовками і списками.

Розмір — до 200 рядків на файл. Довший файл їсть більше контексту і гірше виконується.

Чого не писати: того, що Claude і так бачить з коду — дерево папок, список залежностей, огляд архітектури. /doctor саме таке й пропонує вирізати, а лишити підводні камені, пояснення «чому» і конвенції, які відрізняються від дефолтних.

Багатокрокові процедури — у skill. Правила лише для частини коду — у path-scoped rules (про них нижче).

І його треба періодично рефакторити: прибирати застаріле і суперечливе. Якщо два правила суперечать одне одному, Claude може вибрати будь-яке. /doctor prompt-audit сам знайде застарілі інструкції, посилання на неіснуючі файли і суперечності, а правки застосує тільки коли попросиш.

Як вийшло у мене (на пет-проєкті): CLAUDE.md на 14 рядків, а в ньому @RULES.md на 292 рядки, з деревом src/ і server/src/ всередині. Тобто все, від чого дока відмовляє.

Прогнав на ньому /doctor prompt-audit. З основного:

  • У RULES.md вже застаріли цифри і номери рядків: «24 з 60 хендлерів» — а хендлерів уже 62, database.ts:60 переїхав на :68, а папки, яку правило описує як порожню, взагалі нема
  • Правило посилається на одну міграцію 001_schema.sql, а їх уже вісім
  • Ремарка «бери список з файлової системи, а не з памʼяті» — латка після помилки в одній сесії, сам список поруч правильний. Порада: видалити
  • П’ять skills лежали плоскими файлами в .claude/skills/ замість <name>/SKILL.md, тож жоден із них не вантажився

Кожна знахідка з упевненістю і готовим diff, але нічого не застосовано, поки не скажеш. Конкретні цифри й номери рядків у CLAUDE.md старіють з кожним комітом, краще писати правило і команду, якою це перевірити.

Що ще підключають

Імпорти: @path/to/file будь-де в CLAUDE.md підтягує файл у контекст. Шлях рахується від файлу з імпортом, а не від робочої папки. Вкладеність до чотирьох рівнів. Якщо треба просто згадати шлях без імпорту — у бектіки: `@README`.

Rules: файли в .claude/rules/, одна тема на файл (testing.md, api-design.md). Звичайний файл з правилами вантажиться на старті разом із CLAUDE.md і висить у контексті всю сесію. Але на початку файлу можна вказати paths: з шаблоном, наприклад server/**/*.ts. Тоді правила підтягнуться тільки коли Claude відкриє чи змінить файл, що під цей шаблон підпадає. Не чіпав бекенд — правил для бекенду в контексті нема. Ось це реально економить контекст. Особисті правила для всіх проєктів — у ~/.claude/rules/.

AGENTS.md — якщо в команді різні агенти. Claude Code читає його сам, але за замовчуванням тільки коли поруч нема CLAUDE.md чи CLAUDE.local.md. Хочеш і те, і те — або @AGENTS.md першим рядком у CLAUDE.md, або в /config поставити Project instructions = claude-md-and-agents-md.

Дрібниця, але корисна: HTML-коментарі <!-- ... --> вирізаються перед відправкою в контекст. Нотатки для людей токенів не їдять.

Особисте, що не має потрапити в репо

  • ~/.claude/CLAUDE.md і ~/.claude/rules/ — для всього, що стосується тебе, а не проєкту
  • CLAUDE.local.md + .gitignore — особисте для одного проєкту
  • Якщо працюєш у кількох git worktrees, CLAUDE.local.md буде лише в тому, де створив. Тоді краще імпорт з домашньої папки: @~/.claude/my-project-instructions.md. Перший раз Claude Code покаже діалог підтвердження для таких зовнішніх імпортів
  • .git/info/exclude — як .gitignore, тільки локальний: не комітиться і нікому не видно. Зручно, коли не хочеш навіть .gitignore чіпати. Тільки на файли, які git вже трекає, не діє

Як у мене: в іншому репо лежить мій CLAUDE.md на 4 рядки — три @-імпорти моїх тулів, і все це в .git/info/exclude. Поруч AGENTS.md, який я колись клав, поки тестував інші агенти. Прикол у тому, що CLAUDE.md його не імпортує, тож за замовчуванням Claude цей AGENTS.md просто не бачить.

Підводні камені

  • Імпорт не економить контекст. Він допомагає організувати файл, але імпортоване вантажиться на старті цілком. Економлять тільки rules з paths:
  • Правки CLAUDE.md посеред сесії не застосовуються. Claude працює зі старою версією до /clear, /compact або перезапуску
  • CLAUDE.md — порада, а не гарантія. Що критично — хуки
  • CLAUDE.local.md в проєкті з AGENTS.md вимикає читання AGENTS.md. Лікується тим самим налаштуванням Project instructions

Як почати з нуля

  • /init — Claude пройдеться по кодбейсу і згенерує CLAUDE.md з командами збірки, тестів і конвенціями. Якщо файл уже є, запропонує покращення, а не перезапише
  • З CLAUDE_CODE_NEW_INIT=1 /init інтерактивний: спитає, що налаштувати (CLAUDE.md, skills, hooks), дорозпитає і покаже пропозицію перед записом
  • Далі доповнюєш тим, чого Claude сам не знайде. І чистиш те, що він знайде і так
  • /memory — список усіх файлів інструкцій, відкрити й відредагувати

Приклад для TS

Умовний проєкт: фронт у web/, бекенд у server/.

CLAUDE.md:

@AGENTS.md
 
## Commands
- `npm run typecheck && npm test` after every change
- `npm run dev` starts web and server together
 
## Conventions
- Strict TypeScript, no `any`; types from `const` arrays, not manual unions
- No hardcoded UI strings, only `t('key')`
- Never edit generated files in `src/gen/`
 
## Gotchas
- Server tests need a local Postgres: `docker compose up db`

.claude/rules/api.md — вантажиться тільки коли Claude торкається бекенду:

---
paths:
  - "server/**/*.ts"
---
# API rules
- Validate every request body at the route
- Throw typed errors, never a raw `Error`
- Route handlers stay thin: parse, call one service, respond

Окремо розповім про свої тули — rtk і локальний code graph MCP.

Почитати