Настройка CLAUDE.md для Claude Code
Разбираем, как файл CLAUDE.md на базе идей Андрея Карпаты помогает сделать работу Claude Code более предсказуемой и эффективной при написании кода.
Зачем Claude Code нужны инструкции
Проблема непредсказуемого поведения LLM
Когда я впервые начал использовать Claude Code в своих проектах, я столкнулся с классической проблемой: модель ведет себя слишком «творчески». В теории агентные системы должны следовать логике проекта, но на практике LLM часто пытается внедрить свои собственные паттерны, которые противоречат архитектуре, заложенной в репозитории.
Представьте ситуацию: вы просите Claude Code добавить новый эндпоинт в API. Вместо того чтобы использовать уже настроенный в проекте слой валидации или стандартный формат обработки ошибок, модель начинает писать новый код «с нуля», используя другие библиотеки или стилистику. В итоге вместо чистого кода вы получаете технический долг, который придётся разгребать вручную.
С практической точки зрения, эта непредсказуемость возникает из-за того, что у модели нет жестких рамок. Без внешних инструкций Claude Code опирается только на то, что видит в текущем контексте файлов. Если проект большой, модель может просто не «увидеть» специфические правила, которые вы считаете само собой разумеющимися. Это делает автоматизацию кодинга рискованной: вместо экономии времени вы тратите его на проверку того, не нарушил ли агент базовые принципы вашего проекта.
Роль контекста в автоматизации кодинга
Чтобы превратить Claude Code из простого чат-бота в предсказуемого участника процесса разработки, ему нужен контекст, который не меняется от запроса к запросу. Здесь на помощь приходит концепция, популяризированная Андреем Карпатой, где акцент делается на передаче модели четких инструкций о том, как именно нужно взаимодействовать с кодовой базой.
Файл CLAUDE.md выступает в роли «манифеста» проекта. Это не просто текстовый файл, а набор правил, которые определяют:
- Стиль написания кода (например, использование только функционального подхода).
- Команды для сборки, тестирования и запуска проекта.
- Архитектурные ограничения (какие библиотеки использовать можно, а какие — под запретом).
Если мы посмотрим на типичный процесс, то наличие такого файла позволяет сократить количество итераций. Вместо того чтобы каждый раз писать в промпте: «Используй pytest для тестов и не меняй структуру папки /src», вы один раз фиксируете это в CLAUDE.md.
Для примера, вот как может выглядеть минимальный набор инструкций в этом файле, чтобы Claude Code понимал, как работать с вашим окружением:
markdown# Project Guidelines
## Build and Test Commands
- Build project: `make build`
- Run tests: `pytest tests/`
- Linting: `ruff check .`
## Code Style
- Use type hints for all function signatures.
- Prefer composition over inheritance.
- Error handling: always use the custom `AppError` class from `core/exceptions.py`.
## Architecture
- All database migrations must be placed in `migrations/`.
- Do not use external libraries for JSON parsing; use the built-in `json` module.
С точки зрения системного инженера, это похоже на конфигурационный файл для сервиса. Мы не ждем, что nginx сам догадается, какой порт слушать; мы явно прописываем это в nginx.conf. С CLAUDE.md происходит то же самое: мы переводим абстрактные пожелания к коду в формат жестких инструкций, которые модель считывает перед началом любой задачи. Это обеспечивает ту самую предсказуемость, без которой автоматизация в продакшн-среде невозможна.
Применение методологии Андрея Карпаты
Анализ типичных ошибок при работе с кодом
Когда я впервые начал использовать Claude Code в своих проектах, я столкнулся с классической проблемой: модель работала отлично, но её решения часто были слишком «свободными». Она могла предложить элегантный паттерн, который полностью противоречил архитектуре, заложенной в проекте, или использовать библиотеку, которую мы принципиально не используем, чтобы избежать лишних зависимостей.
С практической точки зрения, основная проблема заключается в отсутствии контекста ограничений. Без чётких инструкций ИИ пытается угадать ваш стиль, и это угадывание часто приводит к следующим ошибкам:
- Нарушение стандартов форматирования. Вместо использования настроенного Prettier или ESLint, модель может генерировать код с другими отступами или кавычками.
- Несоответствие архитектурным паттернам. Если проект построен на чистой архитектуре (Clean Architecture), модель может попытаться внедрить бизнес-логику напрямую в контроллеры.
- Игнорирование специфики окружения. Например, попытка использовать системные вызовы, которые не поддерживаются в вашем Docker-контейнере на базе Alpine Linux.
Если мы посмотрим на процесс разработки, то увидим, что эти ошибки — не случайность, а следствие отсутствия «единого источника истины» для ИИ. Мы ожидаем от инструмента предсказуемости, но даём ему слишком много свободы.
Формирование правил через CLAUDE.md
Чтобы решить эту проблему, я применил подход, вдохновленный идеями Андрея Карпаты, который подчёркивает важность чётких инструкций и понимания структуры данных при работе с нейросетями. Суть не в том, чтобы просить модель «писать хороший код», а в том, чтобы описать, что именно для вашего проекта является «хорошим».
Файл CLAUDE.md служит своего рода манифестом проекта для Claude Code. Это не просто текстовый файл, а набор жестких правил, которые ограничивают пространство поиска решений для модели, делая результат предсказуемым.
Я рекомендую разделять содержимое файла на три логических блока: инструкции по сборке, правила написания кода и команды для терминала. Вот пример того, как может выглядеть такой конфиг для типичного Node.js проекта:
markdown# CLAUDE.md — Project Guidelines
## Build and Test Commands
- Install dependencies: `npm install`
- Run development server: `npm run dev`
- Run tests: `npm test`
- Lint code: `npm run lint`
- Build project: `npm run build`
## Code Style and Patterns
- Use TypeScript for all new files; avoid `any` at all costs.
- Follow functional programming patterns: prefer `map`, `filter`, and `reduce` over `for` loops.
- Error handling: Always use custom error classes from `@/errors`.
- Testing: Use Vitest for unit tests. Mock all external API calls using MSW.
- Formatting: Strictly follow the project's ESLint and Prettier configurations.
## Architecture Rules
- Business logic must reside in `src/domain`.
- Infrastructure concerns (DB, external APIs) belong in `src/infrastructure`.
- Use Dependency Injection for all services to ensure testability.
С точки зрения системного инженера, такой файл работает как конфигурационный файл для системы. Когда Claude Code считывает CLAUDE.md, он получает набор ограничений, которые работают на уровне логики.
Например, если вы попросите модель «добавить новый эндпоинт», наличие правила о src/domain и src/infrastructure не позволит ей просто набросать код в одном файле. Она будет вынуждена соблюсти структуру, которую вы задали. Это превращает Claude из «умного чат-бота» в полноценного участника команды, который понимает правила игры.
Практическая настройка файла
Структура и содержимое CLAUDE.md
Чтобы Claude Code не гадал, как принято писать код именно в вашем проекте, ему нужны чёткие инструкции. Файл CLAUDE.md работает как своего рода «контракт» между разработчиком и ИИ. Вместо того чтобы каждый раз объяснять в промпте, как запускать тесты или какой стиль именования использовать, вы фиксируете это в одном месте.
С практической точки зрения, файл должен быть лаконичным. Если перегрузить его лишней информацией, модель начнёт игнорировать важные инструкции. Я рекомендую придерживаться структуры, которую популяризирует Андрей Карпата, фокусируясь на трёх ключевых аспектах:
- Build and Test Commands: конкретные команды для сборки, запуска и тестирования.
- Code Style Guidelines: правила оформления кода (например, использование конкретных библиотек или запрет на определённые паттерны).
- Project Context: краткое описание архитектуры, чтобы модель понимала, где лежат основные компоненты.
Пример базовой структуры файла:
markdown# CLAUDE.md — Project Guidelines
## Build and Test Commands
- Build: `npm run build`
- Dev server: `npm run dev`
- Test (unit): `npm test`
- Test (e2e): `npx playwright test`
- Lint: `npm run lint`
## Code Style
- Use TypeScript for all new files.
- Prefer functional components over class components.
- Use Tailwind CSS for styling; avoid inline styles.
- Error handling: Always wrap async calls in try/catch blocks and use the custom `AppError` class.
- Naming: Use PascalCase for components and camelCase for functions/variables.
## Architecture Notes
- Frontend: React/Vite located in `/src/client`.
- API: Node.js/Express located in `/src/server`.
- Database: PostgreSQL with Prisma ORM.
Такой подход обеспечивает предсказуемость. Когда вы попросите Claude «добавить новый эндпоинт», он не просто напишет код, а сделает это с использованием Prisma и обернёт в нужный класс обработки ошибок, потому что это прописано в правилах.
Примеры конфигурации для разных стеков
Правила в CLAUDE.md должны адаптироваться под ваш стек. Нет смысла прописывать правила для Python, если вы работаете с Go. Ниже я привел два примера, которые я часто использую в своих проектах.
Python (FastAPI + SQLAlchemy)
В Python-проектах критически важно зафиксировать требования к типизации и способу запуска тестов, так как инструменты вроде pytest могут иметь множество конфигураций.
markdown## Build and Test Commands
- Install deps: `pip install -r requirements.txt`
- Run app: `uvicorn main:app --reload`
- Run tests: `pytest tests/`
- Linting: `flake8 .`
## Code Style
- Follow PEP 8 strictly.
- Use type hints for all function signatures.
- Use SQLAlchemy 2.0 style (select statements) instead of legacy query API.
- Documentation: Use Google-style docstrings for all public methods.
Go (Standard Library + Docker)
Для Go-разработки важно указать способ работы с модулями и специфику запуска контейнеров, если проект подразумевает локальную разработку в изолированной среде.
markdown## Build and Test Commands
- Build: `go build -o bin/app ./cmd/server`
- Run tests: `go test ./... -v`
- Run with Docker: `docker-compose up -d`
- Format: `go fmt ./...`
## Code Style
- Use `golangci-lint` for all linting checks.
- Error handling: Do not ignore errors; wrap them using `fmt.Errorf("context: %w", err)`.
- Project structure: Follow the Standard Go Project Layout (cmd/, internal/, pkg/).
- Concurrency: Prefer channels for communication, but use Mutexes for simple state protection.
Перед тем как внедрять файл, убедитесь, что все указанные команды действительно работают в вашем окружении. Если команда npm test требует предварительной генерации типов или очистки кэша, добавьте это в описание. Предсказуемость работы Claude Code напрямую зависит от точности этих инструкций.
Результаты и ограничения метода
Как улучшается качество генерации
С практической точки зрения, внедрение CLAUDE.md превращает Claude Code из «умного чат-бота» в полноценного участника процесса разработки, который понимает контекст вашего проекта. Если раньше ИИ приходилось каждый раз гадать, какой стиль именования переменных вы предпочитаете или как запускать тесты, то теперь эти правила становятся частью его «оперативной памяти».
Во-первых, повышается предсказуемость кода. Когда в файле четко прописаны правила (например, использование функциональных компонентов в React или запрет на использование определенных библиотек), модель перестаёт выдавать решения «на свой вкус».
Во-вторых, сокращается количество итераций. Вместо того чтобы трижды исправлять импорты или способ обработки ошибок, вы получаете корректный результат с первого раза. Рассмотрим пример того, как описание архитектурных паттернов в CLAUDE.md влияет на генерацию.
Допустим, в вашем проекте принят строгий подход к обработке ошибок через кастомные классы. В CLAUDE.md мы фиксируем это так:
markdown## Code Style & Patterns
- Error Handling: Always wrap async operations in try/catch blocks and throw custom `AppError` instances.
- Testing: Use Vitest for unit tests. Run tests with `npm run test:unit`.
- Naming: Use PascalCase for components and camelCase for utility functions.
Теперь, когда вы попросите Claude: «Напиши функцию для загрузки данных из API», он не просто создаст fetch, а сразу обернёт его в нужную структуру:
typescript// Пример того, что сгенерирует Claude с учетом CLAUDE.md
import { AppError } from './errors';
export async function fetchData(url: string) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new AppError('Failed to fetch data', response.status);
}
return await response.json();
} catch (error) {
// Claude знает, что здесь нужно пробросить AppError
throw new AppError(error.message, 500);
}
}
Без этих инструкций модель могла бы использовать стандартный Error или вообще проигнорировать обработку исключений, что в реальной эксплуатации привело бы к трудноуловимым багам.
Когда инструкции перестают работать
Несмотря на эффективность подхода, важно понимать границы применимости этого метода. CLAUDE.md — это не магический заклинатель, а набор контекстных подсказок. Если перегрузить его, можно столкнуться с обратным эффектом.
Первая проблема — это избыточность. Если вы попытаетесь описать в одном файле всё: от правил расстановки пробелов до глубокой бизнес-логики каждого модуля, вы быстро упретесь в ограничение контекстного окна. Когда файл становится слишком раздутым, модель начинает «забывать» начало инструкций или путать приоритеты. Я называю это «информационным шумом».
Вторая проблема — противоречие между CLAUDE.md и реально существующим кодом. Если в файле написано «используй только pnpm», а в корне проекта лежит package-lock.json, Claude может начать генерировать команды, которые не сработают в вашей среде, или запутаться в управлении зависимостями.
Чтобы минимизировать эти риски, придерживайтесь следующих принципов:
- Принцип минимальной достаточности. Пишите только то, что нельзя определить из самого кода. Не нужно объяснять, что переменные должны быть camelCase, если весь проект уже написан в этом стиле.
- Разделение ответственности. Если проект огромный, не пытайтесь запихнуть в
CLAUDE.mdправила для всех микросервисов. Лучше держать инструкции максимально локальными. - Актуализация. Если вы решили сменить
JestнаVitest, первым делом обновитеCLAUDE.md. Иначе вы получите «галлюцинации», когда ИИ будет предлагать тесты, которые вы больше не запускаете.
Если вы чувствуете, что Claude начал игнорировать правила, проверьте, не слишком ли много текста вы подаёте ему за один раз. Иногда полезно очистить контекст текущей сессии и начать заново, чтобы модель «перечитала» файл с чистого листа. Это похоже на перезагрузку сервиса после изменения конфигурации: иногда это единственный способ гарантировать, что новые параметры действительно вступили в силу.
FAQ
Нужно ли создавать CLAUDE.md для каждого проекта?
С практической точки зрения — да, если вы хотите добиться предсказуемости. Хотя Claude Code может анализировать структуру проекта самостоятельно, он не знает ваших локальных предпочтений по стилю кода или специфики сборки.
Если у вас есть общие стандарты (например, использование pnpm вместо npm или обязательное наличие типов в TypeScript), лучше держать их в глобальном конфиге окружения. Однако проектные нюансы, такие как команды запуска тестов или архитектурные паттерны, должны лежать в CLAUDE.md конкретного репозитория. Это избавляет модель от необходимости каждый раз «гадать» и тратить токены на исследование файловой системы.
Влияет ли размер файла на скорость работы Claude Code?
Размер файла влияет не столько на скорость генерации ответа, сколько на стоимость контекстного окна и точность следования инструкциям. Если CLAUDE.md превращается в многостраничную простыню, модель может начать игнорировать инструкции в середине текста — это классическая проблема «потери внимания» в длинных контекстах.
Я рекомендую придерживаться принципа минимализма. Вместо подробного описания того, как работает ваш фреймворк, дайте только конкретные команды и правила.
markdown## Build & Test
- Build: `npm run build`
- Test: `npm test -- <file_path>`
- Lint: `npm run lint`
Если инструкций становится слишком много, разбейте их на логические блоки, но старайтесь не превышать разумные пределы (до 2–3 КБ текста).
Можно ли использовать эти инструкции с другими моделями?
Да, концепция использования файла с контекстом проекта применима к большинству современных LLM, работающих через CLI или IDE-плагины. Идеи, которые популяризирует Андрей Карпата, сводятся к предоставлению модели «карты местности» и «свода правил».
Вы можете адаптировать этот подход для:
- Cursor (через
.cursorrules); - GitHub Copilot (через файлы
.github/copilot-instructions.md); - Любого кастомного агента, которому вы передаёте контекст при старте сессии.
Суть одна: чем меньше модель тратит времени на выяснение того, как запустить проект, тем больше ресурсов у неё остаётся на решение вашей инженерной задачи.
Как проверить, что Claude Code соблюдает правила?
Самый надёжный способ — это метод «контрольного запроса». После того как вы внесли изменения в CLAUDE.md, попросите модель выполнить действие, которое прямо противоречит новым правилам или требует их применения.
Например, если вы прописали в файле:
Always use functional components instead of class components.
Вы можете выполнить команду:
bashclaude "Create a new React component for a UserProfile card"
Если модель выдаст класс — значит, файл не подцепился или инструкции недостаточно чёткие. Если функциональный компонент — значит, конфигурация работает. Также полезно периодически проверять содержимое контекста, спрашивая напрямую: «Какие правила оформления кода установлены в этом проекте?». Это позволяет убедиться, что модель видит актуальную версию файла.
Часто задаваемые вопросы
Нужно ли добавлять CLAUDE.md в .gitignore?
Нет, этот файл должен быть частью репозитория и закоммичен вместе с кодом. Его задача — обеспечить единообразие работы Claude Code для всех участников команды, которые используют этот инструмент. Если вы оставите файл только у себя локально, коллеги не смогут получить ту же предсказуемость поведения агента, которую настроили вы.
Чем CLAUDE.md отличается от обычного README.md?
README.md предназначен для людей: он описывает, что делает проект, как его установить и запустить. CLAUDE.md — это технический манифест для LLM, где вместо описания бизнес-логики вы фиксируете правила реализации: команды для тестирования, стандарты именования переменных и архитектурные ограничения. Если README — это «что» мы делаем, то CLAUDE.md — это «как» мы это пишем.
Можно ли использовать один CLAUDE.md для нескольких микросервисов?
С практической точки зрения лучше создавать отдельный файл в корне каждого микросервиса. У каждого сервиса могут быть свои специфические требования к тестированию, разные версии зависимостей или уникальные паттерны обработки ошибок. Общий файл быстро разрастётся и станет слишком перегруженным, что снизит точность следования инструкциям из-за избыточного контекста.
Как проверить, что Claude Code действительно учитывает инструкции из файла?
Самый надёжный способ — это контролируемый эксперимент с намеренным нарушением правил. Попросите модель выполнить задачу, которая в теории должна привести к использованию «неправильного» паттерна, описанного в вашем CLAUDE.md. Если агент придерживается установленных стандартов, значит, контекст подхватывается корректно.