ИИ для legacy-кода: как изучить, задокументировать и рефакторить систему
Искусственный интеллект помогает работать с legacy-кодом прежде всего на этапе знакомства с системой. Он может объяснить, что делает функция, откуда приходит вызов, какие таблицы читаются и какие внешние сервисы задействованы. Он также подготовит черновик документации и предложит небольшие изменения. Но объяснение модели — гипотеза о коде, а не знание о бизнесе. Сохранение поведения после рефакторинга нужно подтверждать независимыми проверками, а не ответом той же модели «все осталось без изменений».
Безопасная последовательность такая: сначала составить карту системы, затем зафиксировать наблюдаемое поведение тестами и только после этого менять код небольшими шагами. Эта статья поможет выбрать задачи для ИИ, отличать подтвержденный факт от предположения, определять доказательства для приемки рефакторинга и понимать, когда следует остановиться.
Что ИИ может узнать из кода
Код хранит много ответов, которые человеку пришлось бы долго искать вручную. ИИ хорошо помогает с такими задачами:
- Цепочки вызовов. Кто вызывает функцию, что она вызывает дальше и где завершается обработка запроса.
- Зависимости. Какие библиотеки, модули и внешние сервисы используются и где именно.
- Данные. Какие таблицы, файлы и очереди читаются или меняются, какие поля участвуют в расчете.
- Предполагаемое назначение. Краткое объяснение вроде «похоже, функция рассчитывает скидку для оптовых клиентов» на основе имен, комментариев и логики.
Последний пункт наиболее рискованный. Код показывает, что происходит, но не всегда почему. Если функция проверяет, равен ли регион числу 7, и не начисляет комиссию, модель может правдоподобно объяснить это льготой для региона. В действительности это может быть временное исключение по старому соглашению с партнером или обход ошибки другой системы. Таких бизнес-договоренностей в коде может не быть, и ИИ не восстановит их. О них знают люди: владельцы процесса, бухгалтерия, поддержка, иногда только архив переписки.
Ускорит ли ИИ саму работу — отдельный вопрос без универсального ответа. В одном рандомизированном исследовании в начале 2025 года 16 опытных разработчиков выполнили 246 задач в знакомых им open-source проектах. Когда ИИ-инструменты были разрешены, задачи в среднем занимали на 19% больше времени, хотя участники заранее ожидали ускорения на 24%, а после работы считали, что ускорились на 20%. Это был снимок возможностей инструментов того времени в конкретных условиях, а не оценка всех команд или современных систем; авторы позже обозначили результат как устаревший. В последующей оценке, опубликованной в 2026 году, повторить измерение стало сложнее: часть разработчиков отказывалась работать без ИИ, а 30–50% опрошенных сообщали, что не подавали некоторые задачи, которые не хотели выполнять без него. Новые оценки скорее указывали на ускорение, но доказательства авторы назвали очень слабыми. Для legacy-проекта вывод прост: не планируйте сроки по чужому среднему и не полагайтесь на ощущения команды — измеряйте на своих задачах.
Как восстановить карту системы
До изменений нужна карта: какие части есть в системе и что в них важнее всего. ИИ поможет ее составить, но каждый пункт должен проверить человек.
Точки входа. Откуда в систему приходят запросы: страницы сайта, API, планировщик, обработчики очередей, импорт файлов. Попросите ИИ найти места регистрации маршрутов, расписаний и обработчиков сообщений, затем сравните список с конфигурацией сервера и планировщика. Внешние задачи, например системный планировщик на другом сервере, могут быть не видны в коде.
Критические операции. Какие действия связаны с деньгами, юридическими документами, персональными данными или остатками на складе. ИИ может предложить кандидатов, но важность определяют владельцы процесса.
Внешние сервисы. Платежные системы, доставка, учетные программы, почтовые рассылки. Для каждого выясните, что система отправляет и получает и что произойдет, если сервис не ответит.
Владельцы данных. Кто решает, как должен работать расчет, кто отвечает за таблицу или справочник. Отсутствие владельца — само по себе важная находка.
Где хранится состояние. База данных, файлы, кеш, переменные среды, настройки панели администратора. Особенно опасны места, где поведение зависит от данных вне репозитория.
Удобный формат — таблица с колонками «компонент», «что делает», «откуда это известно» и «кто подтвердил». Последняя колонка сначала может быть почти пустой: так видно, какие знания еще не проверены.
Как зафиксировать поведение
Главный риск рефакторинга legacy-кода — потерять поведение, о котором никто не знал, но от которого кто-то зависел. Защита — characterization tests, или тесты характеризации. Они фиксируют не то, как система должна работать, а то, как она работает сейчас. Если текущее поведение странное, тест все равно его фиксирует, а вопрос «это ошибка?» выносится отдельно.
Практический порядок:
- Выбрать функцию или сценарий для изменения.
- Собрать входные данные: обычные значения, границы диапазонов, пустые и некорректные данные, отрицательные числа и очень большие значения. ИИ может предложить граничные случаи, которые легко пропустить.
- Запустить текущий код на этих данных в разрешенной среде и записать фактические результаты. Именно запустить, а не попросить модель угадать.
- Оформить пары «вход → результат» как тесты.
- Обезличить тестовые данные: реальные имена, телефоны и номера счетов не нужны.
Отдельно зафиксируйте побочные эффекты: какие записи создаются в базе, какие письма отправляются, какие файлы появляются. Для внешних сервисов нужны заглушки, но их следует строить на записанных ответах, а не на догадках о том, как сервис должен был ответить.
Как писать документацию
Документацию legacy-системы легко испортить уверенными формулировками. Текст «функция рассчитывает бонус лояльности» звучит как факт, хотя может быть догадкой модели по имени переменной. Через год никто не вспомнит, что эти слова не проверяли.
Поэтому каждый факт в документации привязывайте к доказательству: файлу, функции, тесту, наблюдению или подтверждению конкретного человека. Непроверенное отмечайте как гипотезу. Шаблон описания функции или модуля:
| Поле | Что записать | Пример |
|---|---|---|
| Назначение | Что делает, с пометкой «подтверждено» или «гипотеза» | Гипотеза: рассчитывает скидку для оптовых клиентов |
| Входы | Параметры, источники данных, настройки | Сумма заказа, тип клиента, таблица тарифов |
| Выходы | Что возвращает и в каком формате | Целое число копеек |
| Побочные эффекты | Записи в базу, письма, вызовы сервисов | Добавляет строку в журнал скидок |
| Подтверждение | Чем подтвержден каждый пункт | Тесты характеризации на 14 входах; владелец процесса подтвердил порог суммы |
| Неизвестное | Что выяснить не удалось | Почему для региона 7 скидка не применяется |
Поле «неизвестное» — не формальность. Оно показывает зоны риска и дает список вопросов владельцам процессов. Попросите ИИ заполнить шаблон, но требуйте для каждого пункта указать строку кода, на которой он основан. Утверждения без привязки автоматически становятся гипотезами.
Как проводить рефакторинг
Работать безопаснее небольшими шагами:
- Один тип изменения за шаг. Отдельно переименование, выделение функции и обновление синтаксиса. Смешанный diff труднее проверять.
- Небольшой diff. Если рецензент не может понять изменение за один просмотр, разбейте его.
- Тесты до изменения. Тесты характеризации должны проходить до и после.
- Проверка совместимости. Форматы данных, API для других систем, поведение под нагрузкой.
- План отката. Как быстро вернуть предыдущую версию, если проблема проявится после выпуска.
Отдельно учитывайте самопроверку модели. В одном непрошедшем рецензирование препринте 2026 года исследователи провели 1 980 вызовов моделей для модернизации 60 фрагментов Python 2, используя 11 моделей из семи семейств. Каждое изменение проверяли строгим тестом поведения. В фрагментах с семантическими ловушками поведение менялось в 39,7% попыток, в контрольных фрагментах без ловушек — в 7,0%. Затем модели оценивали, сохранили ли они поведение. Из 262 случаев изменения поведения та же модель признала корректными 83, или 31,7%. Различия между моделями были большими: от нуля таких пропусков у пяти моделей до 100% у одной. Некоторые модели описывали различие Python 2 и Python 3, которое сломало результат, и тут же заявляли, что поведение сохранено.
У этого исследования четкие ограничения: короткие фрагменты одного языка и один тип задачи, а не полные корпоративные системы. Оно не показывает частоту ошибок в вашем проекте. Практический вывод для legacy-кода: убедительное объяснение модели не заменяет независимую проверку поведения.
Учебный пример: деление при переходе с Python 2 на Python 3
Это учебный пример метода. В Python 2 оператор / для двух целых чисел выполняет деление с округлением вниз: 7 / 2 дает 3, а -7 / 2 — -4. В Python 3 тот же оператор всегда выполняет обычное деление: 7 / 2 дает 3.5. Но есть два условия. Если в модуле Python 2 импортирован from __future__ import division, оператор / уже работает как в Python 3. Если хотя бы один операнд дробный, Python 2 тоже возвращает дробный результат: 7.0 / 2 дает 3.5.
Рассмотрим типичные «исправления». Оставить / как есть — для целых чисел результат изменится с 3 на 3.5. Механически заменить на // — для целых чисел поведение сохранится, но если функция получала дробные значения, 7.0 // 2 даст 3.0 вместо прежних 3.5. Обернуть выражение в int(a / b) — для отрицательных чисел даст -3 вместо -4, потому что int отбрасывает дробную часть, а не округляет вниз.
От автора изменения, человека или ИИ, требуйте три вещи:
- Исходное поведение, полученное запуском старого кода на разных входах: положительные и отрицательные целые, дробные числа, ноль в знаменателе, а также проверка импорта
divisionиз__future__. - Ожидаемый контракт: какие типы действительно поступают в рабочую функцию и должен ли результат оставаться целым.
- Тест после изменения, который дает те же результаты на тех же входах.
Фразы «я учел различия Python 2 и 3» недостаточно. Доказательство — таблица входов и результатов до и после.
Когда остановиться
Не каждую часть legacy-системы стоит рефакторить с ИИ, даже небольшими шагами. В некоторых случаях нужен отдельный разбор с владельцами процесса.
Неизвестные расчеты. Если функция рассчитывает деньги, налоги, начисления или штрафы, а правила никто не может объяснить, сначала нужно выяснить правила, а не выпускать новую версию кода.
Миграция данных. Изменение структуры таблиц или форматов хранения затрагивает накопленные данные. Откатить ошибочную миграцию сложно, если новые данные уже записаны в новом формате.
Внешние побочные эффекты. Отправку платежей, писем клиентам и документов в государственные системы нельзя отменить откатом кода.
Нет воспроизводимой проверки. Если поведение нельзя зафиксировать тестами из-за отсутствия тестовой среды или доступа к данным, рефакторинг становится ставкой вслепую.
В этих случаях ИИ все еще полезен для карты, объяснений, списка вопросов и черновиков тестов. Но менять код следует только после появления проверки.
Итог и первые шаги
ИИ сокращает путь к пониманию legacy-системы, но не делает это понимание автоматически верным. Объяснение модели — гипотеза, документация без доказательств — риск, а рефакторинг без независимой проверки поведения — ставка, даже если модель уверена.
На своем проекте можно:
- Составить с ИИ карту системы: точки входа, критичные операции, внешние сервисы и хранение состояния. Указать, кто подтвердил каждый пункт.
- Выбрать небольшой модуль и написать для него тесты характеризации на обезличенных данных, запуская реальный код.
- Описать модуль по шаблону: назначение, входы, выходы, побочные эффекты, подтверждение, неизвестное.
- Выполнить первый рефакторинг небольшим diff и одним типом изменений, подготовив план отката.
- Составить список зон «стоп»: неизвестные расчеты, миграции, необратимые действия и места без проверок; для каждой сформулировать вопрос владельцу процесса.
- Сравнить фактические затраты времени с ожиданиями, чтобы следующие оценки опирались на ваши данные.
Если нужно определить границы технического пилота — с какого модуля начать, какие проверки поведения зафиксировать и кто будет поддерживать интеграции после изменений, — BotLabs может разобрать с вами систему и предложить реалистичный первый шаг.
Частые вопросы
Можно, но риск потерять неизвестное поведение станет выше. Тесты после переписывания проверяют новую версию, а не то, как система работала раньше. Если старая функция имела незаметную особенность — например, специфическое округление или исключение для отдельной категории клиентов, — тесты после переписывания уже не зафиксируют ее. Безопаснее сначала создать независимые проверки важных контрактов на старом коде и только потом менять его.
Честно помечайте их как неизвестные или гипотезы. Подтвержденные факты связывайте с кодом, тестами, наблюдениями в разрешенной среде или словами конкретного владельца процесса. Гипотезы собирайте отдельно и обсуждайте с людьми, которые знают процесс: бухгалтерией, поддержкой, продажами. Объяснение ИИ не становится знанием только потому, что его добавили в документацию.
Как помощник на отдельных этапах — возможно: для карты зависимостей, объяснений, черновиков тестов и небольших преобразований. Но безопасность большой миграции зависит не от модели, а от проверок поведения, понятных связей между частями системы, плана переноса данных и возможности отката каждого этапа. Без этого даже точный помощник не сделает миграцию безопасной.
Консультация по legacy-пилоту
За 15 минут с техническим специалистом BotLabs обсудим один legacy-модуль, известные бизнес-правила и возможность проверить его поведение. Определим, какие подтверждения нужны до изменения кода и с чего начать подготовку пилота.
Legacy-модуль
Проверки поведения
15 минут со специалистом: выберем границы модуля и проверки поведения, необходимые до рефакторинга.


