Оптимизация Claude Code через CLAUDE.md
Разбираем, как файл CLAUDE.md на основе наблюдений Андрея Карпаты помогает улучшить поведение Claude Code и избежать типичных ошибок при написании кода.
Проблема непредсказуемости LLM в разработке
Проблема непредсказуемости LLM в разработке
Когда я впервые начал использовать Claude Code для автоматизации рутинных задач в своей домашней лаборатории, я столкнулся с классической проблемой: модель ведёт себя слишком «свободно». С точки зрения инженера, это означает отсутствие предсказуемости. Вы даёте задачу, а на выходе получаете код, который работает, но нарушает архитектуру проекта или использует библиотеки, которые вы принципиально не планировали внедрять.
Проблема не в том, что модель «глупая», а в том, что у неё нет контекста ваших локальных стандартов. Без чётких инструкций LLM пытается угадать, как принято писать код именно в вашем репозитории, и часто ошибается.
Типичные ошибки при генерации кода
В моей практике я выделил три сценария, когда отсутствие контекста превращает помощь ИИ в дополнительную работу по рефакторингу.
Во-первых, это нарушение стиля кодирования. Вы можете использовать строгую типизацию в TypeScript или придерживаться определённого порядка импортов, но Claude может выдать код в стиле «как получится». Это заставляет вас тратить время на исправление мелочей, которые не влияют на логику, но портят чистоту проекта.
Во-вторых, использование несовместимых версий или библиотек. Если ваш проект работает на Python 3.10 с определённым набором зависимостей, модель может предложить решение, использующее синтаксис 3.12 или сторонний пакет, который вы не хотите устанавливать.
Пример того, как может выглядеть «неправильный» ответ, если модель не знает ваших ограничений:
python# Модель предложила использовать библиотеку pandas для простой фильтрации,
# хотя в проекте принят только стандартный модуль csv для экономии ресурсов.
import pandas as pd
def filter_data(file_path):
df = pd.read_csv(file_path)
return df[df['status'] == 'active']
В-третьих, это игнорирование структуры проекта. Модель может попытаться создать новый файл в корне директории вместо того, чтобы положить его в /src/services/ или /internal/, что нарушает логику вашего сборщика или систему импортов.
Почему стандартных промптов недостаточно
Многие пытаются решить проблему через длинные системные промпты или подробные описания в каждом запросе. С практической точки зрения — это путь в никуда. Это создаёт избыточный шум в контекстном окне и заставляет вас повторять одно и то же при каждом новом сеансе работы.
Стандартный промпт — это как попытка объяснить новому сотруднику правила компании каждый раз, когда вы даёте ему задачу. Это неэффективно. Вам нужен не разовый инструктаж, а «единый источник истины» (Single Source of Truth), который будет всегда под рукой у модели.
Если мы посмотрим на подход, который популяризирует Андрей Карпата, становится ясно: модели нужен компактный, структурированный и всегда доступный файл с правилами проекта. Вместо того чтобы писать в чате: «Пожалуйста, используй только async/await и не добавляй лишние логи», вы один раз фиксируете это в конфигурационном файле.
Проблема в том, что Claude Code, как и любой агентный инструмент, должен понимать не только что делать, но и как это делать в рамках конкретной экосистемы. Без этого механизма вы всегда будете бороться с результатами работы ИИ, а не использовать его для ускорения разработки.
Роль файла CLAUDE.md в рабочем процессе
Роль файла CLAUDE.md в рабочем процессе
Когда я начинал работать с автоматизированными агентами, основной проблемой была их непредсказуемость. Вы просите инструмент написать функцию, а он использует библиотеку, которую вы не планировали внедрять, или нарушает принятый в проекте стиль именования. В случае с Claude Code эта проблема стоит особенно остро: агент обладает огромными знаниями, но он не знает контекста именно вашего проекта.
Файл CLAUDE.md решает эту задачу, выступая в роли «памяти проекта». Это не просто текстовый файл с заметками, а структурированный набор инструкций, который Claude считывает при каждом взаимодействии. Если рассматривать это системно, то CLAUDE.md — это своего рода конфигурационный файл для поведения модели, аналогичный .eslintrc для линтера или Makefile для автоматизации сборки.
Механика работы инструкций для Claude Code
Claude Code работает по принципу активного контекста. Когда вы запускаете терминальный интерфейс, агент сканирует рабочую директорию. Если он находит CLAUDE.md, эти данные становятся частью его системного промпта. Это позволяет избежать лишних уточнений и экономит время на исправление типичных ошибок.
С практической точки зрения, файл должен содержать три ключевых блока:
- Build & Test commands: конкретные команды для сборки и запуска тестов.
- Code style: правила именования, предпочтения в синтаксисе и архитектурные паттерны.
- Project context: описание того, что делает приложение и как устроены основные модули.
Представим, что у нас есть проект на Python. Вместо того чтобы каждый раз объяснять Claude, как запускать тесты, мы фиксируем это в файле:
markdown# Project Context: Data Processor API
## Build and Test Commands
- Install dependencies: `pip install -r requirements.txt`
- Run tests: `pytest tests/`
- Run linter: `flake8 .`
## Code Style
- Use type hints for all function signatures.
- Prefer f-strings over `.format()`.
- Follow PEP 8 strictly.
- Error handling: Always wrap I/O operations in try-except blocks with specific exceptions.
Благодаря такой разметке, когда вы дадите команду fix the bug in user service, Claude не будет гадать, как проверить исправление. Он сам выполнит pytest tests/, чтобы убедиться в корректности работы. Это обеспечивает предсказуемость результата — то, что я ценю в любой инженерной системе.
Принципы Андрея Карпаты для эффективного кодинга
Идея использования подобных файлов не возникла на пустом месте. В основе лежит подход, который популяризирует Андрей Карпата, один из ключевых исследователей в области ИИ. Его наблюдения касаются того, как эффективно взаимодействовать с LLM (Large Language Models), чтобы минимизировать «галлюцинации» и отклонения от логики.
Карпата подчеркивает, что модели работают значительно лучше, когда им предоставляют четкие границы и примеры (few-shot prompting). В контексте CLAUDE.md это означает, что мы не просто говорим «пиши красиво», а даем конкретные инструкции, которые ограничивают пространство поиска модели.
Если мы посмотрим на его рекомендации по эффективному использованию ИИ в разработке, можно выделить несколько принципов, которые ложатся в основу хорошего CLAUDE.md:
- Минимизация неопределенности: Чем меньше у модели выбора в вопросах синтаксиса, тем меньше вероятность ошибки.
- Приоритет контекста над знаниями: Модель должна опираться на правила вашего проекта, а не на свои общие знания из обучающей выборки.
- Итеративность: Файл не должен быть статичным. Если вы заметили, что Claude постоянно ошибается в одном и том же месте (например, забывает про обработку ошибок в базе данных), это сигнал — нужно добавить соответствующее правило в
CLAUDE.md.
С точки зрения архитектуры, это превращает взаимодействие с ИИ из «угадывания желаний» в управляемый процесс. Вы создаете среду, в которой агенту физически трудно нарушить ваши стандарты.
Практическое применение и настройка
Структура идеального CLAUDE.md
Когда я внедрял автоматизацию в свои рабочие процессы, я быстро понял: нейросеть — это не магия, а инструмент, которому нужны чёткие инструкции. Если вы просто скажете Claude «напиши код», вы получите усреднённый результат, который придётся переделывать. Файл CLAUDE.md работает как контекстный якорь. Он не заменяет документацию проекта, но он задаёт правила игры для ИИ-агента в рамках конкретной директории.
Опираясь на наблюдения Андрея Карпаты, я выработал структуру, которая минимизирует «галлюцинации» и заставляет модель придерживаться вашего стиля. Идеальный файл должен быть лаконичным. Если он раздуется до размеров учебника, модель начнёт игнорировать часть инструкций из-за ограничений контекстного окна.
Я рекомендую разделять CLAUDE.md на четыре логических блока:
- Build & Test Commands: Конкретные команды для сборки, запуска тестов и линтинга. Это избавляет Claude от необходимости угадывать, как запустить ваш проект.
- Code Style & Patterns: Правила именования, предпочтения в архитектуре (например, использование Composition вместо Inheritance) и запрещённые приёмы.
- Project Context: Краткое описание того, что делает проект и какие ключевые зависимости используются.
- Error Handling & Logging: Как именно в вашем проекте принято обрабатывать исключения и в каком формате писать логи.
С практической точки зрения, это превращает Claude из «умного чат-бота» в полноценного участника команды, который знает, что в этом проекте мы не используем any в TypeScript и всегда пишем тесты на Vitest.
Примеры правил для поддержания чистоты кода
Чтобы добиться предсказуемости, правила должны быть императивными. Вместо размытых формулировок вроде «старайтесь писать чистый код», используйте прямые указания.
Ниже я привожу пример конфигурации CLAUDE.md для типичного Node.js проекта с использованием TypeScript. Вы можете адаптировать этот шаблон под свой стек.
markdown# CLAUDE.md - Project Guidelines
## Build and Test Commands
- Install dependencies: `npm install`
- Build project: `npm run build`
- Run tests: `npm test`
- Run specific test: `npm test -- <file_path>`
- Lint check: `npm run lint`
## Code Style & Patterns
- Use functional programming patterns; avoid classes where possible.
- Prefer `const` over `let`. Never use `var`.
- Use explicit return types for all exported functions.
- Error handling: Always use custom error classes from `@/errors`.
- Naming: Use PascalCase for types/interfaces, camelCase for variables and functions.
- Async/Await: Always use `try/catch` blocks in async functions.
## Project Structure
- Source code resides in `src/`.
- Business logic in `src/services/`.
- Data access layer in `src/repositories/`.
- Tests in `tests/` mirroring `src/` structure.
## Technical Constraints
- No external CSS libraries; use Tailwind utility classes only.
- Use Zod for all runtime schema validation.
- Avoid heavy dependencies; prefer native Web APIs.
Если мы посмотрим на этот конфиг, станет ясно, почему он работает. Когда Claude решит добавить новую функцию, он увидит строку про Zod и try/catch. Вместо того чтобы написать стандартный if (error), он создаст валидацию схемы и обернёт вызов в блок обработки ошибок, соответствующий вашему стандарту.
Для поддержания порядка в терминале, я всегда проверяю, как Claude интерпретирует команды. Если вы используете Docker для локальной разработки, обязательно добавьте это в блок команд:
markdown- Run environment: `docker-compose up -d`
- Database migrations: `docker-compose exec db npm run migrate`
Это гарантирует, что при попытке запустить тесты, Claude не будет пытаться использовать локальный экземпляр PostgreSQL, если проект требует контейнеризированную среду. Предсказуемость конфигурации — это залог того, что ваш CI/CD не упадет из-за того, что ИИ решил «улучшить» структуру проекта вопреки вашим правилам.
Результаты внедрения инструкций
Снижение количества итераций правок
Когда вы работаете с ИИ-агентами вроде Claude Code без контекстных инструкций, вы часто попадаете в цикл «бесконечных правок». Агент пишет код, вы замечаете, что он не соблюдает стиль проекта или использует неподходящую библиотеку, возвращаете его назад, он исправляет одно, но ломает другое. С точки зрения системного инженера — это неэффективное использование вычислительных ресурсов и вашего времени.
Внедрение CLAUDE.md позволяет перенести правила из вашей головы (и из истории чата) в статический файл, который агент считывает перед началом каждой задачи. Это превращает процесс из «угадай, что я хочу» в работу по четкому регламенту.
Если мы посмотрим на типичный сценарий, то без инструкций агент может попытаться использовать npm там, где в проекте настроен pnpm, или написать асинхронную функцию в стиле, который не принят в вашем репозитории.
Пример того, как секция Code Style в CLAUDE.md помогает избежать лишних циклов:
markdown## Code Style
- Use TypeScript for all new files.
- Prefer functional components over class components.
- Use pnpm for package management.
- Error handling: always wrap async calls in try/catch blocks and log to our internal logger.
В результате, вместо того чтобы тратить пять итераций на исправление импортов и типов, агент с первой попытки выдаёт код, который проходит ваш lint и test. Мы фактически сокращаем дистанцию между «запросом» и «готовым PR».
Повышение предсказуемости поведения агента
Для меня, как для человека, который привык к предсказуемости конфигураций в systemd или Ansible, поведение ИИ-агента часто кажется хаотичным. Сегодня он пишет тесты на Jest, а завтра — на Vitest. Файл CLAUDE.md выступает в роли конфигурационного файла для «мозгов» агента.
Основываясь на наблюдениях Андрея Карпаты, ключевой фактор успеха здесь — это предоставление правильного контекста и ограничений. Когда у агента есть четкий набор правил, его действия становятся детерминированными.
Чтобы добиться максимальной предсказуемости, я рекомендую разделять инструкции на логические блоки: архитектурные решения, команды для запуска и правила тестирования. Это позволяет агенту не просто «писать код», а встраиваться в существующую экосистему вашего проекта.
Вот пример структуры файла, которая делает работу агента стабильной:
markdown## Build & Test Commands
- Install dependencies: `pnpm install`
- Run development server: `pnpm dev`
- Run tests: `pnpm test`
- Run linting: `pnpm lint`
## Architecture Patterns
- Use the Repository pattern for all database interactions.
- Services must be stateless.
- Dependency injection is required for all external API clients.
С практической точки зрения, это решает проблему «галлюцинаций» в командах. Вам больше не нужно объяснять Claude Code, как запустить тесты в вашем специфическом окружении — он уже знает это из документации проекта. Это снижает когнитивную нагрузку на разработчика: вы фокусируетесь на логике задачи, а не на том, чтобы подсказать агенту правильный флаг для docker-compose или npm.
Заключение
Итоговые рекомендации по внедрению
Использование CLAUDE.md — это не попытка «научить» нейросеть программировать, а способ задать ей предсказуемый контекст. Без этого файла Claude Code работает в режиме «чистого листа», пытаясь угадать ваши предпочтения, что неизбежно приводит к конфликтам с существующим стилем проекта.
С практической точки зрения, внедрение этого файла стоит разделить на три этапа:
- Анализ текущего состояния. Не пытайтесь сразу прописать идеальные правила. Сначала посмотрите, как вы сами пишете код. Если в проекте используется
pnpmвместоnpm, это должно быть первым пунктом в секции Build Commands. - Создание базового конфига. Начните с малого: команды сборки, тестов и основные правила именования.
- Итеративное уточнение. Если вы заметили, что Claude в третий раз подряд пытается использовать
axiosвместо вашегоfetch-враппера, добавьте это ограничение в файл.
Что стоит включить в конфигурацию
Чтобы файл приносил реальную пользу, а не превратился в свалку инструкций, придерживайтесь структуры, которую предлагает подход Андрея Карпаты. Я рекомендую сфокусироваться на трёх ключевых блоках:
Команды управления проектом Это избавляет модель от необходимости гадать, как запустить линтер или тесты.
markdown## Build and Test Commands
- Install dependencies: `pnpm install`
- Run development server: `pnpm dev`
- Run tests: `pnpm test`
- Lint code: `pnpm lint`
- Type check: `pnpm exec tsc --noEmit`
Стиль кодирования Здесь важно указывать не абстрактные понятия вроде «пиши красиво», а конкретные технические требования.
markdown## Code Style Guidelines
- Use functional components with TypeScript.
- Prefer explicit return types for all exported functions.
- Use Tailwind CSS for styling; avoid inline styles.
- Error handling: always use the custom `AppError` class.
Архитектурные паттерны Если у вас в проекте строгая структура папок, Claude должен об этом знать, чтобы не разбрасывать файлы по всему дереву.
markdown## Project Structure
- Components go in `src/components/`.
- Business logic must reside in `src/hooks/` or `src/services/`.
- API definitions are located in `src/api/`.
Когда этот подход перестанет работать
Важно понимать границы применимости CLAUDE.md. Этот файл отлично справляется с локальными правилами конкретного репозитория, но он не заменяет полноценную документацию проекта или архитектурный дизайн.
Если проект разрастается до масштабов монорепозитория с десятками независимых пакетов, один файл CLAUDE.md в корне станет слишком громоздким и начнет «размывать» внимание модели. В таких случаях я рекомендую размещать отдельные файлы конфигурации в директориях каждого микросервиса или пакета. Это обеспечит ту самую предсказуемость, к которой стоит стремиться при настройке любой автоматизированной системы.
FAQ
Нужно ли создавать CLAUDE.md для каждого проекта?
Да, это имеет смысл, если у проектов разный стек или разные стандарты разработки. Файл CLAUDE.md работает как локальный контекст, который Claude Code считывает при инициализации сессии.
Если вы работаете над микросервисом на Go, вам нужны одни правила (например, про обработку ошибок через if err != nil), а для фронтенд-проекта на React — совсем другие (правила именования компонентов или использование Tailwind). Вместо того чтобы каждый раз объяснять модели, как запускать тесты или какой линтер использовать, вы просто оставляете инструкции в корне проекта.
С практической точки зрения, это избавляет от необходимости дублировать команды в чате. Если в проекте используется специфический скрипт для сборки, например:
bash# Вместо стандартного npm run build используем кастомный скрипт
make build-prod
Просто пропишите это в секции Build Commands вашего CLAUDE.md, и модель будет использовать именно его.
Как CLAUDE.md влияет на контекстное окно?
Этот файл не «раздувает» контекстное окно так, как это делает огромный системный промпт или бесконечная история переписки. Claude Code считывает CLAUDE.md как часть текущего контекста, но делает это эффективно.
Важно понимать: правила в файле — это не просто текст, это инструкции по поведению. Если вы напишете слишком много лишнего, вы действительно начнете тратить токены впустую. Поэтому я рекомендую придерживаться принципа предсказуемости: только конкретика.
Плохо:
- «Пиши код красиво, чисто и в соответствии с современными стандартами индустрии».
Хорошо:
- «Используй только функциональные компоненты и хуки. Избегай использования Class components».
Чем конкретнее инструкции, тем меньше модель будет «галлюцинировать» и пытаться угадать ваши предпочтения, экономя тем самым полезный объем контекста для самого кода.
Можно ли использовать эти правила в других IDE?
Напрямую — нет, так как CLAUDE.md заточен под специфику работы CLI-инструмента Claude Code. Однако идеи, заложенные в этот подход (в том числе идеи, описанные Андреем Карпатой), можно адаптировать под другие инструменты.
Если вы используете Cursor или Windsurf, вы можете создать аналогичные файлы конфигурации, такие как .cursorrules. Принцип остается тем же: вы создаёте «манифест проекта», который диктует модели правила игры.
Для тех, кто привык работать через стандартные расширения в VS Code или JetBrains, эти правила можно перенести в Custom Instructions в настройках самого чат-бота. Но я считаю, что хранение инструкций прямо в репозитории — это более системный подход, так как правила «путешествуют» вместе с кодом.
Заменяет ли этот файл полноценный системный промпт?
Нет, это разные уровни абстракции. Системный промпт определяет общие когнитивные способности модели, её тон и базовые принципы логики. CLAUDE.md же — это проектная спецификация.
Представьте это так: системный промпт — это образование инженера, а CLAUDE.md — это техническое задание (ТЗ) на конкретный объект. Инженер может быть отличным специалистом (системный промпт), но если он не прочитает ТЗ (ваш CLAUDE.md), он построит дом не из того кирпича.
Для эффективной работы лучше всего использовать их в связке:
- Системный промпт отвечает за то, чтобы модель была лаконичной и не писала лишнего.
- CLAUDE.md отвечает за то, чтобы команда
pytestзапускала тесты именно в той директории, где они лежат, а не в корне.
Часто задаваемые вопросы
Нужно ли добавлять CLAUDE.md в .gitignore?
Нет, этот файл должен быть частью репозитория. Его задача — предоставить модели контекст, который будет одинаковым у всех участников команды, работающих с Claude Code. Если вы исключите его из контроля версий, предсказуемость поведения ИИ будет зависеть только от локальных настроек каждого разработчика, что нарушает единообразие проекта.
Как часто нужно обновлять содержимое CLAUDE.md?
Файл стоит актуализировать всякий раз, когда в проекте меняются ключевые правила: например, вы переходите на новую версию языка, внедряете новый линтер или меняете структуру директорий. С практической точки зрения, если вы заметили, что Claude Code начал систематически предлагать решения, которые вам приходится исправлять, — это сигнал, что инструкции в CLAUDE.md устарели или недостаточно точны.
Можно ли использовать CLAUDE.md для описания архитектуры проекта?
Да, это один из самых эффективных способов использования файла. Вместо того чтобы каждый раз объяснять модели, как взаимодействуют компоненты системы, вы можете кратко описать основные паттерны и связи в CLAUDE.md. Это снижает вероятность того, что модель предложит решение, которое логически вписывается в задачу, но архитектурно конфликтует с существующей структурой.
Влияет ли размер CLAUDE.md на стоимость запросов?
Размер файла напрямую влияет на объем передаваемого контекста, а значит, и на количество потребляемых токенов. Чтобы сохранить баланс между точностью и экономией, избегайте избыточного описания очевидных вещей. Пишите только те правила, которые не следуют из стандартных практик или структуры вашего проекта, чтобы сохранить лаконичность и предсказуемость.