Как ревьюить код, написанный ИИ
На что смотреть в изменениях от ассистента, какие признаки должны насторожить и как устроить ревью, чтобы оно не превратилось в формальность.
Код от ассистента читается легко. Имена аккуратные, комментарии на месте, структура знакомая. Именно поэтому его опасно ревьюить по привычке: привычное ревью ищет следы спешки и небрежности, а здесь их нет. Ошибки ИИ выглядят иначе — это уверенно написанный код, который делает не совсем то, что нужно.
Сначала размер
Ассистент охотно меняет двадцать файлов там, где хватило бы двух: заодно переименует, заодно «улучшит», заодно переформатирует. Такой дифф нельзя прочитать внимательно, и его не читают — его пролистывают.
Первое правило ревью: изменение должно быть такого размера, чтобы его можно было понять целиком. Если нет — его возвращают с просьбой разбить. Это не придирка, а условие, без которого всё остальное бессмысленно.
Читай не только то, что в диффе
Дифф показывает изменённые строки, но не показывает, кто их вызывает. Ассистент мог поменять сигнатуру функции и поправить два вызова из пяти. Мог добавить новый обработчик, не подключив проверку прав, которая есть у соседних. Открой места использования и соседние файлы — там часто и лежит ошибка.
Красные флаги
Что мы ищем в первую очередь:
- Дубликаты. Новая функция
formatPrice, хотя в проекте уже естьformatMoney. Ассистент не всегда видит весь код и решает задачу заново. Через полгода в проекте три способа сделать одно и то же, и они расходятся. - Проглоченные ошибки.
try/catch, который возвращаетnullили пустой массив. Приложение не падает — оно тихо показывает пустоту, и никто не знает почему. - Отключённые проверки.
any,@ts-ignore,eslint-disable,--no-verify. Ассистент снимает препятствие самым коротким путём. - Изменённые тесты. Тест падал, и его «починили», поменяв ожидаемое значение. Каждое изменение в тестах требует объяснения, почему старое ожидание было неверным.
- Выдуманные API и пакеты. Метод библиотеки, которого нет в установленной версии, или пакет с правдоподобным названием, которого не существует — или, хуже, существует, но опубликован не тем, кем ты думаешь.
- Заглушки в боевом коде. Демо-данные «на случай, если API не ответил», захардкоженный пользователь,
TODO: добавить проверку. - Доверие клиенту. Цена, роль, идентификатор владельца берутся из тела запроса.
- Запросы без границ. Выборка без пагинации и лимита, запрос в базу внутри цикла.
- Комментарии, которые не совпадают с кодом. Комментарий говорит «проверяем права», а строки ниже их не проверяют. Ассистент описывает намерение, а не результат.
Порядок, который работает
- Начни с задачи. Прочитай, что просили сделать, а потом смотри, сделано ли именно это — не больше и не меньше.
- Потом тесты. Они показывают, что автор считает правильным поведением. Если тестов нет, а изменение касается денег или доступа, — это первый комментарий.
- Запусти. Пять минут ручной проверки сценария ловят то, что не видно в тексте.
- Спроси автора. «Почему здесь так?» Если человек, отправивший изменение, не может объяснить строку, её не должно быть в продакшне — неважно, кто её написал.
Кто отвечает
Самое важное правило не техническое. Код, который сгенерировал ассистент, принадлежит тому, кто отправил его на ревью. «Это ИИ написал» не объяснение, а признание, что автор его не читал. Ревьюер, в свою очередь, отвечает за то, что одобрил.
Если ревью превратилось в нажатие кнопки «одобрить», лучше честно это признать и договориться о меньших изменениях, чем делать вид, что код кто-то проверил.
SUBXCAT может провести ревью кодовой базы, собранной с ассистентом, и помочь настроить процесс, в котором такие ошибки ловятся до продакшна.