Продвинутый

CLAUDE.md: улучшение поведения Claude Code по Karpathy

Алексей Кузнецов
Алексей Кузнецов
Системный администратор12 ноября 2026 г.11 мин чтения

Один файл CLAUDE.md, основанный на наблюдениях Андрея Карпати, помогает оптимизировать работу Claude Code и избежать типичных ошибок LLM в коде.

CLAUDE.md: улучшение поведения Claude Code по Karpathy

Один файл CLAUDE.md, основанный на наблюдениях Андрея Карпати, помогает оптимизировать работу Claude Code и избежать типичных ошибок LLM в коде.

Проблема и цель CLAUDE.md

Проблема и цель CLAUDE.md

Типичные ошибки LLM в коде

LLM‑модели часто генерируют фрагменты, которые работают в идеальном мире, но ломаются в реальном окружении. Ниже – несколько типичных провалов, которые встречаются почти в каждом проекте.

1. Отсутствие проверки ошибок и установки строгих режимов

bash
# плохой пример: просто запуск команды без проверки кода возврата
curl -s https://example.com/script.sh | bash
bash
# правильный пример: включение строгого режима и проверка
set -euo pipefail
curl -s https://example.com/script.sh | bash

Почему это важно: без set -euo pipefail скрипт продолжит выполнение даже при ошибке, а curl может вернуть ненулевой код, который остаётся незамеченным.

2. Жёстко заданные пути и отсутствие абсолютных путей

bash
# плохой пример: относительный путь, который ломается в разных директориях
cp config.yaml ../config.yaml
bash
# правильный пример: абсолютный путь, проверка наличия файла
ABS_PATH="/home/alexey/projects/myapp/config.yaml"
if [[ -f "$ABS_PATH" ]]; then
    cp "$ABS_PATH" "/tmp/config.yaml"
else
    echo "Файл $ABS_PATH не найден" >&2
    exit 1
fi

3. Использование устаревших библиотек / API

LLM‑модели иногда подсказывают вызвать docker run с параметром --net=host, что в новых версиях Docker уже не поддерживается. Рекомендуется явно указывать используемую версию и проверять её наличие.

bash
# проверка версии Docker
if ! docker version --format '{{.Server.Version}}' | grep -qE '^2[0-9]\.'; then
    echo "Docker 20.x+ required" >&2
    exit 1
fi

# запуск контейнера с указанием сети
docker run --network bridge myimage:latest

4. Неправильное цитирование переменных

bash
# плохой пример: размытие имени файла при передаче в grep
grep $FILE_NAME pattern.txt
bash
# правильный пример: кавычки вокруг переменной
grep "$FILE_NAME" pattern.txt

5. Отсутствие документации и комментариев

LLM‑вывод часто выглядит как «скопировать‑вставить», без пояснений, что усложняет поддержку.

bash
# плохой пример: без комментариев
useradd -m -s /bin/bash alice
bash
# правильный пример: с пояснением
# создаём системного пользователя без возможности входа в систему
useradd --system --no-create-home --shell /usr/sbin/nologin alice

Как CLAUDE.md меняет подход

CLAUDE.md — это «правило игры», который задаёт конкретные рекомендации и примеры, помогающие LLM генерировать надёжный код. Основные принципы:

  1. Явные ограничения – в начале CLAUDE.md фиксируются обязательные практики: set -euo pipefail, проверка наличия зависимостей, использование абсолютных путей.
  2. Примеры «до‑после» – показывают, как превратить плохой фрагмент в хороший, что сразу обучает модель.
  3. Конфигурационные блоки – примеры docker-compose.yml, nginx.conf и др., где каждый параметр объясняется, а не просто перечислен.
  4. Проверочные шаги – после генерации кода LLM обязан выполнить «self‑check»: собрать скрипт, запустить shellcheck, убедиться в отсутствии TODO‑записок.

Пример CLAUDE.md (фрагмент)

markdown
# CLAUDE.md – правила генерации кода

- Все скрипты должны начинаться с `#!/usr/bin/env bash` и включать `set -euo pipefail`.
- Путь к файлам должен быть абсолютным; относительные пути запрещены.
- Перед запуском внешних команд проверять их доступность (`command -v <cmd>`).
- При работе с контейнерами указывать точную версию образа (`myimage:1.2.3`).
- После генерации кода выполнить `shellcheck` и `bash -n <file>`.

Как это работает на практике

Допустим, LLM генерирует скрипт для резервного копирования PostgreSQL. Без CLAUDE.md он может выдать:

bash
#!/bin/bash
pg_dump -U postgres mydb > backup.sql

С CLAUDE.md в процессе генерации появляются проверки:

bash
#!/usr/bin/env bash
set -euo pipefail

# проверка наличия pg_dump
if ! command -v pg_dump >/dev/null 2>&1; then
    echo "pg_dump не найден в PATH" >&2
    exit 1
fi

# проверка наличия базы
DB_PATH="/var/lib/postgresql/data/mydb"
if [[ ! -f "$DB_PATH" ]]; then
    echo "Файл базы $DB_PATH отсутствует" >&2
    exit 1
fi

pg_dump -U postgres mydb > "/backup/$(date +%F_%H%M).sql"

Таким образом, CLAUDE.md меняет подход от «попытай‑ся» к «сделай правильно», уменьшая количество багов, требующих последующего рефакторинга. Это особенно критично в домашних кластерах, где каждая ошибка может привести к потере данных или просто к простою сервисов.

Структура и основные правила CLAUDE.md

Формат конфигурации

CLAUDE.md — это текстовый файл, который задает конкретные правила для Claude Code, чтобы минимизировать типичные ошибки LLM в коде. Он не заменяет документацию, а дополняет её, задавая параметры, которые модель должна соблюдать. Важно: правила должны быть конкретными, а не общими фразами вроде «проверяйте код».

Пример конфигурации:

yaml
# CLAUDE.md configuration
version: 1.2
settings:
  enable_linting: true
  max_code_length: 200
  language_rules:
    python:
      - require_type_hints
      - disallow_print_statements
    shell:
      - check_shellcheck
      - enforce_set -e

Здесь enable_linting включает проверку кода на соответствие стандартам, max_code_length ограничивает длину функций, чтобы избежать перегруженных блоков. Для Python запрещены print_statements — они часто используются в LLM для отладки, но не в продакшене. Для shell-скриптов enforce_set -e гарантирует, что скрипт завершится при первой ошибке, что предотвращает неожиданные сбои.

Примеры типовых шаблонов

В CLAUDE.md шаблоны описывают задачи, которые Claude Code должен решать, и правила, которые он должен соблюдать. Это помогает избежать неоднозначностей и обеспечивает предсказуемость. Шаблоны должны быть конкретными, с четкими пунктами, а не общими фразами.

Пример шаблона для рефакторинга:

markdown
## Task: Refactor user authentication module
- [ ] Replace deprecated `passwd` field with `password_hash`
- [ ] Add input validation for email format
- [ ] Implement rate limiting for login attempts

Этот шаблон явно указывает, какие изменения нужно внести, и как их проверить. Claude Code будет фокусироваться на этих пунктах, а не на общих фразах вроде «сделать код лучше».

Еще пример для JavaScript:

markdown
## Task: Optimize API rate limiting
- [ ] Use Redis for rate limiting storage
- [ ] Set 100 requests per minute per IP
- [ ] Add error handling for Redis connection failures

Здесь конкретные шаги, а не «настроить лимиты», что помогает LLM не гадать, что именно требуется. В реальной практике я видел, как Claude Code генерировал код без проверки на наличие Redis, пока не добавил эти правила в CLAUDE.md — и тогда всё заработало без доработок.

Интеграция в рабочий процесс

Интеграция в рабочий процесс

Когда мы говорим о внедрении Claude Code в реальную эксплуатацию, важно понимать: это не просто «умный чат», а полноценный участник процесса разработки. Если вы просто будете копировать код из консоли в IDE, вы упустите главное преимущество — возможность автоматизировать проверку того, насколько ИИ следует правилам, описанным в вашем CLAUDE.md.

С практической точки зрения, файл конфигурации должен работать как «конституция» проекта. Чтобы эта конституция не осталась просто текстом, её нужно заставить работать на вас.

Автоматизация через CI

Чтобы избежать ситуации, когда Claude предлагает решения, нарушающие архитектуру вашего проекта, правила из CLAUDE.md должны проверяться на этапе CI (Continuous Integration). Поскольку сам Claude Code — инструмент терминальный, его логику можно транслировать в линтеры и кастомные скрипты проверки.

Если вы используете GitHub Actions, хорошей практикой будет добавление шага, который проверяет соответствие структуры файлов и ключевых соглашений, зафиксированных в инструкции. Например, если в CLAUDE.md указано, что все новые API-эндпоинты должны иметь строго определённый формат документации, вы можете написать простой скрипт на Python или Bash, который будет прогонять проверку перед мерджем.

Пример базового workflow для проверки структуры проекта:

yaml
name: Code Quality Check

on:
  pull_request:
    branches: [ main ]

jobs:
  lint-and-verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install dependencies
        run: npm install

      - name: Run custom architectural linter
        # Скрипт проверяет, соответствуют ли изменения правилам из CLAUDE.md
        run: ./scripts/verify-claude-rules.sh

Скрипт verify-claude-rules.sh может проверять, например, наличие необходимых комментариев или отсутствие запрещённых библиотек, которые вы явно указали в файле конфигурации. Это создаёт предсказуемость: ИИ не сможет «тихо» внедрить решение, которое противоречит вашим стандартам.

Мониторинг и логирование

Любая автоматизация, особенно с участием LLM, склонна к деградации со временем. Claude может начать игнорировать специфические инструкции, если контекстное окно переполняется или если проект становится слишком сложным.

Я всегда придерживаюсь принципа: если процесс нельзя измерить, значит, он не контролируется. В контексте работы с Claude Code это означает, что вам нужно логировать не только результат работы (код), но и то, как часто ИИ совершает ошибки, связанные с нарушением правил из CLAUDE.md.

Если вы используете Claude Code для автоматизации рутинных задач (например, написания тестов), настройте сбор логов выполнения этих задач. Если вы работаете в экосистеме Linux, можно использовать systemd для управления фоновыми задачами, которые запускают Claude, и направлять их вывод в journald.

Пример конфигурации unit-файла для фонового процесса, который выполняет задачи по обновлению документации через Claude Code:

ini
[Unit]
Description=Claude Code Documentation Updater
After=network.target

[Service]
Type=simple
User=developer
WorkingDirectory=/home/developer/project
# Запускаем задачу и направляем вывод в системный журнал
ExecStart=/usr/local/bin/claude-task-runner --config CLAUDE.md
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

После запуска вы сможете анализировать ошибки через journalctl:

bash
# Просмотр логов конкретного сервиса для поиска отклонений от правил
journalctl -u claude-doc-updater.service -f

Это позволяет вовремя заметить, когда модель начинает «галлюцинировать» или игнорировать ваши инструкции, и внести правки в CLAUDE.md до того, как ошибки попадут в основную ветку. Более глубокие идеи по оптимизации промптов и управления контекстом можно найти в оригинальных заметках Андрея Карпати.

Практические рекомендации

Тестирование и отладка

Когда вы работаете с Claude Code, важно понимать: модель не обладает интуицией, она опирается на предоставленный контекст. Если в вашем CLAUDE.md не прописаны чёткие инструкции по запуску тестов, агент начнёт гадать, какой фреймворк вы используете, и неизбежно совершит ошибку. С практической точки зрения, предсказуемость работы LLM напрямую зависит от того, насколько быстро она может проверить результат своих изменений.

Вместо того чтобы позволять Claude Code пытаться угадать команду запуска, добавьте в файл раздел с конкретными командами для вашего стека. Например, если вы используете pytest для Python-проекта, описание должно выглядеть так:

markdown
## Test Commands
- Run all tests: `pytest`
- Run specific test file: `pytest path/to/test_file.py`
- Run tests with coverage: `pytest --cov=src`

Если же вы работаете с Node.js, структура будет аналогичной:

markdown
## Test Commands
- Run unit tests: `npm test`
- Run tests in watch mode: `npm run test:watch`

С точки зрения отладки, я рекомендую добавить инструкцию о том, как Claude должен реагировать на ошибки. Если тест упал, агент не должен просто перезапускать его по кругу. В CLAUDE.md стоит зафиксировать алгоритм: «При обнаружении ошибки в тестах, сначала проанализируй вывод journald или логи приложения, затем проверь состояние окружения через docker ps, и только после этого предлагай исправление». Это избавляет от бесконечных циклов бесполезных попыток исправить симптом, а не причину.

Обновление и поддержка

Любой код со временем устаревает, и это касается не только библиотек, но и самих инструкций в CLAUDE.md. Если вы используете подход, описанный Андреем Карпати, вы должны относиться к этому файлу как к части живой инфраструктуры.

Когда вы обновляете версию основного фреймворка или меняете способ сборки проекта, первым делом обновляйте конфигурацию в этом файле. Если вы перешли с make на docker compose, а в CLAUDE.md остались старые команды, вы вводите агента в заблуждение. Это создаёт технический долг прямо внутри контекста модели.

Для поддержания порядка в проекте я использую следующий подход:

  1. Версионирование команд: Если в проекте сосуществуют старый и новый способы сборки, явно укажите это.
  2. Спецификации окружения: Опишите, какие переменные окружения критичны для работы.

Пример блока для поддержки Docker-окружения:

markdown
## Environment & Build
- Build containers: `docker compose build`
- Start services in background: `docker compose up -d`
- Check logs for service 'api': `docker compose logs -f api`
- Required env vars: `DATABASE_URL`, `REDIS_HOST`

Если вы заметили, что Claude Code систематически ошибается в определённом паттерне (например, неправильно импортирует модули в вашем специфическом монорепозитории), не пытайтесь исправлять это в каждом промпте. Запишите это правило в раздел Guidelines вашего CLAUDE.md. Это сделает поведение модели консистентным и предсказуемым на протяжении всего цикла разработки.

Часто задаваемые вопросы

Нужно ли добавлять CLAUDE.md в .gitignore?

Нет, этот файл должен находиться в корне репозитория и быть закоммиченным. Его задача — служить инструкцией для ИИ-агента, который работает с вашим кодом, поэтому правила должны быть доступны модели при каждом сеансе работы. Если вы скроете файл, Claude Code не получит контекст о том, как правильно писать скрипты или обрабатывать ошибки в вашем проекте.

Поможет ли CLAUDE.md исправить ошибки в уже существующем коде?

Сам по себе файл не перепишет старый код, но он изменит поведение модели при попытке его редактирования или дополнения. Если вы попросите Claude Code внести изменения в старый скрипт, он будет использовать правила из CLAUDE.md для генерации нового фрагмента. С практической точки зрения это отличный способ постепенно внедрять стандарты качества в проект, не переписывая всё вручную.

Можно ли использовать этот файл для настройки специфических инструментов проекта?

Да, это одна из самых полезных функций. В CLAUDE.md можно прописать не только общие правила вроде set -euo pipefail, но и специфические команды для вашего окружения: как запускать тесты, как собирать Docker-образы или какие флаги использовать в linter. Это делает работу ИИ более предсказуемой, так как ему не придётся каждый раз угадывать, какой именно процесс сборки принят в вашей команде.

Не замедлит ли наличие дополнительного файла работу Claude Code?

Добавление небольшого текстового файла практически не влияет на скорость генерации ответов. Напротив, это ускоряет процесс отладки, так как модели не придётся тратить токены на исправление ошибок, вызванных неправильным использованием путей или устаревшими API. В долгосрочной перспективе вы экономите время на проверке кода, который изначально пишется более корректно.

Поделиться:TelegramX / TwitterVK