Прямой ответ
LLM-ревью в CI приносит пользу в узкой, но реальной нише: комментарии к диффу — забытый close()/контекст-менеджер, проглоченное исключение, отсутствующая проверка None, несоответствие докстринга коду, явные опечатки в логике условий, — то, что человек-ревьюер замечает на пятом файле диффа, а линтер не формализуется правилом. Настройка, при которой это работает, а не спамит: ревью только изменённых строк (дифф, а не весь репозиторий — контекст и стоимость), промпт с явным «сообщи только о багах и рисках, не о стиле» (стиль — работа линтера, и LLM-замечания о стиле — главный источник шума), порог уверенности (комментировать только «уверен, что это баг» — иначе поток «возможно, стоит рассмотреть» убивает доверие за неделю), и статус в CI — info/soft (не блокирующий: модель ошибается, и блокировка мержа ложным срабатыванием дороже пользы). И отдельный контур — приватность: код уходит в облачный API (политика использования данных провайдера, opt-out из обучения) или остаётся в контуре на локальной модели (Ollama-сценарий) — для закрытых репозиториев выбор осознанный, а не «вставили токен в секрет и забыли».
Что LLM ловит лучше линтера, а что — хуже
Сильные стороны (семантика, а не синтаксис): логические несоответствия (условие противоречит имени функции/документации), незакрытые ресурсы и утечки в неочевидных ветках, опасные дефолты (shell=True, pickle.loads пользовательских данных — инъекции), отсутствующие краевые случаи в новой логике («что если список пуст»), рассинхрон теста и кода. Слабые стороны: стиль и форматирование (ruff/black делают лучше и детерминированно), знание приватных соглашений команды (модель не знает, что self._repo всегда инициализирован в базовом классе — ложные срабатывания), архитектурный контекст за пределами диффа, и главное — уверенность не коррелирует с верностью: правдоподобное «здесь гонка» может быть выдумкой. Отсюда разделение труда: детерминированные проверки (ruff, mypy, pytest, pip-audit) — блокирующие в CI (матрица Actions); LLM — необязательный второй читатель с правом совещательного голоса.
Конвейер: дифф, промпт, постинг
Технически шаг CI прост: git diff origin/main...HEAD → отсев незначащего (lock-файлы, генерат, вендоры — по путям), нарезка по файлам/чанкам (лимит контекста), промпт: «Ты — ревьюер. Только баги, безопасность, корректность. Стиль не комментируй. Формат: файл:строка, серьёзность, объяснение. Если замечаний нет — ответь 'LGTM'». Ответ парсится и постится как review-комментарии к PR (готовые действия или свой скрипт на GitHub API — секреты и токены). Критичные детали практики: детерминизм температуры (temperature 0 — одинаковый дифф даёт одинаковые замечания, иначе повторный прогон шумит по-новому); дедупликация (тот же комментарий на каждом пуше раздражает — хеш замечания и пропуск уже сказанного); стоимость (прогон на каждый push ветки умножает токены — триггер только на synchronize/opened, или только на PR в main); таймаут и деградация (API модели лёг — шаг скипается, CI зелёный: ревью-бот не должен ронять пайплайн). Локальный вариант — тот же конвейер с Ollama на раннере (медленнее, но код не покидает контур).
Фильтр шума: почему боты-ревьюеры надоедают
Главная причина, по которой команды отключают LLM-ревью через месяц, — шум: двадцать «возможно, стоит добавить обработку ошибки» на каждый PR приучают игнорировать и бота, и ревью. Фильтры по убыванию эффекта: ограничение объёма (не больше N замечаний на PR — топ по серьёзности); только новые строки (замечания к коду вне диффа — почти всегда ложные: модель не видит контекста); запрет стиля явным списком в промпте («не комментируй именование, форматирование, отсутствие тестов, документацию»); калибровка по истории (замечания, которые ревьюеры отметают — паттерны в промпт-исключения); серьёзность в пороге (постить только high — «уверен, что баг/уязвимость»). Метрика здоровья бота — доля замечаний, на которые команда отреагировала правкой (не «лайком»): ниже трети — бот шумит, ужесточайте промпт или отключайте. И человеческий фактор: LLM-замечания подписываются как бот и не считаются ревью — аппрув ставит человек (протокол разделения ролей — автоматика советует, решает ответственный).
Практический сценарий: внедрение за день без разочарования
День 1: шаг в CI (готовое action или ~50 строк скрипта: дифф → API → комментарии), триггер — только PR в main, temperature 0, промпт с жёстким «только баги/безопасность, max 5 замечаний, LGTM если нет», статус — не блокирующий. Первые две недели — наблюдение: сколько замечаний, сколько полезных (команда помечает реакцией); по итогам — правки промпта (типовые ложные паттерны в исключения) или отключение «комментариев к тестам» (частый источник мусора). Ключевой момент сценария — бот находит реальную проблему: забытый response.close() в новом обработчике — правка в том же PR, польза осязаема. И контрпример, который сценарий переживает: бот «находит гонку» в однопоточном коде — ревьюер отклоняет одной реакцией, мерж не заблокирован (info-статус), доверие сохранено. Через квартал статистика: ~2 полезных замечания на 10 PR — немного, но каждое на пятом файле диффа человек мог пропустить; бот остаётся как дешёвая страховка, не претендуя на роль ревьюера.
FAQ
Заменит ли LLM human code review? Нет: он не знает бизнес-контекста, соглашений команды и цены ошибки в вашем домене; его роль — первый проход по механическим проблемам до человеческого взгляда (экономия внимания ревьюера на архитектуре и логике). Команды, заменившие людей ботом, получают формально «отревьюенный» код с непроверенными решениями.
Какая модель нужна: облачная или локальная? Облачные сильнее на рассуждениях; локальные (Ollama, модели 8–30B) — приватность и ноль стоимости прогона, качество замечаний ниже, но «забытый close» ловят. Для открытых репозиториев/стартапов — облако с opt-out обучения; для закрытого кода с NDA — локальный контур или on-prem API.
Стоит ли давать LLM запускать тесты и итерировать? Агентные циклы (ревью → правка → прогон) технически возможны (function calling), но в ревью-контексте опасны: автоправки бота без человеческого чтения попадают в main. Разумная граница: бот комментирует, правит человек; автофикс — только для детерминированных инструментов (ruff --fix), не для модели.
Как оценивать качество LLM-ревью до внедрения? Прогоните пайплайн офлайн на истории: последние 50 смерженных PR — сколько замечаний бот дал бы и сколько из них совпало с реальными замечаниями ревьюеров/багами постфактум. Час работы даёт честную оценку до того, как бот начнёт писать в реальные PR.
Источники: документация GitHub Actions, политики приватности LLM-провайдеров, Ollama — ссылки в шапке.