
Наша компания Octomind занимается созданием ИИ-агентов, но её кодовая база по-прежнему в основном пишется людьми. Мы любим LLM и используем их везде, где можем, от нашего продукта до внутренних рабочих процессов. Но, несмотря на весь хайп, ситуация далека от того, чтобы агенты писали большую часть нашего кода.
У нас есть веские причины на то, чтобы пока не присоединяться к таким компаниям, как Anthropic (генерируется 80%), Microsoft (30%) и Google (25%).

Пока нам недостаёт в них некоторых жизненно важных элементов. В статье мы расскажем, почему это важно, и что нужно, чтобы закрыть эту нехватку.
Эксперименты с кодинг-агентами в повседневном написании кода
Мы уже много месяцев используем Cursor, Claude Code и Windsurf, но никто из нас не может искренне сказать, что они повысили нашу продуктивность существенным образом (допустим, на 20% или больше). Да, автодополнение кода по Tab часто оказывается качественным, и я добился определённого успеха при генерации юнит-тестов, особенно когда можно было копировать уже имеющиеся тесты (например, при появлении новых маршрутов выполнения).
Тем не менее, всё это далеко от заявляемых другими роста производительности на 80 с лишним процентов. Ведомые в равной мере FOMO и любопытством, мы с моим коллегой Фабио решили на прошлой неделе реализовать фичу из дорожной карты полностью при помощи ИИ.
Прежде, чем погрузиться в процесс, мы изучили документацию инструментов, чтобы точно не упустить ничего полезного. Также мы обновили свои правила Cursor и файл CLAUDE.md, чтобы инъецировать в них наши новые знания о продукте и процессе разработки, включили BugBot для ревью написанного ИИ кода и приступили к работе.
Фича, которую мы пытались создать (с помощью ИИ)
Наша компания создаёт платформу сквозного тестирования на основе агентов. Тесты не привязаны к ветвям, а стали центральной частью нашей системы, которая не поддерживает относящиеся к ветвям версии тестовых случаев. Всё это работает нормально, пока пользователи не начинают применять развёртывание по ветвям.
Представьте SaaS-приложение с тремя тестами: логин, создание поста, редактирование поста. Тестируемое приложение разрабатывается с развёртыванием по ветвям для каждого пул-реквеста (PR). Теперь представьте ветвь, меняющую поток логина, допустим, добавлением 2FA. Старый тест логина (проверяющий только имя пользователя + пароль) теперь проходить не будет, блокируя конвейер для этого PR.
На текущий момент у нас есть два варианта действий:
Удалять не проходящий тест, чтобы он не блокировал несвязанные с ним PR, чинить его вручную (или с помощью ИИ), чтобы он обрабатывал новый поток, выполнять мерджинг, а затем снова включать его.
Изменять тест напрямую и мерджить PR; но теперь пока вы не закончите, будут поломаны конвейеры всех остальных разработчиков.
Ни то, ни другое не подходит. Первый блокирует другие; второй нарушает доверие к тому, что вы смерджили.
Для устранения этой проблемы мы хотели расширить концепцию ветвей на наши тесты. При создании ветви можно создать копию теста, относящуюся к конкретной ветви. Копия выполняется только для этой ветви и её можно свободно изменять. При мерджинге ветви она становится новым стандартом.
Мы решили, что два разработчика смогут реализовать эту фичу примерно за неделю.
Первая попытка: во все тяжкие
В нашей первой итерации мы решили поручить работу агентам. Мы не ожидали, что это сработает идеально, но хотели посмотреть, что из этого получится.
У нас монорепозиторий довольно приличных размеров, поэтому невозможно было «просто закинуть всё в контекст». Мы относимся к тестированию серьёзно, поэтому у нас есть меры защиты, позволяющие ИИ проверять результаты своей работы.
Итак, я написал подробное описание и прикрепил к контексту необходимые файлы. Это не было каким-то «чудом, сотворённым крошечным промптом» — я итеративно дорабатывал промпт, чтобы он стал максимально конкретным. Примерно за пять минут агент создал план с одиннадцатью разумными TODO:

Мы нажали на run, и тут всё пошло наперекосяк. Агент начал выдавать строки, но споткнулся на простейших операциях, с которыми легко справился бы любой разработчик, например, регенерации клиента Prisma после изменения схемы базы данных (да, в правилах Cursor об этом было написано).
Я несколько раз повторял процесс, уточняя промпты. Агент сообщил об успехе сообщением: «Теперь фича должна работать правильно! Кнопка fork должна функционировать, а вы должны увидеть форки тестовых случаев при помощи нового фильтра». При этом он:
Не завершил все пункты списка TODO
Не создал ничего, что могло бы работать на нашем сервере разработки (к которому он имел доступ через компьютер)
Игнорировал предоставленные нами простейшие гайдлайны по кодингу
Вот неполный список промахов, которые бы не совершил живой разработчик:
Он создал компонент React для новых кнопок... но не подключил его к существующим компонентам
Игнорировал нашу стандартную библиотеку логгинга
Использовал очень неэффективные запросы к базе данных (выполнял дополнительный запрос каждого ID, join которых выполнялся в другом месте)
Игнорировал наши стандарты наименований и структуры
Добавил две новые внешние библиотеки для тривиальных задач, которые мы уже реализовали
И это я ещё не говорил о багах. Это просто те вещи, которые становятся сразу очевидны и которые не упустил бы разработчик. Да, мы попробовали несколько этапов уточнений «по-прежнему не работает, ты забыл использовать новую кнопку» и другие подобные улучшения. В результате получился PR на две тысячи строк, который требовал ревью и почти полного переделывания.
Вторая попытка: мелкие инкрементные изменения
Я решил начать заново. Мы и не ожидали, что это сработает — предположительно, подобные агенты лучше справляются с небольшими фичами. Поэтому я сделал шаг назад и продумал, как сам бы делал это поэтапно. Именно для подобных рассуждений я и люблю обычно использовать LLM — не для кодинга, а для обмена мнениями в режиме планирования.
Затем я снова попросил его создать план, на этот раз только для первого пункта: загрузки правильного теста из базы данных на основании URL исполнения.
Он сгенерировал ещё один длинный, вроде бы разумный план. Я позволил ему выполнить работу, ожидая на этот раз вмешиваться намного чаще. Спустя множество контекстов у меня получился ещё один пул-реквест.
Примерно 1200 строк кода, и это лишь для одной части. Работает ли он? Ну... как минимум, он проходит проверку типов. Насчёт остального не уверен.
В духе того же эксперимента я передал PR на ревью BugBot. Он оставил четыре комментария; в одном из них говорилось, что поломана обработка транзакций. Это вредит целостности данных, поэтому я перенаправил комментарий в чат с агентом.
Ответ ИИ был таким:
«Разумеется, это огромный недосмотр с моей стороны. Прошу прощения. Сейчас всё исправлю...»
Извинения приняты. Он действительно пропатчил отдельные места кода, а когда я спросил, увидел ли он ещё какие-то проблемы, агент ответил:
Рекомендация
— Исправить целостность транзакций: сделать так, чтобы все вызовы базы данных в getFullTestCasesWithPrerequisites использовали один и тот же клиент транзакций. (И… ещё семь пунктов)
Всё это находилось в одном файле. Единственный контекст, который был ему нужен — это схема базы данных, то есть буквально то, над чем он только что работал.
Кроме того, у него есть привычка упрощать себе жизнь:

Он проверяет наличие ошибок линтера, но только с head -30 и несколькими regex-фильтрами, чтобы убедить себя, что всё в порядке.
Но самое плохое не в том, что он уверенно отметил наполовину сделанную работу, как законченную, извинился за «огромный недосмотр», исправил одно, поломав при этом другое (см. немецкое слово verschlimmbessern), и игнорировал уже имеющийся дизайн и UX.
Самые важные проблемы
1. Утеря ментальной модели
Допустим, агенты теперь могут с небольшой помощью человека выпускать фичи среднего уровня сложности. И даже допустим, что мы устранили проблему «ждём три минуты, потом проверяем тысячу строк вывода», превратив разработчиков из кодеров в менеджеров агентов. Это та мечта, которую продают многие посты на LinkedIn.
Но даже в этом случае сохраняется огромная проблема: я теряю ментальную модель моей кодовой базы.
Сейчас я знаю, как изменение одной части повлияет на другую, где обычно скрываются баги и как ведёт себя модель данных. Это понимание исчезает, когда ИИ вбрасывает PR на тысячи строк, которые иногда даже мерджатся автоматически. Когда так поступает коллега, я верю, что он тщательно всё продумал, и при ревью или продолжении его работы я разберусь в контексте. При работе с ИИ такой цикл обучения теряется.
Поэтому когда появляется сложный баг или фича с пограничным случаем (а с подобными вещами ИИ по-прежнему не справляется), кажется, что я вижу кодовую базу впервые. Наверно, я бегло просмотрю ревью фич, которые ИИ может реализовать сам (если у меня нет инструментов автоматического ревью наподобие CodeRabbit), но это очень далеко от понимания, которое мы получаем при самостоятельном взаимодействии с кодом.
Пока я не смогу полностью доверять ИИ, мне нужно хранить собственную ментальную модель. В противном случае, каждый раз, когда мне придётся делать что-то самому, будет казаться, что я пришёл в новую компанию.
2. Отсутствие саморефлексии
В настоящий момент ИИ плохо справляется с оценкой собственных успехов. Постоянно возникающие подобные ответы только раздражают:


Я попросил его выполнять такие проверки перед реализацией фичи, на что он ответил мне так:
УМЕРЕННАЯ СТЕПЕНЬ УВЕРЕННОСТИ — я могу правильно это реализовать, но с небольшими оговорками:
Общая оценка: я могу правильно реализовать задачу, но это потребует большого внимания к деталям, тщательного тестирования и, потенциально, уточнений об отсутствующих методах и бизнес-логике. Уровень сложности доступный, но не тривиальный.
Это похоже на самооценку живого разработчика, потому что модель попугайски повторяет обучающие данные людей. Проблема в том, что для оценки своих способностей она не должна использовать обучение людей (по крайней мере, до недавнего времени), потому что она не человек.
И это фундаментальная проблема: у модели нет концепции собственных ограничений. О том, может ли она справиться с задачей, вы узнаете только тогда, когда дадите ей попробовать. Стажёр может сказать: «Я такого ещё никогда не делал». LLM крайне вряд ли так поступит.
Хуже того, в нашей следующей маленькой задачей он оценил свои навыки ещё выше:
СЛОЖНОСТЬ: ВЫСОКАЯ — Это рефакторинг приличного размера
МОИ СПОСОБНОСТИ: ВЫСОКАЯ СТЕПЕНЬ УВЕРЕННОСТИ — Я определённо реализую это правильно, потому что:
План очень подробен и в нём конкретно написано, что нужно изменить
Я понимаю текущую архитектуру и поток данных
Изменения соответствуют установленным в кодовой базе паттернам
Этапы реализации чётко определены
Задачу определённо можно реализовать, и у меня есть сильная уверенность в том, что я могу сделать это правильно: достаточно просто поэтапно следовать подробному плану и реализовать всё недостающее.
Хорошие стороны агентов
ИИ совершенно точно может найти своё место в инструментарии разработчика. Я ежедневно пользуюсь ChatGPT и режимом Ask Cursor для мозгового штурма, отладки и решения небольших проблем. Автодополнения по Tab правильны в 80% случаев, то есть они вполне оправдывают своё использование. Я даже отдаю ИИ задачи наподобие написания юнит-тестов для чистых интерфейсов и рефакторинга небольших фрагментов кода. Мне скучно обёртывать цикл в Promise.allSettled, но для ИИ это тривиальная и быстрая задача. Кроме того, он отлично справляется с воссозданием с нуля распространённых паттернов, например, обход древовидной структуры.
А для далёких от техники пользователей автоматизация при помощи ИИ может раскрывать огромные возможности. В нашей компании буквально так и устроена работа: автоматизация технической задачи, но в чётко очерченных границах и при помощи специализированных агентов. Они не пишут кодовую базу целиком, а работают с узкими, наблюдаемыми её частями с последующей проверкой результатов.
Другие специализированные инструменты могут обеспечивать подобный уровень полезности. И может быть, однажды ИИ сможет справляться со всем тем, что рекламируют сегодня (будь то LLM или что-то более совершенное).
Но пока мы к этому ещё не пришли, и and это начинают признавать всё большее количество людей.