Как проверить PR от AI-агента и удалить лишние изменения
Практический процесс проверки PR, созданного AI-агентом: зафиксировать критерии приёмки, изучить полный diff, провести независимый обзор в новом контексте, удалить лишнее малыми шагами, повторить проверки и оставить окончательное решение человеку.
Содержание

AI-агент может быстро исправить ошибки или реализовать функцию, но вместе с этим переформатировать посторонние файлы, добавить абстракции, изменить конфигурацию или переписать больше кода, чем требует задача. Перед слиянием важна не минимальная длина diff сама по себе. Нужен набор изменений, где каждое существенное решение связано с требованием, сопровождающий может его объяснить, а команда — проверить тестами или другими доказательствами.
Один разработчик описал в X личный приём: после создания PR он запускает второго агента в новом контексте и просит найти то, что можно сократить или удалить. Автор прямо отметил дополнительные затраты времени и токенов и не представлял метод как гарантированное решение. Другой пользователь сообщил, что Codex исправил множество ошибок, но изменил код настолько широко, что пользователь перестал его понимать. Это примеры проблемы, а не доказательство того, что второй агент всегда улучшает PR.
В процессе ниже второй агент играет роль критичного рецензента, а не судьи. За область изменений, доказательства, риски и итоговое решение отвечает человек.
Процесс из семи шагов
- Зафиксировать контракт приёмки: требуемое поведение, то, что нельзя менять, допустимую область и команды проверки.
- Собрать точный список изменений через Conversation, Commits, Checks, Files changed и локальные команды Git.
- Передать агенту с новым контекстом только задачу на анализ; в первом проходе запретить редактирование.
- Для каждого замечания выбрать: оставить, упростить, удалить, вынести в другой PR или передать человеку — обязательно с доказательствами.
- Применять только одобренные сокращения небольшими обратимыми порциями.
- До и после сокращения выполнять один и тот же релевантный набор тестов и проверок.
- Полностью перечитать финальный diff и сливать только то, что сопровождающий способен объяснить.
1. Сначала составьте контракт приёмки
Формулировка «сделай PR чище» слишком расплывчата и провоцирует новую субъективную переработку. Короткий контракт должен содержать:
- Проблему и наблюдаемый результат: что увидит пользователь или вызывающий код.
- Сохраняемое поведение: интерфейсы, ошибки, совместимость и семантика данных, которые нельзя нарушить.
- Допустимую область: ожидаемые модули, API, схемы, конфигурацию и тесты.
- Явные нецели: без обновления фреймворка, глобального форматирования, посторонних переименований и «запаса на будущее».
- Ограничения по риску: безопасность, права, миграции, производительность, наблюдаемость, откат и обратная совместимость.
- Проверку: реальные команды проекта для форматирования, lint, типов, тестов, сборки, миграций и E2E.
Если правильный результат нельзя описать, нельзя надёжно определить и лишний код. Сначала уточните контракт.
2. Изучите полный diff, а не пересказ агента
GitHub распределяет контекст PR по нескольким представлениям: Conversation содержит описание и обсуждение, Commits — историю ветки, Checks — автоматические проверки, Files changed — фактический diff. Официальный процесс ревью позволяет комментировать строки, предлагать изменения, отмечать файлы как Viewed и завершать проверку решением Comment, Approve или Request changes.
Для локального запуска GitHub предлагает:
gh pr checkout <PR_NUMBER>
git fetch origin
Замените origin/main на настоящую базовую ветку и получите обзор изменений от общего предка до HEAD:
git diff --stat origin/main...HEAD
git diff --name-status origin/main...HEAD
git log --oneline origin/main..HEAD
По документации Git, git diff A...B показывает изменения от merge base A и B до B. После статистики прочитайте полный diff и подозрительные пути:
git diff origin/main...HEAD
git diff origin/main...HEAD -- path/to/suspicious-file
На этом проходе ничего не удаляйте. Разделите файлы на группы:
| Группа | Контрольный вопрос |
|---|---|
| Основная реализация | Реализует ли файл конкретный пункт контракта? |
| Необходимая поддержка | Действительно ли нужны тесты, документация, миграция или конфигурация? |
| Расширение области | Есть ли глобальное форматирование, массовые переименования, посторонние абстракции или обновления зависимостей? |
| Сгенерированные файлы | Должны ли они храниться вместе с исходником или попали в PR случайно? |
| Неопределённый риск | Затронуты ли безопасность, данные, совместимость или неизвестная рецензенту область? |
Сложность сама по себе не доказывает избыточность. Защитные проверки, миграции и ветки совместимости могут быть длинными, но обязательными.
3. Новый контекст — для анализа, не для немедленного редактирования
Ценность нового контекста в другой цели: не завершить реализацию, а оспорить область и доказательства. Это практический приём из пользовательского отчёта, а не требование GitHub и не измеренная гарантия.
Передайте агенту контракт, полный diff, важные вызовы, тесты и правила репозитория. Подойдёт такой запрос:
Ты выполняешь вторую проверку этого pull request как сопровождающий. Цель — не переписать код, а найти минимальный объяснимый набор изменений, который сохраняет контракт приёмки.
Первый проход — только анализ. Не меняй файлы.
Прочитай цель PR, полный diff, связанные вызовы, тесты и ограничения репозитория.
Для каждого замечания укажи:
1. файл и точный hunk или символ;
2. требование, которому служит изменение;
3. доказательство: вызов, тест, контракт интерфейса, документация или отсутствие доказательства;
4. риск удаления или упрощения;
5. действие: ОСТАВИТЬ / УПРОСТИТЬ / УДАЛИТЬ / ВЫНЕСТИ / РЕШЕНИЕ ЧЕЛОВЕКА;
6. точную проверку после изменения.
Правила:
- не предлагай удаление только из-за длины или другого стиля;
- зелёные тесты не являются единственным доказательством корректности требований;
- особенно проверяй постороннее форматирование, дублирующие абстракции, неиспользуемые функции, рефакторинг вне задачи и необъяснённые изменения зависимостей или конфигурации;
- сохраняй безопасность, совместимость, миграции, обработку ошибок и наблюдаемость без явных контрдоказательств;
- отмечай неопределённость и не выдумывай бизнес-правила;
- в конце предложи план сокращения от низкого риска к высокому. Код не пиши.
Формат «сначала отчёт» не даёт рецензенту создать ещё один крупный рефакторинг под видом сокращения. Каждое предложение должно ссылаться на файл, участок и доказательство.
4. Решение по каждому замечанию принимает человек
| Решение | Когда подходит | Что нужно подтвердить |
|---|---|---|
| Оставить | Код реализует контракт или обязательную безопасность, совместимость, миграцию, эксплуатацию | Связь с требованием, путь вызова, тест, интерфейс или документированное ограничение |
| Упростить | Поведение нужно, но реализация дублирует ветки, обёртки или уровни | Эквивалентность поведения и покрытие важных границ |
| Удалить | Изменение не связано с задачей, не используется или является случайным форматированием/переименованием | Поиск по репозиторию, сборка и релевантные тесты не показывают зависимости |
| Вынести | Работа полезна, но не входит в текущий контракт | Её можно отдельно описать, протестировать, проверить и откатить |
| Передать | Затронута незнакомая область, безопасность, миграция или скрытое правило | Нужен владелец кода, эксперт или characterization test |
Подозрительными, но не автоматически лишними, являются: много общих слоёв вокруг одного вызова; две реализации без описанного периода совместимости; массовое форматирование; новая зависимость или конфигурация без объяснения; тесты, проверяющие форму реализации вместо поведения; подавление всех исключений; помощники без вызовов; код «на будущее».
Отсутствие теста тоже не доказывает ненужность. Это может быть пробел покрытия. Сначала зафиксируйте текущее поведение тестом или привлеките владельца модуля.
5. Сокращайте малыми порциями и оставьте точку восстановления
Перед изменениями проверьте рабочее дерево и создайте локальную резервную ссылку:
git status --short
git branch backup/ai-pr-before-trim
Чтобы целиком вернуть файл к состоянию общей базы:
BASE=$(git merge-base origin/main HEAD)
git restore --source="$BASE" -- path/to/unrelated-file
Для отдельных участков используйте интерактивный режим:
git restore -p --source="$BASE" -- path/to/file
Git предупреждает: если отслеживаемого пути нет в источнике восстановления, команда удалит путь, чтобы соответствовать источнику. Проверяйте $BASE и путь, а затем сразу смотрите diff. Можно править вручную; важно не добавлять новый посторонний рефакторинг.
Обрабатывайте одну одобренную группу за раз:
git diff
git add -p
git diff --cached
git commit -m "Remove unrelated changes from AI-generated PR"
Небольшие коммиты показывают, что удалено, почему и какой проверкой это подтверждено. Не скрывайте процесс разрушительным переписыванием истории во время ревью.
6. До и после используйте сопоставимую проверку
Тесты должны подтверждать сохранение принятого поведения, а не просто уменьшение diff. По возможности сохраните результат исходного PR и повторяйте те же релевантные команды после каждой порции:
<format-check-command>
<lint-command>
<typecheck-command>
<targeted-unit-test-command>
<relevant-integration-test-command>
<build-or-e2e-command>
Берите команды из документации проекта или CI. Проверяйте нормальный путь, важные границы и ошибки, права, пустые значения, конкурентность, тайм-ауты, повторы, публичные интерфейсы, форматы данных, миграции, сборку, типы, lint, безопасность и обязательные GitHub Checks.
Если после удаления тест падает, верните эту порцию или восстановите её из резервной ветки, затем выясните причину. Не меняйте одновременно тест и реализацию только ради зелёного статуса, если человек не подтвердил, что старое ожидание действительно неверно.
Зелёный набор тестов важен, но может быть неполным. Понимание сопровождающего остаётся обязательным.
7. Перечитайте финальный diff и оформите решение
После сокращения снова откройте Files changed и пройдите все файлы. GitHub снимает отметку Viewed с файла, если после просмотра он изменился, поэтому такие файлы нужно проверить заново. Снова проверьте Commits и Checks и убедитесь, что результаты относятся к последнему коммиту.
Можно выполнить ещё одно независимое ревью финального diff, но задайте условие остановки: только замечания с доказательствами, без бесконечного стилистического рефакторинга. Затем человек отправляет решение:
- Approve — контракт выполнен, изменения объяснимы, риски обработаны, проверки прошли.
- Request changes — осталась лишняя область, непонятная логика или падающие проверки. Блокировка слияния зависит от правил репозитория и защиты ветки.
- Comment — обратная связь нужна, но это не одобрение и не формальный запрос изменений.
Чек-лист перед слиянием
- Каждый изменённый файл связан с требованием, необходимым тестом или явно описанной поддержкой.
- Сопровождающий способен объяснить важные hunks своими словами.
- Необъяснённые зависимости, конфигурации, права, миграции и сгенерированные файлы удалены, вынесены или переданы эксперту.
- Исходный и сокращённый PR проверялись сопоставимым набором команд.
- Локальные тесты, сборка и проверки последнего коммита соответствуют правилам проекта.
- Риски безопасности, данных и совместимости проверены владельцем области.
- Если diff всё ещё слишком широк, независимые изменения разделены.
- Решение ревью и последующие задачи записаны.
Типичные сбои и восстановление
Второй агент снова переписывает модуль
Остановите выполнение, верните режим «только отчёт», ограничьте доступные файлы и потребуйте для каждого предложения hunk, требование и проверку. Эстетический рефакторинг без доказательств отклоняется.
Агенты спорят
Не голосуйте. Сравните вызовы, интерфейсы, пути отказа, тесты и исторические ограничения. При слабых доказательствах временно сохраните код, добавьте покрытие или позовите владельца области.
Тесты зелёные, но код непонятен
Покрытие не равно понятному дизайну. Разделите PR, добавьте документацию или потребуйте объяснить критический путь. Непрозрачный код нельзя сливать только из-за зелёного CI.
Надёжных тестов нет
Добавьте минимальный characterization test или выполните повторяемую ручную проверку с записанным результатом. Для рискованного кода отсутствие доказательств — повод остановиться, а не разрешение агенту гадать.
PR слишком велик
Разделите основное поведение, рефакторинг, обновления зависимостей, форматирование и миграции на независимо проверяемые изменения. Небольшие PR проще проверить и откатить.
Запрос для выполнения уже одобренных изменений
Реализуй только одобренные пункты: [СПИСОК ID].
Не меняй файлы вне списка и не выполняй попутный рефакторинг.
Для каждой логической группы:
1. покажи фактический diff;
2. запусти назначенные команды проверки;
3. сообщи команды, коды завершения и краткое описание ошибок;
4. перечисли оставшиеся неопределённости.
Остановись и запроси решение человека, если пункт меняет контракт приёмки, публичный интерфейс, безопасность или миграцию.
Смысл процесса не в том, чтобы «добавить ещё одного агента». Генерация и проверка разделяются: один контекст предлагает реализацию, другой оспаривает область и доказательства, а человек отвечает за выбор и приёмку. Нужен не самый короткий diff, а минимальный объяснимый и проверенный набор изменений, который решает задачу.
Источники и границы выводов
- Личный опыт: пост и ответы Arnav Gupta в X о проверке сокращений в новом контексте. Это не общая статистика.
- Пользовательский отчёт: автор написал, что после исправлений Codex перестал понимать широко изменённый код; оригинал не содержит репозитория, diff или результатов тестов.
- Документация GitHub: проверка предлагаемых изменений, локальное получение PR, справка по pull requests.
- Документация Git: git diff и git restore.