Как я променял свой бизнес на фулл-стек вайб-кодинг
Будучи человеком довольно непоседливым, не так давно я начал заставать себя проводящим по 16 часов в день за кодом — и это стало для меня серьёзным сигналом.
Совсем непохоже на то, как я два года до этого тянул агентство по лидогенерации, к которому не лежала душа.
AI-вайбкодинг разбудил мою детскую страсть к программированию, зародившуюся ещё в Доме Детского Творчества за изучением Pascal (язык программирования, не актёр из HBO-сериала Одни из нас).
Без каких-либо задних мыслей о стартапах (хотя иногда мелькало) за последние 8 месяцев я накодил около 30 проектов. Часть — застряли в стадии недоделок, часть — коммерческие заказы, но большинство — вполне себе законченные и рабочие фан-проекты.
От инфракрасной камеры для наблюдения за белохвостыми оленями в штате Делавэр до 3D игры, сделанной за 5 дней. От утилит с одной фичей до полномасштабных веб-приложений с аутентификацией и системой платежей. Как видите, покидало меня из стороны в сторону знатно.
Я нашёл свой личный икигай: с одной стороны, понимаю код, который пишет AI и умею управлять AI-агентом, с другой — вряд ли стал бы разработчиком с нуля. Вероятно, канонический случай для многих вайб-кодеров.
Хотя после довольно трудоёмких фулл-стек проектов я уже не считаю себя им. За AI до сих пор нужен глаз да глаз. Поэтому я, скорее, — программист в паре с AI-ассистентом.
Так или иначе, после того, как я начал кодить, остановиться было невозможно. Была лишь небольшая пауза при переезде из США на Бали.
Снежный ком
С позиции нормального человека мои выходные назвать захватывающими сложно. Случайная идея чего-нибудь закодить вспыхивает в моем воспаленном уме, и зная, что барьер её реализовать минимален, Остапа начинает нести.
Научить муравья выбраться из лабиринта при помощи Q-таблиц или AI ассистент для чтения научных статей. Погнали! Радуюсь, что даю порезвиться моему внутреннему дитяте. И глазом не моргнув.
Но зачем? Есть ли оправдание так безответственно тратить время на проекты, которые не попадут даже в категорию "когда-нибудь я превращу их в стартап"? По опыту знаю, что случайно посаженные семена со временем дают довольно непредсказуемые и порой великолепные всходы.
Издательство начинается с одной книги. Приглашение танцевального чемпиона на двухдневный мастер-класс может вылиться в регулярную организацию международных турниров.
Недавно я глянул выступление Андрея Карпати в Беркли. Он называет это снежным комом. Когда снежки квази-рандомных проектов со временем собираются в снежный неостановимый ком. Он намекнул, что похожая динамика была в лаборатории OpenAI, где он был сооснователем. Во что это вылилось, мы все знаем.
В чем же основная мотивация? Подозреваю, что меня двигает любопытство и тяга бросить вызов сложной, но по зубам авантюре. И на выходе получить некий полезный (для меня, по крайней мере) продукт, который развлекает меня в процессе.
Иногда интенсивность такая, что мне нужен выходной после выходных. Поэтому решил, что некоторые выходные стоит разбавить тем, чтобы публично делиться своим опытом. Отсюда и статья.
Идея за Solar 5D
А расскажу я про один из последних проектов:
Идея была проста: скрестить между собой сплав особо горячих технологий, превратив его в нечто клевое и образовательное.
Я выбрал триаду.
1. Three.js: JavaScript фреймворк с богатым 3D движком для веб-проектов.
Первый опыт я получил с VibeJam - конкурс, который я превратил в свой личный 5-тидневный хакатон.
На выходе: Симулятор водного скутера (скорее, аркада, по правде говоря).
С AI прослеживается тренд, когда ты сначала делаешь, а потом разбираешься в том, что получилось. Некая гибридная модель вайб-кодинга, после которого догоняешься знаниями.
Прямо сейчас прохожу 93-часовой курс по Three.js от Bruno Simon. Один из крутейших образовательных продуктов в моей жизни. Стоит своих $95. Зацените тут (честная нереферальная ссылка):
2. MediaPipe. Гугловский фремворк для задач компьютерного зрения (распознание жестов, мимики, позы, объектов).
Рекомендую взглянуть на возможности движка в Х аккаунте AA. Он освоил связку Three.js + Computer Vision. От него пришло вдохновение для проекта, который освещаю.
3. Realtime API. API речь-в-речь от OpenAI - тот самый, что питает голосовой режим ChatGPT. Всё еще в бета-версии (на май 2025), но работает без нареканий.
Да, затраты на API кусаются, но ценник тает каждый месяц и для демки норм. Вполне сойдет их mini модель.
От них также пришло вдохновение после показа демки с планетами, используя голос.
Видение проекта в моем воображении формулировалось так: более или менее точное представление солнечной системы с управлением камеры курсором мышки, жестами через компьютерное зрение, и голосом, позволяющим общаться с AI как с учителем астрономии (безусловно в стиле Дэвида Аттенборо, и никак иначе).
Как я кодил этого зверя
Я привык работать в связке Next.js + TypeScript. LLM меньше делают ошибок в генерации типизированных языков, поэтому я реже использую JavaScript.
Хайп может ввести в заблуждение, и безусловно это также вопрос навыков, но на текущем этапе, повторюсь, AI агентов нужно микроменеджить.
Бывает, уходят часы на отловку багов. Для тяжелых случаев я переключаюсь на более дорогие модели с reasoning (o3, gemini pro max, и т.д.). И даже с такими ограничениями, без AI я бы кодил в десятки раз медленнее (хотя не факт, что кодил бы).
Со временем собираются кусочки кода и суперпромпты для направления агентов, которые легко передаптировать под новые проекты.
Еще одна штука, которая меня ускоряет - это диктовка. Как Карпати твитнул недавно, английский — это сейчас самый модный язык программирования. Я надиктовываю код на английском через:
С радостью делюсь гитхаб репозиторием, с которого сейчас начинаю каждый новый Next.js проект. Он кстати содержит Realtime API setup, который довольно нетривиален:
Сам проект также опенсорсный и доступен тут:
Three.js
Внимание: это будет более технический и богатый на формулы раздел.
Демо продукта внизу. Благодарочка Screen Studio, через которую получается записывать такие классные шоукейсы.
Если интересно поиграться с самим продуктом, напишите мне в телегу, и я поделюсь.
Чтобы отправить проект в космос, я попросил GPT попросить NASA прислать параметры планет:
Далее, простой сетапчик Three.js сцены с 9 сферами SphereGeometry:
Изначально, я выбрал логарифмическую шкалу расстояний. Но позже поменял на линейную:
value - расстояние от планеты до Солнца в млн км
maxDist - максимальное расстояние от Солнца до Нептуна в млн км
spread - коэффициент для пропорционального масштабирования расстояний в плоскости XZ
Со значением spread = 360 (произвольное число, при котором всё помещается на экран) Меркурий получился отстоящим от Солнца на 4.64 юнита, а Сатурн: на 114.
Для радиусов планет я оставил логарифмическую шкалу. Линейная была бы слишком экстремальной, ибо радиус Солнца ≈ 10 × радиуса Юпитера ≈ 109 × радиуса Земли ≈ 285 × радиуса Меркурия.
Логарифм "сжимает" большие числа и "растягивает" маленькие, поэтому планеты и Солнце становятся различимыми.
rad_min = 1 (для Меркурия как самого маленького)
rad_max = 10 (для Солнца)
Для Земли (6,371 км в радиусе): 2.5. Для Юпитера (69,911 км): 6.2.
Навигация и анимация
Для навигации с помощью курсора мыши, используем классические для Three.js OrbitControls:
Далее я добавил угол наклона оси, вращение вокруг собственной оси и вокруг Солнца.
Когда мы фокусируемся на небесном объекте вращение вокруг собственной оси плавно останавливается, чтобы не закружилась голова.
Ну и коронное - вращение также контролируется с помощью жестов рук, используя веб-камеру (об этом позже).
Текстуры
Все текстуры: планет, Солнца, колец Сатурна и Млечного Пути найдены на сайте:
Разрешения 2К достаточно, хотя для Млечного взял 8К.
В качестве материала я выбрал THREE.MeshBasicMaterial - он позволяет обойтись без источника света.
Не забыть скорректировать цвета (иначе буду бледными):
{planet}Texture.colorSpace = THREE.SRGBColorSpace
UV развёртка
Нацепить 2D текстуры на 3D сферы было трививальным, а вот с кольцами Сатурна пришлось покорпеть.
Плотные кольца начинают обволакивать Сатурн практически сразу и простираются до 2.27 его радиуса (речь о так называемых A, B, C кольцах - диффузные кольца уходят гораздо дальше)
const inner = planetRadius * 1.11
const outer = planetRadius * 2.27
Вдруг сейчас вспомнил, что писал диплом в Институте Прикладной Астрономии РАН. Вероятно, это тоже отчасти послужило вдохновением к проекту.
Текстура с кольцами - PNG файл с альфа-каналом. Белые участки = прозрачно.
Задача надеть 1D текстуру на геометрию кольца RingGeometry решается так:
UV координаты (от 0 до 1 по обоим осям) используются, чтобы 3D объект обернуть в плоскую структуру. В нашем случае у 3D диска нулевая толщина, то есть он теряет одно измерение и становится 2D.
Мы используем UV, чтобы 1D текстуру усадить на 2D кольца, которое обитает в 3D пространстве.
U координата:
V координата:
Млечный Путь
Восхитительный Млечный Путь это всего лишь одна картинка, которая обернула нашу 3D коробку через:
texture.mapping = THREE.EquirectangularReflectionMapping
Компрессия изображений
Поскольку мы работаем с вебом, размер файлов влияют на производительность.
Я использовал Squoosh для сжатия текстур. 7 MB легим движением руки со звуком "сквуууш" ужимаются до неприличных 500 KB (93%)! Да и интерфейс у приложения чертовски приятен.
Голосовой контроль
Перед тем как подключать голосовой AI, для каждой планеты я сделал подлёт камеры и захват планеты, которая продолжает двигаться по орбите. Дабы камера следовала за ней и не упускала из вида.
Озвучу два принципа, которые были внедрены:
1. Лерпинг: позиция камеры и цели обновляются через линейную интерполяцию (lerp). Влияет на плавность движения.
2. Сдвиг камеры зависит от размера объекта. Таким образом Юпитер и Меркурий при приближении выглядят одинакового размера.
OpenAI Realtime API
Голосовой модуль реализован через Realtime API от OpenAI. У них есть фича (Tool Calling), вызывающая функции, которые мы сами придумаем и пропишем.
Например, как только AI осознает, что речь идет об определенной планете, он вызывает функцию подлёта камеры, передавая название планеты в качестве параметра.
Я столкнулся с багом: если после моего вопроса AI вызывал функцию подлёта, он напрочь забывал про мой вопрос.
Вторая часть кода на скрине решила вопрос:
И умелыми жестами рук...
Уже упоминал, что распознание жестов рук ложится на библиотеку MediaPipe. Я внедрил два жеста на основе одного простого алгоритма.
1. Каждый кадр MediaPipe распознает по 21-й ключевой точке на каждой руке.
2. Нас интересует пять точек на каждом кончике пальцев [3, 7, 11, 15, 19] и точка на запястье [0].
3. Для каждого кончика пальца считаем 3D Евклидово расстояние до запястья:
4. Усредняем все пять расстояний, чтобы получить единую метрику "открытости ладони" (avgDist на скрине)
Путем эксперимента, порог оказался 0.35.
Сворачиваемся
Я кайфанул от этого проекта, и поделившись ходом процесса, считаю, что отдал ему должное.
Но я не планирую его оставлять в таком виде, хотя видение реализовано. Он слишком хорош, чтобы его не развивать дальше.
Буду рад любым вашим вопросам, обратной связи и предложениям.
Еще раз ссылка на конечный продукт:
Также заглядывайте ко мне в телеграм канальчик: