Best practices и паттерны организации кода

Предыдущие статьи разобрали конкретные инструменты: план-режим, TDD-петлю, паттерн explore → plan → code → commit. Эта статья — про организационный слой: привычки и принципы, которые делают все эти инструменты эффективными. Здесь нет ничего принципиально нового — только то, что отделяет пользователя, который «иногда использует Claude Code», от того, кто встраивает его в ежедневный процесс.


CLAUDE.md: инфраструктура, а не README

Типичная ошибка — воспринимать CLAUDE.md как «краткое описание проекта». На практике это первый файл, который Claude читает при старте каждой сессии, и он полностью определяет то, насколько агент понимает контекст без предварительного объяснения.

Хороший CLAUDE.md содержит не нарративное описание, а операциональные данные: что запускать, чего не трогать, что сейчас в работе.

# payments-service

## Build & test
npm run build        # TypeScript компиляция
npm test             # Jest — запускать после каждого изменения
npm run lint         # ESLint + Prettier

## Architecture constraints
- HTTP-обработчики только в src/handlers/, не в src/routes/
- Прямые вызовы БД запрещены из handlers/; только через src/db/
- Типы для внешних API — в src/types/external/

## Code standards
- Функции не длиннее 40 строк; если длиннее — нужна декомпозиция
- Ошибки оборачивать в AppError, не бросать нативные Error

## Current context
- Активная задача: миграция с Stripe v2 на v3 API
- src/legacy/ — code freeze до Q3, не трогать

Три принципа для CLAUDE.md:

Команды, а не объяснения. «Запусти npm test» вместо «мы используем Jest». Агент должен знать, что выполнять, а не что читать в документации.

Ограничения явно. Что заморожено, что нельзя менять, какие инварианты нарушать опасно. Это экономит куда больше токенов, чем любое другое поле.

Текущий контекст задачи. Что сейчас в работе — чтобы агент не тратил половину контекстного окна на разведку того, что вы уже знаете.

Auto memory позволяет Claude самому дописывать в CLAUDE.md находки между сессиями — например, нестандартный способ запуска тестов или скрытую зависимость. Это удобно, но стоит периодически чистить автозаписи: устаревший контекст хуже, чем его отсутствие.

Проверь себя
Представьте проект без CLAUDE.md. Что вы вынуждены делать в начале каждой новой сессии, чего можно полностью избежать с хорошо написанным файлом? Назовите хотя бы два конкретных момента.

Дисциплина контекста: главный навык

Самый распространённый антипаттерн — не плохой промпт, а загрязнённое контекстное окно. Когда сессия тянется несколько часов через несколько разных задач, агент работает в пространстве, где перемешаны обсуждение архитектуры, три версии одного файла и отладочные сообщения трёхчасовой давности. Качество деградирует не потому что модель слабее, а потому что сигнал тонет в шуме.

Одна задача — одна сессия. Закончили — /clear, начинаете следующую с чистого листа. CLAUDE.md и файлы на диске никуда не деваются; теряется только история переписки, которая к следующей задаче всё равно не нужна.

/compact перед глубоким дайвом. Команда сжимает историю в суммари, освобождая место в контексте. Используйте до того, как предстоит долгое исследование незнакомого кода — лучше войти со сжатым суммари, чем упереться в лимит на середине задачи.

Импорты @file точечно. Вместо «смотри на весь src/auth/» — @src/auth/handlers.ts именно про нужный файл. Агент сам дочитает зависимости, если потребуется; не нужно загружать всё заранее.

Контекст перед командой. Первый промпт — не «добавь Google OAuth», а «вот текущий auth-flow: @src/auth/session.ts и @src/auth/jwt.ts. Задача — добавить Google OAuth, не ломая существующий JWT. Ограничение: не менять sessionMiddleware». Агент сначала понимает, потом действует.

flowchart TD A([Начало работы]) --> B{Новая задача?} B -->|Да| C["/clear — чистая сессия"] B -->|Продолжение| D{Контекст близок к лимиту?} D -->|Да| E["/compact — сжать историю"] D -->|Нет| F[Продолжить сессию] C --> G[Добавить @файлы точечно] E --> G F --> G G --> H[Первый промпт: контекст + цель + ограничения] H --> I[Работа агента] I --> J{Задача завершена?} J -->|Да| K[git commit → /clear] J -->|Застрял| L[Остановиться, уточнить контекст] L --> G style C fill:#d4edda,stroke:#28a745 style E fill:#d4edda,stroke:#28a745 style K fill:#d4edda,stroke:#28a745 style L fill:#fff3cd,stroke:#ffc107
flowchart TD
    A([Начало работы]) --> B{Новая задача?}
    B -->|Да| C["/clear — чистая сессия"]
    B -->|Продолжение| D{Контекст близок к лимиту?}
    D -->|Да| E["/compact — сжать историю"]
    D -->|Нет| F[Продолжить сессию]
    C --> G[Добавить @файлы точечно]
    E --> G
    F --> G
    G --> H[Первый промпт: контекст + цель + ограничения]
    H --> I[Работа агента]
    I --> J{Задача завершена?}
    J -->|Да| K[git commit → /clear]
    J -->|Застрял| L[Остановиться, уточнить контекст]
    L --> G
    style C fill:#d4edda,stroke:#28a745
    style E fill:#d4edda,stroke:#28a745
    style K fill:#d4edda,stroke:#28a745
    style L fill:#fff3cd,stroke:#ffc107
Решения по управлению контекстом: когда чистить, когда сжимать, когда продолжать

Декомпозиция задач: вертикальный срез

Новичок разбивает задачу горизонтально: сначала все модели, потом все роуты, потом все тесты. Опытный режет вертикально — один полный срез функциональности до конца, включая тест.

Пример. Задача — добавить экспорт данных в CSV.

Горизонтальная декомпозиция (хуже):

Шаг 1: создай модели для ExportJob
Шаг 2: добавь все роуты для экспорта
Шаг 3: реализуй генерацию CSV
Шаг 4: напиши тесты для всего

Вертикальная декомпозиция (лучше):

Шаг 1: реализуй экспорт таблицы users в CSV + тест
Шаг 2: добавь фильтрацию по дате + тест
Шаг 3: реализуй async ExportJob для больших выборок + тест
Диаграмма сравнения горизонтальной декомпозиции по слоям и вертикальной по функциональным срезам

Почему это работает: каждый шаг проверяем и откатываем отдельно. Ошибка на шаге 2 не ломает шаг 1. Агент каждый раз работает с меньшим, понятным контекстом. Если одна итерация пойдёт не так — потери минимальны.

Для многошаговых задач, которые не умещаются в одну сессию, полезно вести чеклист прямо в CLAUDE.md. Claude вычёркивает пункты по мере выполнения и при возобновлении сессии сразу видит, где остановился.

Проверь себя
Почему вертикальная декомпозиция задачи лучше горизонтальной при работе с агентом? Что именно улучшается — назовите два аргумента.

Мульти-агентные паттерны

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

Writer/Reviewer — один агент пишет код, второй в чистом контексте проверяет его. Reviewer не видит историю написания и замечает то, что Writer замылил в процессе. Это основной use case, описанный в статье про Субагенты и контекстная изоляция.

Параллельная обработка — если нужно проанализировать 20 файлов легаси-кода: по субагенту на каждый файл, результаты собрать в конце. Один агент с 20 файлами в контексте теряет точность ближе к концу списка.

Специализация — разные субагенты для разных ролей:

.claude/agents/
  security-reviewer.md    # Только security-аспекты
  perf-analyzer.md        # Профилирование и узкие места
  test-writer.md          # Специализация на написании тестов

Для большинства повседневных задач один агент с чистым контекстом достаточен. Субагенты добавляют оверхед — не применяйте их без конкретной причины.


Что реально отличает опытного пользователя

Всё вышесказанное складывается в несколько рабочих принципов.

Инвестировать в CLAUDE.md заранее. Новичок объясняет агенту контекст в каждой сессии. Опытный — один раз написал хороший CLAUDE.md, и агент знает всё необходимое с первого токена. Время, потраченное на CLAUDE.md, окупается с первой же сессии.

Говорить о результате, а не о шагах. Вместо «открой файл, найди функцию X, измени Y» — «функция calculateTax возвращает неверный результат для EU-ставок; разберись и исправь, проверяя npm test -- calculateTax после каждого изменения». Агент умеет планировать — дайте ему цель и верификатор.

Давать явные стоп-условия. Агент без стоп-условия идёт до лимита токенов или до произвольного «мне кажется, готово». Со стоп-условием — до зелёного теста, до PR, до явного «если три попытки подряд не работают — остановись и объясни проблему». Об этом подробнее в статье Плановый режим и разработка через тесты.

Не смешивать задачи в одной сессии. Это кажется лишней работой, пока не встретишь агента, который путает контекст двух задач и уверенно делает не то.

Использовать git как страховку. Коммит перед каждым большим шагом — не потому что агент обязательно ошибётся, а потому что это позволяет сравнить diff и откатиться без потерь. Claude Code умеет делать осмысленные коммиты с содержательными сообщениями — давайте ему эту задачу явно. Подробности — в статье Git, коммиты и пул-реквесты.

Проверь себя
Вы просите агента «добавить валидацию email в форму регистрации». Это инструкция в стиле «шаги» или «цель + верификатор»? Как переформулировать её в стиле опытного пользователя?

Быстрое повторение
В чём преимущество вертикальной декомпозиции (один срез с тестом) над горизонтальной (все модели, потом роуты, потом тесты)?
Быстрое повторение
Как загрязнённое контекстное окно снижает качество работы Claude Code?

See also