Новое поколение софта с недетерминированным кодом. Или как я начал разговаривать со своими программами, дописывая их прямо на ходу
У каждого айтишника есть свое личное кладбище домашних проектов. Тебе приходит в голову отличная идея автоматизировать какую-нибудь рутину или творческую штуку. Ты садишься за редактор, пару вечеров бодро пилишь ядро и это начинает работать и решать какой-то частный случай нужной задачи. Но потом понимаешь, что есть еще куча случаев когда это не работает по 1001 причине и надо дописывать поддержку все новых и новых деталей. На третьи выходные запал пропадает, потому что вместо самой задачи ты уже две недели строишь к ней панели управления и делаешь софт а не ту задачу ради которой он предназначен. Проект отправляется в долгий ящик, а ты остаешься на полудоделаных костылях и оставляешь попытки все это довести до ума и загораешься чем-то другим.
Последние несколько месяцев я живу в совершенно другой реальности. Мои новые программы вообще не имеют кнопок, окошек и меню настроек. У них у всех один интерфейс - микрофон, строка ввода текста с кнопкой отправить и терминал. Более того, у них нет даже строго детерминированного кода, который можно запустить и получить результат. Нет момента релиза, когда можно выдохнуть и сказать - ну все, программа дописана, теперь просто пользуемся. Я открываю окно терминала, запускаю там pi, и дальше мы с ним в одном текстовом чате одновременно делаем дело и тут же проектируем и пишем саму программу или обрывки кода и функции программы, которые делают части дела. Ощущение от этого довольно странное - будто ты сначала едешь на велосипеде и прямо на полном ходу он постепенно трансформируется сначала в скутер, потом в внедорожник, потому что решил свернуть с асфальта на кукурузное поле.
Что за софт такой?
Если посмотреть на любую привычную нам программу, от блокнота до тяжелого видеоредактора, ее жизнь всегда строго поделена на три отдельных этапа: написать, попользоваться, изменить. И эти этапы никогда не смешиваются во времени, они идут строго друг за другом по кругу.
Сначала ты надеваешь каску разработчика. Ты сидишь в среде разработки, пишешь код, продумываешь логику, пытаешься заранее угадать все случаи жизни, собираешь проект. В момент сборки происходит магия превращения живой мысли в застывший бетон. Получается готовый файл или сервис - по сути, замороженный артефакт. В нем уже ничего само не изменится, он умеет ровно то, что в него заложили пять минут или пять лет назад.Потом ты снимаешь каску строителя и надеваешь шляпу обычного пользователя. Ты берешь этот застывший артефакт и начинаешь с ним работать. И вот тут всегда начинается самое интересное. Ровно в середине работы ты понимаешь, что в одном месте логика жмет, в другом не хватает маленькой галочки, а на третьем шаге программа делает откровенную глупость, которую ты просто не мог предвидеть, пока не столкнулся с реальными данными.
Что приходится делать в классическом мире? Правильно, бросать свою задачу на полпути. Ты закрываешь программу, выходишь из рабочего потока, снова лезешь в исходники, вспоминаешь, как там все устроено, правишь код, пересобираешь этот бетонный куб заново и запускаешь его с начала. Пока ты этим занимался, творческое настроение уже улетучилось, а что именно ты хотел сделать в самом начале - забылось. Разделение на время создания софта и время его использования кажется нам настолько естественным, что мы даже не замечаем, сколько сил съедает это постоянное переключение контекста.
В агентном софте, в котором я сейчас поселился, этой стены нет. Все три процесса - использование программы, ее написание и переделка - схлопнулись в один процесс и происходят одновременно. Внутри одного и того же разговора с системой.
Устроено это на удивление просто, без всякой космической магии. Вместо монолитного приложения у тебя есть папка с проектом. В этой папке лежат небольшие рабочие скрипты на условном питоне, которые умеют делать конкретные атомарные действия - например, нарезать аудио, сходить по сети в какую-нибудь модель или склеить картинки. А рядом с ними лежат обычные текстовые файлы с инструкциями на человеческом языке - как этими скриптами пользоваться, в каком порядке их запускать, какие правила соблюдать и чего делать категорически нельзя. И, что интересно, ни один из этих артефактов ты не пишешь сам. Они появляются и преобразуются исходя из логики решаемой конкретной задачи.
Поверх этой папки живет агент. Когда ты к нему приходишь, ты не нажимаешь кнопку старт. Ты просто пишешь ему в чат обычными словами, какую задачу нужно провернуть сегодня. Он читает свои текстовые инструкции, сам находит нужные скрипты или соображает где их взять и как изготовить, запускает их, смотрит на результат и двигается дальше. То есть на этом уровне ты просто пользуешься софтом, отдавая команды голосом или текстом. Но самое главное начинается через пару минут, когда ты видишь промежуточный результат и понимаешь, что хочется иначе. Ты не прерываешь работу, не открываешь другой редактор и не идешь править код руками. В том же самом диалоге, прямо следующей репликой ты говоришь агенту что не так с текущим процессом и каким он должен быть. Агент пытается переписать программу так чтобы процесс стал таким как тебе нужно.
Буквально пишешь ему: слушай, на этом шаге получилось кривовато, давай-ка открой свой скрипт сборки, поменяй там логику выравнивания текста, запиши себе в инструкцию больше никогда так не лепить строчки впритык, и сразу же перезапусти этот шаг на наших текущих файлах. И он идет, правит свой собственный код, обновляет свою документацию и тут же продолжает выполнять твою рабочую задачу уже обновленным инструментом.
Получается удивительный гибрид. Софт перестает быть мертвым молотком, которым ты либо бьешь по гвоздю, либо несешь его в кузницу на переплавку. Он становится живым и пластичным. Он дописывается и умнеет ровно в тот момент, когда ты им пользуешься, питаясь твоими замечаниями по ходу реального дела. Ты не проектируешь систему заранее на полгода вперед, пытаясь предусмотреть все края и углы. Ты начинаешь с пары кривых костылей и за десяток рабочих вечеров прямо в процессе разговоров выращиваешь из них идеально подогнанный под твои руки комбайн.
Как это живёт на практике
Чтобы это не звучало как сухая философия из мира далекого будущего, покажу на живом примере, который крутится у меня почти каждый вечер. Некоторое время назад я плотно подсел на генерацию музыки в Suno. Занятие это азартное - сидишь, крутишь стили, подбираешь тексты, и довольно быстро у тебя скапливаются тысячи треков, которые самому искренне нравятся. Хочется ими поделиться с миром или хотя бы красиво сложить в коллекцию чтобы слушать. Ну и если есть звук, то почему бы не сделать клип - с видеорядом интереснее? Садиться в полноценный видеоредактор, руками искать сотни картинок, двигать их по таймлайну под каждый куплет и настраивать вылеты титров - это верный способ возненавидеть свое хобби примерно ко вторнику. Писать под это дело классическую программу с графическим интерфейсом, ползунками и превьюшками - значит закопаться на полгода в верстку окошек. Поэтому у меня вырос живой агентный конвейер, который делает из музыки готовые видеоклипы.
Под капотом у этого конвейера с полдюжины шагов, и каждый шаг - это отдельный скрипт со своей подробной текстовой инструкцией для агента. В общих чертах маршрут выглядит так: сначала система заглядывает в мою музыкальную папку и находит группу треков, которым я поставил лайки и просит выбрать какой взять в работу. Причем я могу ему задать и не тот который он предложил, а тот что звучит сейчас у меня на телефоне, зная его название - это работает из коробки для этого ничего не надо было делать. Реальность такова, что агент понимает то, что ты ему говоришь человеческим языком и это дает большшие преимущества перед исполняемым кодом старого типа. Затем запускается модуль распознавания речи, который внимательно слушает песню и вытаскивает из нее текст с привязкой каждого слова ко времени до долей секунды. Это нифига не тривиальный процесс и он редко проходит как по маслу для каждой новой песни, агенту приходится изощряться с разбиением музыки на части и пробовать разные параметры, чтобы используя модель whisperX small получить точные таймстампы для строк из песни. И для тех строк которые не получились - подобрать значения "на глаз" исходя из известных таймстампов. Эту задачу мне не удавалось решать детерминированным софтом без привлечения толстых моделей, запускаемых на видюхах или платных облачных сервисов. Хотя.. насчет облачных сервисов надо будет проверить на лимиты триалов и пары-тройки их десятков может быть и хватит.
Дальше в дело вступает нейросетевой сценарист. Он берет этот размеченный по времени текст, слушает структуру песни и режет ее на логические сцены по несколько секунд. На каждую сцену он придумывает визуальный сюжет - что именно должно быть в кадре, какой там свет, какое настроение и как это связано со смыслом строчек. После этого промпты со сценарием улетают в генератор изображений, который рисует пачку картинок к каждому кадру. И в финале скрипт-монтажер берет эти статичные картинки, пускает по ним плавное движение виртуальной камеры с легкими наездами и покачиваниями, склеивает их через мягкие переходы точно под ритм, накладывает сверху аккуратные титры и выдает готовый видеофайл.
Звучит как обычный автоматический скрипт, где нажал одну кнопку и ушел пить чай, но вся соль в том, что с творческими задачами полная автоматика почти всегда выдает пластмассу. Тут нужен человек в процессе, но не загруженный дурацкой рутиной, которая убивает все желание это делать. Поэтому весь интерфейс к этой фабрике клипов - это обычный чат с агентом.
Выглядит наш сеанс примерно так. Я запускаю агента пока гуляю по парку и пишу ему: давай возьмем последний трек про геометрию, и начнем собирать по нему клип. Проходит пара минут. За это время он сам сходил в папку, нашел нужный файл, прогнал его через расшифровку звука, понял что получилась лажа - подогнал параметры whisper, получил правдоподобный результат, проверил все два раза, вызвал сценариста - наделал промптов, подготовил 4 варианта обложки и несколько пробных кадров. В чат вываливается отчет со ссылками на картинки. Я их смотрю - одна из обложек отличная. Но вижу что картинки для математической песни содержат каракули вместо формул.
В обычной программе я бы сейчас полез руками редактировать какой-нибудь огромный файл конфигурации или переписывать текст в окошках, что ясное дело, невозможно сделать гуля по парку. Здесь я просто пишу в чат одну фразу: ставь 2ю обложку первым кадром и генерируй иллюстрации через арену роутером Max для всех картинок где есть формулы, чтобы формулы нормально отображались на картинках и были осмысленными, а не каракулями.
И вот происходит слияние. Агент одновременно правит конкретный сценарий моего текущего клипа и тут же идет в системный файл конвейера, редактируя правила поведения для будущих запусков. Мне не нужно думать о том, что сейчас я пользователь, а через минуту разработчик. Я просто разговариваю с системой о том, что мне нужно получить, а она сама разбирается, что нужно подкрутить в текущих скриптах и как это лучше сделать.
Мы едем дальше. Я говорю: сценарий и картинки отличные - собирай видео. Еще через несколько минут я открываю готовый ролик. Картинки вышли отличные, формулы нарисованы правильно, камера движется, но я замечаю досадный косяк сборки. В паре мест строчки песни оказались слишком длинными, и титры вылезли почти к самым краям кадра, смотреть неудобно. А еще мне вдруг захотелось, чтобы на инструментальном проигрыше камера не просто ехала вбок, а медленно отдалялась назад, создавая ощущение простора.В скрипте сборки видео никакого отдаления на проигрышах вообще не было предусмотрено в коде - там просто чередовались легкие наезды и панорамы. Если бы это был классический пет-проект, я бы вздохнул, закрыл плеер, открыл документацию по библиотеке обработки видео, полчаса вспоминал математику масштабирования кадров, сломал бы по дороге наложение звука, починил обратно и только к полуночи увидел результат.
Вместо этого я возвращаюсь в наш диалог и пишу: слушай, картинки супер, перерисовывать их не надо, но давай допилим сам сборщик видео. Во-первых, научи скрипт автоматически бить длинные фразы титров на две строчки, если там больше пяти-шести слов, чтобы они не липли к краям экрана. Во-вторых, добавь в код сборщика новый тип движения камеры с плавным отдалением от центра и включи его для всех кадров, где в разметке нет слов. Как допишешь скрипт - просто пересобери финал из уже готовых картинок.
Агент задумывается на минуту, шуршит питоновским файлом, сам тестирует, не отвалился ли синтаксис, запускает быструю пересборку видео без повторной генерации графики и кладет передо мной обновленный клип. Титры аккуратно сложены в две строчки по центру, на гитарном соло камера красиво улетает назад над зимним лесом. А главное - мой конвейер только что стал чуточку умнее и обзавелся новой функцией, причем я не написал ни строчки кода руками и ни на секунду не отвлекся от создания конкретного ролика.
Готовый видеоклип в таком процессе получается почти как приятный побочный эффект от самой беседы. Ты просто идешь, общаешься с системой о музыке и картинках, на ходу подпиливаешь ей шестеренки обычными человеческими словами, а сбоку из этого разговора сам собой выпадает смонтированный ролик. И к десятому такому вечеру ты вдруг замечаешь, что замечаний к системе становится все меньше, потому что все твои вкусы и мелкие правки уже бережно вписаны в ее скрипты и инструкции во время прошлых посиделок.
Поймал себя на мысли, что после такого опыта смотреть на привычные тяжелые программы с сотнями вкладок и выпадающих меню становится как-то грустно. Очень быстро привыкаешь к тому, что софт - это не бетонная коробка, к которой ты должен приспосабливаться и учить расположение кнопок, а живой собеседник, который перестраивает сам себя под твою задачу прямо во время работы.
Если представить, что любой сложный инструмент можно превратить в такой живой разговорный конвейер, который сам себя дописывает по вашим замечаниям в чате - какую свою рутину, рабочую головную боль или творческую задачу вы бы перевели на такие рельсы в первую очередь? С каким софтом вам хотелось бы просто поговорить человеческим языком вместо того, чтобы сто раз тыкать мышкой по менюшкам?



















