Недавно я активно занимался отправкой и проверкой пул-реквестов проекта PyTorch, созданных с существенной помощью LLM. Этот процесс сильно отличается ситуации в начале года, когда было понятно, что LLM вполне подходит для проектов, создаваемых с нуля, но для кодовой базы в продакшене их код оставался безнадёжно низкокачественным. Можете посмотреть мои смердженные PR, в описании которых упоминается Claude Code; у Джейсона Энсела тоже был подобный опыт (ссылка на Meta*; также есть список issue, на которые он ссылался в совей статье). Сейчас всё активнее обсуждается (Саймон УиллисонLLVM) то, как процесс код-ревью должен адаптироваться к этой новой эпохе LLM. Мой вклад в эти обсуждения таков: внутри команд код-ревью должен поменяться, превратившись в первую очередь в механизм согласования с человеком.

Вот простой пример: хорошо известно, что LLM склонны генерировать код в излишне защитном стиле. Скажем, они постоянно вставляют повсюду try...catch или проверяют переменную на определённый тип, даже если системные инварианты подразумевают, что они всегда будут этого типа. Если кто-то отправляет мне PR с такими проблемами, я пишу к ним комментарии не только затем, чтобы их устранили. Если бы меня волновало только это, я бы просто отправил свои комментарии напрямую в Claude Code. Настоящая проблема заключается в том, что человек, работающий с LLM, не согласился со мной в том, что этот код в защитном стиле плох, поэтому смысл ревью заключался в том, чтобы мы пришли к общему с ним пониманию, какой код слишком защитный, а какой нет. В самых тривиальных случаях разработчик мог просто не прочитать сгенерированный LLM результат; тогда решить проблему с его стороны можно, прочитав код. Но иногда приходится и выполнять реальную человеческую работу; например, разработчик должен понять какую-то глобальную системную инварианту, чтобы разобраться, необходим ли защитный стиль. Если мы договоримся о глобальных системных инвариантах, то не будет причин с моей стороны выполнять код-ревью: исходный автор кода может просто приказать LLM устранить проблемы и вывести меня за рамки этого цикла, пока он не согласует вывод LLM со своим пониманием, после чего мы уже должны выполнить более затратное согласование между двумя живыми людьми. В идеале я вообще не должен писать комментарии ревью о механических проблемах, потому что они заранее были решены исходным автором.

Верно и обратное: когда я отправляю сгенерированный LLM пул-реквест на человеческое ревью, то пытаюсь передать высокоуровневую информацию. Как работает новый код? Что мне нужно знать об уже имеющейся системе, чтобы понимать этот код? Это даже необязательно указывать в описании PR: если LLM предлагает исправление, которое я не могу понять сам или оно кажется слишком непонятным, то я просто прикажу ей попробовать реализовать его иначе, пока получившийся diff будет очевидно корректным. Токены дёшевы: мы должны ожидать большего от автора кода, потому что затраты на генерацию таких PR сильно снизились. Аналогично, я с готовностью выброшу код и начну сначала; вы не должны испытывать вину за то, что тратите моё время (его писал не я! Я потратил своё время на понимание задачи, и об этом времени я не жалею.)

Многие пытаются продать нам страх того, что разработчики, не освоившие ИИ-инструменты, останутся на обочине. Лично я думаю, что хороший разработчик ПО обладает множеством различных навыков, и ясно, что LLM-кодинг уже сегодня меняет относительный вес этих навыков относительно друг друга. Мне намного важнее способность читать код, рассуждать об общей картине, чётко доносить информацию и обладать хорошим вкусом, чем способность механически писать код. Существует архетип джуниор-разработчика, не очень хорошо справляющегося с кодингом, но обладающего очень хорошими высокоуровневыми софт-навыками; мне кажется, что такие люди будут очень ценны в нашем новом мире. И наоборот: думаю, в будущем я буду быстро терять терпение, если мне придётся снова и снова объяснять кому-то одно и то же, потому что стану меньше ценить сырую «способность кодить». Идеальное для меня состояние напоминало бы нынешнюю мою работу с коллегами-сениорами: я доверяю им в том, что они принимают хорошие низкоуровневые решения, поэтому могу сосредоточиться на общей картине и расширять свою ментальную модель работы системы.

У современных LLM нет памяти: при каждом запуске им приходится заново открывать для себя всю систему. Предназначение людей, предназначение команды заключается в коллективном хранении общего видения того, что система должна делать в целом. Я хочу, чтобы ревью кода трансформировалось в соответствии с этим предназначением.

Meta Platforms*, а также принадлежащие ей социальные сети Facebook** и Instagram**:*признана экстремистской организацией, её деятельность в России запрещена;**запрещены в России

Комментарии (5)


  1. Dhwtj
    06.01.2026 10:03

    Если вам понадобилось защитное программирование, значит у вас плохие (в данном случае, неявные) гарантии инвариантов. Переделайте гарантии инвариантов, чего на LLM пенять то?

    Остальную часть статьи не понял

    Полез в мр. Так и есть. LLM заштопал то что ему сказали (один случай), но не вылечил (надо было гарантировать отсутствие data race в инвариантах).

    Промпт плохой:

    "Fix the thread-safety issue in this test"

    Промпт лучше:

    "There's a thread-safety issue with shared IStreamAdapter.

    Analyze if this is a test bug or API design problem.

    Suggest fix at the appropriate level."

    И желательно самому это увидеть и дать расширенный контекст

    "Here's the test, here's ReadAdapterInterface.h,

    here's getRecord implementation.

    Where should the fix live?"


    1. ToniDoni
      06.01.2026 10:03

      Что плохого в трай кечах и вообще в защитном программировании?


      1. Dhwtj
        06.01.2026 10:03

        Как заплатка нормально

        Но это плохой дизайн или просто не выразительный язык которые не смогли сделать невалидное состояние непредставимым (невозможным)

        try-catch ещё скрывает/ломает control flow, усложняет понимание что может пойти не так. Result/Either делают ошибки явными в сигнатуре - это то что Влашин продвигает в "Domain Modeling Made Functional"


  1. ToniDoni
    06.01.2026 10:03

    Непонятно так как оно должно выглядеть?


  1. MDyuzhev
    06.01.2026 10:03

    Хорошая мысль про «память команды». У LLM нет памяти между сессиями, и кто-то должен хранить контекст. Мы это решаем файлом CLAUDE.md в корне репозитория. Туда скидываем архитектуру, правила, текущий статус. Агент читает при старте и не задаёт глупых вопросов.

    Но самое ценное тут про сдвиг от «как написано» к «зачем написано». Раньше на ревью ловили баги и стиль. Теперь ловим несогласованность в понимании задачи между людьми. Это и раньше была главная проблема, просто теперь от неё не спрячешься за «ну код же работает».