Легаси-код, рефакторинг и большие кодовые базы

Легаси-код — это не просто «старый код». Это код, который работает в продакшене, который никто не решается трогать, и документация к которому последний раз обновлялась в 2017 году. Большие кодовые базы добавляют сверху слой масштаба: сотни тысяч строк, неочевидные зависимости, архитектурные решения без объяснения причин.

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

Quick recall
Какое главное ограничение Claude имеет при анализе легаси-кода?

Разведка: понять кодовую базу за час

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

Ты входишь в незнакомый Python-проект. Сначала разберись в структуре:
1. Прочитай README, если есть
2. Посмотри на верхнеуровневую структуру директорий
3. Найди точки входа (main.py, __main__.py, setup.py, pyproject.toml)
4. Определи, какие внешние зависимости используются и зачем
5. Найди самые большие файлы — вероятно, там ключевая логика

После разведки — напиши короткое summary: что делает проект, как он организован,
какие 3-5 файлов являются сердцем кодовой базы.

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

Для более глубокого погружения в конкретный модуль:

Объясни мне src/core/transaction_processor.py.
Не пересказывай код построчно — мне нужно:
- Какую бизнес-задачу решает этот модуль?
- Каков основной поток данных (входные данные → трансформации → выход)?
- Какие внешние зависимости он использует?
- Что выглядит нестандартно или рискованно?
flowchart TD A["Вход в легаси-проект"] --> B["Разведка сверху вниз\nструктура, зависимости, entry points"] B --> C["Создать черновик CLAUDE.md\nархитектура, ловушки, паттерны"] C --> D{Тип задачи} D -->|"Найти и понять код"| E["Минимальный контекст\nтолько нужные файлы"] D -->|"Изменить / рефакторить"| F["Написать тесты\nна текущее поведение"] D -->|"Объяснить новичку"| G["/onboard slash-команда"] D -->|"Аудит большой базы"| H["Субагенты\nпо модулям"] F --> I["Рефакторинг маленькими шагами"] I --> J["Тесты зелёные → коммит"] E --> K["/clear между задачами"] J --> K G --> K H --> K
flowchart TD
    A["Вход в легаси-проект"] --> B["Разведка сверху вниз\nструктура, зависимости, entry points"]
    B --> C["Создать черновик CLAUDE.md\nархитектура, ловушки, паттерны"]
    C --> D{Тип задачи}
    D -->|"Найти и понять код"| E["Минимальный контекст\nтолько нужные файлы"]
    D -->|"Изменить / рефакторить"| F["Написать тесты\nна текущее поведение"]
    D -->|"Объяснить новичку"| G["/onboard slash-команда"]
    D -->|"Аудит большой базы"| H["Субагенты\nпо модулям"]
    F --> I["Рефакторинг маленькими шагами"]
    I --> J["Тесты зелёные → коммит"]
    E --> K["/clear между задачами"]
    J --> K
    G --> K
    H --> K
Рабочий процесс при входе в легаси-проект: от разведки до безопасного изменения кода
Quick recall
В каком порядке изучать незнакомую кодовую базу: сверху вниз или от деталей к общему?

CLAUDE.md как онбординг-документ

CLAUDE.md в большом проекте выполняет двойную функцию: это инструкция для агента и документ онбординга для новых разработчиков. Разница с обычным README — CLAUDE.md пишется в императивном стиле («делай так», «не делай так»), а не описательном.

Для легаси-проекта CLAUDE.md особенно ценен: без него агент будет снова и снова «открывать» одни и те же ловушки. Пример структуры:

# Проект: LegacyBilling


::widget{id="rc-3"}

## Архитектура (важно понять перед правками)
- src/core/ — ядро биллинга, изменять осторожно, тесты минимальны
- src/legacy/ — код 2012 года, НЕ трогать без крайней необходимости
- src/api/ — REST API, все изменения через Feature Flag

## Известные ловушки
- calculate_invoice() в billing.py имеет side effect: пишет в audit_log напрямую.
  При тестировании нужно мокать audit_log.write.
- Модуль payments/ использует глобальный state — не запускать тесты параллельно.
- В .env.example есть устаревший DB_LEGACY_URL — он нужен только для миграций.

## Как запускать тесты
pytest tests/ -x --ignore=tests/legacy/  (legacy-тесты сломаны, известная проблема)

## Паттерны кода
- Все новые классы через dataclass + TypedDict для возвращаемых значений
- Логирование через structlog, не через print или logging напрямую

Как сгенерировать первый черновик через агента:

Прочитай структуру проекта и ключевые файлы.
Сгенерируй черновик CLAUDE.md с секциями:
- Архитектура проекта (2-3 абзаца)
- Известные ловушки и нестандартные решения
- Команды для запуска и тестирования
- Паттерны кода, которых придерживается проект

Я отредактирую черновик — сейчас нужна основа, а не финальный документ.

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

Check yourself
Вы впервые открываете легаси-проект на 150 000 строк кода. CLAUDE.md ещё не существует. Что вы сделаете первым шагом — и почему именно это, а не что-то другое?

Безопасный рефакторинг: маленькие шаги

Главный риск рефакторинга легаси — сломать что-то, что «просто работало». Агент не страхует от этого сам по себе, но помогает выстроить процесс, где каждый шаг проверяем.

Паттерн «тест → рефактор → тест»:

Вот функция process_payment() из src/payments/processor.py.
Перед рефакторингом:
1. Напиши unit-тесты, покрывающие текущее поведение функции
   (включая граничные случаи и обработку ошибок)
2. Убедись, что тесты проходят на текущем коде
3. Только потом предложи рефакторинг

Цель: убрать дублирование между process_payment() и process_refund() —
там ~40 строк идентичного кода.

Это прямое применение подхода из Планового режима и разработки через тесты к легаси-контексту. Тесты на текущее поведение — «сеть безопасности», которая фиксирует контракт функции до того, как её начнут менять.

Паттерн Strangler Fig — постепенное вытеснение старого кода новым — агент реализует через конкретные шаги:

Хочу применить паттерн Strangler Fig к модулю src/legacy/user_auth.py.
Новая реализация будет в src/auth/.

1. Создай src/auth/authenticator.py с тем же публичным интерфейсом
2. Добавь feature flag AUTH_USE_NEW_IMPL в settings.py
3. Обнови точку входа: при флаге=True — новый код, при флаге=False — старый
4. Напиши тесты, которые запускаются против обеих реализаций

Начни с анализа legacy-модуля и предложи план перед кодингом.
Check yourself
Перед вами функция process_payment() на 200 строк без тестов. Вы хотите разбить её на несколько меньших. Что должно быть первым шагом — и что произойдёт, если его пропустить?

Что не делегировать агенту при рефакторинге:

  • Решение «стоит ли вообще рефакторить» — это архитектурное и бизнес-решение
  • Удаление кода, который «кажется неиспользуемым», без явной проверки через все точки использования в проекте
  • Рефакторинг сложных модулей с side effects без предварительного покрытия тестами

Субагенты для анализа большой кодовой базы

Если проект огромный — 200+ файлов, несколько крупных модулей — одного агентного контекста не хватит для полного анализа. Здесь работает паттерн из Субагентов и контекстной изоляции: разбить анализ на независимые подзадачи.

Проведи архитектурный аудит проекта. Раздели работу:

Субагент 1: Проанализируй src/api/ — структура эндпоинтов, паттерны
валидации, обработка ошибок. Верни: список проблем по категориям
(безопасность, качество кода, покрытие тестами).

Субагент 2: Проанализируй src/core/ — бизнес-логика, связанность модулей,
наличие тестов. Верни: dependency graph и модули с высокой связностью.

Субагент 3: Проанализируй src/data/ — работа с БД, SQL-запросы, ORM-паттерны.
Верни: потенциальные N+1 запросы, неиндексированные колонки.

Собери результаты в единый отчёт с приоритизацией проблем.

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

Управление контекстом при работе с большой базой

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

Начинайте сессию с минимальным контекстом. Вместо «покажи весь проект» — «покажи только модуль X и его прямые зависимости». CLAUDE.md задаёт карту, агент читает только нужные файлы.

Используйте /clear между задачами. После завершения рефакторинга одного модуля очищайте контекст перед переходом к следующему — артефакты прошлой задачи мешают фокусу.

Git worktrees для параллельного рефакторинга. Если нужно одновременно рефакторить два независимых модуля, запустите два экземпляра Claude Code в разных worktrees:

git worktree add ../project-auth-refactor auth-refactor
git worktree add ../project-api-refactor api-refactor
# В каждой директории — отдельная сессия claude

Это исключает конфликты и позволяет агентам работать параллельно без пересечения контекстов. Подробнее о worktrees — в Git, коммитах и пул-реквестах.

Check yourself
Вы рефакторите два независимых модуля большого проекта — auth и payments. Что лучше: работать последовательно в одной сессии или использовать git worktrees с отдельными сессиями Claude Code?

Онбординг через агента: команда /onboard

CLAUDE.md, написанный для агента, работает и для человека — но можно пойти дальше. Создайте кастомную slash-команду /onboard, которая запускает структурированный тур по проекту:

# .claude/commands/onboard.md
Ты — опытный разработчик, который вводит нового коллегу в проект.

1. Прочитай CLAUDE.md и объясни архитектуру проекта простыми словами
2. Покажи основной flow: как обрабатывается типичный запрос от HTTP до БД
3. Перечисли 5 файлов, которые нужно понять в первую очередь
4. Предупреди о 3 главных ловушках из CLAUDE.md
5. Предложи первую небольшую задачу для знакомства с кодовой базой

Запуск: просто введите /onboard — и агент проведёт новичка (или вас самих после перерыва) по проекту структурированно. О том, как устроены кастомные slash-команды и что можно хранить во frontmatter — в статье Слэш-команды: встроенные и кастомные.


See also