Прошлой весной я выкатил интеграцию с платежами, которой был реально доволен. Мы с агентом строили ее четыре дня. Хэппи-пас работал, тесты проходили, демо выглядело чисто. Я запустил.
Через три недели у пользователя списали деньги дважды: обработка идемпотентности оказалась ненастоящей, потому что ключ был привязан к значению, которое не было уникальным между повторными попытками. Агент написал именно то, о чем я просил. Просто я не подумал спросить, безопасен ли ключ ретрая, и никого рядом не было, кто мог бы мне это сказать.
Вот о чем я хочу поговорить. Не о том, что ИИ пишет плохой код: в большинстве случаев не пишет. Проблема уже и сложнее: когда строишь в одиночку с агентом, некому сказать тебе о том, что ты не додумался проверить.
Пузырь
Работая с агентом, ты заложник того контекста, который дал ему в начале. Ты описываешь, что хочешь, он строит под это описание, и качество результата ограничено качеством твоей постановки задачи. Если в постановке есть дыра, агент не заполняет ее: он уверенно строит вокруг нее, и дыра уходит в прод вместе с фичей.
В команде это переживаемо, потому что ты не единственный голос в комнате. Открываешь пулл-реквест, и на него смотрит кто-то, кто не был у тебя в голове. Коллега говорит: "Подожди, а что будет, если это вызовут дважды?" и дыра закрывается до того, как доедет до продакшена. Код-ревью это именно тот механизм, через который слепое пятно одного человека ловит тот, кто его не разделяет.
В одиночной разработке дыр в пузыре нет. Ты, агент и ваши общие допущения замкнуты в петлю. Ты формулируешь запрос из своей компетентности, агент строит на основе запроса, ты оцениваешь результат той же компетентностью, которой писал запрос. Если ты не знал, что ключ идемпотентности должен выживать при ретраях, никто в этой петле этого не знает. Тебя не поправят. Получишь чистое демо и проблему, которая всплывет позже, в самый неподходящий момент.
Неудобная часть в том, что петля ощущается продуктивной на всем пути. Ты шипишь, тесты зеленые. Реальность приходит позже: пользователь, аудитор, исследователь безопасности, настоящий пиковый трафик. И только тогда выясняется, что проект разошелся с нормой, о существовании которой ты не знал.
Узкое место сместилось с промптинга на верификацию
Восемнадцать месяцев назад сложной частью работы с ИИ было добиться от агента нужного результата. Ты учился промптить: будь конкретным, давай примеры, разбивай задачу. Этот навык важен, он и сейчас важен, но уже не там, где проекты ломаются.
Агенты достаточно хороши, чтобы "сделай то, что я просил" в целом работало. Открытым остался другой вопрос: было ли то, что ты просил, правильным. Узкое место сместилось от "как описать задачу" к "откуда я знаю, что результат готов к продакшену". Второй вопрос сложнее, потому что требует понимания, что значит "готов к продакшену" для кода именно твоего типа, а это как раз те знания, которых не хватает менее опытному соло-разработчику.
Это бьет по изолированным разработчикам сильнее всего, и бьет неравномерно. Сеньор, работающий в одиночку, тоже имеет это узкое место: просто он несет больше стандартов верификации в собственной голове и ловит больше своих пробелов. Фаундер, первый раз делающий SaaS с агентом, сталкивается с тем же узким местом почти без внутренних стандартов, которые его закрыли бы. Инструмент одинаково мощный для обоих. Разница полностью в том, что каждый из них знает, что проверять.
Проблема "волшебных слов"
Мой коллега придумал для этого формулировку, которая у меня осталась. Он называет это проблемой "волшебных слов". Волшебные слова не в том, как промптом заставить агента сделать фичу, а в том, по каким критериям проверять, насколько хорошо он ее сделал. И, что важнее, какие критерии передать агенту, чтобы он мог проверять себя сам.
Загвоздка в том, что таких слов тысячи, и они специфичны под конкретный домен. "Напиши тесты" не волшебное слово, это пожелание. Реальные критерии выглядят так: пиши юнит-тесты на логику и интеграционные тесты на границы; покрывай интеграционными тестами основной бизнес-сценарий, включая крайние случаи; распределяй покрытие так, чтобы интеграционные тесты не дублировали то, что и так проверяют юнит-тесты; не пиши тесты, которые принимают те же ошибочные допущения, что и сам код. Это один узкий угол одной дисциплины. Перемножь на безопасность, обработку данных, состояния ошибок, конкурентность, доступность, контракты API и каждое другое измерение, которому реальный продукт должен соответствовать, и начинаешь понимать масштаб.
В команде тебе не нужно держать все это в собственной голове, потому что команда держит это коллективно. Инженер, которому важна безопасность, поймает дыру в авторизации; тот, кто год назад обжегся на гонке состояний, заметит баг конкурентности. В одиночку тебе нужно либо знать все волшебные слова самому, либо получить их откуда-то за пределами пузыря. Большинство не могут знать их все. Так что настоящий вопрос: откуда берутся волшебные слова, если у тебя их нет?
Откуда берется внешняя оценка, когда работаешь один
По большому счету, есть только три источника стороннего мнения, и стоит честно обозначить, чего стоит каждый.
- Коллега. Самый качественный вариант и тот, которого у соло-разработчика по определению нет. Ближайшие замены: платный ревью от фрилансера-сеньора, технический советник или сообщество. Можно запостить свой подход в тематическом Discord или на форуме и спросить, чего не хватает. Это работает, но медленно, нерегулярно и настолько хорошо, насколько хорош тот, кто случайно ответил. До "на каждый коммит" не масштабируется. Как правило, дает вердикт по тому, в чем ты уже подозревал риск, а не по тому, о чем вообще не думал спросить.
- Стандарт. Кодифицированные нормы существуют по делу: OWASP для веб-безопасности, профильный compliance-фреймворк для твоего домена, гайды по стилю языков и фреймворков, референсные архитектуры. Стандарт самый дешевый из доступных внешних мнений, потому что написан и ждет тебя. Его ограничение: нужно знать о существовании стандарта, прежде чем идти его проверять, и нужно уметь правильно применять. Стандарт сам не придет и не скажет, что он здесь уместен. За ним нужно идти, а это возвращает тебя к проблеме пузыря, но уровнем выше.
- Сервис. Эта категория за последний год выросла быстрее всего: инструменты, созданные специально для того, чтобы быть сторонним мнением. Статические анализаторы и линтеры существуют давно. Новая волна: системы непрерывного сканирования, заточенные конкретно под код, сгенерированный ИИ. Инструменты, которые следят за кодовой базой во времени и проверяют ее по закодированным критериям: утечки секретов, галлюцинированные зависимости, логика контроля доступа, которая ломается между коммитами, тесты, похожие на тесты, но ничего не проверяющие. Часть запускается как CI-чек, часть работает как постоянный агент, который сам открывает пулл-реквесты с исправлениями.
Скажу честно об ограничениях, потому что это правда: никакой сервис не заменяет понимания собственного продукта. Сканер ловит категории, которые кто-то догадался закодировать. Он не поймает доменную ошибку, которую никто не предвидел, или бизнес-логическую ошибку: идеально валидный код, делающий ровно не то. Что эти инструменты делают хорошо: снижают стоимость проверок, которые поддаются кодификации. Тогда твое ограниченное внимание идет на то, что кодификации не поддается. Используемые так, они ближайшее к ревьюеру на каждом коммите, чего соло-разработчик может добиться. Используемые как гарантия, они становятся новой версией того же ложного ощущения безопасности, которое и привело к проблеме.
Этот пробел закрывает Enji Guard: сервис, который гоняет ИИ‑написанный код через правила конкретного проекта и проверки безопасности и зависимостей на каждом изменении, а не только при мерже.<br />Важно понимать, что это только один из сервисов, который может помочь в качественном ревью, но он не сможет покрыть все возможные проблемы при генерации кода.
