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

Почему старый код с ИИ портится быстрее
Старый код несет привычки, которые ни одна команда не выбрала бы специально сегодня. Там встречаются расплывчатые имена, вспомогательные функции, которые делают три задачи сразу, скопированные условия и бизнес-правила, спрятанные в неожиданных местах. Модель ИИ читает такие шаблоны как норму и начинает воспроизводить их.
Именно поэтому ИИ может очень быстро сделать legacy-систему еще более запутанной. Модель не понимает, какой странный паттерн — это реальное правило, а какой появился из-за поспешного исправления три года назад. Она предсказывает следующий вероятный код, поэтому копирует привычки репозитория, и хорошие, и плохие.
Из-за скорости это легко не заметить. Новые файлы сначала выглядят аккуратно, а ревьюеры чувствуют прогресс, потому что кода появилось так много и так быстро. Потом всплывают проблемы: дублирующаяся логика с чуть разными названиями, расплывчатые комментарии и еще одна утилита, которая почти совпадает с пятью более старыми.
Риск растет, когда команда слишком рано позволяет инструменту рефакторить общий код. Слабое изменение в одном общем модуле редко остается локальным. Оно расходится через импорты, тесты, обработку ошибок, feature flags и небольшие предположения по всей кодовой базе. К тому времени, когда кто-то замечает проблему, команда уже разбирает широкий diff вместо того, чтобы исправить одну плохую правку.
Legacy-системы также ломаются в местах, которые команды забывают протестировать. Люди проверяют счастливый путь, потому что это быстро и демо все еще работает. Они пропускают неудобные случаи, которые держали систему живой годами: частичные обновления, циклы повторных попыток, старые форматы данных, особенности часовых поясов и правила, привязанные к одному крупному клиенту или одной старой интеграции.
ИИ не создает этот риск из ничего. Он просто усиливает то, что уже есть. Если в репозитории смешаны стили, скрытая бизнес-логика и слабые тесты, инструмент распространяет эти проблемы быстрее, чем обычно успевает человек. Сначала это кажется продуктивным, а затем разгребание хвостов начинает съедать время, которое команда думала, что сэкономила.
Решите, где ИИ может писать код
Пилот идет не так, когда инструменту разрешают трогать весь репозиторий. Сначала нарисуйте карту. Командам нужны четкие зоны записи до первого промпта, а не после первого неудачного merge.
Большинству команд стоит начать со скучных областей. Это звучит ограничивающе, но экономит время. Если модель напишет слабый helper для тестов, вы исправите его за минуты. Если она поменяет правила биллинга или проверки авторизации, можно потратить неделю, разбирая ущерб.
Хорошими стартовыми зонами обычно бывают папки с тестами, узкие utility-файлы, внутренние скрипты, админские инструменты, которые не влияют на пользовательские сценарии, и сгенерированные адаптеры для стабильных схем. Записывайте эти зоны по пути к папке, а не по расплывчатой категории. "/tests/integration" — понятно. "Helpers" — нет.
Запрещенные области требуют того же уровня детализации. В большинстве legacy-систем это означает логику биллинга и ценообразования, миграции базы данных, аутентификацию, права доступа, контракты публичного API и код, который обрабатывает чувствительные или регулируемые данные.
Старые системы также прячут бизнес-правила в неожиданных местах. Файл может выглядеть как обычный formatter, но тихо определять налог, уровень доступа или даты продления. Если команда не уверена, считайте эту область закрытой, пока кто-то не разберет реальное поведение.
У каждой разрешенной области должен быть человеческий владелец. Один человек должен проверять промпты, смотреть diff и решать, остается ли область открытой для правок ИИ. Совместное владение кажется справедливым, но обычно означает, что никто не замечает, когда слабый код начинает накапливаться.
Простой принцип работает хорошо: один владелец на папку, короткий список разрешенных зон и расширение только после нескольких чистых циклов ревью. Сначала это кажется жестко. Но это дешевле, чем разгребать последствия.
Задайте правила рефакторинга до начала пилота
Инструменты ИИ обожают наводить порядок. Они переименовывают методы, разбивают файлы, меняют порядок импортов и переписывают код, который вообще не входил в задачу. В legacy-кодовой базе это превращает маленькое исправление бага в pull request, который никто не хочет ревьюить.
Начните с жесткого правила: инструмент может делать только мелкие рефакторинги после того, как существующие тесты проходят. Если тесты красные или у этой области нет тестов, оставляйте форму кода как есть. Сначала исправьте баг или добавьте маленькую функцию. Наведение порядка подождет.
Безопасная политика на первую неделю проста:
- Держите каждый pull request сосредоточенным на одном изменении.
- Не перемещайте файлы.
- Пропускайте крупные переименования, выделение модулей и переписывание импортов.
- Не меняйте поведение, если только задача не просит изменить поведение.
Эти ограничения экономят время. Ревьюеры быстрее замечают реальные изменения, когда diff маленький. Если релиз что-то ломает, команда может откатить один pull request, а не распутывать десять смешанных правок.
Большие переименования и переносы файлов в первую неделю нужно полностью запретить. ИИ часто считает их безобидной чисткой. Но в старых системах это не так. Переименование может сломать логи, скрипты, дашборды, ручной SQL или код, который зависит от поиска по строке. Перемещение файла может запутать шаги сборки и правила владения, которые никто не задокументировал.
Просите инженеров прямо писать цель в pull request простыми словами: «исправить ошибку округления в сумме счета» или «добавить недостающую проверку на null в выгрузке клиентов». Звучит просто, но так и ИИ, и ревьюер держат в голове одну задачу. Когда заявленная цель узкая, лишние рефакторинги легче отклонить.
Еще одно правило важно: по умолчанию сохраняйте старое поведение. Legacy-системы часто содержат странную логику не просто так, даже если причина некрасивой. Если команде нужно другое поведение, заведите отдельную задачу и рассматривайте это изменение отдельно. Смешивать наведение порядка с изменением поведения — вот как пилот превращается в месяц ремонтной работы.
Сразу закройте рискованные области
Некоторые части системы должны оставаться недоступными на старте. Не нужно запрещать инструмент везде. Но нужны четкие красные зоны, где человек полностью сохраняет контроль.
Начинайте с всего, что связано с деньгами, доступом или необратимыми изменениями данных. Legacy-системы прячут старые правила в странных местах, и сгенерированный код может их пропустить, при этом звуча очень уверенно.
Простая проверка помогает: если ошибка может списать не ту сумму, дать не тот доступ или уничтожить данные, запретите ИИ редактировать эту область, пока старший инженер не даст прямое одобрение.
Код для биллинга требует особой осторожности. Старые продукты часто несут годы исключений: скидки для одной группы клиентов, обработка налогов по регионам, условия контрактов, которые менялись в середине квартала. ИИ может сделать этот код чище и при этом сломать правило, по которому выставляются счета.
Безопасность требует такого же подхода. Сгенерированный рефакторинг может перенести проверку авторизации, убрать защиту, которая выглядела повторяющейся, или расширить доступ так, что это не бросится в глаза при быстром ревью. Пусть люди пишут и утверждают такие изменения, пока команда точно не поймет, где инструмент помогает, а где начинает отклоняться в сторону.
Потоки удаления и изменения схемы нужно проводить через отдельные ворота, потому что их трудно откатить. Если ИИ предлагает удалить столбец, поменять тип или переписать миграцию, остановитесь и рассматривайте это как отдельное решение. Не прячьте такое изменение внутри более крупной ветки чистки.
Для расчетов с клиентами держите небольшую библиотеку примеров. Используйте реальные кейсы из счетов, возвратов, пропорционально рассчитанных планов и пограничных случаев округления. Запускайте их перед merge, и пусть принятие merge зависит от этих результатов.
Это звучит жестко, потому что так и есть. Но все равно это дешевле, чем исправлять один плохой merge в закрытой области.
Проводите первый пилот маленькими шагами
Пилот лучше всего работает, когда он почти скучный. Выберите один низкорисковый сервис, отдайте его маленькой команде и удерживайте объем работ настолько узким, чтобы ревьюер мог прочитать каждое изменение без спешки.
Хорошие стартовые точки — внутренние инструменты, небольшие фоновые задачи или тонкий API с понятными тестами. Пропустите логин, платежи, безопасность, миграции данных и все, что может быстро подорвать доверие. Первая победа — это контроль, а не скорость.
Соберите правила на одной странице. Если они не помещаются на одну страницу, команда ими не воспользуется. На этой странице должны быть ответы на четыре базовых вопроса: какие папки инструмент может менять, какие файлы требуют одобрения человека перед merge, может ли инструмент рефакторить старый код или только добавлять изолированные изменения, и какие правки ревьюеры должны отклонять сразу.
Сделайте команду небольшой. Двух-четырех инженеров достаточно. Один ревьюер должен принимать финальное решение, чтобы стандарты не поплыли после третьего дня.
Во время пилота отслеживайте одну простую метрику: как часто ревьюеры отклоняют изменения, написанные ИИ. Если половина черновиков возвращается потому, что код трудно читать, имена неаккуратные или инструмент тихо задел чужие файлы, это скажет вам больше, чем любой объем вывода.
Назначьте жесткий стоп через две недели. Потом вручную проверьте слитые изменения. Ищите предупреждающие признаки: повторяющиеся helper-функции, diff, который стал шире, чем ожидалось, комментарии, объясняющие очевидный код, и тесты, которые проходят, но почти ничего не говорят.
Технический лидер или CTO на частичной занятости может быстро увидеть картину, если прочитает десять слитых изменений подряд. Если код все еще выглядит как ваш код, пилот можно расширять. Если каждое изменение требует доработки, остановитесь и сначала ужесточите правила.
Простой пример на биллинге
Биллинг — это то место, где ИИ может сэкономить время или создать дорогие ошибки.
Одна команда начала со старого модуля счетов, которого все избегали. Он все еще работал, но никто не доверял ему настолько, чтобы менять его быстро. Вместо того чтобы позволить ИИ трогать логику счетов, они дали ему узкую задачу: написать тесты вокруг модуля.
Это сделало пилот полезным, не подвергая риску движение денег. ИИ сгенерировал тестовые случаи для пеней за просрочку, итогов счета и странных форматов дат из прошлых записей клиентов. Некоторые тесты были грубоваты, но ревьюеры могли исправить слабые проверки за минуты.
Во время ревью команда нашла кое-что важнее самих тестов. Одни и те же правила дат всплывали в трех разных файлах. Один файл рассчитывал даты оплаты, другой форматировал даты напоминаний, а третий подгонял даты счетов для экспорта. Каждая версия выглядела немного по-своему. Такую дубликацию ИИ-инструмент легко повторит еще раз, и из маленького беспорядка получается большой.
Поэтому они провели жесткую границу. ИИ не мог редактировать налоговые правила или логику повторных попыток платежа вообще. Эти области несли слишком большой бизнес-риск и слишком много скрытых граничных случаев. Плохое изменение там не просто сломало бы код. Оно могло бы списать не ту сумму или повторить неудавшийся платеж не вовремя.
После этого ревью команда вручную привела в порядок обработку дат. Они вынесли общую логику в один helper, проверили ее на реальных счетах и снова заставили тесты проходить. Только потом они расширили сферу ИИ, и даже тогда права остались узкими: добавлять или обновлять тесты, предлагать изменения для helper-функций и рефакторить только после того, как ревьюеры одобрят точные файлы.
Эта политика скучная, и именно поэтому она работает. Команда стала быстрее в той части кодовой базы, которую никто не хотел трогать, но не позволила инструменту забредать туда, где определяются налоги, повторные попытки или состояние платежа.
Ошибки, которые превращают пилот в разбор хвостов
Худшие пилоты обычно проваливаются по скучным причинам. Команда дает инструменту слишком много свободы, слишком быстро сливает красивые diff и замечает ущерб только после того, как начинают копиться тикеты в поддержку.
Первая ошибка — это объем. Если ИИ может редактировать любую папку с первого дня, он забредет в старые скрипты, заброшенные helper-файлы и код, который уже никто полностью не понимает. Узкая зона записи всегда лучше широкой.
Следующая проблема приходит с крупными рефакторингами. ИИ-инструмент может вернуть чистый diff, который выглядит умнее кода, который он заменил. Но это не делает его безопасным. В старых системах переименование, перенос файла или переписывание общего helper-а может сломать части продукта далеко от исходной задачи.
Уборка стиля делает ситуацию еще хуже. Команды просят о маленьком исправлении, а потом принимают патч, который еще и форматирует файлы, переименовывает переменные и меняет форму функций. Ревью сразу становится сложнее. Когда изменения поведения прячутся внутри косметических правок, никто не может понять, какая именно строка вызвала баг.
Планы отката — еще одно слабое место. Если merge затрагивает чувствительный путь и у команды нет быстрого способа вернуться назад, пилот превращается в ночную ремонтную работу. До того как слить рискованный результат, решите, кто может сделать revert, как быстро он это сделает и какой сигнал остановит rollout.
Скорость тоже может обмануть людей. Если команда измеряет успех только количеством закрытых тикетов или сэкономленных часов, она может не заметить реальную цену. Одна быстрая неделя мало что значит, если следующие две уходят на поиски багов, шумные diff и потерянное доверие.
Полезный пилот требует нескольких проверок: ограничьте правки небольшим набором файлов, отклоняйте широкие рефакторинги во время теста, отделяйте изменения поведения от наведения порядка, заранее делайте понятными шаги отката перед merge и отслеживайте не только output, но и количество дефектов, время на ревью и объем доработок.
Именно здесь важна техническая лидерская роль. Хорошая политика сначала кажется жесткой, но она экономит гораздо больше времени, чем стоит.
Что делать дальше
После короткого пилота запишите правила защиты. Если они живут в чатах или в голове одного менеджера, люди начинают гадать. И тогда маленькие исключения превращаются в новый беспорядок.
Достаточно короткой командной политики. Укажите, где ИИ может писать код, какие файлы остаются закрытыми, что считается приемлемым рефакторингом и когда человек должен взять управление на себя. Пишите просто. Если новый инженер не может прочитать это за пять минут, текст слишком длинный.
Большинству команд в этой политике нужны только четыре части:
- разрешенные типы файлов и папки
- закрытые области, такие как биллинг, auth и проверки безопасности
- правила ревью для diff, созданных ИИ
- правила для промптов, включая примеры запросов, которые команде не стоит использовать
Ревьюерам тоже нужно обучение. Многие команды фокусируются на промптах и забывают о качестве diff. Ревьюер должен отклонять расплывчатые запросы вроде «почисти это» или «сделай лучше», потому что они часто приводят к широким изменениям со слабым смыслом. Он также должен отклонять diff, где в одном проходе смешаны переименования, рефакторинг, изменения логики и форматирование. Такие изменения съедают часы на ревью и скрывают баги.
Не пересматривайте закрытые области каждый день. Это только создает давление в пользу исключений. Перенесите проверку на ежемесячный обзор. Смотрите на инциденты, боль на ревью, покрытие тестами и данные по откатам. Если в одной закрытой области теперь есть хорошие тесты и понятный владелец, откройте узкий путь. Если она по-прежнему приносит сюрпризы, оставьте ее закрытой.
Некоторые команды могут настроить это сами. Другим нужен внешний обзор, особенно если legacy-код затрагивает выручку, uptime или данные клиентов. Oleg Sotnikov на oleg.is работает со стартапами и малым и средним бизнесом как CTO на частичной занятости, и именно в такой настройке границ опытная техническая экспертиза особенно окупается. Короткая проверка зон записи, закрытых областей и правил одобрения может сэкономить месяцы тихой уборки позже.
Следующий шаг намеренно скучный: запишите политику, научите ревьюеров отклонять слабые промпты и грязные diff и назначьте на календаре одну дату для первого ежемесячного пересмотра границ.
Часто задаваемые вопросы
С чего ИИ должен начать в legacy-репозитории?
Начните с низкорисковых областей, которые команда может быстро проверить: тесты, внутренние скрипты, админские инструменты и небольшие utility-файлы с понятным поведением. Держите ИИ подальше от биллинга, auth, прав доступа, миграций и любого кода, который может списать деньги, открыть данные или удалить записи.
Почему ИИ может так быстро ухудшить старый код?
ИИ копирует паттерны, которые видит. Если в репозитории есть поспешные исправления, расплывчатые имена и спрятанные бизнес-правила, модель будет повторять их быстрее. В итоге вы получаете аккуратные на вид diff сейчас и больше разборок позже.
Стоит ли разрешать ИИ-рефакторинг в первую неделю?
Нет. В первый пилот просите ИИ только о узких изменениях. Пусть инженеры вручную делают переименования, переносы файлов и переписывание общих модулей, пока команда не начнет доверять тестам и процессу ревью.
Какие части системы должны быть закрыты в первый день?
Блокируйте все, что связано с деньгами, доступом или необратимыми изменениями данных. Обычно это правила биллинга и ценообразования, аутентификация, права доступа, контракты публичного API, изменения схемы и потоки чувствительных данных клиентов.
Насколько большим должен быть первый пилот ИИ-кодинга?
Сделайте первый пилот маленьким настолько, чтобы один ревьюер мог прочитать каждый diff без спешки. Для большинства команд хорошо подходит один низкорисковый сервис, одна небольшая команда и окно в две недели. Для первого запуска важнее контроль, чем скорость.
Что ревьюеры должны отклонять сразу?
Отклоняйте расплывчатые запросы вроде "почисти это" и diff, где смешаны изменения логики с форматированием, переименованиями или переносами файлов. Также отклоняйте правки, которые затрагивают посторонние файлы или скрывают настоящий смысл задачи.
Как понять, что пилот действительно работает?
Смотрите на процент отклонений, число откатов, размер diff и объем доработок после merge. Если ревьюеры понимают каждое изменение за несколько минут, а команда редко откатывает правки ИИ, значит процесс, скорее всего, работает.
Может ли ИИ помочь с биллингом, не трогая логику биллинга?
Да. Безопасный способ — генерировать тесты и примеры для счетов, возвратов, пропорционального расчета, округления и работы с датами. Люди должны сами контролировать налоговые правила, логику повторных попыток и изменения состояния платежа.
Когда стоит расширять доступ ИИ к записи?
Расширяйте доступ только после нескольких чистых циклов ревью. Открывайте по одной папке за раз, закрепляйте за каждой областью одного владельца и убедитесь, что тесты покрывают старые странные случаи, прежде чем увеличивать доступ.
Когда есть смысл обратиться к fractional CTO за помощью?
Зовите внешнюю помощь, когда команда не может договориться о границах или когда рядом с пилотом находятся выручка, uptime или данные клиентов. Короткая проверка от опытного CTO на частичной занятости может заранее ужесточить зоны записи, закрытые области и правила одобрения, прежде чем мелкие ошибки разрастутся.