[Перевод] Почему ИИ рано поручать код-ревью
Кажется, кого ни спроси — всякий сегодня мастерит инструмент для код-ревью на основе ИИ. Тем самым все обещают совершить революцию в программировании и управлении кодом. Но мы, попробовав почти все имеющиеся на рынке инструменты код-ревью и написав собственный, пришли к выводу, который невозможно отрицать: ИИ для этой цели просто не годится.
В этом посте мы подробнее рассмотрим, чего реально не хватает при код-ревью с использованием искусственного интеллекта, и почему человек в таком качестве незаменим. Кроме того, этот анализ поможет нам лучше понять, в чём ИИ действительно хорош.
Ложноположительные результаты и проблема доверия
Одна из самых больших проблем с ИИ-инструментами для ревью кода — их склонность к ложноположительным результатам. Если вы таким инструментом когда-либо пользовались, то, вероятно, помните, как тягостно продираться сквозь болото мелких рекомендаций или несущественных предупреждений. ИИ-модели проектируют так, чтобы они были полезны, и порой с этим перебарщивают. Хлебом их не корми, только дай придраться к коду, даже качественному и безупречному. Модель так устроена, что пытается одновременно быть полезной и многословной — ведь именно этому её и обучали!
Создавая собственный ИИ-инструмент для ревью кода, мы большей частью старались как можно сильнее сократить ложноположительные результаты — над этим мы работали больше, чем над любой другой частью системы. Здесь могут пригодиться такие профессиональные секреты: например, вынуждать БЯМ вызывать функции, чтобы таким образом сообщать о проблемах. Другой вариант — выполнять постобработку с применением дополнительных промптов, чтобы проверять таким образом релевантность. Но БЯМ по природе своей — это недетерминированные системы с нечёткой логикой, поэтому невероятно сложно заставить их делать ровно то, что вы сформулировали.
Из-за ложноположительных результатов притупляется восприимчивость к сигналам (alert fatique), и за назойливыми рекомендациями ИИ теряются реальные проблемы. Когда ревьюерам приходится просеивать тривиальную обратную связь, они вообще теряют доверие к инструменту и начинают его игнорировать. ИИ-ревьюеры так устроены, что уделяют внимание сначала количеству, а затем качеству — поэтому их подсказки вскоре начинают восприниматься как шум, а не как полезные советы.
Ограниченный контекст и фрагментарное представление о базе кода
Большинство современных ИИ-ревьюеров не вполне понимают вашу базу кода за пределами актуального пул-реквеста. Некоторые игроки пытаются использовать генерацию с дополненной выборкой (RAG), чтобы подтягивать код, на который стоят ссылки в пул-реквесте, но на практике такая работа нетривиальна и редко выполняется качественно. Попробуйте проиндексировать всю базу кода и извлечь из неё только релевантные данные, которые могут меняться от ветки к ветки. Также постоянно приходится бороться с необходимостью уравновесить дополнительный контекст с контекстными окнами, доступными БЯМ, издержки при этом растут.
Именно поэтому лишь немногие ИИ-ревьюеры эффективно пользуются контекстом, выходящим за пределы актуального пул-реквеста. Поэтому обратная связь, которую можно от них получить, остаётся поверхностной. Они указывают мелкие стилевые проблемы или предлагают простые оптимизации, но упускают более существенные и высокоуровневые аспекты качества кода. К высокоуровневым проблемам относятся, например, архитектурная согласованность, соображения производительности в контексте конкретных фич или понимание зависимостей, действующих в широком контексте всей системы. Именно в этих областях код-ревью делает разницу, а искусственному интеллекту часто не хватает контекста для такой работы, поэтому он справляется с ней плохо.
Непонимание намерений
Каждое изменение, вносимое в код, чем-нибудь продиктовано. Большинство ИИ-инструментов для ревью кода не в состоянии этого осознать. В отличие от человека, способного оценивать изменения, исходя из бизнес-задач, сроков проекта или более обширных целей, ИИ-ревьюер рассматривает контекст шириной всего в несколько строк кода. Он не в состоянии охватить общую картину или понять, чем обоснованы те или иные решения.
Здесь между человеком и ИИ настоящая пропасть, и она важна, так как именно исходя из намерений разработчики зачастую идут на деликатные компромиссы. Например, человек может предпочесть более прямолинейное решение, при котором ради удобочитаемости кода можно частично пожертвовать производительностью — это разумно, если поддержкой кода будут заниматься самые разные коллеги в коллективе. Бывает и так, что какая-то ошибка может быть наскоро исправлена, чтобы успеть уложиться в важный дедлайн — это делается с полным пониманием, что позже это место потребуется оптимизировать. ИИ не в состоянии взвешивать такие факторы, для него все проблемы одинаково безотлагательны. Так он вновь упускает широкий контекст, естественно, учитываемый живым ревьюером.
Одноходовые ревью
Большинство ИИ-ревьюверов рассматривают код «залпом» — быстро просматривают его и пытаются отыскать в нём проблемные места. Вы как автор кода не можете поговорить с нейронкой, обсудить найденную им проблему и объяснить, почему вы написали код именно так. ИИ-ревьюеры предназначены для анализа кода, а не для обмена идеями и не для поиска компромиссов.
Любой, кому доводилось конструктивно обсуждать с коллегой код в процессе ревью, знает, что именно такие обсуждения по-настоящему идут на пользу базе кода. Когда пытаешься объяснить, почему предпочёл табуляцию пробелам, не хватит одних только доводов о сути кода, намерениях и имевшемся времени (NIT).
Более того, ИИ-инструменты обычно не представляют истории изменений кода и не обладают информацией о предшествовавших дискуссиях. Они действуют без учёта тех выводов, которые были сделаны на предыдущих этапах ревью или прямо в контексте текущей рабочей дискуссии. Из-за такой отвлечённости нейронка не осознаёт, какие участки кода уже были обсуждены или признаны приемлемыми на предыдущих ревью, будь то онлайн или на общем сборе команды.
Как это используется на практике? — Не важно
ИИ-ревьюер не представляет, как конкретный фрагмент кода используется в контексте всего приложения. Например, ИИ может пометить метод как потенциально медленный, не учитывая, что тот относится к малоактивной области кода — скажем, это функция админки, лишь иногда используемая несколькими коллегами. Напротив, ИИ может не распознать, что безобидный с виду запрос входит в состав фичи, которая должна работать с максимальной производительностью — каждая миллисекунда на счету. Живой ревьюер, в свою очередь, достаточно компетентен и может оценить, насколько критичен данный код с точки зрения производительности всей системы и насколько он удобен для пользователя.
Не учитывается командный ритм работы
Эффективный код-ревью требует понимать далеко не только саму программу, но и актуальную динамику в команде. Если джуниор отправляет пул-реквест, то его рецензент может рассматривать внесённые изменения пристальнее обычного, понимая, что человек ещё учится. ИИ не различает новичков и опытных разработчиков, а также не понимает нюансов, характерных для конкретных команд: например, какие области кода наиболее важны, в каких есть богатая история изменений. Все эти нюансы принципиально важны в процессе ревью.
Что мы теряем, полностью доверяя ревью кода нейронке
Бесспорно, код-ревью силами ИИ очень эффективен, но такой подход сопряжён с серьёзными компромиссами. Когда мы целиком полагаемся на ИИ при ревью, теряются важные и чисто человеческие аспекты этого процесса — работа в команде, обмен знаниями, наставничество и приход к общему мнению. Эти факторы не только крайне важны при поиске багов, но и способствуют общему росту, спаянности команды и более глубокому взаимопониманию в коллективе.
Командная работа и обмен знаниями
Когда твой код просматривают коллеги, это стимулирует сотрудничество. Код-ревью служит разработчику платформой, на которой удобно обсуждать архитектуру, наилучшие практики и решения, принимаемые при проектировании. Такие дискуссии бесценны, они повышают спаянность команды и могут приводить к невероятным озарениям, а также закладывать почву для дальнейшей разработки. В процессе ревью коллега может предложить альтернативный паттерн проектирования, тем самым не только улучшив код, но и просветив автора этого кода.
Наставничество и оттачивание навыков
Ревью нужны не только для того, чтобы сдать более качественный код — они важны и как возможность чему-то научиться. Джуниоры получают ценную обратную связь, поэтому могут быстрее расти. Опытный рецензент может объяснить, почему конкретный подход более эффективен или лучше масштабируется, либо подсказать, какие ещё области в базе кода стоит исследовать. ИИ может сообщить, что цикл неэффективен, но не способен дать более широкий контекст, пояснить, почему в данном конкретном случае лучше подошёл бы другой вариант.
Как приходить к общему мнению и вести учёт
Кроме того, код-ревью помогает добиться взаимопонимания — обсуждая проблему, найти для неё наилучшее решение. ИИ может дать какие-либо рекомендации, но не способен рассмотреть проблему в разных ракурсах, принять взвешенное решение. Если код будет одобрен ИИ, человек может впасть в ложную самоуспокоенность — «если ИИ ничего не засёк, то, наверное, код нормальный». Такой подход мешает полноценно учитывать, что происходит с кодом.
Сильные стороны ИИ при ревью кода
Скорость и эффективность
Нейронка рецензирует код быстро. Безумно быстро. Она может дать обратную связь за считанные секунды, и в этом с ней не сравнится ни один человек. Поэтому нейронка отлично справится с черновым ревью, перед тем, как код будет тщательно изучен человеком.
Синтаксис и единообразие стиля
ИИ отлично отлавливает синтаксические ошибки, помогает соблюдать нормы оформления кода и придерживаться практик, принятых в компании. Линтеры выполняют эту работу уже не один десяток лет, но ИИ помогает вывести её на новый уровень, так как, исходя из последних обновлений, указывает устаревшие методы или небезопасные приёмы.
Соблюдение стандартов кода
ИИ легко выявляет отклонения от принятых стандартов программирования или обнаруживает конкретные паттерны, противоречащие общепринятым в компании или отрасли. Это особенно помогает обеспечить соответствие стандартам и поддерживать качество кода.
Обеспечение наилучших практик
При работе ИИ может сверяться с распространёнными паттернами и наилучшими практиками, принятыми в конкретных фреймворках или языках программирования. Поэтому он помогает выявлять устаревшие или нежелательные методы, которые можно заменить на более эффективные или безопасные альтернативы.
Низкоуровневые баги и уязвимости в области безопасности
ИИ исключительно эффективен при выявлении низкоуровневых проблем, например, грубых опечаток, распространённых ошибок и потенциальных уязвимостей — например, учётных данных, жёстко вшитых в код, либо точек, в которых удобно выполнить SQL-инъекцию.
Заключение. Без человека по-прежнему никак
В конечном счёте, сегодня человек превосходит ИИ при ревью кода именно потому, что ориентируется в контексте. Человек понимает цели проекта, насколько опытен автор кода, а также с какой целью вносились те или иные изменения. Кроме того, живой ревьюер укрепляет командный дух, работает наставником и отвечает за изменения — на это не способна ни одна машина. Человек учитывает нюансы, помогающие уравновесить конфликтующие приоритеты, учесть компромиссы и гарантировать, что код-ревью пойдёт на пользу как всей базе кода, так и команде, которая с ней работает. Пока ИИ не может в этом отношении заменить человека, он лишь дополняет и расширяет человеческие возможности.
Мы смогли убедиться, что при идеально построенном ревью кода максимально используются сильные стороны как человека, так и нейронки. ИИ эффективен в качестве ассистента, которому можно поручать рутинные задачи, доверять соблюдение стандартов программирования, при этом он быстро выявляет низкоуровневые проблемы. ИИ всегда может быть на подхвате у человека, помогать ему лучше понимать код и гарантировать соблюдение наилучших практик.
Тем временем человек привносит в процесс ревью стратегический подход, глубже понимает код и может сориентироваться в серых зонах, где важны намерения и контекст. Считайте ИИ могучим помощником, которому можно поручить рутинные задачи, а самому заняться более важными делами: продуманно проектировать систему, заниматься наставничеством и вместе писать отличный софт.
Habrahabr.ru прочитано 12856 раз