Вам достался проект, написанный агентом. С чего начать, если никто ничего не понимает?
В предыдущей статье я рассуждал о долге компетенций: AI помогает быстро собрать работающую систему, но люди не всегда успевают разобраться, как её поддерживать и что делать при сбоях.
Представим ситуацию. Вам передали сервис на Rust + MongoDB. Большую часть кода написали AI-агенты, разработчики переключились на другие задачи или ушли из компании. Автотестов почти нет, документация ограничивается README. Сервис уже в продакшене, пользователи им пользуются, а бизнес ждёт новых функций. Причём желательно с той же скоростью, с которой предыдущая команда запустила проект. Никто в вашей команде всерьёз не работал ни с Rust, ни с MongoDB. И это не учебный проект, который можно отложить до лучших времён.
Справедливости ради, такие истории случались и до AI. Помню, как некоторые разработчики спорили, что тесты — пустая трата времени, ведь вместо них можно пилить фичи, а документация нередко существовала только в головах отдельных разработчиков. Теперь к этому добавилась возможность за короткий срок написать большой объём кода на стеке, который никто толком не знает.
Не начинайте с переписывания
Первая реакция может быть предсказуемой: «Зачем нам Rust и MongoDB? Мы знаем Go и PostgreSQL. Давайте всё перепишем».
Проблема в том, что вы пока не знаете, что именно собираетесь переписывать. Переход с документной модели MongoDB на реляционную БД потребует спроектировать схему, перенести данные, переделать запросы и проверить, что старое поведение сохранилось, а в коде могут найтись бизнес-правила и редкие сценарии, которые никто не описал. И тут бизнес вполне закономерно спросит: «А зачем вы всё переделываете? И так все работает нормально, чо начали то?».
Можно заменить одну неизвестную систему другой. Только за ошибки в новой уже будете отвечать вы. Я бы сначала разобрался в состоянии проекта и лишь потом решал, что с ним делать. Тем более продукт продолжает работать, а задачи из бэклога никуда не делись.
Первые две недели: с чего начать
За две недели не получится изучить каждый угол проекта. На старте важнее понять, где изменения можно вносить относительно безопасно, а где команда пока действует вслепую.
В первые дни нужны доступы к репозиторию, окружениям, CI/CD, логам и метрикам. Попробуйте самостоятельно собрать и поднять сервис на отдельном стенде. Если README работает только после пяти устных подсказок прежнего разработчика (или после применения магии), это уже результат проверки. Выясните, кто сейчас отвечает за продакшен, куда приходят алерты и что команда будет делать, если сервис упадёт сегодня вечером. Отдельно проверьте, существуют ли резервные копии и есть ли проверенный способ восстановить данные из них.
До конца первой недели я бы прошёл два-три важных бизнес-сценария: от входящего запроса до записи в БД, ответа клиенту или отправки события. Не нужно читать подряд пятьдесят тысяч строк кода(если решили, то удачи). Нужна простая схема: какие компоненты участвуют в сценарии, что они меняют, где могут возникнуть ошибки и что пока непонятно. Заодно стоит выяснить, можно ли откатить приложение и что будет с данными после миграции. Вернуть старую версию сервиса и отменить изменение данных — разные задачи.
На второй неделе можно переходить к проверкам. Выберите две-три наиболее опасные ситуации из найденных в первую неделю: например, повторный запрос на списание денег, сбой внешней зависимости или потерю соединения с БД. Воспроизведите их на тестовом стенде и добавьте проверки там, где поведение уже удалось подтвердить. Если при этом выяснилось, что по логам нельзя понять причину сбоя, займитесь логированием и метриками. Дальнейшее исследование распределите между разработчиками, а с бизнесом договоритесь, какие задачи можно брать сейчас и какие требуют дополнительных проверок.
Это примерный порядок, а не обещание, что за десять рабочих дней любая команда освоит чужую систему. Важно получать проверяемые результаты: сервис удалось воспроизводимо запустить, тест ловит сбой, который раньше никто не проверял, инструкция по откату испытана на стенде.
Если старая команда ещё на связи
Я бы обязательно воспользовался этим шансом. Попросите разработчиков рассказать не только как работает система, но и почему она стала такой. Почему выбрали MongoDB? Какие альтернативы рассматривали? Какие инциденты уже случались и какие временные обходные решения остались в коде? Особенно полезный вопрос: «Какие части проекта вы сами не стали бы менять без дополнительной проверки?» А если код активно писали агенты — «Что приняли без полноценного ревью и какие сценарии так и не успели проверить?»
Допустим, вы заметили странную задачу по расписанию, которая перезапускает один из компонентов. Возможно, это временный обход проблемы, о которой знают только прежние разработчики. Удалить её как «мусор» опасно: вместе с ней можно вернуть старый инцидент.
Не нужно превращать встречи в разбор чужих ошибок. Если начать с фразы «А зачем вы вообще выбрали MongoDB?», разработчики могут занять оборонительную позицию. Лучше попросить показать один реальный сценарий, который трудно было реализовать, и рассказать, где он ломался. Обычно после этого появляются куда более полезные вопросы, чем на формальной презентации архитектуры.
Отдельно попросите показать, как команда разбирала инциденты: где искала логи, как откатывала релизы, приходилось ли вручную исправлять данные. Особенно интересны операции, которые нельзя просто запустить ещё раз. Такие знания редко попадают в README, хотя при первом сбое понадобятся раньше, чем ADR. Хорошо бы договориться о возможности вернуться с вопросами после нескольких дней самостоятельного изучения. Ответы стоит записать и проверить: люди забывают детали, а код меняется.
Если инцидент случился раньше, чем вы разобрались
Есть неприятный сценарий, который не вписывается в план первых двух недель: сервис падает уже завтра. Команда ещё не изучила стек, а пользователям всё равно, что вам передали проект только вчера. Поэтому я бы заранее договорился, кто руководит разбором инцидента, кто может выполнить откат, где хранятся доступы и кому эскалировать проблему, если своих знаний не хватает. Под рукой должны быть хотя бы логи, история последних релизов и понятный порядок действий при отказе базы или внешнего сервиса. Не обязательно сразу иметь идеальный runbook. Но вариант «спросим у AI и что-нибудь выполним на продакшене» вряд ли можно считать планом.
Отдельно важно понимать процедуру отката. Вернуть предыдущий контейнер иногда просто, а вот восстановить изменённые данные или отменить уже отправленный платёж — совсем другая история. Если процедура восстановления не проверена, это риск, о котором бизнес должен узнать сейчас, а не после первого серьёзного сбоя.
Какие риски проверять первыми
Представим, что у вас сервис с десятками тысяч строк кода, незнакомой базой и почти без тестов. Плохая идея — открыть список технического долга и начать чинить то, что сильнее раздражает на ревью. Начните с цены ошибки, одно дело — запутанный код формирования отчёта, а другое — создание заказа, списание денег, выдача прав доступа или обработка события, которое может прийти повторно.
Рассмотрим процесс покупки: сервис сохраняет заказ в MongoDB, затем отправляет событие в Kafka. Если запись в базе прошла, а публикация не удалась, заказ существует, но следующие сервисы о нём не узнают. Как система обнаружит, что событие не отправилось? Есть ли механизм повторной публикации, например, Transactional Outbox. И что произойдёт, если получатель обработает одно событие дважды? Сам по себе outbox не избавляет от необходимости учитывать дубликаты. Ответ «вроде должно работать» меня бы насторожил.
Необязательно сразу исправлять всё найденное. Более того, попытка закрыть все проблемы одновременно может привести к тому, что команда начнёт чинить их поверхностно, не разобравшись в причинах. Для критического риска стоит записать, что именно может сломаться, как это проверить, как заметить сбой и кто займётся исследованием. Пока ответов нет, серьёзные изменения в этом участке лучше отложить, но работа над более понятными задачами может продолжаться.
И здесь появляется неприятный разговор о сроках. Нельзя обещать прежнюю скорость разработки и одновременно делать вид, что восстановление понимания системы ничего не стоит.
Агент написал код. Что именно проверяли люди?
Все перечисленные проблемы встречаются и в обычном легаси. Не стоит лукавить, будто только агент умеет забыть обработку ошибок или написать лишнюю абстракцию. Разница в скорости, с которой такие решения могут попасть в проект. Агент за короткое время создаст несколько модулей и интеграций, а аккуратная структура репозитория сама по себе ничего не гарантирует.
Допустим, агент добавил API-метод для получения заказа. Код выглядит аккуратно, запрос к базе работает, тесты проходят. Но при ревью выясняется, что обработчик проверяет существование заказа, но не проверяется принадлежит ли он текущему пользователю. Тесты, которые написал агент, проверяли только happy path. В итоге пользователь потенциально может увидеть чужой заказ. Поэтому отдельно проверяйте авторизацию, работу с секретами и сторонние зависимости. AI не уникальный источник таких ошибок, но генерация кода не заменяет ревью безопасности.
Ещё один момент: прежде чем отправлять агенту весь репозиторий или логи, выясните, что разрешено правилами компании. В них могут находиться секреты и пользовательские данные. Желание быстро разобраться в чужом коде не повод создавать новую проблему.
Тесты нужны не ради красивого процента покрытия
Соблазн понятен: попросить ИИ пройти по проекту, написать тесты и получить зелёный CI, но агент может закрепить тестами ошибочное поведение исходного кода.
Представим, что скидка рассчитывается неправильно. Агент читает функцию и пишет проверку ровно на тот результат, который она сейчас выдаёт. Тест проходит, покрытие растёт, ошибка остаётся. Поэтому ожидаемое поведение нужно искать не только в реализации. Подойдут требования, договорённости с продуктом, контракты соседних сервисов, примеры реальных операций. Если ничего не сохранилось, придётся восстанавливать правила вместе с аналитиками и людьми, которые знают продукт.
Я бы начал с нескольких интеграционных тестов на критические сценарии: повторный запрос, ошибка записи, отказ внешнего сервиса. Там, где важно реальное поведение MongoDB, тест должен работать с реальной БД, а не с моками, которые повторяют наши предположения. Проверять взаимодействие нескольких сервисов иногда придётся уже на другом уровне.
Есть ещё characterization tests: они фиксируют, что система делает сейчас. Такие тесты полезны перед рефакторингом, но не доказывают, что текущее поведение соответствует требованиям. Это важно не перепутать.
Как делать новые задачи, пока проект ещё незнакомый
Допустим, продукт просит добавить возможность отменять заказ до передачи в доставку. На словах небольшая фича: добавить API-метод, поменять статус в базе, вернуть ответ. Агент справится с таким заданием быстро, вот только неизвестно, что в этом проекте означает «отменить заказ».
Я бы сначала выяснил бизнес-правила: можно ли отменять оплаченный заказ, кто запускает возврат денег, что делать, если доставка уже начала оформляться, и как ведёт себя система при двух одновременных запросах. Затем прошёл бы текущий сценарий по коду и интеграциям. Возможно, статус заказа читает другой сервис, который о новом состоянии пока ничего не знает. А возможно, возврат уже предусмотрен, только вызывается из другого места.
После этого можно написать тесты на согласованное поведение: отмена разрешена в одних состояниях и запрещена в других, повторный запрос не запускает второй возврат, параллельная обработка не оставляет заказ одновременно отменённым и переданным в доставку. Конкретные проверки зависят от того, как устроены платежи и доставка, поэтому нельзя просто скопировать их из примера. Дальше уже реализация, ревью с участием человека, разобравшегося в соседних компонентах, проверка на стенде и план отката. Если изменение затрагивает схемы или уже исполненные операции, одного отката приложения может быть недостаточно.
Вместо обещания «сделаем за день, ИИ же напишет» появляется более честная оценка: сначала нужно проверить несколько неизвестных. Это не попытка затормозить фичу, а способ не узнать о скрытых связях от пользователей после релиза.
Как изучать стек, который никто не знает
Если команда раньше работала с PostgreSQL, не надо требовать от всех за пару недель стать экспертами по MongoDB. Лучше выяснить, какие её возможности использует конкретный сервис. Если есть операции над несколькими документами, разбираемся с транзакциями и конфликтами. Если основная нагрузка приходится на чтение, смотрим запросы, индексы и планы выполнения. Если приложение использует репликацию, нужно выяснить, какие настройки применяются, какие гарантии нужны продукту.
Здесь обучение через маленькие эксперименты полезнее курса «Mongo за 24 часа» от инфоцыган. В отдельном окружении можно проверить конфликт двух операций, отключить БД, дождаться тайм-аута, вернуть соединение и посмотреть, восстановилось ли приложение. Помню, как сам останавливал PostgreSQL в Docker Compose, чтобы проверить, что произойдёт с подключениями после возвращения базы. На словах кажется, что сервис должен восстановиться. Но лучше один раз увидеть реальное поведение, чем строить план восстановления во время инцидента.
Агент может предложить эксперимент и помочь разобраться с документацией, но выводы придётся проверить. Иногда несколько часов консультации с человеком, который эксплуатировал такую базу в продакшене, полезнее недели самостоятельных поисков. Цель — не выучить всю MongoDB, а научиться безопасно поддерживать именно этот сервис.
Как погружать команду и не стать единственным экспертом
Есть ловушка: техлид сам разбирается в архитектуре, находит проблемы, пишет первые тесты, а затем становится человеком, к которому идут вообще со всеми вопросами. Знания просто переезжают из голов прежних разработчиков в одну новую. Поэтому лучше вовлекать коллег в исследование с самого начала, а не выдавать им готовые выводы на созвоне.
Выдать ссылку на README и показать архитектурную схему недостаточно. Надо давать небольшие задания, по которым понятно, разобрался человек или просто повторил чужое объяснение. Сначала разработчик поднимает сервис и прослеживает один запрос от API до базы или внешнего сервиса. Затем вносит небольшое изменение, добавляет проверку и проходит обычное ревью. Следующее упражнение я бы дал на воспроизведение сбоя: отключить внешнюю зависимость и разобраться, что произошло с запросом и данными. Где искать ошибку? Повторится ли операция? По каким логам это видно?
После этого полезно попросить человека коротко рассказать команде, что он выяснил. Не презентацию на сорок слайдов (которую смотрят, параллельно сидя в телефоне или читая twitter), а разбор одного сценария с демонстрацией.
Если в команде пять разработчиков
Представим, что у вас пять backend-разработчиков. Никто толком не знает Rust и MongoDB, а продуктовый бэклог никто не отменял. Можно назначить одного ответственным за базу, другого — за Kafka, третьего — за деплой, а остальных оставить на фичах, но тогда при отпуске «эксперта по MongoDB» работа с базой встанет. Мне ближе распределение по сценариям. Один изучает создание заказа и запись данных, второй — обработку событий, третий — сборку и деплой, четвёртый — метрики и диагностику, пятый — тестирование критических операций. При этом каждый результат проверяет ещё один участник команды. Если один разобрался с транзакцией, другой должен суметь воспроизвести эксперимент. А следующее изменение в исследованном обработчике можно отдать уже другому разработчику.
Здесь помогают совместная работа и ротация. Ревью должно быть не формальным LGTM, а проверкой предположений, на которых держится изменение. Да, конкретная задача может идти дольше. И время на изучение технологий нужно закладывать в планирование. Нельзя одновременно требовать прежнюю скорость поставки и рассчитывать, что команда освоит новый стек по вечерам.
QA, инфраструктуру, аналитиков и продактов надо подключать к тем вопросам, где у них есть нужные знания. Иногда только аналитик помнит, почему операция должна вести себя именно так. Лучше задать лишний вопрос, чем в пятницу вечером выяснить, что сделали не то. Помните, нет глупых вопросов.
Какая документация нужна в первую очередь
Можно попросить агента сгенерировать описание каждого модуля, десяток диаграмм и README на всё подряд. Получится много текста, который потом все собираются прочитать «когда будет время». Я бы начал с документов, которые понадобятся в конкретной ситуации: как запустить сервис, как проверить его работоспособность, где искать ошибки, как откатить релиз и восстановить данные. Отдельно стоит записывать обнаруженные бизнес-ограничения и причины архитектурных решений. Если причину выбора MongoDB установить не удалось, так и напишите. Не надо просить AI придумать правдоподобное обоснование задним числом.
Лучше обновлять инструкции по мере работы. Проверили восстановление БД — зафиксировали команды и ограничения. Разобрались с повторной доставкой события — описали, что делает обработчик. Хорошая проверка инструкции — дать её разработчику, который не участвовал в исследовании, и посмотреть, сможет ли он выполнить действия без подсказок.
ИИ как помощник, а не источник истины
Я не предлагаю запрещать агентам писать/читать код или помогать с диагностикой. Они могут быстро найти обращения к коллекции, восстановить цепочку вызовов и предложить сценарии отказа. Но если агент утверждает, что код работает правильно, попросите объяснить почему. Затем проверьте выводы тестами или экспериментами — особенно там, где ошибка может привести к потере данных или денег.
В учебном окружении иногда полезно сперва разобраться в проблеме самостоятельно и потом сравнить выводы с ответом агента (понимаю, что лень может взять своё). Во время настоящего инцидента приоритет, конечно, восстановление сервиса, а не проверка чьей-то самостоятельности.
Как объяснить всё это бизнесу. Кто будет все за это платить бабки
Если прийти к бизнесу со словами «нам нужно несколько недель чтобы разобраться с этим ИИ-дерьмом, хз как предыдущая команда его разрабатывала, даже sdd не использовали, а скиллы у них в голове видимо», поддержки можно и не получить. Пользователям нужны новые функции, а история происхождения кода их не интересует.
Я бы начал с последствий. Не подтверждена безопасная повторная обработка платежа, никто не проверял восстановление БД, после определённой миграции нельзя откатить приложение прежним способом. Это уже конкретные риски, последствия которых можно объяснить и оценить вместе с бизнесом. Затем определить приоритеты и согласовать время на проверки. При этом не стоит объявлять запрет на все фичи. Если новая задача затрагивает понятный участок, её можно брать. Если требуется менять критический обработчик, поведение которого команда пока не понимает, сначала нужны проверки. Важно согласовать это явно, а не молча срывать сроки или закрывать риски за счёт постоянных переработок команды.
Прогресс тоже можно показывать без сложных KPI. Раньше никто не мог воспроизвести сбой обработчика — теперь есть тест, который его выявляет. Восстановление из бэкапа существовало только на словах — теперь его проверили на отдельном стенде, а инструкцией смог воспользоваться второй разработчик.
А если проект всё-таки лучше переписать?
Такое вполне возможно, но решение стоит принимать после того, как вы разобрались в текущем поведении и ограничениях. Если главная проблема — отсутствие тестов, переход с Rust на Go не исправит это. Если MongoDB подходит под модель данных, а команда её не знает, иногда дешевле научиться с ней работать, чем переносить всё на PostgreSQL.
Другое дело, если сама архитектура создаёт постоянные проблемы и есть проверенная более простая альтернатива. Тогда можно рассматривать миграцию. Я бы всё равно не переписывал систему одним большим релизом: сначала зафиксировал бы важные сценарии тестами, определил границы изменений и продумал перенос данных. Иначе новая реализация унаследует старые неизвестные, а добавит к ним новые.
Когда можно сказать, что проект освоили
Не тогда, когда у команды появилась дока в конфлуенсе и 80% покрытия. Попробуйте ответить на вопросы: может ли новый разработчик поднять сервис без звонка автору, способен ли кто-то кроме техлида диагностировать сбой, умеет ли команда выпустить и при необходимости откатить изменение, проверяла ли она восстановление данных?
Вывод
Большой проект, написанный с помощью агентов, не обязательно плохой. Но то, что он работает сегодня, ничего не говорит о готовности команды поддерживать его завтра. Можно потратить месяцы на аудит, тесты и документацию, но если при каждом инциденте команда продолжает звонить одному человеку, проблема никуда не исчезла. Вы просто назначили нового ответственного за долг компетенций.
Мой тг канал @tsymbaldev