Рынок сейчас охвачен одной светлой надеждой: купить подписку на нейросеть и наутро обнаружить, что команда стала работать вдвое быстрее. Надежда понятная. Примерно с той же надеждой покупают абонемент в спортзал.
Сначала честное предупреждение. Опытные команды с сильным техническим руководством, скорее всего, не найдут здесь ничего нового. Уникального тут нет: всё описанное давно известно и много где работает. Эта статья для тех, кто полноценный процесс разработки в своей компании или команде ещё не отстроил. Я делюсь практическим опытом, на котором у нас держится перевод команды разработки на AI-driven development — разработку, где код пишут AI-агенты под руководством разработчиков.
Нельзя внедрять автопилот там, где не отстроены дороги. Это как будто совершенно очевидная мысль, но почему-то в гонке за переходом на разработку кода AI-агентами про это часто забывают. Поэтому статья не про AI. Она про скучную часть: контроль версий, тесты, сборку, выкатку, бэклог. Тезис простой, как и в прочих материалах моего небольшого канала про AIDD: если технологического процесса нет, агент ускорит разработку ровно до первой ручной выкатки в пятницу вечером. Без конвейера нейросеть похожа на спорткар в утренней пробке: под капотом триста лошадей, а до офиса он доезжает одновременно с соседней малолитражкой.
Ниже — полный цикл на живом примере: от мысли «а хорошо бы…» до момента, когда изменение уже работает у пользователей, а они этого даже не заметили. Для выкатки это лучшая похвала.
Что за зверь
Речь про внутренний сервис компании, хотя аналогичный подход применяется и в клиентских проектах. Сервис вырос, как это водится, из небольшой утилиты и сейчас держит на себе изрядный кусок жизни: управление проектами (проекты же для бизнеса это не только про разработку, верно?), финансовый учёт, управление клиентскими лицензиями Битрикс24, отчётность сотрудников и далее по списку, который удлиняется каждую неделю.
Отдельная и, пожалуй, главная его часть — агентский API. Через него рядовые сотрудники, включая разработчиков, по сути, и работают с Битрикс24: не руками в интерфейсе, а через своих AI-агентов, которым сервис открывает ровно то, что разрешено. Это тема для отдельной статьи, и она вовсе не техническая — она про то, как меняется сама работа людей. Здесь достаточно одного вывода: сервис давно перестал быть игрушкой. Если он лежит, лежит не демо-стенд, а рабочий день.
Значит, менять его надо часто и при этом не ронять. Противоречие известное, и решают его обычно молитвой и словом «аккуратненько».
Бэклог: ничего не придумывали
Первое искушение любой команды — написать свой трекер задач. С канбаном, интеграциями и личной гордостью. Мы удержались.
Весь код живёт в GitHub. Бэклог — это issues и GitHub Projects. Инструмент существует, работает и, что важнее, не требует от нас его поддерживать. Мы не дописывали к нему плагины и не натягивали чужие процессы. Взяли как есть. Мы даже интеграцию с Битрикс24 не делали, потому что нафига? Агент может работать с GitHub и агент может работать с Битрикс24 через тот самый агентский API. Всё. Вот она и интеграция, только гибкая.
Стадий в канбане три, и пока этого хватает:
1. Бэклог — всё, что пришло в голову и записано, чтобы не потерялось.
2. В работе — то, что взяли и делают.
3. Закрыто — фича выпущена или баг исправлен.
Возможно, стадий станет больше. Пока каждая новая колонка выглядела бы как новый стул в приёмной: сидеть на нём некому, а пыль вытирать придётся.
Теперь деталь, ради которой этот раздел и написан. В GitHub Projects у нас почти никто не ходит. На красивую доску посмотрели пару раз, порадовались и перестали. Вся работа с бэклогом замкнута на AI-агента. Пришла идея посреди разговора о чём-то другом — агент через специальный скилл заводит issue, сам кладёт его в нужную стадию и сам вешает метки по нашим правилам. Человеку остаётся сказать фразу. Записывать задачу, искать нужную колонку и вспоминать, как называется метка для «это срочно, но не горит», больше не нужно.
А закрывается задача и вовсе без участия людей. Пулл-реквест ссылается на issue, при слиянии GitHub закрывает задачу и переносит её в «Закрыто». Доска в итоге всегда честная — не потому, что все дисциплинированные, а потому, что дисциплина переложена на автоматику.
Код: в main только через пулл-реквест
Главное правило, которое к тому же реализовано на уровне защиты ветки в GitHub, простое и ни для кого не делает исключений: в основную ветку изменения попадают только через пулл-реквест. Никаких «я быстренько поправлю прямо в main». Быстренько — это самый дорогой вид починки.
Кто пишет код? Весь код пишет агент. Разработчик ставит задачу, следит за своим пониманием задачи и понимание задачи агентом, задаёт вопросы, разбирает предложенное решение и отвечает за результат. Руками код он теперь трогает не чаще, чем раньше трогал документацию. То есть, как вы уже поняли, никогда. Это нормально. Важно другое: агент работает внутри того же процесса, что и человек, — с теми же ветками, тестами и правилами слияния. Скидок на «он же умный» нет.
Тесты проходят трижды.
Первый раз — локально, на машине разработчика, ещё до пулл-реквеста. Агент написал изменение — агент же прогнал тесты. Красное до чужих глаз не доходит.
Второй раз — в CI (continuous integration, непрерывная интеграция: автоматическая проверка каждого изменения), на каждом пулл-реквесте и потом ещё раз после слияния в main. На облачной машине GitHub, не на нашем сервере: проверка стиля кода, проверка типов, тесты, сборка. Слить ветку, пока проверки красные, невозможно — не «нежелательно», а технически невозможно. Заодно GitHub проверяет, не конфликтует ли ветка с основной. Если кто не знал - это стандартные возможности, тут нет магии. Нужен конфиг для GitHub. Любой агент вам его заточит за 5 минут, вы главное - попросите.
Третий раз - при сборке на проде, потому что гладиолус.
Тестов много, и с каждой новой функцией их становится больше. Это не гарантия, что ничего не сломано, — такой гарантии не даёт никто, кроме коммерческих предложений. Но на этом уровне мы проверяем всё, что можем проверить, и знаем, что именно не проверили.
Отдельный тест следит за миграциями базы. Миграции у нас только добавляют: новые таблицы, новые колонки. Удалять и переименовывать запрещено, и запрет держит не устная договорённость, а тест. Зачем — станет понятно через пару разделов.
Выкатка: сервер сам приходит за работой
После слияния в main и зелёного CI начинается выкатка. Вот здесь у многих команд и прячется главный тормоз: один человек, который «знает, как деплоить», и его ноутбук.
У нас выкатку запускает не человек и даже не GitHub. На продакшен-сервере работает агент выполнения задач CI — runner. Он держит исходящее соединение с GitHub и время от времени вежливо интересуется: нет ли для него работы? Когда работа появляется, он выполняет её у себя.
Из этого следует несколько приятных вещей:
в секретах GitHub нет SSH-ключа от продакшена;
на сервере нет входящего порта для деплоя;
нет реестра контейнерных образов: образ собирается прямо на сервере;
секреты приложения лежат только на сервере, в GitHub их нет.

Выкатывается ровно тот коммит, который проверил CI, а не тот, что оказался последним в main к моменту выкатки. Иначе в продакшен могло бы уехать то, что CI ещё не досмотрел.
Релизы идут строго по одному. Начатый релиз никогда не прерывается. Если за это время в очереди накопилось два — выкатывается самый свежий, промежуточный пропускается. Его изменения всё равно входят в свежий.
Blue-green: новую версию ставят рядом, а не вместо
На сервере живут две копии приложения — условно синяя и зелёная — и прокси перед ними. В каждый момент трафик получает ровно одна копия. Какая именно, записано одной строкой в одном файле. Не в голове администратора, не в чате, не в таблице «кто где» — в файле.
Выкатка идёт так:
1. На сервере скриптом собирается образ новой версии.
2. Запускается та копия, которая сейчас простаивает.
3. Проверка здоровья: новая копия должна ответить, что она жива, и назвать номер своего коммита. До тридцати попыток с интервалом в две секунды. Одного «я жива» мало: на том же порту мог остаться старый контейнер, который тоже жив и тоже рад ответить.
4. Если проверка не прошла — стоп. Трафик не тронут, пользователи ничего не заметили, сломанная копия оставлена, чтобы прочитать её логи.
5. Если прошла — прокси переключается на новую копию. Это точка невозврата: до неё любую ошибку исправляет бездействие, после неё — только откат.
6. Старая копия ещё шестьдесят секунд дорабатывает начатые запросы. Самый долгий запрос к Битрикс24 ограничен пятнадцатью секундами, так что запас четырёхкратный.
7. Старую копию останавливают, но не удаляют. Остановленная копия — это готовый откат: её достаточно снова запустить.
8. Уборка: на сервере остаются три последних образа, остальное удаляется.

Теперь про миграции. Шестьдесят секунд обе версии работают с одной базой. Старая версия ничего не знает о новых колонках, но и не падает от них. А вот если бы новая версия удалила колонку, старая упала бы посреди чьего-то запроса. Поэтому запрет на удаление держит тест, а не память о том, почему так нельзя. Память у команды, как известно, коллективная, то есть ничья.
Та же история с фоновыми задачами. Планировщик — напоминания, проверки порталов — тикает в обеих копиях. Чтобы за минуту перекрытия ничего не ушло дважды, каждое действие сначала застолбляется записью в базе. Кто первый записал, тот и выполняет. Второй видит запись и скромно отходит.
Как узнать, что релиз прошёл
Можно, конечно, спросить в чате: «Ну что, выехало?» Но у нас для этого есть способы скучнее и надёжнее:
Комментарий в пулл-реквесте. После выкатки бот пишет в слитый пулл-реквест: релиз выпущен, вот состояние сервиса до и после. Цвет копии между строками должен смениться. Не сменился — значит, трафик никуда не переехал, что бы ни утверждала зелёная галочка.
Статус на коммите — галочка или крестик.
Сводка в Actions — та же таблица до и после.
Журнал выкаток на сервере — каждый релиз и откат с временем.
Если выкатка упала, GitHub присылает уведомление тому, кто слил пулл-реквест. Не всем, не в общий чат, не начальнику — тому, кто слил. Письмо, адресованное лично, хотя бы читают.
Если что-то пошло не так
Что случилось | Что происходит |
|---|---|
CI красный | Выкатка не запускается. Продакшен не тронут. |
Сборка упала | Релиз остановлен до переключения. Продакшен не тронут. |
Новая копия не прошла проверку | Релиз остановлен до переключения. В пулл-реквесте появляется комментарий, что продакшен обслуживает прежний коммит. |
Новая версия работает, но с ошибкой | Скрипт отката запускает прошлую копию и переключает прокси обратно. Ничего не пересобирается, база не трогается. |
Прошлой копии уже нет | Выкатывается один из трёх сохранённых образов. |
Ручной откат на сервере — только для аварий и только по согласию ответственного. Исправление потом всё равно проходит через пулл-реквест. Правило «через PR, а не руками» не отменяется даже пожаром — пожар тушат руками, а ремонт делают по проекту.
Каждую ночь делается резервная копия базы, хранятся семь последних. Порядок восстановления описан заранее, а не будет сочиняться в момент восстановления.
А где стейджинг?
Его нет, и это осознанное решение. Для нашего сервиса отдельное промежуточное окружение было бы переусложнением: ещё один сервер, ещё одна база, ещё одна вещь, которая расходится с продакшеном именно в тот момент, когда на неё полагаются.
При этом ничто не мешает его добавить. Промежуточный сервер, отдельный тестовый портал Битрикс24, прогон пользовательских сценариев в специальном окружении — всё это ложится в ту же схему ещё одной ступенькой. Конвейер для того и строится, чтобы ступеньки добавлялись, а не изобретались заново.
QA тоже делает агент
Последнее звено. После выкатки агенты проверяют не только тесты, но и пользовательские сценарии — прямо в интерфейсе приложения: открыть страницу, нажать кнопку, убедиться, что результат совпал с ожидаемым. Та часть контроля качества, которую раньше делал человек с чек-листом и терпением, тоже автоматизирована.
Терпение при этом, кстати, никуда не делось. Просто теперь оно уходит на постановку задачи, а не на тридцатый клик по одной и той же кнопке.
Итого
Цикл целиком выглядит так:
Идея → агент заводит issue в бэклог с нужными метками.
Задачу берут в работу → агент пишет код в ветке под присмотром разработчика.
Тесты локально → пулл-реквест → тесты и сборка в CI. Красное не сливается.
Слияние в main → задача закрывается автоматически.
Runner на сервере забирает выкатку → blue-green → проверка → переключение.
Комментарий о релизе в пулл-реквесте → агент проверяет сценарии в интерфейсе.
Ни одно из этих звеньев не про AI. Это обычная инженерная дисциплина, известная задолго до нейросетей под скромным названием CI/CD — непрерывная интеграция и доставка. Но именно она превращает «агент написал код за десять минут» в «изменение у пользователей сразу после слияния», а не через неделю согласований, ручной выкатки и вопроса «а кто последний трогал сервер?».
Без неё агент пишет быстро, а выкатывается всё так же медленно. Ускорение остаётся на ноутбуке разработчика и до пользователя не доезжает — как курьер, который очень быстро бегает, но адреса не знает.

Комментарии 0