В одной из задач для ashikov.ru я добавлял проверку окончаний файлов. Обычный текст должен был заканчиваться ровно одним LF, Markdown — двумя.
Реализация выглядела законченной. Проверка была встроена в общий make check, положительные и отрицательные сценарии проходили, итоговая команда завершалась успешно.
Отдельное ревью нашло случай, который всё это не покрывало: файл с CRLF мог пройти проверку, хотя нарушал заявленное правило.
Проблема была не в отсутствии тестов. Проверок было достаточно, чтобы убедительно подтвердить решение, но недостаточно, чтобы его опровергнуть.
После нескольких таких случаев я стал иначе относиться к ревью результатов coding agent. Второму агенту полезно давать задачу, правила репозитория и получившееся изменение, но не историю работы первого агента.
Независимость проверки зависит не только от того, кто проверяет результат. Она зависит и от того, какой контекст проверяющий получил до начала ревью.
Чистый контекст — не пустой контекст
Второй агент не должен работать вслепую.
Ему нужны:
- исходная задача или issue
- актуальные правила репозитория
- критерии готовности
- текущее состояние кода
- diff
- доступные воспроизводимые проверки
Этого достаточно, чтобы самостоятельно ответить на вопрос: выполнена ли задача.
Я стараюсь не передавать до первого прохода другое:
- историю диалога с исполнителем
- его план реализации
- объяснение выбранного решения
- результаты собственного self-review
- итоговый отчёт о том, почему работу следует считать готовой
Это уже не контракт задачи, а интерпретация автора.
контекст задачи
→ что должно быть истинно
контекст исполнителя
→ почему он считает, что это уже истинно
Для независимого ревью нужен первый.
Объяснение автора задаёт направление проверки
После завершения задачи coding agent обычно выдаёт хороший отчёт. Он перечисляет изменения, объясняет решения и приводит выполненные проверки.
Для владельца задачи это полезный артефакт.
Для нового ревьюера он может оказаться слишком сильной подсказкой.
Если второй агент сначала получает такой текст:
реализовано A
учтён случай B
проверено C
все проверки проходят
у него уже есть готовая модель результата. Можно проверить перечисленные утверждения и получить ещё одно подтверждение той же модели.
Но мне от второго прохода нужно другое.
Я хочу, чтобы агент сам восстановил связь:
требование
→ реализация
→ доказательство
и попытался найти место, где она разрывается.
Поэтому первым вопросом становится не «правильно ли первый агент сделал задачу», а:
Какие свойства задачи это изменение действительно доказывает и какой контрпример покажет, что доказательства недостаточно?
Так ревью начинается с контракта, а не с объяснения автора.
Как зелёный make check пропустил CRLF
В случае с окончаниями файлов контракт был простым:
обычный текст → ровно LF
Markdown → ровно LF LF
Реализация анализировала последние байты файла. Для обычного текста условие проверяло наличие допустимого LF в конце и отсутствие лишнего LF.
На первый взгляд этого хватало.
Но отдельное ревью проверило обратный вопрос: какие недопустимые последовательности всё ещё удовлетворяют этому условию?
Так обнаружился CRLF.
Последним байтом там тоже является LF. Поэтому проверка могла вернуть успешный результат, хотя перед ним находился запрещённый CR.
Похожий крайний случай существовал и для Markdown.
После ревью условие исправили и добавили регрессионные сценарии именно для этих окончаний.
Для меня здесь важен не сам CRLF. Такая ошибка исправляется несколькими строками.
Интереснее другое: первый проход уже имел работающую реализацию, тестовые сценарии и зелёный общий gate. Дополнительную ценность дало не повторное выполнение тех же проверок, а попытка самостоятельно найти вход, на котором заявленное свойство перестаёт выполняться.
Второй агент должен заново построить доказательство
Если задача первого агента — реализовать изменение, то задача второго должна быть сформулирована иначе.
Первый идёт примерно так:
контракт
→ решение
→ проверки
→ готовый результат
Второму полезнее двигаться от результата обратно:
результат
→ какое свойство подтверждено
→ чем оно подтверждено
→ какие случаи не покрыты
→ соответствует ли это исходному контракту
Такой проход может обнаружить не только ошибку в коде.
Он может показать, что тест проверяет внутреннюю деталь вместо требуемого поведения, отрицательный сценарий отсутствует, часть критериев вообще не имеет доказательства или изменение затронуло область за пределами задачи.
В предыдущем материале независимое ревью было одним из слоёв доказательства готовности coding agent. Здесь для меня важна следующая граница: ревью становится действительно независимым, только если проверяющий самостоятельно восстанавливает это доказательство.
Отчёт первого агента лучше читать после ревью
Отчёт исполнителя я не выбрасываю.
Я меняю порядок.
Сначала второй агент получает задачу и результат и формирует собственный вывод. После этого можно открыть отчёт первого и сравнить две картины.
Тогда отчёт становится дополнительным источником проверки.
Например, исполнитель утверждает, что некоторый сценарий проверен. Ревьюер самостоятельно не нашёл соответствующего доказательства. Это конкретное расхождение, которое нужно разобрать.
Или ревьюер обнаружил существенную границу, которой вообще нет в отчёте первого агента. Значит, эту часть задачи первый проход, вероятно, не доказал.
Получается простой порядок:
реализация
→ self-check исполнителя
→ независимое ревью с чистым контекстом
→ сравнение с отчётом исполнителя
→ исправления
→ повторные проверки
Отчёт автора остаётся полезным, но перестаёт определять направление первого независимого прохода.
Другая модель не обязательна
Для второго ревью можно использовать другую модель. Различия между моделями иногда помогают получить другой способ анализа.
Но сама смена модели не создаёт независимость.
Если второму агенту передать весь диалог первого, его план, объяснение архитектуры и готовый self-review, новый исполнитель всё равно начинает работу внутри уже сформированной модели решения.
И наоборот, новый запуск той же модели с отдельным контекстом может дать полезную проверку, потому что ей приходится самостоятельно восстанавливать требования и доказательства.
Поэтому я разделяю две вещи:
другая модель
≠
независимое ревью
отдельный контекст
→ возможность независимо восстановить доказательство
Смена модели может усилить второй проход. Изоляцию контекста она не заменяет.
Не каждое изменение требует второго агента
Такой процесс нужен не для каждого коммита.
Если изменение механическое, область мала, контракт однозначен, а существующая автоматическая проверка полностью покрывает требуемое свойство, дополнительный агент часто ничего не добавит.
Отдельный проход становится полезнее, когда первый агент сам принимает много решений: выбирает архитектуру, определяет границы изменения, добавляет новые проверки или работает со множеством веток поведения.
Я особенно использую его для изменений в CI/CD, автоматизированных workflow, правилах репозитория и другой логике, где легко получить формально зелёный результат при неполном контракте проверки.
Чем больше свободы было у исполнителя при построении решения и собственного доказательства, тем ценнее независимое восстановление этого доказательства.
Второй агент нужен не для второго мнения
Само количество агентов ничего не гарантирует.
Два агента могут последовательно подтвердить одну и ту же ошибочную модель задачи.
Мне нужен не второй голос, который скажет, что решение выглядит разумно. Нужен второй путь от требований к доказательствам.
Поэтому роли я разделяю так:
первый агент:
реализуй задачу и докажи готовность
второй агент:
не доверяй этому доказательству
и построй своё
Если оба независимо приходят к одному результату, уверенность становится выше.
Не потому, что второй ИИ автоматически умнее первого.
А потому, что ему не дали готовый ответ на вопрос, который он должен был проверить.
