# ИИ-сгенерированный код: когда он помогает, а когда скрывает проблемы

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

## Почему сначала кажется, что это очень быстро

ИИ-сгенерированный код в первые несколько дней кажется безопасным, потому что прогресс легко увидеть. Появляется экран. Форма отправляется. Отчёт загружается с реальными данными. Для небольшой команды это важно. Два человека могут за полдня сделать то, на что раньше уходила почти неделя.

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

Стартапы снова и снова видят один и тот же сценарий. Первая версия работает на одном удачном пути. Она достаточно хорошо совпадает со спецификацией. Она экономит время именно тогда, когда времени меньше всего. И эта победа реальна. Если вам нужен внутренний дашборд, админ-инструмент или простая страница отчёта, ИИ может убрать много скучной работы. Он пишет связующий код, заполняет типовые шаблоны и быстро доводит сырой вариант до рабочего состояния.

Проблемы появляются на границах. Слабая архитектура редко возникает внутри одной страницы или одной функции. Она проявляется там, где одна часть продукта соприкасается с другой: auth, billing, permissions, очереди, общие данные, повторы, фоновые задания и сторонние API. В таких зонах есть правила, проблемы со временем и сценарии сбоев, которые сгенерированный фрагмент редко понимает целиком.

Небольшие команды обычно замечают это позже, когда на доработку уже не остаётся времени. Те же разработчики, которые быстро двигались вперёд, теперь вынуждены чинить странное поведение в production, искать дублирующуюся логику по файлам и распутывать код, который в одиночку выглядел нормально. Крупная компания ещё может какое-то время скрывать такие издержки. Команда из пяти человек обычно не может.

Вот в чём компромисс. ИИ-сгенерированный код может дать настоящую скорость, когда задача узкая, а границы понятны. Но он же может скрыть слабую структуру, если функция пересекает границы системы и код растёт из копий, исправлений и новых промптов. Первая неделя кажется быстрее. Следующие шесть месяцев показывают, действительно ли это было дёшево.

## Где ИИ-сгенерированный код помогает небольшой команде

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

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

То же относится к заготовкам для тестов и вспомогательным скриптам для миграций. ИИ хорошо пишет первый черновик unit-тестов, seed-данных, mock-ответов и типового кода вокруг новой таблицы или поля. Он также может подготовить файлы миграции для обычных изменений схемы. Разработчику всё равно нужно проверить имена, крайние случаи и безопасность отката, но медленный первый проход уже не начинается с нуля.

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

Больше всего это окупается на повторяемых шаблонах. Если у команды уже есть один хороший обработчик API, одно надёжное фоновой задание или один чистый шаблон страницы, ИИ может перенести этот шаблон на всю кодовую базу с неплохой последовательностью. Это важнее, чем просто скорость. Повторяемые шаблоны проще проверять, тестировать и потом заменять.

Простое правило помогает: пусть ИИ пишет скучный код после того, как человек определил форму. Если команда уже понимает, где живёт логика, как выглядит модель данных и как должны работать ошибки, ИИ часто экономит время и не оставляет после себя бардак.

## Где он начинает скрывать слабую архитектуру

Проблемы обычно начинаются в тех частях продукта, которые на экране выглядят просто, но внутри несут наибольший риск. Auth и billing — самые частые примеры. ИИ-сгенерированный код легко создаёт форму входа или страницу с тарифами. Настоящая работа живёт в правах доступа, правилах сессий, состояниях платежа, возвратах, повторах и журналах аудита.

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

Общие модели тоже тихо начинают расходиться. Команда сначала работает с одной моделью «user», а потом добавляет поля для статуса пробного периода, роли в команде, тарифного плана, налогового региона, флагов поддержки и внутренних заметок. Если ИИ продолжает расширять эту модель без чёткой границы, разные части приложения начинают по-разному понимать, что такое пользователь.

Вскоре код для checkout читает одну версию, админ-панель — другую, а фоновые задания — третью. Никто не планировал такого расхождения. Оно распространяется, потому что скопированная логика распространяется быстро. Один хелпер вставляют во второй сервис, потом в cron-задачу, потом в worker очереди. Небольшое несовпадение в одном месте превращается в несколько немного разных правил.

Повторы, очереди и пути сбоев быстрее всего показывают слабую структуру. Если запрос на платёж истекает по времени, приложение повторяет попытку, проверяет статус у платёжного провайдера или случайно создаёт второй платёж? Если задача падает после отправки части цепочки писем или после обновления одной таблицы, но не другой, у кода должно быть понятное правило восстановления.

Ненадёжные продукты часто показывают одни и те же признаки. Проверки авторизации появляются в контроллерах, middleware и случайных вспомогательных файлах. Правила billing протекают в UI-код вместо того, чтобы жить в одном сервисе. Worker-ы копируют бизнес-логику из веб-запросов. Обработка ошибок меняется от одного endpoint к другому.

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

## Как оценить функцию до генерации кода

Скорость — это приятно, но быстрый промпт может закрепить плохую идею. Прежде чем просить ИИ написать код, сделайте несколько заметок, которые заставят всё прояснить. Если вы не можете объяснить функцию простыми словами, код будет гадать за вас, а догадки потом обходятся дорого.

Начните с одного предложения: какую задачу эта функция решает для пользователя? Держите формулировку узкой. «Показать ежемесячный отчёт по продажам для одного менеджера магазина» — ясно. «Улучшить отчётность» — нет. Такое предложение убирает шум и помогает быстрее заметить расползание объёма.

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

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

Нужен и дом для операционной логики. Решите, где будут логи, где будут тесты и кто отвечает за повторы при сбоях. Если подтверждение платежа не успело прийти вовремя, повторяет ли попытку фронтенд или этим занимается фоновой job? Если отчёт загружает устаревшие данные, где вы увидите это первым? Эти решения сильнее влияют на код, чем сам промпт.

Хорошо работает простое правило: не генерируйте код, пока этих заметок нет. Олег Сотников давно говорит об этом в работе с продуктом и архитектурой, в том числе в AppMaster.io. Генерация кода — это дешёвая часть. А вот разбор кода, который пересёк границы, скопировал правила данных или скрыл пути сбоя, и становится настоящим счётом.

## Простой пример для продукта: страница отчёта против checkout

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

Такую страницу можно делать с неровностями, потому что ошибки быстро замечают. Её используют три коллеги. Они и так примерно понимают, какими должны быть цифры. Если что-то выглядит странно, они попросят исправление. Даже если код не красивый, нагрузка на поддержку остаётся низкой, и команда не теряет деньги каждую минуту, пока баг лежит в системе.

Checkout — полная противоположность. Он одновременно касается выручки, доверия и поддержки. Маленькая ошибка в checkout может дважды списать деньги с карты, применить не ту скидку, потерять заказ после оплаты или заблокировать клиента на мобильном устройстве. Команда платит за такой баг не один раз: потерянные продажи, работа с возвратами, сердитые письма и часы, потраченные на поиск причины.

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

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

Именно поэтому страницы отчётов часто хорошо подходят для скорости, а checkout требует более медленной и строгой работы. Используйте нагрузку на поддержку и риск для выручки как фильтр. Они показывают, где быстрый код достаточно хорош, а где он превращается в дорогое исправление.

## Как обычно выглядит cleanup

Большая часть cleanup после ИИ-сгенерированного кода — не самая красивая работа. Команды редко останавливаются и переписывают весь продукт. Они тратят дни на поиски одного и того же правила в четырёх местах и проверяют, какая из копий действительно используется приложением.

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

То же самое происходит со структурой проекта. Похожий код оказывается в папках, которые выглядят по-разному, но делают почти одно и то же, например `services/orders`, `modules/order` и `features/create-order`. Название само по себе может быть нормальным. Проблема в том, что следующему разработчику приходится гадать, где находится настоящая логика заказа. ИИ часто добавляет ещё одну папку, которая в моменте кажется удобной, а через месяц — запутывает.

Исправления багов становятся дорогими очень обычным способом. Команда находит ошибку округления в итогах счёта и патчит первую же функцию, которую видит. Ошибка возвращается, потому что тот же расчёт был скопирован в admin endpoint, background worker и задачу экспорта CSV. Теперь команда чинит не один дефект, а ищет копии.

Прослеживание одного запроса тоже становится медленным. Простое действие вроде «создать аккаунт» должно легко читаться. Вместо этого запрос проходит через controller, helper, сгенерированный сервис, второй слой проверки, задачу в очереди и fallback-обработчик почти с тем же кодом. Каждый файл выглядит маленьким. Вместе они делают путь слишком сложным, чтобы ему доверять.

Поэтому cleanup обычно начинается со скучных решений. Выберите одно место для проверок. Выберите один шаблон папок и постепенно двигайтесь к нему. Удаляйте копии после каждого исправления, а не оставляйте их «на всякий случай». Если один запрос трудно проследить за 20 минут, это уже тревожный сигнал.

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

## Ошибки, которые часто делают небольшие команды с ИИ-кодом

Небольшая команда может много выпускать с ИИ-сгенерированным кодом и всё равно сделать продукт сложнее в эксплуатации уже через месяц. Проблемы начинаются, когда никто не воспринимает новый код как долгосрочную часть системы. Он быстро появляется, проходит короткое демо и тихо становится чужой головной болью.

Первая ошибка — размытая ответственность. Один человек пишет промпт, другой вставляет результат, третий одобряет pull request, и никто не чувствует себя ответственным за поведение после релиза. Когда баг появляется в billing, auth или отчётности, команда теряет время, пытаясь понять, кто вообще достаточно хорошо знает код, чтобы его исправить.

Ещё одна частая ошибка — слишком рано принимать абстракции. ИИ любит генерировать слои: service classes, helpers, factories, wrappers и adapters. Часть из этого действительно нужна. Но многое — просто церемония вокруг простого кода. Если у функции один сценарий использования, обычная функция часто лучше, чем три файла и паттерн с красивым названием.

Команды также пропускают логи, потому что демо работает. Это плохой обмен. Чистое демо почти ничего не говорит о том, что происходит при реальном трафике, странных входных данных или частичных сбоях. Если checkout ломается у 3 процентов пользователей, а полезных логов нет, время, сэкономленное на генерации, исчезает за один день.

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

Последний пункт важнее, чем многие команды готовы признать. Закрытые задачи создают ощущение скорости, но пользователям всё равно, сколько карточек переехало по доске. Им важно, работает ли функция, может ли поддержка объяснить проблему и сможет ли команда изменить её на следующей неделе без страха.

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

## Короткая проверка перед объединением

ИИ-сгенерированный код может выглядеть готовым задолго до того, как его безопасно выпускать. Короткое ревью перед объединением экономит много cleanup позже, особенно маленькой команде, которая не может позволить себе неделями незаметно терять качество в production.

Начните с владения бизнес-правилами. Если окно возврата — 14 дней, это правило должно жить в одном понятном месте, а не одновременно в API, админ-панели и background job. Когда ИИ пишет код из нескольких промптов, он часто повторяет одно и то же правило в немного разных формах. Так и появляются баги.

Потом прочитайте названия. Хорошие названия звучат как сам продукт, а не как генератор. Если команда говорит «trial», «paid plan» и «expired account», код должен использовать те же слова. Когда названия расходятся, люди неправильно понимают поток и позже чинят не ту часть.

Полезная проверка перед объединением проста. Убедитесь, что каждое бизнес-правило имеет одного владельца в коде. Прочитайте тесты и посмотрите, есть ли там сценарии сбоя, а не только удачные случаи. Запустите одну или две ошибки и проверьте, что логи показывают, что именно сломалось и где. Потом попросите другого разработчика за несколько минут проследить запрос от входа до результата.

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

Простой пример это хорошо показывает. Допустим, экспорт отчёта ломается, когда файл слишком большой. В объединении должен быть тест на это ограничение, понятное сообщение об ошибке и логи, которые укажут на worker или endpoint, отказавший в обработке. Если единственное доказательство — «у меня на машине работало», ещё не объединяйте.

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

## Что делать дальше, если кодовая база уже кажется шаткой

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

Запишите этот поток простыми словами. Достаточно одной страницы: точка входа, слой сервисов, модель данных, внешние вызовы, тесты и точки сбоя. Команды обычно быстро находят проблему. Редко виноват сам ИИ-сгенерированный код. Проблема чаще в слабой границе, которая позволяет грязным решениям расползаться.

Сначала чините именно эту границу. Если интерфейс общается напрямую с базой данных, поставьте между ними слой сервиса. Если промпты создали три версии одной и той же проверки, перенесите проверку в одно общее место. Если фоновые задания прячут бизнес-правила, вынесите эти правила в код, который команда может читать и тестировать. Одна чистая граница может убрать больше риска, чем переписывание десяти экранов.

Несколько правил помогают лучше, чем длинный документ о процессе. Просите маленькие изменения внутри существующих шаблонов, а не полные переписывания. Требуйте, чтобы каждое сгенерированное изменение называло файлы, которые оно затрагивает, и зачем. Проверяйте движение данных, ответственность, обработку ошибок и тесты до того, как смотреть на стиль кода. Отклоняйте дублирующие хелперы, скрытые побочные эффекты и новые абстракции без явной необходимости.

Если команда снова и снова упирается в одну и ту же стену, внешняя архитектурная проверка может сэкономить время. Полезная проверка описывает продукт, изучает workflow с ИИ и смотрит, не вынуждают ли решения по инфраструктуре писать неудобные пути в коде.

Это также тот момент, когда CTO на частичной занятости может помочь, не тормозя команду. Олег Сотников через oleg.is работает со стартапами и небольшими компаниями над архитектурой продукта, рабочими процессами разработки с ИИ и выбором инфраструктуры до того, как cleanup превращается в переписывание. Цель не в идеальном коде. Цель — в кодовой базе, где следующая функция занимает два дня вместо двух недель, и где одно исправление не ломает пять других путей.

Начните с одного потока, исправьте одну границу и сделайте следующий merge гораздо труднее испортить.
