Представьте: в пятницу вечером руководитель уверенно сообщает, что переход со Spring Boot 3.5 на 4.0 будет простым и его можно закончить за выходные. Скорее всего, вы уточните, на чём основана такая оценка, и напомните о несовместимых изменениях. Теперь заменим руководителя на GitHub Copilot или другую большую языковую модель (LLM). Она предлагает рефакторинг метода, новую зависимость или готовый шаблон реализации. Ответ выглядит аккуратно и звучит уверенно. Модель не предупреждает, что может ошибаться. Возникает вопрос: проверяем ли мы такой код столь же строго, как заявление руководителя, или сразу принимаем его?
По данным отчёта Sonatype за 2026 год, 27,76% из 36 870 сгенерированных LLM рекомендаций по обновлению зависимостей ссылались на несуществующие версии этих зависимостей. Получается, одна из трёх-четырёх зависимостей — выдуманная. И проблема не ограничивается зависимостями: та же ложная уверенность может присутствовать в любой строке кода, созданной ИИ.
Одна из причин — эвристика беглости восприятия (fluency heuristic). Если информация изложена ясно, понятно и привычно, то человек склонен считать её более правдоподобной. Организационный психолог Томас Чаморро-Премузик отмечает, что уверенность человека слабо связана с его реальной компетентностью. Люди часто доверяют тому, кто говорит первым и звучит убедительно, даже если более тихий участник обсуждения лучше понимает проблему. Ответы LLM эффективно запускают этот когнитивный механизм. Модели почти всегда выдают связный, структурированный и уверенный ответ. Имена классов соответствуют соглашениям, обработка исключений выглядит разумно, а код напоминает тысячи знакомых примеров. Мозг быстро распознаёт привычный шаблон и предлагает не тратить время на дополнительную проверку.
Исследователи Карнеги–Меллона: модель выдумала от 69% до 88% ответов, сохраняя авторитетный тон.
Хорошее оформление, однако, ничего не говорит о корректности самого кода. Исследователи Университета Карнеги–Меллона показали, что модель выдумала от 69% до 88% ответов, сохраняя при этом авторитетный тон. Из-за такой подачи ошибки трудно заметить даже опытным специалистам.
Где Java-разработчики особенно уязвимы? Во-первых, правдоподобные, но вымышленные зависимости. Maven Central содержит огромное количество артефактов и их версий. Модель легко создаёт координаты, которые выглядят настоящими. Например, она может перепутать org.apache.commons:commons-csv с org.apache.commons:commons-text или предложить несуществующий артефакт commons-utils. Регулярные правила именования помогают LLM правдоподобно угадывать, но одновременно помогают атакующему. Он может зарегистрировать пакет с вымышленным именем, которое уже встречается в ответах моделей. Такой приём называют slopsquatting — разработчик копирует зависимость из ответа ИИ и случайно подключает пакет злоумышленника. Один такой вымышленный пакет скачали более 30 000 раз всего за три месяца.
Во-вторых, скрытое влияние транзитивных зависимостей. В pom.xml могут быть явно указаны десятки зависимостей, тогда как Maven фактически разрешает сотни транзитивных компонентов. Предлагая обновить одну верхнеуровневую библиотеку, модель обычно не видит полное дерево проекта и не знает всех последствий. Например, обновление spring-cloud-openfeign способно изменить версию commons-fileupload, которая приходит через feign-form. Именно такой сценарий произошёл с CVE-2025-48976. В Spring Cloud OpenFeign 4.3.0–4.3.1 модуль feign-form-spring версии 13.6 подтягивал уязвимый commons-fileupload версии 1.5. Обновление OpenFeign до версии 4.3.2 перевело feign-form-spring на версию 13.6.1, где commons-fileupload обновлена до безопасной версии 1.6.0 с устранённой уязвимостью. Безопасное на вид изменение одной строки в pom.xml нельзя оценивать отдельно от всего дерева зависимостей.
В-третьих, шаблонный код, который компилируется, но работает неверно. Java-код часто содержит много повторяемой структуры: конфигурационные классы, аннотации Spring, репозитории, DTO и маппинг. LLM хорошо воспроизводит такие шаблоны, поэтому результат выглядит профессионально. Но компиляция и внешнее сходство с принятым шаблоном не гарантируют правильного поведения. Возможные примеры: @Transactional установлен не на том методе; SecurityFilterChain выглядит полным, но оставляет эндпоинт без защиты; конфигурация ObjectMapper незаметно отбрасывает неизвестные поля; корректный с точки зрения типов код создаёт узкое место под нагрузкой. В таких случаях ошибка находится в семантике, а не в синтаксисе.
Наконец, устаревшие способы работы с API. Модель, обученная на старых проектах, может уверенно предлагать устаревшие API, удалённые методы или подходы, рассчитанные на Java 11, хотя проект работает на Java 21. Без контекста она не знает точные версии JDK, Spring Boot и других компонентов. Код из прошлогоднего стека может не собраться или вести себя иначе в текущем окружении.
Часть ошибок выявляется автоматически. Если координаты Maven не существуют, mvn compile не сможет разрешить зависимость. IntelliJ IDEA заранее подсветит проблему. Но семантические ошибки, такие как неправильное размещение @Transactional, не видны статическому анализу. Поэтому разработчикам стоит внедрять практики проверки: использовать инструменты вроде Dependabot для проверки реальных версий, запускать тесты и проверять дерево зависимостей. Доверие к ИИ должно быть осознанным, а не автоматическим.

