PING был собран и развёрнут за два календарных дня. Не за двое суток непрерывной работы и не в режиме срочного хакатона. Работа шла с паузами: я формулировал следующую обратную связь, запускал нужную роль Codex, смотрел на результат и решал, куда двигаться дальше.
При этом Codex не был помощником, который дописывал отдельные функции за разработчиком. Он провёл почти весь инженерный цикл: участвовал в постановке проекта, предложил архитектуру, подготовил продуктовые документы, разделил работу на задачи, написал код, создал тесты, провёл ревью, сформировал commits, отправил проект в GitHub и развернул его на нескольких серверах.
Моя роль была другой. Я принёс исходную проблему, обсуждал решение с AI-архитектором и принимал продукт как будущий пользователь. Когда первая версия dashboard заработала, мне не понадобилось пользоваться ей несколько недель, чтобы заметить проблемы интерфейса. За пятнадцать лет работы с веб-проектами сформировался взгляд проектировщика: я вижу, когда элемент находится не там, где его ожидаешь, когда блок занимает место, но не помогает решать задачу, или когда важная информация уходит ниже первого экрана.
Поэтому эта история не о том, как «нейросеть всё сделала». Она о другом: как организовать работу нескольких AI-ролей так, чтобы за короткое время получить не только работающий код, но и продукт, который можно проверить, развернуть и продолжать развивать.
Сначала мы спроектировали не приложение, а процесс разработки
До начала работы над PING были определены три основные роли Codex:
- шеф или архитектор — разбирает исходную задачу, формирует требования, выбирает архитектурные границы и определяет следующий шаг;
- разработчик — получает одну ограниченную задачу, меняет код, пишет тесты и готовит результат;
- ревьюер — независимо проверяет реализацию, сопоставляет её с требованиями и возвращает вердикт.
Это было важнее, чем сразу выбрать FastAPI или начать собирать Docker Compose.
Если одна и та же AI-сессия сама придумывает требования, пишет реализацию и затем объявляет её правильной, возникает замкнутый контур. Ошибка в исходной трактовке легко проходит через архитектуру, код и тесты, потому что все этапы продолжают одну и ту же линию рассуждения.
Разделение ролей не делает модель безошибочной, но создаёт дополнительные точки проверки. Разработчик должен показать, что конкретная задача выполнена. Ревьюер смотрит на результат отдельно и может вернуть его со статусом Needs Revision. Архитектор оценивает, не нарушена ли общая логика проекта и можно ли открывать следующую задачу.
На этом этапе переходы между ролями запускал я. Технически их можно было связать автоматически: после реализации отправлять задачу ревьюеру, при замечаниях возвращать разработчику, после Approved передавать архитектору. Но для первого проекта мне было полезно видеть весь процесс и самому переключать его стадии.
Получился не полностью автономный конвейер, а AI-разработка с ручной оркестрацией ролей.
Контекст и продуктовая задача
↓
Шеф / архитектор
↓
Ограниченная 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 действовал достаточно самостоятельно.
Он:
- Читал PRD, карточку задачи и текущую проектную память.
- Проверял состояние репозитория.
- Изучал существующий код и ограничения.
- Менял необходимые файлы.
- Добавлял или обновлял тесты.
- Запускал
pytest, проверки синтаксиса и Compose config. - Выполнял runtime-проверки.
- Документировал решения, ограничения и остаточные риски.
- Готовил результат для ревью.
После этого отдельная роль ревьюера повторно анализировала изменения. Ревьюер мог запустить собственные тесты, проверить отрицательные сценарии и вернуть задачу разработчику.
Только после успешного ревью архитектор оценивал результат в контексте проекта и определял следующий шаг.
Эта же схема продолжилась за пределами кода. 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-интерфейсом:
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-разработку внутреннего сервиса, ускорить MVP или выстроить процесс с ролями, ревью и безопасными границами доступа, напишите — разберём задачу и определим разумный первый шаг.
Связаться