Почему ревью кода с ИИ не должно быть полностью автономным¶
Самый очевидный способ сделать ИИ-ревьюера — webhook: появляется merge request, модель читает diff, публикуются комментарии. Это первая идея, которая приходит всем, и именно её я отказался реализовывать, потому что уже оказывался по другую сторону такого инструмента. Бот, оставляющий двенадцать комментариев в каждом MR, примерно за неделю приучает команду пропускать все двенадцать, включая единственный важный. Эта статья об альтернативе, на которой построен mr-review: модель готовит черновик, человек принимает решение, и в MR не попадает ничего, чего он предварительно не прочитал. Цикл намеренно медленнее, но только такой вариант, по моим наблюдениям, команды продолжают использовать.
Далее описана текущая реализация mr-review по его документации и исходникам; на момент написания актуальна версия 0.2.2.
Что идёт не так, когда публикует бот¶
Три проблемы, усиливающие друг друга.
Шум. Модель, которой поручили проверить diff, найдёт что сказать о каждом фрагменте: ведь её об этом попросили. Замечания о стиле, пересказ кода, предложения добавить docstring, вопросы об имени переменной. Каждое можно обосновать; вместе они скрывают единственный комментарий о том, что цикл повторных попыток может дважды списать деньги. Ревьюеры привыкают к низкой ценности замечаний бота и читают их как вывод линтера — то есть пролистывают.
Уверенная чепуха. Иногда модель ошибается, причём связными предложениями и с готовым исправлением. Человек в такой ситуации обычно выражает сомнение, модель — нет. В публичном MR на комментарий теперь нужен ответ, и автор десять минут объясняет боту перед коллегами, почему код правильный. Именно такой опыт заставляет инженеров ненавидеть инструмент.
Усталость. Каждый комментарий требует времени автора и ревьюера. Когда большинство замечаний бесполезны или неверны, затраты ничего не дают, и разумная реакция — перестать их нести: отключить уведомления бота, массово закрывать обсуждения или тихо попросить его убрать. Главный провал автономного ревьюера не в плохой проверке, а в том, что его игнорируют. Вместе со всеми остальными пропускают и то ревью, которое могло предотвратить инцидент.
Все три проблемы следуют из одного решения: вывод модели отправляется прямо в MR. Поставьте между ними человека — и каждая проблема изменится.
Последовательность этапов¶
Ревью в mr-review проходит четыре этапа и движется только вперёд:
Brief определяет задание модели. Режим thorough, security, style или performance задаёт акцент; переключатели — контекст рядом с diff; произвольные инструкции — особенности репозитория. Точный промпт можно получить текстом до отправки, поэтому вопрос «что мы у неё спросили?» никогда не остаётся загадкой.
Dispatch отправляет промпт модели, получает потоковый ответ и разбирает его на комментарии: файл, строка, важность от critical до suggestion и текст. От модели требуется простой JSON-массив. Если вместо него приходит обычный текст, весь ответ сохраняется как один suggestion, а ошибка разбора показывается пользователю. В MR пока ничего не изменилось.
Polish — этап, которого нет в автономной схеме. Комментарии появляются в интерфейсе, и человек читает их. Можно изменить текст или важность, можно отклонить замечание. Здесь двенадцать превращаются в три. Уходят два замечания о стиле, пересказ и уверенная чепуха — прежде чем кому-то пришлось отвечать. У замечания о повторных попытках повышается важность и уточняется формулировка: человек знает кодовую базу, а модель — нет.
Post публикует оставшиеся комментарии с отметкой kept как замечания к строкам MR и завершает итерацию. Получается короткое ревью, за которое поручился человек и под которым стоит его имя.
В инструменте нет получателя webhook, планировщика и режима CI; документация прямо перечисляет это среди отсутствующих возможностей. Проверка начинается по действию человека. Это ограничение определяет весь дизайн.
Человек задаёт контекст репозитория до анализа и утверждает замечания перед публикацией. Автоматическое ревью готовит основания для решения.
Что добавляет человек¶
Легко принять этап редактирования за страховку, позволяющую ловить ошибки модели. Но человек в процессе даёт ещё две вещи, которых модели принципиально не хватает.
Первая — контекст за пределами diff. Модель видит изменение; ревьюер знает, что endpoint вызывает мобильный клиент, который нельзя обновить ещё год, что в 03:00 с этой таблицей работает задача обслуживания партиций, что команда в прошлом квартале решила не добавлять сюда кеширование. Технически верное, но неуместное замечание знающий человек отклоняет за секунду. Без этих знаний понадобилось бы целое обсуждение.
Вторая — оценка того, что вообще стоит говорить. Ревью — сообщение коллеге, и с ростом длины его ценность падает. Модель не чувствует этого ограничения. Человек чувствует и применяет его: результат похож на отзыв внимательного инженера, использовавшего инструмент.
Помощник ревьюера, а не контролёр слияния¶
Рабочая модель такова: ИИ помогает ревьюеру, а не решает судьбу MR. Он без усталости читает весь diff, замечает пропущенный await на четырёхсотой строке, проверяет каждый путь ошибки по требованиям режима безопасности и передаёт результат тому, кто подпишет ревью. Решение принимает человек. Команда получает отзыв человека.
Так инструмент остаётся честным и относительно собственных ограничений. Подключить можно и локальные модели: поддерживается любой совместимый с OpenAI API. Локальная модель обычно выдаёт больше шума и ошибок, чем передовая; при автономном подходе эта разница попадает в MR, здесь — на этап редактирования, где стоит ревьюеру нескольких дополнительных отклонений и ничего остальным. Снижение качества модели не разрушает процесс, потому что последнее слово остаётся за человеком.
Цена такого подхода¶
Человек в процессе медленнее webhook, а ревью не появляется само. Нужно открыть инструмент, выбрать MR, запустить анализ, отредактировать и опубликовать результат — несколько минут на проверку. Команде, желающей заменить ревьюера ботом, инструмент не подойдёт: здесь он ускоряет человека и помогает ему проверять тщательнее. Для команды, уже отключавшей автономного ревьюера, несколько минут — цена того, чтобы отзывы вообще читали.
mr-review работает в одном или двух контейнерах с GitLab, GitHub, Gitea, Forgejo и Bitbucket, поддерживает модели Anthropic и совместимые с OpenAI API, а результаты хранит в YAML на диске. Развёртывание описано во вводной статье. Вся его конструкция — эти четыре этапа.
Главное здесь — третий этап. На входе двенадцать комментариев, на выходе три, и под ними имя человека.