Я отдал разработку мессенджера двум AI. Код заработал, статья — нет

Когда заблокировали Telegram, я решил написать свой семейный мессенджер.

Точнее — решил не писать его.

Мне давно было интересно, насколько далеко можно зайти с coding agents на задаче, которая уже не похожа на лендинг, CRUD или очередной todo-list. Мессенджер — хороший кандидат: backend, база, несколько клиентов, синхронизация, состояния сообщений, push-уведомления, авторизация, deployment. Ошибки быстро перестают быть локальными: одно устройство считает сообщение прочитанным, другое ещё нет, третье просыпается от push и должно корректно восстановить состояние.

Я рассказал идею web-LLM. Сейчас уже не помню, был это ChatGPT или Claude. Дальше буду называть его ChatGPT — здесь важнее роль, чем конкретная модель.

ChatGPT превратил идею в большой стартовый prompt, потом разбил его на пять последовательных заданий step 1, step 2, step 3, step 4, step 5. А выполнять их я отдавал Codex CLI.

Получилась странная команда из трёх участников:

  • ChatGPT — архитектор и планировщик;
  • Codex — разработчик;
  • я — человек, который переносил задания из одного окна в другое, запускал работу и проверял, что получилось.

То есть в первой версии этого процесса я буквально работал API между двумя AI.

Программный код я руками не писал.

Через несколько дней у меня был большой кроссплатформенный проект с backend, базой, Android, iOS, Desktop, Web, push, синхронизацией и развёртыванием на сервер.

Потом я неделю пытался пользоваться им как настоящим мессенджером.

На этом эксперимент можно было бы закончить. Но я решил сделать ещё один шаг: раз AI написал приложение, пусть AI напишет и статью о том, как он это сделал.

Но пришёл ответ модератора Habr:

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

В итоге код, написанный AI, дошёл до работающей системы.

Текст, написанный AI, до публикации не дошёл.

И именно после этого мне стало интереснее не то, может ли AI написать мессенджер, а другой вопрос: что вообще остаётся разработчику, если он больше не пишет код?

Задача была настоящей

Причина проекта была прозаической.

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

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

Я хотел проверить не «может ли нейросеть сгенерировать приложение». Это к тому моменту уже не выглядело особенно интересным.

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

  • мобильный клиент;
  • backend;
  • база данных;
  • web;
  • инфраструктура;
  • синхронизация;
  • тестирование.

И поставить дополнительное условие: я не пишу программный код сам.

Если Codex упирается в проблему, я могу посмотреть результат, сформулировать, что не работает, изменить направление. Но не открывать файл и не чинить функцию руками «потому что так быстрее».

Сначала появился не код, а контракт

Первое, что сделал ChatGPT, — большой master prompt.

Это был не запрос уровня:

Сделай семейный мессенджер на Kotlin.

Скорее документ уровня vision + architecture contract.

В нём были зафиксированы границы решения:

  • self-hosted сервер,
  • Kotlin/Ktor backend
  • PostgreSQL
  • Kotlin Multiplatform-клиент Android/iOS/Desktop/Web
  • общий transport contract
  • polling
  • invite-коды
  • простой deployment на обычный VPS

То есть пространство решений агенту оставалось большое, но оно не было бесконечным.

После этого ChatGPT разрезал работу на пять шагов.

Первый шаг — специально запрещал сразу писать всю бизнес-логику. Нужно было сначала поднять монорепозиторий, shared contract, skeleton backend и KMP-клиента.

Второй шаг — полностью сделать backend.

Третий — инфраструктуру и deployment.

Четвёртый — клиент.

Пятый — отдельный self-review: пройтись по shared DTO, API, persistence, deployment, KMP-архитектуре, sync consistency и security assumptions так, будто проект смотрит principal engineer.

Получалось примерно так:

проблема ↓ я ↓ ChatGPT ↓ master prompt ↓ step_1 → step_2 → step_3 → step_4 → step_5 ↓ я ↓ Codex ↓ код / тесты / конфигурация ↓ я ↓ проверка

Сейчас мне особенно забавно смотреть на это с точки зрения современных agent workflows.

Сегодня я бы как раз старался убрать себя из механической передачи контекста между агентами. А тогда это и был мой workflow.

Что получилось

Проект довольно быстро перестал выглядеть как игрушка.

В репозитории появились:

shared-contract/ backend/ client/ infra/

shared-contract был общим источником transport-моделей для backend и клиента.

backend — Ktor, Exposed, PostgreSQL, Koin.

client — Compose Multiplatform с target'ами Android, iOS, Desktop и Web.

Внутри появились авторизация, профиль, контакты, личные сообщения, семейный чат, статусы доставки, presence, location API, sync, push token, admin API, health checks.

Для инфраструктуры — deployment на VPS, PostgreSQL, systemd, Caddy, prod/dev окружения.

Если смотреть только на размер, в исследовании репозитория получилось около 13 тысяч строк Kotlin/Gradle в 113 файлах.

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

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

На грубой оценке я бы закладывал на подобный MVP как минимум месяц.

Это не benchmark. Я не запускал параллельно человеческую команду и не мерил часы. И уж точно из этого нельзя делать вывод «Codex заменяет семь сотрудников».

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

А здесь первая большая рабочая система появилась за несколько дней. Это действительно впечатляет. Но потом началось самое интересное.

Настоящая разработка началась после генерации

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

Backend есть.

Клиент есть.

Сообщение отправляется.

Push приходит.

Можно сделать красивый скриншот и написать пост про будущее разработки.

Я же хотел понять, можно ли этим пользоваться.

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

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

Поставил приложение на телефоны детей и попросил их какое-то время писать мне только через него.

И вот здесь проект из «13 тысяч строк, которые написал AI» превратился в обычный мессенджер со всеми неприятностями состояния.

Особенно хорошо это было видно на unread counters.

На бумаге схема выглядит почти смешно:

LOCAL_PENDING → SENT → DELIVERED → READ Отправили. Сервер принял. Другое устройство получило. Пользователь прочитал.

Но как только устройств становится несколько, появляется масса вопросов:

  • Какой клиент уже получил событие?
  • Что делать после reconnect?
  • Что если push разбудил приложение, а локальный cursor синхронизации устарел?
  • Когда именно уменьшать unread?
  • Что делать, если клиент повторно запросил уже виденное сообщение?
  • Как восстановиться после перезапуска сервера?

У меня начали разбегаться счётчики новых сообщений.

В git-истории похожая картина видна и без моих воспоминаний: отдельные исправления авторизации, deployment, FCM, long polling, stale sync cursor, поведения при сетевой ошибке. Были платформенные проблемы. Менялся web target. Исправлялись вещи, которые первый вариант сделал недостаточно хорошо.

AI не выдал идеальный продукт с первой попытки.

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

Для меня это оказалось важным различием.

Сгенерировать огромную поверхность системы агент умеет поразительно быстро.

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

Он наступает, когда два устройства ожидают друг от друга правильного состояния.

Я не писал код. Но работы почему-то меньше не стало

Здесь у меня начал ломаться исходный вопрос эксперимента.

Я хотел понять, можно ли убрать разработчика из разработки.

Если считать разработкой набор текста в IDE, ответ получался почти издевательски простым да:

  • Я не писал endpoint'ы
  • Не создавал таблицы Exposed
  • Не раскладывал `expect/actual`
  • Не собирал вручную Koin-модули
  • Не писал polling engine
  • Не правил Compose-компоненты

Этим занимался агент.

Но каждый раз оставалось другое:

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

Самой непривычной была именно смена масштаба.

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

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

И это уже совсем другая профессия, хотя внешне я всё ещё «разработчик».

Потом проект умер. И это был хороший результат

Примерно неделю я гонял систему в почти реальном режиме.

Не буду делать вид, что вся семья торжественно мигрировала на мой мессенджер и забыла Telegram.

Основную нагрузку создавал я сам.

Но были реальные телефоны детей, реальные push, реальные сообщения и настоящая проблема синхронизации нескольких клиентов.

А потом я нашёл рабочий способ снова нормально пользоваться Telegram. И выяснилось очевидное. Семье не нужен собственный self-hosted мессенджер, если привычный Telegram снова работает.

Можно было продолжать:

  • Поднять нормальный HTTPS
  • Дочистить secure storage
  • Отдельно прогнать iOS
  • Полировать installation flow

Но зачем?

Проект остановился не потому, что Codex не смог его закончить. Он остановился потому, что исчезла проблема. И это, пожалуй, один из самых полезных результатов эксперимента.

Когда стоимость написания кода резко падает, становится намного дешевле проверить идею.

Но одновременно становится намного дешевле построить ненужную вещь.

Раньше сама стоимость разработки часто заставляла долго спорить до начала работы: точно ли это нужно, точно ли такой scope, точно ли сейчас.

AI снижает этот барьер.

Можно сказать: «давайте просто сделаем и посмотрим». Это прекрасно. Но продуктовый вопрос никуда не исчезает. Он просто догоняет тебя позже.

Тогда я решил довести эксперимент до конца

К этому моменту я был очень впечатлён.

Я занимаюсь разработкой достаточно давно, чтобы понимать размер того, что произошло.

Один coding agent за несколько дней создал систему, для которой в обычной работе я ожидал бы несколько специалистов и заметно больше календарного времени.

Да, она была не production-ready.

Да, в ней оставались ограничения.

Да, пришлось долго проверять и исправлять.

Но это был уже не прототип из пяти экранов.

Я хотел рассказать об этом другим.

И тут возникла очевидная идея.

Если весь эксперимент построен на максимальном делегировании AI, почему бы не сделать так же со статьёй на habr?

Получалась красивая цепочка:

идея ↓ AI формирует vision ↓ AI декомпозирует ↓ AI пишет код ↓ я проверяю ↓ работающий продукт ↓ AI пишет статью о продукте

В статье на habr я не скрывал происхождение кода. Наоборот, она начиналась почти демонстративно:

Я отдал разработку мессенджера двум AI. Код заработал, статья — нет

И дальше честно говорила, что статью сделал AI. Мне казалось, что в этом и есть главная фишка.

Но я получил сообщение от модератора Habr:

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

Я не хочу спорить здесь с политикой Habr или рассуждать о том, насколько точно кто-то умеет определять AI-текст.

В этой истории мне интереснее другое.

Программный код, написанный AI, я мог принимать по поведению системы. С текстом оказалось иначе. Он может быть фактически аккуратным. В нём могут быть правильные технологии и реальные фрагменты кода. Но этого недостаточно.

Кто-то ещё должен захотеть его читать.

И в моём эксперименте граница полной автоматизации неожиданно обнаружилась не в KMP, не в PostgreSQL и не в синхронизации. Она обнаружилась в человеческой приёмке.

Самая неудобная часть эксперимента

После проекта у меня появилось ещё одно ощущение, которое я пока не могу превратить в доказанный вывод.

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

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

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

Если потом сказать, что код целиком написал агент, меняется ли ценность проделанной работы в его глазах?

Так что всё-таки осталось разработчику?

В начале я формулировал эксперимент довольно просто:

можно ли сделать сложный программный продукт, вообще не программируя его руками?

Для этого проекта мой ответ — да.

Я действительно не писал программный код.

Но теперь мне кажется, что вопрос был неверным.

Писать код и разрабатывать продукт — больше не одно и то же действие. Из моей работы почти полностью исчез набор текста.

Зато остались:

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

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

Ни один падающий тест не сообщает об этом.

Вместо вывода

Я начинал этот проект, потому что хотел проверить возможности coding agents. И да — они оказались намного выше моих ожиданий.

Если бы несколько лет назад мне сказали, что я смогу за несколько дней получить от одного агента backend, KMP-клиент на несколько платформ, базу, deployment, push и рабочую синхронизацию, я бы отнёсся к этому как минимум скептически.

Сейчас меня удивляет уже другое.

Когда написание кода становится дешёвым, главными становятся вещи, которые раньше можно было отложить за большим объёмом реализации.

Правильно ли мы вообще поняли задачу?

Работает ли система вне happy path?

Нужна ли она кому-нибудь?

Можем ли мы проверить то, что агент произвёл?

Кто отвечает за итог?

Я хотел проверить, можно ли убрать человека из программирования.

Из написания кода — почти получилось.

Из разработки продукта — нет.

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

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

Пожалуй, поэтому второй раз эту статью пишу уже не как демонстрацию того, что умеет AI.

А как историю о том, что осталось мне.

Исходный код family-messenger открыт на GitHub.