Разбор

Два дня с Codex: как AI-команда довела внутренний MVP от идеи до production

PING был спроектирован, разработан, проверен, отправлен в GitHub и развёрнут с помощью Codex. Разбор того, как роли, ревью и границы доступа превратили AI-разработку в управляемый процесс.

Автор: Сергей Кауров Опубликовано: Обновлено: Тема: AI и автоматизация

Схема AI-команды, которая ведет MVP от задачи до production
Место для изображения материала: схема ролей, задач, ревью и production-деплоя в AI-разработке.

PING был собран и развёрнут за два календарных дня. Не за двое суток непрерывной работы и не в режиме срочного хакатона. Работа шла с паузами: я формулировал следующую обратную связь, запускал нужную роль Codex, смотрел на результат и решал, куда двигаться дальше.

При этом Codex не был помощником, который дописывал отдельные функции за разработчиком. Он провёл почти весь инженерный цикл: участвовал в постановке проекта, предложил архитектуру, подготовил продуктовые документы, разделил работу на задачи, написал код, создал тесты, провёл ревью, сформировал commits, отправил проект в GitHub и развернул его на нескольких серверах.

Моя роль была другой. Я принёс исходную проблему, обсуждал решение с AI-архитектором и принимал продукт как будущий пользователь. Когда первая версия dashboard заработала, мне не понадобилось пользоваться ей несколько недель, чтобы заметить проблемы интерфейса. За пятнадцать лет работы с веб-проектами сформировался взгляд проектировщика: я вижу, когда элемент находится не там, где его ожидаешь, когда блок занимает место, но не помогает решать задачу, или когда важная информация уходит ниже первого экрана.

Поэтому эта история не о том, как «нейросеть всё сделала». Она о другом: как организовать работу нескольких AI-ролей так, чтобы за короткое время получить не только работающий код, но и продукт, который можно проверить, развернуть и продолжать развивать.

Сначала мы спроектировали не приложение, а процесс разработки

До начала работы над PING были определены три основные роли Codex:

  • шеф или архитектор — разбирает исходную задачу, формирует требования, выбирает архитектурные границы и определяет следующий шаг;
  • разработчик — получает одну ограниченную задачу, меняет код, пишет тесты и готовит результат;
  • ревьюер — независимо проверяет реализацию, сопоставляет её с требованиями и возвращает вердикт.

Это было важнее, чем сразу выбрать FastAPI или начать собирать Docker Compose.

Если одна и та же AI-сессия сама придумывает требования, пишет реализацию и затем объявляет её правильной, возникает замкнутый контур. Ошибка в исходной трактовке легко проходит через архитектуру, код и тесты, потому что все этапы продолжают одну и ту же линию рассуждения.

Разделение ролей не делает модель безошибочной, но создаёт дополнительные точки проверки. Разработчик должен показать, что конкретная задача выполнена. Ревьюер смотрит на результат отдельно и может вернуть его со статусом Needs Revision. Архитектор оценивает, не нарушена ли общая логика проекта и можно ли открывать следующую задачу.

На этом этапе переходы между ролями запускал я. Технически их можно было связать автоматически: после реализации отправлять задачу ревьюеру, при замечаниях возвращать разработчику, после Approved передавать архитектору. Но для первого проекта мне было полезно видеть весь процесс и самому переключать его стадии.

Получился не полностью автономный конвейер, а AI-разработка с ручной оркестрацией ролей.

text
Контекст и продуктовая задача
            ↓
    Шеф / архитектор
            ↓
   Ограниченная task card
            ↓
       Разработчик
            ↓
     Тесты и отчёт
            ↓
        Ревьюер
       ↙         ↘
Needs Revision  Approved
       ↓           ↓
 Разработчик   Архитектор
                   ↓
       Следующая задача или приёмка

Архитектор получил контекст, а не готовое техническое задание

Работа над проектом началась с описания ситуации.

Клиентские сайты периодически не открывались у части пользователей. При этом серверы продолжали работать, а проблемные запросы могли не появляться в access- и error-логах. Нужно было понять, какие данные позволят отличить сбой приложения от региональной, сетевой или инфраструктурной проблемы.

Я не приносил архитектору заранее выбранный стек и подробную схему таблиц. Мы обсуждали:

  • какие вопросы должна закрывать первая версия;
  • какие серверы уже можно использовать;
  • какие данные действительно нужны для диагностики;
  • что должно находиться в центральном приложении;
  • как должны работать независимые точки наблюдения;
  • что сознательно не войдёт в MVP;
  • какие риски появляются при локальной разработке и production-деплое.

Архитектор предлагал варианты и объяснял компромиссы. Из разговора постепенно появились продуктовая модель, PRD, ограничения MVP и набор отдельных задач.

Так был выбран компактный стек: FastAPI для central API и dashboard, SQLite для масштаба первой версии, Docker Compose для воспроизводимого запуска, отдельные лёгкие сервисы для точек наблюдения. AI в runtime-логике самого PING не понадобился: HTTP-коды, timeout и сетевые ошибки лучше классифицировать обычными детерминированными правилами.

Получился показательный контраст: сам продукт не использует AI для принятия решений, но почти весь продукт был создан с помощью AI.

Большая задача стала серией маленьких проверяемых изменений

Формулировка «создать систему мониторинга сайтов» слишком велика для надёжного исполнения — человеком или моделью.

Архитектор разделил проект на последовательные задачи:

  • подготовить локальную среду;
  • создать основу central application;
  • определить модель данных;
  • добавить API для точек наблюдения;
  • реализовать сам сервис проверки;
  • добавить авторизацию и dashboard;
  • вывести историю и график;
  • настроить retention;
  • подготовить Docker Compose и документацию;
  • развернуть central и точки наблюдения;
  • улучшить интерфейс после просмотра результата.

У каждой задачи были:

  • конкретная цель;
  • ограниченный scope;
  • список затрагиваемых файлов или слоёв;
  • критерии приёмки;
  • проверки;
  • явно записанный Out of Scope.

Последний пункт особенно важен для AI-разработки. Модель часто способна увидеть соседнюю проблему и попытаться исправить её вместе с основной задачей. Иногда это полезно, но в реальном проекте незаметное расширение scope увеличивает риск и усложняет ревью.

Поэтому разработчик должен был не просто «улучшить dashboard», а выполнить определённый набор изменений и не трогать, например, схему данных, probe API или production-конфигурацию, если этого не требовала задача.

Декомпозиция превратила большую AI-задачу в серию небольших проверяемых изменений.

Во-первых, результат каждой итерации можно было проверить отдельно. Во-вторых, следующая задача строилась на уже принятом состоянии проекта, а не на предположении, что большая генерация когда-нибудь сойдётся в работающую систему.

Codex выполнял работу полного цикла

Внутри каждой задачи разработчик Codex действовал достаточно самостоятельно.

Он:

  1. Читал PRD, карточку задачи и текущую проектную память.
  2. Проверял состояние репозитория.
  3. Изучал существующий код и ограничения.
  4. Менял необходимые файлы.
  5. Добавлял или обновлял тесты.
  6. Запускал pytest, проверки синтаксиса и Compose config.
  7. Выполнял runtime-проверки.
  8. Документировал решения, ограничения и остаточные риски.
  9. Готовил результат для ревью.

После этого отдельная роль ревьюера повторно анализировала изменения. Ревьюер мог запустить собственные тесты, проверить отрицательные сценарии и вернуть задачу разработчику.

Только после успешного ревью архитектор оценивал результат в контексте проекта и определял следующий шаг.

Эта же схема продолжилась за пределами кода. Codex самостоятельно работал с Git, GitHub и серверами. Он создавал commits, выполнял разрешённый push, подключался по SSH, загружал файлы, собирал контейнеры, проверял health endpoint и анализировал логи.

Человек не набирал эти команды вместо него. Человек определял, продолжать ли процесс и соответствует ли результат задаче.

Два дня получились не за счёт спешки

Когда звучит формулировка «MVP за два дня», легко представить два дня непрерывной генерации кода.

В этом проекте всё было спокойнее. Между отдельными итерациями были паузы. Я смотрел результат, формулировал замечания, передавал их архитектору и запускал следующую роль. Значительная часть времени была не занята ручным программированием, потому что его выполнял Codex.

Скорость появилась из сочетания нескольких факторов:

  • архитектура и документация создавались в том же контуре, что и код;
  • не было ожидания передачи задачи между разными людьми;
  • разработчик сразу запускал тесты и готовил отчёт;
  • ревьюер получал уже структурированный результат;
  • архитектор хранил контекст проекта и формировал следующую задачу;
  • технические операции на GitHub и серверах выполнялись тем же инструментом;
  • продуктовая обратная связь быстро превращалась в новые task cards.

Но скорость не означала, что весь продукт появился из одного промпта. Наоборот, результат складывался из большого количества небольших переходов: постановка, реализация, проверка, возврат, повторная проверка, приёмка.

Работающий dashboard ещё не был удобным dashboard

Первая версия PING технически решала задачу.

Точки наблюдения выполняли проверки, central сохранял результаты, dashboard показывал сайты, статусы, график и историю. Тесты проходили. Основной сценарий работал.

Но при первом просмотре интерфейса стало видно, что его нужно переделывать.

Не потому, что им долго пользовались и постепенно накопились жалобы. Достаточно было открыть страницу и оценить её как рабочий инструмент.

Некоторые проблемы считывались сразу:

  • важная информация не помещалась на первом экране;
  • вертикальные интервалы делали страницу длиннее без практической пользы;
  • полный дневной график занимал много места и был перегружен;
  • часть элементов управления находилась далеко от данных, которыми управляла;
  • отдельные блоки повторяли одну и ту же информацию;
  • подписи и заголовки были крупнее, чем требовала их функция;
  • фильтры были технически доступны, но располагались не там, где их ожидаешь;
  • таблица деталей требовала более понятной навигации;
  • английские подписи мешали восприятию внутреннего рабочего интерфейса.

Это была не проверка кода. Это была продуктовая оценка.

За пятнадцать лет в веб-разработке я проектировал и видел достаточно интерфейсов, чтобы замечать такие вещи без длительного пользовательского исследования. Опыт не даёт абсолютной гарантии, что любое решение будет идеальным. Но он позволяет быстро увидеть очевидное: какой элемент забирает внимание, где нарушена иерархия, почему пользователь потеряет контекст и что можно убрать без потери смысла.

Я формулировал проблему интерфейса, архитектор превращал её в задачи

Я не всегда описывал обратную связь в терминах конкретных CSS-свойств или функций.

Формулировки могли быть продуктовыми:

Основная информация должна помещаться на первом экране.

Фильтры должны находиться рядом с графиком.

Этот блок занимает место, но не даёт нового ответа.

Выбор периода должен одинаково управлять графиком и таблицей.

Размер элементов не должен отвлекать от самих данных.

Задача архитектора состояла в том, чтобы превратить такое наблюдение в технически исполнимую итерацию.

Например, требование «сделать экран компактнее» раскладывалось на конкретные изменения:

  • убрать отдельную шапку выбранного сайта;
  • сократить вертикальные отступы;
  • пересобрать сводную таблицу;
  • удалить дублирующие колонки;
  • перенести легенду и фильтры;
  • уменьшить подписи осей;
  • приблизить control количества строк к pagination;
  • локализовать интерфейс;
  • сохранить состояние фильтров в URL;
  • не менять при этом API, схему данных и расчёты uptime.

После этого задача уходила разработчику, проходила тестирование и ревью, а я снова смотрел на результат.

Иногда изменение принималось сразу. Иногда выяснялось, что технически корректное решение всё ещё выглядит не так, как должно. Тогда архитектор обновлял требования, а задача возвращалась на новый цикл.

Именно здесь проявилась полезная граница между продакт-оунером и AI-архитектором.

Я отвечал за то, что должно стать удобнее и почему. Архитектор отвечал за то, как разложить это на изменения, не разрушив остальные части системы.

Человек не обязан читать каждую строку, но обязан понимать результат

В традиционном представлении контроль разработки часто связывают с ручным просмотром всего кода.

При работе с Codex это не всегда лучший способ использовать время. Если человек обязан заново выполнить всю работу модели, выигрыш от автоматизации исчезает.

В PING контроль строился через систему доказательств.

Для каждой задачи оставались:

  • исходные требования;
  • список изменённых файлов;
  • автоматические тесты;
  • результаты runtime-проверок;
  • review-отчёт;
  • описание принятых решений;
  • список того, что не менялось;
  • остаточные риски;
  • commit, соответствующий принятой версии;
  • следующий шаг.

Я не переписывал код за разработчиком и не вручную повторял каждую серверную команду. Но я мог проверить, что задача не вышла за границы, результат соответствует продуктовой цели, а критичные файлы не попали в Git.

Ответственность человека не исчезает — она перемещается с ручного исполнения на управление процессом и приёмку результата.

Разные роли нужны ещё и потому, что Codex ошибается

Самостоятельность Codex не означает безошибочность.

В проекте были ситуации, когда задача формально выглядела выполненной, но следующая проверка находила проблему.

Один из показательных примеров — локальный режим без авторизации. Для быстрой UI-разработки был создан отдельный Docker Compose, в котором dashboard открывался без формы входа. В коде действовал fail-closed guard: отключение авторизации разрешалось только при сочетании PING_ENV=development и PING_AUTH_DISABLED=true.

Функциональные тесты проходили. Но финальное ревью обнаружило другой уровень риска: порт 8000 публиковался на всех интерфейсах хоста. То есть локальный dashboard без авторизации потенциально мог быть доступен не только через localhost.

Задача вернулась на доработку. Публикацию ограничили loopback-интерфейсом:

yaml
ports:
  - "127.0.0.1:8000:8000"

После этого снова прошли Compose-, HTTP- и auth-проверки.

Другой пример возник при production-обновлении через нестабильное SSH-соединение. Codex загрузил файлы в промежуточную область, но проверка контрольных сумм показала, что передача завершилась не полностью. Процесс остановился до замены рабочих файлов и пересборки контейнера.

Эти ситуации важнее рассказа о том, сколько тестов прошло. Они показывают правильную установку процесса:

Мы не предполагали, что модель не ошибётся. Мы строили контур, в котором ошибка должна быть обнаружена до того, как станет production-инцидентом.

Git был границей между работой модели и публичным результатом

Codex самостоятельно выполнял Git-операции, поэтому правила репозитория были частью архитектуры AI-разработки.

В публичный GitHub не должны были попадать:

  • .env;
  • реальные production-конфиги;
  • пароли и токены;
  • приватные ключи;
  • SQLite-базы;
  • локальные копии production-данных;
  • runtime-каталоги;
  • внутренняя проектная память и служебные файлы AI-процесса.

В репозитории оставались код, тесты, безопасные примеры конфигурации и публичная документация.

Перед commit Codex проверял git status, staged changes и состав файлов. Commit должен был соответствовать конкретной принятой задаче. Push выполнялся отдельно — после того как локальная версия была принята и было подтверждено, что именно отправляется в remote.

Здесь человек контролировал не каждую команду git add, а соблюдение правила:

Публичная история проекта должна содержать только те артефакты, которые действительно предназначены для публикации.

Это особенно важно для AI-инструмента, который способен одновременно читать проектную память, production-документацию, локальные конфиги и исходный код. Наличие доступа к файлу не означает, что файл должен попасть в commit.

Локальная разработка получила отдельную безопасную среду

Для интерфейсных итераций не хотелось каждый раз проходить production-подобную авторизацию и пересобирать контейнер после изменения Python-кода.

Codex подготовил отдельный Local Compose:

  • без подключения production .env;
  • без admin password hash и session secret;
  • с bind mount исходного кода;
  • с uvicorn --reload;
  • с отключением login только в явном development-режиме;
  • с публикацией только на 127.0.0.1.

Это ускорило итерации интерфейса, но не ослабило production-контур.

Такой пример хорошо показывает, что безопасность AI-разработки — не запрет на удобные режимы. Наоборот, локальная среда должна быть удобной, иначе появятся неформальные обходы. Но удобство должно быть ограничено средой и не переноситься в production случайным флагом.

Деплой тоже выполнял Codex

Проект не использовал сложный автоматический CI/CD pipeline.

Но называть деплой ручным тоже неточно: команды выполнял Codex.

Он:

  • проверял локальную версию;
  • подключался к серверу;
  • подтверждал текущее состояние;
  • создавал backup;
  • загружал разрешённые файлы;
  • сверял контрольные суммы;
  • собирал или перезапускал нужный сервис;
  • проверял внутренний и внешний health endpoint;
  • проверял закрытость dashboard для неавторизованного пользователя;
  • анализировал логи;
  • подтверждал поступление результатов от точек наблюдения;
  • документировал итог.

Ручной была оркестрация. Я запускал deployment-задачу и следил, чтобы Codex не выходил за её границы.

Например, в задаче могло быть разрешено пересобрать только central application, но запрещено останавливать точки наблюдения, менять базу или использовать --remove-orphans. Если требовалась операция с более высоким риском, она оформлялась отдельно.

Для масштаба MVP такой подход оказался рациональнее, чем немедленно строить отдельную инфраструктуру CI/CD. При этом сам runbook уже содержит основу будущей автоматизации: preflight, backup, staging, checksum, запуск, проверки и rollback.

Код после AI остался обычным инженерным кодом

Есть опасение, что AI-разработка создаёт код, который работает только до первой следующей функции.

В PING этому противостояли не специальные «правила для нейросети», а обычные инженерные практики:

  • небольшие задачи;
  • явные слои;
  • тесты;
  • ограниченные зависимости;
  • документация решений;
  • рефакторинг после стабилизации поведения;
  • отдельные шаблоны и стили;
  • проверяемые интерфейсы между central и точками наблюдения;
  • отказ от преждевременного усложнения.

Например, первая версия dashboard содержала слишком много представления внутри Python-кода. После стабилизации интерфейса архитектор выделил отдельную задачу на рефакторинг web-слоя: HTML перенесли в Jinja2 templates, пользовательские стили — в отдельный CSS, а Python оставили маршрутизацию, запросы и подготовку context.

Это изменение не добавляло новой пользовательской функции. Оно делало следующую итерацию безопаснее.

Так и проверяется развиваемость AI-кода: не тем, насколько «по-человечески» он написан, а тем, можно ли локально изменить один слой, пройти тесты и не сломать соседние сценарии.

Скорость дала не только модель

Было бы неправильно объяснить двухдневный результат только возможностями Codex.

Модель действительно выполнила огромный объём работы. Но скорость появилась из системы:

  • у проекта был конкретный внутренний пользователь;
  • проблема была хорошо понятна;
  • scope MVP оставался небольшим;
  • архитектор декомпозировал работу;
  • разработчик не ждал ручной передачи контекста;
  • ревьюер работал с теми же артефактами;
  • Git и deployment находились в том же контуре;
  • продуктовая обратная связь была быстрой и конкретной;
  • пятнадцать лет опыта позволяли сразу замечать слабые решения интерфейса.

Без последнего пункта Codex мог бы построить технически корректный dashboard и остановиться на первой версии. Он не знает сам по себе, какой объём информации нужен именно мне на первом экране и какой порядок действий кажется естественным в моей рабочей практике.

Это появилось из сочетания AI-исполнения и человеческого опыта.

Что в таком процессе остаётся за человеком

Даже если автоматизировать передачу задач между ролями, у человека остаются функции, которые нельзя свести к нажатию кнопки «Approve».

Понимание исходной потребности

Формально корректная система может решать не ту проблему. Человек знает, зачем продукт создаётся и какой результат действительно полезен.

Продуктовый вкус

Тест может подтвердить, что фильтр работает. Но он не скажет, удобно ли его искать, не занимает ли он лишнее место и соответствует ли интерфейс ожиданиям пользователя.

Приоритеты

Архитектор может предложить несколько разумных улучшений. Человек решает, какое из них важно сейчас, а какое не стоит усложнения MVP.

Ответственность за границы

Codex способен выполнить опасную команду так же быстро, как безопасную. Человек определяет, какие данные, серверы и операции вообще допустимы в текущем процессе.

Финальная приёмка

Approved от ревьюера означает, что реализация соответствует требованиям. Но только владелец продукта может сказать, что сам результат его устраивает.

Не один промпт, а управляемая AI-команда

PING появился не потому, что удалось придумать особенно длинный запрос.

Сначала были определены роли. Затем в диалоге с архитектором появилась продуктовая модель. Большая задача превратилась в последовательность небольших изменений. Разработчики Codex реализовывали их, ревьюеры проверяли, архитектор сохранял целостность проекта, а я принимал результат как продакт-оунер.

За два спокойных календарных дня этот процесс прошёл путь от исходной проблемы до работающего production.

Самое важное здесь не скорость и не сам факт использования Codex.

AI ускоряет исполнение только тогда, когда работает внутри понятной структуры:

  • роль знает свою функцию;
  • задача имеет границы;
  • результат оставляет проверяемые артефакты;
  • ревью отделено от реализации;
  • Git отделяет рабочее состояние от публичного;
  • production-операции ограничены;
  • человек оценивает не только правильность кода, но и полезность продукта.

Такой процесс можно автоматизировать сильнее. Роли могут сами передавать задачи друг другу, а проверки — запускаться без участия человека.

Но автоматизация переходов не отменяет главного: у продукта должен оставаться владелец, который понимает исходную задачу, видит результат целиком и способен сказать не только «это работает», но и «этим удобно пользоваться».

Продолжить по теме

Материал относится к теме «AI и автоматизация». На странице темы можно пройти дальше по связанным материалам: от общих принципов внедрения до архитектуры, компонентов, ограничений и кейсов.

Открыть базу знаний AI и автоматизация AI-компоненты Архитектура систем

Обсудить похожую задачу

Если вы хотите организовать AI-разработку внутреннего сервиса, ускорить MVP или выстроить процесс с ролями, ревью и безопасными границами доступа, напишите — разберём задачу и определим разумный первый шаг.

Связаться