Smells of AI-Generated Code.
Recurring problems in code written by AI coding assistants — how to recognize each one, why models produce it, how to fix it, and the rules that detect it.
ИИ-ассистент оборачивает код в лишние функции, классы или интерфейсы, добавляющие слой косвенности, не скрывая никакой сложности и не давая переиспользования, — абстракции, которые лишь пробрасывают вызов к единственной точке вызова.
ИИ-ассистенты склонны вставлять свежую, слегка подправленную копию существующей логики вместо переиспользования или извлечения общей функции, раздувая дублированный код, тогда как рефакторинг тихо исчезает.
ИИ-ассистенты нагромождают новый, почти дублирующий код рядом с уже существующим вместо того, чтобы перестроить его, поэтому дублирование растёт, а рефакторинг — переработка, поддерживающая здоровье кодовой базы, — незаметно исчезает.
Модель вручную пишет самописный код для того, что уже делает стандартная библиотека, имеющаяся зависимость или хелпер уже в репозитории, — добавляя дублированную, хуже протестированную логику вместо вызова того, что уже есть.
Сгенерированный ИИ код, который вызывает функции, методы, параметры, ключи конфигурации или пакеты, выглядящие правдоподобно, но не существующие в той версии библиотеки, от которой вы зависите.
ИИ-ассистенты склонны генерировать код, который обрабатывает только успешный, корректный случай — пропуская валидацию ввода, обработку ошибок, проверки на null/пустоту и краевые случаи — поэтому код работает в демо и ломается в продакшене.
ИИ-ассистенты выдают функциональный код, который молча опускает средства защиты, которые человек добавил бы по привычке — валидацию ввода, авторизацию, кодирование вывода, работу с секретами — потому что "оно компилируется и возвращает 200" выглядит как готово.
Комментарии, которые являются артефактами генерационного диалога — пересказанные промпты, пошаговый нарратив, чат-ремарки и заглушки-эллипсисы вроде `// ... rest of the code here`, закоммиченные в исходники вместо настоящей документации.
ИИ-ассистенты раздувают простую логику избыточными комментариями, защитной церемонией и скопированными почти-дубликатами вместо того, чтобы переиспользовать или извлечь существующий код, наращивая число строк без добавления ценности.
ИИ-ассистент даёт новому коду обобщённые заглушки-имена или новое соглашение, игнорируя существующие идентификаторы и доменный словарь репозитория, что подрывает читаемость и плодит дублирующиеся, неверно описанные понятия.
Сгенерированный ИИ код, который тихо игнорирует устоявшиеся соглашения репозитория — переизобретает вспомогательные функции, выбирает не ту библиотеку и использует не принятое в проекте именование и обработку ошибок — из-за чего кодовая база дрейфует к обобщённому, усреднённому по интернету стилю.
ИИ-ассистенты уверенно выдают API, библиотеки и идиомы, которые были актуальны несколько лет назад, но теперь объявлены устаревшими, удалены или вытеснены, потому что их параметрическое знание заморожено на моменте обучающего среза, а старый паттерн по-прежнему статистически наиболее распространён в их корпусе.
ИИ-ассистенты подстраховываются от сбоев, которые не могут произойти, оборачивая уже безопасный код в избыточные проверки на null, мёртвые охранные условия и всеохватные блоки try/except, добавляющие сложность без добавления безопасности.
ИИ-ассистенты вшивают зависящие от окружения значения — URL, порты, пути, тайм-ауты, ключи и магические числа — прямо в логику вместо чтения их из конфигурации или окружения, потому что литерал является наиболее вероятным следующим токеном, а модель не знает о вашем существующем слое конфигурации.