Модель переписала код за минуту. Как не пустить нейросеть в прод, если она сломала типы и пути
Пошаговый мануал: как поймать опечатки ИИ линтом и тайп-чекером до коммита на примере одного упавшего билда.
📘 Нейросеть сдала задачу за 60 секунд. Код выглядит идеально: правильные отступы, умные комментарии, чистая архитектура. Вы нажимаете кнопку сборки проекта, и терминал заливает экран красным. Билд упал.
Это классическая ловушка искусственного интеллекта. Модель пишет текст по смыслу, а компилятор проверяет голые факты — имена файлов, пути в импортерах (командах подключения других частей кода) и сигнатуры типов (строгие правила о том, какие данные принимает функция). Человек тоже пропустит это беглым взглядом, потому что глаз замыливается от чистоты логики. Но машина ошибается там, где нужно механически сопоставить строки.
Шаг 1. Разбираем аварию на детали без паники
Представьте ситуацию из вашего короткого поста. Агент убрал неиспользуемую функцию и заодно решил переименовать переменную userId в uid во всей бизнес-логике для краткости. В девяноста девяти файлах он справился блестяще. На сотом споткнулся: обновил использование переменной внутри функции, но забыл поменять её тип в описании интерфейса (шаблона данных). Компилятор TypeScript (языка со строгой проверкой типов) выдает ошибку: «Expected UserId, received Uid» (Ожидался UserId, пришел Uid). Никакой магии, чистая механика сопоставления строк. Программа просто отказывается запускаться, потому что обещала принимать один формат имени, а получила другой.
Или второй сценарий той же аварии. Агент перенес файл из папки /features/checkout в /modules/order. Он поправил все импорты внутри этого файла, но главный входной маршрут приложения остался указывать на старый путь. Ошибка будет звучать иначе, но суть та же: битый импорт из соседней папки. Линтер (автоматический проверяльщик стиля и простых ошибок) или сборщик выдадут ENOENT: no such file or directory (файл или каталог не существует).
Шаг 2. Почему модель всегда будет путать буквы, а линтер — нет
Нейросеть работает вероятностями. Она знает, что слово «идентификатор» часто сокращают до id, и смело меняет userId на uid. Для неё это семантика (смысл), полет творческой мысли. Ей неважно, что в корне проекта лежит файл src/types/user.ts, где черным по белому написано interface User { readonly userId: string; }. Компьютерная логика видит две разные последовательности символов. Для машины UserId и Uid так же далеки друг от друга, как трактор и самокат.
Линтер и проверка типов работают детерминированно (предсказуемо, по жесткому алгоритму). Им плевать на красоту вашей архитектуры. Инструмент eslint (популярный линтер) просто берет правило «запрещены короткие имена айдишников» или «все файлы должны экспортироваться строго через индекс», идет по строке и ставит красную метку, если символы не совпали. Type-checker (проверка типов) строит карту всех имен в проекте и сверяет каждую передачу данных с этой картой. Опечатка в имени поля, забытый аргумент у функции — эти ошибки отлавливаются мгновенно на этапе форматирования и сборки без обращения к нейросети.
Шаг 3. Ваша личная лаборатория: собираем щит перед коммитом
Чтобы больше никогда не пускать такой код в общую ветку, добавьте одну железную команду в ваш терминал перед каждым сохранением изменений. Если вы используете менеджер пакетов npm (Node Package Manager — стандартный инструмент запуска скриптов в JavaScript-проектах), цепочка выглядит так: npm run lint && npm run typecheck (или ваши локальные аналоги, например yarn lint && yarn tsc).
Разберем эту строку для новичка. Знак амперсанда «&&» означает жесткий конвейер: вторая команда запустится только тогда, когда первая отработает абсолютно чисто. Если линтер найдет хоть одну лишнюю запятую или несогласованный тип — тайп-чекер даже не начнет работу. Терминал остановится и покажет вам конкретный файл, конкретную строку и причину падения.
Как читать этот красный текст правильно. Не копируйте его обратно в чат с моделью со словами «просто перепиши». Скролльте до первой красной строки. Если видите Cannot find module '../old-path/utils' — открывайте проводник и смотрите, действительно ли папка называется old-path. Если видите Type 'Uid' is not assignable to type 'UserId' — идите в интерфейс, найдите поле userId и допишите туда | Uid (разрешив оба типа на время горячего фикса) или честно замените везде на UserId. Чините строго по тексту ошибки.
Настройте пре-коммит хуки (Git hooks — автоматические проверки, которые срабатывают прямо в момент попытки сделать коммит). Husky (утилита для легкого управления этими хуками) позволяет заблокировать сохранение кода в систему контроля версий, пока npm run lint возвращает единицу (код ошибки). Пока в терминале есть красные строки — кнопка Commit в вашем редакторе VS Code должна быть физически некликабельна. Это единственный способ победить лень и усталость глаза после трех часов рефакторинга с агентом.
Шаг 4. Что делать, если агент упорно ломает одно и то же место
Иногда модель попадает в петлю: вы просите починить тип, она чинит его в одном файле и тут же ломает в другом. Хватит просить «почини». Дайте ей жесткие границы. Закрепите контекст правил в специальном файле .cursorrules или AGENTS.md в корне репозитория. Пропишите там текстом: «Запрет на переименование ключей пользовательских идентификаторов. Идентификатор всегда userId. Любое изменение требует ручного подтверждения сигнатуру в types/index.d.ts».
Если ошибка плавающая (то появляется, то исчезает при перегенерации), остановите автогенерацию. Заблокируйте стабильные слои руками. Отключите агенту доступ к папке /types и /config. Пусть он переписывает компоненты в /ui, но физические контракты между модулями правьте самостоятельно. Компьютер лучше человека справляется с поиском опечаток, но архитектурный якорь должен держать человек.
Итог вместо морали
Красота сгенерированного кода обманчива ровно до первого прохода статического анализатора. Перед тем как писать git commit -m «feat: refactor auth by agent», вбейте в консоль свои чекеры. Сначала закрывайте красные строки линта, потом возвращайтесь к обсуждению бизнес-логики. Если билд прошел — зеленая строчка SUCCESS гарантирует, что хотя бы базовые законы физики в вашем цифровом мире не нарушены.
По вопросам сотрудничества пишите @CeBers_dev
Завтра сделайте следующее: откройте терминал в своем рабочем проекте, выполните npm run lint и npm run typecheck. Сфотографируйте первый выпавший красный трейсбэк (отчет об ошибке). Откройте указанный файл и исправьте ровно ту опечатку, которую подсветил инструмент, ничего не меняя вокруг. Зафиксируйте изменения и попробуйте собрать проект снова. Повторяйте, пока строка терминала не станет полностью зеленой.