Новинка: Grom Zvuk — наша музыкальная модельПослушать и попробовать

SaaS умер? Как я повторил Discord и Telegram за 24 часа

SaaS умер? Как я повторил Discord и Telegram за 24 часа

25 сентября в 22:35 я отправил первый промпт. Это была стена текста без единой запятой, в которой я объяснял, как мне важно получить рабочий продукт вроде Discord, что меня бесит, как там сделаны чаты, поэтому чат делаем как в Telegram, и что всё должно работать чётко, как в Zoom: передовые кодеки, стабильность и качество звука. Ещё там были голос, роли и права, стрим экрана, PostgreSQL и «эхо не должно быть совершенно». Через 24 часа, вечером 26 сентября, версия 0.3.1 стояла в проде с подписанными сборками для macOS, Windows и Linux, веб-версией и лендингом. Продукт называется Calab, код открыт на GitHub. За эти сутки я написал 90 сообщений, 29 из них - просто скриншоты с подписью «сделай как тут». Ни строчки кода, ни одного запущенного теста. Всё остальное сделали модели. Ниже цифры, счёт в долларах, хронология и список того, где нейросети ошибались, потому что без него история выглядит слишком красиво.

Что именно получилось за сутки

Calab - self-hosted мессенджер для команды. Голосовые комнаты с активацией голосом или push-to-talk, Opus с DTX, RNNoise и эхоподавлением AEC3, серверный mute и перетаскивание участников между комнатами. Стрим экрана в AV1 с simulcast, пресеты от «экономии» до оригинала, до трёх стримов на комнату, веб-камера с сеткой и PiP. Чат с пузырями как в Telegram: файлы, реакции, закрепы, упоминания, превью ссылок, поиск, личные сообщения. Пространства, роли и битовые права на каждую комнату, гости по ссылке без регистрации. Клиенты на Electron с автообновлением, веб и мобильный веб для iPhone, локализация на четыре языка. Сервер на Go, LiveKit с TURN/TLS на 443, Caddy, Docker Compose с харднингом, бэкапы по таймеру, GitHub Actions с публикацией в S3.

Главный экран Calab: голосовая комната с участниками слева, канал команды с сообщениями и вложениями справа

Это не CRUD с формами. Здесь WebRTC, SFU, кодеки, нативные хуки клавиатуры, подпись и нотаризация macOS - всё то, что обычно называют «сложной частью». Скриншоты в README и на странице продукта настоящие, из релизной сборки.

Строк исходников92 972: Go 28 471, TypeScript 60 871, proto 1 362, SQL 1 286, CSS 982. Без сгенерированного кода и эталонов
Коммитов в main282, из них 31 - мержи веток агентов
Релизов в прод7: v0.1.0, 0.1.1, 0.2.0, 0.2.1, 0.3.0, 0.3.1, 0.3.2
Тесты60 файлов на Go против настоящих Postgres, Valkey и LiveKit, 92 unit-теста клиента на 750+ кейсов, 13 e2e-спеков, 43 визуальных эталона
Документация37 документов, 22 архитектурных решения (ADR), TESTING.md со ~150 ручными сценариями для человека
Локализация1 186 ключей на четыре языка

Хронология: полтора часа до первого созвона

22:35 - первый промпт. Лид час читает про кодеки, TURN и эхо, пишет 11 документов архитектуры и первые ADR. Я вмешиваюсь дважды: «меня смущает такой высокий битрейт» (в расчётах стояли 435 Мбит/с как худший случай для SFU, переписали в потолки против типичного трафика) и «бэк на Go, максимально лёгкий сервер».

Около полуночи - MVP, через полтора часа после промпта. И это не скелет проекта, а медиа-спайк: два клиента созваниваются через SFU на стенде и показывают экран. Мы это тут же потестировали вдвоём с лидом, созвон работал. Всё остальное время суток ушло не на «сделать, чтобы работало», а на «сделать продукт».

Ночь. Перед сном я написал лиду: «Не торопись, у тебя есть целый год, чтобы сделать приложение. Ах да, забыл сказать: я ухожу в отпуск, поэтому вопросов не задавай, сам решай, что куда». И ушёл спать. Год модели не понадобился. Пока я спал, сервер, клиент и инфраструктура писались параллельно, потом прошли четыре круга ревью кода и независимое UX-ревью по скриншотам. Никто не спросил, какой домен, где хранить бэкапы и как подписывать сборки, всё решили сами. К утру стенд жил с Valkey, бэкапами, харднингом контейнеров и TURN на 443, домены были заведены, macOS-сборка подписывалась и нотаризовалась в GitHub Actions, фид обновлений лежал в S3. Это самая жуткая часть истории, если честно: просыпаешься после «отпуска» длиной в одну ночь, а у тебя есть инфраструктура, которую ты не поднимал, и продукт, который ты не видел.

10:00. Проснулся, открыл ноутбук, а на нём Опусы крутят визуальные тесты, которые прощёлкивают 300 с лишним экранов подряд. Первое сообщение дня оркестратору было не про продукт: «Ты чего творишь, твои агенты там бесполезные тесты гоняют, а ну-ка оптимизируй процессы, всё должно работать максимально продуктивно и не жрать токены как самолёт». Для масштаба: подписка за $200 за ночь потеряла 30% недельного лимита. И надо сказать, что это очень хорошо: за эти 30% появились сервер, клиент, стенд и подписанные сборки. Просто дальше так жечь было нельзя.

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

Утренняя версия Calab в светлой теме до редизайна: канал «общий», стрим Веры Ким и переписка агентов про чек-лист релиза

Лид разобрал причины: долгоживущие агенты с огромным контекстом, общее рабочее дерево, ревью, порождающие ревью, полные прогоны тестов. И переписал правила работы, о них ниже. Дальше всё шло свежими агентами.

10:00–13:00. Скриншоты Discord: «изучи дизайн, у нас как-то устарело всё». Появились островок голоса внизу, карточка активной комнаты, пузыри в стиле Telegram. Выбрали лицензию. Вышли v0.1.0 и v0.1.1 - хотфикс перемещения участников: выяснилось, что нужный метод LiveKit есть только в облачной версии, написали свой и оформили как ADR-0019.

13:00–16:00. Веб-камера и v0.2.0. Я потестировал прод и принёс шесть багов: Caps Lock не назначается, голос не подключается, приложения нет в списке «Запись экрана», нет личных сообщений, скачивание через белый экран, нужна мобильная версия. Всё, кроме личных сообщений и мобильной версии, закрыл хотфикс v0.2.1. Заметная часть этого дня прошла не за ноутбуком: я гулял с женой и сидел в парке, а с лидом переписывался с телефона через Orca. Скриншоты багов улетали оттуда же, с телефона.

16:00–18:00. Личные сообщения, мобильный веб, локализация, эхо на колонках, индикация речи, оптимистичный вход в комнату, звук нового сообщения из файла, который я прислал. К шести вечера, примерно через 12 часов чистой работы бота, приложение в целом было готово: всё, что было в первом промпте, работало в проде. Дальше шла полировка.

Вечер. Тест с iPhone и Discord под рукой, v0.3.0 и v0.3.1. К концу суток картинка была уже вылизанная: не «работает», а «не стыдно показать».

После полуночи. Ещё 12 замечаний по интерфейсу: размеры аватаров, счётчик, таймер, меню участника, профиль, перетаскивание комнат, задержка отпускания push-to-talk. Ревизия тестов: с 346 снимков до 33 ключевых экранов. v0.3.2, уже за пределами первых суток. Эти часы в цифрах ниже учтены.

Кто работал: три модели и один человек

Никакого «одного чата с ChatGPT». В Claude Code работала иерархия агентов.

Лид на Claude Fable 5.1 держал архитектуру, писал ADR и постановки, принимал результат по скриншотам, мержил ветки и разговаривал со мной. Лид не пишет код, и это моё требование, а не случайность: я специально попросил Fable хороводить Опусами, чтобы экономить. Самая дорогая модель думает и принимает решения, а строчки кода печатают те, что дешевле. Кодеры на Claude Opus 5.5: каждая задача - свежий агент с точной постановкой и ссылками на нужные документы, всего 233 запуска плюс 13 долгоживущих «панелей» под стенд, ревью, лендинг и разбор PR. Sonnet 5 делал механику: changelog, переводы, перезапись эталонов, статистику. И один агент прожил весь цикл - стенд-инженер, который держал состояние сервера, деплоил, проверял, тегировал, публиковал релизы и следил за автообновлением. В пике параллельно работало около 12 агентов, и у каждого была своя задача: один оптимизировал стримы и кодеки, другой разбирался с инфраструктурой и TURN, третий писал лендинг, четвёртый улучшал UX по скриншотам Discord, кто-то гонял интеграционные тесты против настоящего Postgres. Со стороны это выглядело как отдел разработки, у которого нет ни одного сотрудника.

Интерфейс Orca в полдень 26 сентября: десять агентов проекта Calab, панели стенда и ревью живут по 14 часов, в статусной строке 39% недельного лимита подписки

Я в этой схеме заказчик и арт-директор, не оператор. Типичный мой вклад - скриншот Discord с подписью «хочу такой же UI» или «очень странная обводка на сообщении». Лид переводит это в постановку, агент делает, лид смотрит скриншот результата и принимает или возвращает.

Правила, без которых схема не работает, записаны в CLAUDE.md репозитория, потому что каждое из них выучено на ошибке:

  1. Свежий агент на задачу, потом агент завершается. Долгоживущий агент с контекстом в сотни тысяч токенов перечитывает его каждым ходом, и это главная статья расходов.
  2. Изоляция. Каждый кодер в своём git worktree, со своими портами и тестовыми базами. Пока этого не было, агенты стирали друг другу тестовые данные и откатывали чужие правки.
  3. Агент коммитит сам, лид только мержит и тегирует. Пока лид был единственным коммитером, каждая правка делала лишний круг.
  4. Одно ревью на изменение, фиксим только блокеры, остальное в бэклог. Иначе ревью порождают ревью, а релиз ждёт.
  5. Тесты только по затронутому. Полный визуальный прогон на машине владельца запрещён, локально 33 ключевых экрана, полная матрица ночью в CI.
  6. Отчёт агента до 15 строк: сделано, файлы, проверки с цифрами, риски.

Счёт: $12 400 и куда они ушли

Данные из локальных транскриптов Claude Code, скрипт tools/usage-stats.py и файл docs/13-usage.md лежат в репозитории и обновляются перед каждым тегом. Так выглядела сводка на 22,5 часа, за несколько часов до конца:

Сводка usage-stats через 22,5 часа работы: 19 324 ответа моделей, 16 млн токенов вывода, 6,3 млрд токенов чтения кэша

Итоговые цифры чуть больше, они включают ночную v0.3.2.

МодельОтветовВывод, млн токеновЧтение кэша, млн
Opus 5.5, код18 76614,585 741
Fable 5.1, лид1 8062,00810
Sonnet 5, механика1 0510,33217
Итого21 62316,96 768

Считаю по прайс-листу API: Opus и Fable по тарифу Opus-класса, $15 за миллион входа, $75 за миллион выхода, чтение кэша $1,5, запись $18,75; Sonnet - $3, $15, $0,3 и $3,75.

Чтение кэшаВыводВсего
Opus 5.5$8 612$1 094$10 769
Fable 5.1$1 215$150$1 499
Sonnet 5$65$5$91
Итого$9 892$1 249≈ $12 400

Посмотри, куда ушли деньги. 80% - чтение кэша, то есть повторное чтение контекста агентами, и только 10% - собственно написание кода. Половина суммы сгорела в первые 15 часов, пока агенты жили по 14 часов каждый и получали задачи «допиши ещё вот это». После перехода на свежих изолированных агентов типичная задача вроде «исправить гонку в reconcile с интеграционным тестом» стала стоить две минуты и около 60 тысяч токенов, а фича с сервером, клиентом и тестами - 15–25 минут и 150–350 тысяч. По подписке Claude Code выходит на порядок дешевле, но прайс-лист честнее показывает, что такое «продукт за вечер» в токенах.

Где нейросети ошибались

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

Голос не подключался в проде при зелёных тестах. Политика безопасности приложения разрешала соединения только с *.app.calab.ru, а сервер голоса живёт на rtc.calab.ru, соседнем домене. Домены менялись по ходу, тесты ходили на localhost и ничего не заметили. Пользователь видел бесконечное «Переподключение…». Теперь e2e на реальном стенде стоит в релизном скрипте до тега.

Caps Lock, три гипотезы. Я попросил push-to-talk на Caps Lock, как в Discord. Первая версия: macOS не отдаёт эту клавишу, нужен патч libuiohook. После «в релизе не работает» вторая: патч не попал в бинарь. Оказалось, попал, а настоящая причина в том, что у меня две раскладки и macOS переключает их по Caps Lock, событие не доходит до приложения. Ремап через hidutil не помог. Третья, рабочая: читать физическую клавишу через IOHIDManager, как делает Discord. Модель прошла ровно тот путь, который прошёл бы живой инженер, и ошибалась в тех же местах.

Стрим экрана в голосовой комнате Calab: развёрнутый экран участника с планом релиза, справа список участников и зрителей

«В эмуляции всё хорошо». Мобильную версию агент проверял в Chromium с эмуляцией iPhone. В настоящем Safari кнопки наезжали друг на друга, внизу оставалась пустая полоса, автофокус улетал. Переделали тесты под WebKit, но и он не воспроизводит клавиатуру и тулбары Safari: последние два бага подтвердились только на телефоне в моих руках.

Ревью порождали ревью. Бюджет публикаций потянул второе ревью, оно - уборку гостей, та - флейк тестов, флейк - разделение ночного прогона. Всё по делу, но релиз ждал час. Отсюда правило «во время релиза на main только блокеры».

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

Мелочи с последствиями. Локальный тест Caddy с боевым доменом дёрнул Let's Encrypt и потратил лимит сертификатов. Линтер без корневого конфига показал ложный «0 issues», а CI покраснел. Агент предложил взять звук уведомления из ICQ - чужие права, заменили на свой синтез, потом на мой файл.

Что делал человек

Из 90 сообщений примерно 60 - правки продукта, и почти все они про вкус, а не про технику. «А откуда у тебя там 400+ мегабит?» «В Discord Caps Lock работает, а тут нет.» «Чат по дизайну ближе к Telegram.» «Кнопки round, так круче.» «Скрины в 2x, а то мыло.» «Когда я говорю, в Discord зелёный кружок, у нас такого нет, а очень хочется.» «Когда вхожу в комнату, появляюсь только после подключения, в Discord сразу.» «Слишком большая задержка при отпускании push-to-talk, в Discord 20 миллисекунд и ползунок.» «Гигантский аватар, обводка выезжает, шрифты меньше.»

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

Так умирает ли SaaS

Аккуратный ответ: умирает SaaS как «набор фич за подписку». Если ценность продукта - экраны, формы, роли, уведомления и интеграции, один человек с подпиской за пару сотен долларов повторит это за выходные, причём с автотестами, документацией и CI, которых у половины стартапов нет. Мы показали это на Discord-подобном продукте, где WebRTC, SFU, кодеки и нативные хуки, а не CRUD.

Что не повторяется за вечер и остаётся бизнесом. Дистрибуция и доверие: у нас есть продукт, но нет пользователей, у Discord сотни миллионов. Эксплуатация: стенд, бэкапы, сертификаты, инциденты, апдейты LiveKit - сутки дали версию 0.3, а не «готово навсегда». Реальные устройства и сети: эхо на колонках, VPN на Windows в корпоративной сети, iPhone в руках - модель тестирует только то, что может эмулировать. Вкус: все «как в Discord, только у нас некрасиво» пришли от меня. Право и данные: лицензии зависимостей, чужие звуки, персональные данные - модель напоминает, решает человек.

Честная формулировка такая: инженерная себестоимость продукта упала в 20–50 раз, а всё остальное - нет. Ров вокруг SaaS теперь не в коде.

Как повторить

Документация раньше кода: архитектура, медиа-правила, модель данных, протокол, дизайн-система, ADR - это то, что агенты читают вместо твоего объяснения. Шесть правил из раздела про команду с первого дня, а не после того, как счёт за кэш дойдёт до пяти тысяч. Один долгоживущий агент на стенд и релизы со скриптом, который делает preflight, деплой, проверку, тег, фид и останавливается на первом FAIL. Считай токены и смотри на чтение кэша, а не на вывод. И держи человека в цикле качества: скриншоты «как здесь», короткие «не так», проверки на реальном устройстве.

Где попробовать

Calab открыт на GitHub под Business Source License 1.1: для личного и некоммерческого использования бесплатно, для бизнеса по лицензии GPTunneL. Скачать приложение или открыть веб-версию можно на странице продукта, а issue на GitHub закрывает тот же конвейер из статьи: нейросеть пишет план прямо в задаче, человек одобряет, агент открывает pull request.

Модели, которые собрали Calab, есть в GPTunneL: Claude Opus 5.5 для кода и Claude Fable 5.1 для архитектуры, без VPN и с оплатой в рублях за токены. Если хочешь такой же конвейер под свой продукт, напиши нам: мы уже знаем, где он ломается.