AI-агенты генерируют код с темпом, который намного превосходит любые возможности человека по его проверке. Такой сдвиг переносит работу инженера на более высокий уровень: от набора строк в IDE к управлению общей структурой. Агенты могут написать работающую функцию, но более серьезная проблема заключается в том, будет ли система, в которую эта функция вливается, держаться вместе через полгода.
Мэтт Эрман (Matt Erman), старший инженер-программист в Blackboard и автор книги издательства Manning «Grokking Software Architecture», присоединился к Тому Хаулетту в 6-м эпизоде подкаста The Next Commit. Обследование было сосредоточено вокруг проблемы, над которой Мэтт работал с позиции архитектора. Его вывод: основы хорошей разработки программного обеспечения по-прежнему актуальны, но подход команд к их практике должен измениться. Ниже представлен его план действий по сохранению целостности архитектуры в условиях масштабирования генерации кода агентами, а также объяснение того, почему верификация должна взять на себя ту нагрузку, с которой ручной просмотр больше не справляется.
Почему интеллект агента — это проблема, а не решение
Распространенная жалоба на агентов для кодинга заключается в том, что они глупы. Мэтт перевернул это представление с ног на голову, заявив: «[part]часть проблемы с AI-агентами заключается в том, что они слишком умны[/part]», и продолжил: «Они знают весь интернет. Все, что вы вообще можете знать об архитектуре, AI-агент может знать или знает».
Именно эта широта знаний и представляет собой риск. Агент, обладающий в своих обучающих данных всеми архитектурными паттернами и получивший расплывчатую задачу, попытается применить их все одновременно. «Если вы его не ограничите, он по сути возьмет сборную солянку из всех этих разных архитектур, идей и паттернов и просто смешает их вместе, — сказал Мэтт, — потому что он не понимает, чего вы на самом деле пытаетесь добиться».
Большинство инженерных организаций, внедряющих AI-инструменты, сделали важное структурное открытие: ограничения на самом деле являются ключом к успеху. Чем сильнее вы сужаете пространство решений с помощью архитектурных границ, тем больше знания агента превращаются в актив, а не в источник энтропии. «Чем лучше вы можете ограничить его архитектурно, чем лучше вы можете ограничить его границами, тем лучше будут ваши результаты, — сказал Мэтт, — потому что это не позволит агенту выйти за их пределы. Или, если он попытается, сборка упадет, и агенту придется повторить попытку».
Проверка человеком не масштабируется, поэтому прекратите пытаться ее масштабировать
С точки зрения Мэтта, код-ревью силами людей уперлось в стену. «AI-агенты выдают настолько много кода, что проверка человеком становится практически невозможной, потому что ее нельзя масштабировать», — отметил он. «Даже если бы у вас было десять человек, проверяющих код, все, что они бы делали, — это проверяли код и не занимались больше ничем».
Добавьте больше ревьюеров — и вы получите больше точек отказа. Люди устают. Они уходят в отпуск. У них бывает плохой день, и они ставят автоматическую подпись под диффом, который следовало бы поставить под сомнение. Умножьте это на объем, который генерируют агенты в настоящее время, и человеческое ревью становится самым слабым звеном в системе.
Ответом Мэтта на эти вызовы является смещение акцентов в инвестициях. «Вы оптимизируете не код, вы оптимизируете цикл обратной связи», — сказал Мэтт. «Вы по сути масштабируете процесс верификации вокруг агента вместо того, чтобы масштабировать процесс ручного ревью. Потому что именно это в конечном итоге мы сможем масштабировать».
Защитная сетка смещается от человеческого внимания к автоматизированной независимой проверке кода. Цикл работает одинаково каждый раз, на скорости машины и для каждого изменения. Он замечает то, что упускает рассеянный ревьюер, и он не устает.
Функции пригодности: механизм, удерживающий архитектуру на месте
Несущим элементом слоя верификации Мэтта являются архитектурные функции пригодности. Они тестируют то, до чего не могут добраться модульные (unit) и интеграционные тесты: структурные правила самой системы.
«Вы можете писать сколько угодно модульных тестов, — сказал Мэтт. — Они проверят ваш код... но они необязательно проверяют архитектурные границы». Функция пригодности проверяет это. Она гарантирует, что контроллер остается чистым, компонент уважает направление зависимостей, а код не лезет напрямую в базу данных там, где должен проходить через правильный сервисный слой.
Причина, по которой это важно — стоимость. Архитектурное нарушение может не вызывать никаких видимых проблем месяцами. Затем оно усугубляется. «Со временем ваша архитектура продолжает деградировать до тех пор, пока вы не дойдете до точки, когда она просто полностью рухнет», — сказал Мэтт. «Когда это происходит, исправление обходится намного дороже, чем устранение случайного бага в коде, потому что речь идет о фундаментальных компонентах, которые необходимо переделывать и перепроектировать». Баг имеет малую зону поражения, тогда как архитектурная гниль может разрушить все приложение.
Функции пригодности отрабатывают вложенные в них усилия дважды. После реализации они отвергают нарушения и заставляют агента переделать всё правильно. Перед реализацией они выступают в роли исполняемой спецификации. Мэтт встраивает их в инженерные инструкции, которые читает агент перед планированием (в них же описана целевая архитектура). «Поэтому, когда он разрабатывает план, у него уже [всё] распланировано на основе того, как должна выглядеть архитектура». Агент приступает к планированию уже с ограничениями, поэтому он редко отклоняется от курса изначально.
Когда что-то все же ускользает, Мэтт исправляет это, а затем фиксирует защиту. «Единственное, что крайне важно — не просто исправить проблему, но и написать вокруг нее регрессионные тесты», — сказал Мэтт. Каждый дефект, который просочился сквозь фильтры, становится регрессионным тестом — долговечной записью, из которой могут извлечь урок и команда, и агент.
Разбивайте работу на фазы, которые действительно можно проверить
Предоставление агенту возможности реализовать целую фичу за один присест создает кошмар при отладке. Если тесты падают в самом конце, вы понятия не имеете, какая именно часть все сломала. «Вы могли сделать что-то на третьей фазе, что прямо вызвало регрессию на первой, — сказал Мэтт. — Вы понятия не имеете, с чего начинаете».
Его процесс разбивает каждую функцию на фазы, каждая из которых представляет собой чистую границу коммита. Каждая фаза должна отвечать тем же требованиям, что и вся функция целиком. «Все тесты должны проходить, не должно быть никаких регрессий по сравнению с предыдущей фазой», — пояснил он. Успешно пройденная фаза фиксируется как базовая контрольная точка перед началом следующей.
Результатом становится локализация проблем. Когда регрессия обнаруживается на седьмой фазе, а предыдущие фазы зеленые, причина локализована в самом последнем инкременте. «Если во время этой фазы что-то идет не так, вам не о чем беспокоиться, — сказал Мэтт. — Вы просто возвращаетесь назад, берете последний коммит в git и начинаете заново». Это та же самая дисциплина, которая всегда определяла хорошую инкрементальную разработку, примененная теперь для того, чтобы результаты работы агента оставались проверяемыми на каждом шаге.
Архитектура — это масштаб, а не название должности
Одна из самых убедительных мыслей Мэтта заключается в том, что любой, кто вносит изменения в систему — независимо от своей должности, — по сути принимает архитектурные решения. «Каждый раз, когда вы вносите изменения в класс, решаете, какая таблица попадает в базу данных или какие сервисные вызовы совершаются, в конечном итоге все это является архитектурными решениями», — сказал он. «Разница лишь в том, в каком масштабе они принимаются».
Разработчик программного обеспечения принимает решения на уровне границ компонентов. Старший инженер работает на уровне границ приложения. Архитектор смотрит на всю систему в целом. Тот же тип решений, но другой масштаб. Эта концепция становится еще более важной в эпоху агентов, поскольку ценность инженера смещается вверх по цепочке. «Вместо того чтобы инженер писал код на более низком уровне, ценность инженера фактически переходит в плоскость архитектурных суждений», — сказал Мэтт.
Он описал профессиональный рост архитектора как три этапа:
- Сначала приходит осознание: понимание того, как изменения распространяются по системе, кто является потребителями ниже по потоку и что происходит при вызове определенного компонента.
- Затем следует согласование, когда ваша работа начинает соответствовать замыслу системы, а вы понимаете, как и почему всё устроено.
- Ответственность заслуживается в последнюю очередь. «По мере того как вы начинаете завоевывать доверие, вам в конце концов начинают делегировать больше ответственности», — сказал Мэтт. «Это то, что зарабатывается со временем».
Что критически важно, это доверие не распространяется на агента. «Вы не доверяете ИИ-агенту вслепую, но вы доверяете системе верификации, которую вы построили вокруг агента», — сказал Мэтт. «Если вы не доверяете созданной вами системе верификации, она, вероятно, недостаточно хороша». Инженер отвечает за замысел, ограничения и доказательства. Агент действует внутри них.
Главный вывод
Мэтт создал всю свою систему контроля вручную, файл за файлом навыков и функция за функцией пригодности. Это работает для дисциплинированного инженера, обслуживающего одну кодовую базу. Это не масштабируется до уровня организации, которая запускает множество агентов в десятках проектов, где архитектура должна соответствовать единому стандарту независимо от того, какой инструмент написал код.
Здесь его с трудом приобретенный опыт пересекается с тем, чем верификация кода должна стать в масштабе. SonarQube выступает в роли независимого слоя верификации для всего кода и работает во всех трех циклах. В цикле агента он передает архитектурный контекст агентам кодирования в процессе их планирования и написания, поэтому ограничения задаются еще до генерации первой строки. В цикле верификации CI он обеспечивает соблюдение задуманной структуры с помощью шлюзов качества, которые ваша команда уже использует, и отмечает отклонения как проблемы до их слияния. В цикле поддержки кода он обнаруживает вашу реальную архитектуру во всей кодовой базе, выявляя отклонения, которые накапливаются месяцами, а не только нарушения в сегодняшнем диффе. Каждое изменение проверяется по единому многоуровневому стандарту с нулевым доверием и лучшим в отрасли низким уровнем ложноположительных срабатываний, независимо от того, какой инструмент написал код, поэтому инженер сохраняет функцию принятия решений, в то время как слой верификации берет на себя объем работы.
Теперь код пишут агенты. Архитектура по-прежнему остается за вами. Команды, которые заложат это владение в независимый и обязательный к исполнению стандарт, смогут сохранить целостность своих систем и через год.
Слушайте полный разговор с Мэттом Эрманом в подкасте The Next Commit.










