— Дорогой, я так больше не могу: вацап у мамы не работает, телега не едет, а ВК-звонки показывают вместо лица размытую квадратную кракозябру. Сделай с этим что-нибудь, а?
— Ну а что я могу с этим сделать?
— Придумай что-нибудь, тыжпрограммист теперь!
— ээээээээээээ, чьорт (((
Не, ну а чо? У меня даже в аське шестизнак был, если что! Фикли там думать - мутим свой мессенджер! Делов-то ))) Отправил сообщение - принял сообщение, позвонил - ответил, что там еще эти мессенджеры умеют? Смайлики там всякие, гифки. Пффффф
На самом деле шестизнак я потерял, так как пароль забыл, а потом был девятизнак 305128631 - до сих пор помню! Или это в Квипе уже было? Ладно, проехали. Короче, все же знают что такое мессенджер? Сколько их в мире существует - 1000? 2000? Ну что-то около того наверное. Надо было просто ресерчнуть, какой работает в России и дать рекомендацию. Ну пусть бы у тещи и жены на телефонах стало на 5 иконок больше, пусть бы они каждый раз тыкались в поисках, какой работает сегодня. Неудобненько конечно, но куча людей же так и делали! Вот - чесслово, надо было тоже так и сделать. Отбрехаться.
Но шило не утаишь не только в мешке, но и в других местах тоже))
Было принято решение, которое обусловило следующий год моей жизни. Честно - не жалею нисколько, на самом деле! Это, наверное, было чуть-ли не самым продуктивным временем за всю мою жизнь - так быстро, много и разнообразно я еще не изучал, наверное, никогда.
При этом я вполне ясно понимал, что сейчас буду изобретать велосипед. Мы же уже выяснили на WeekendDiver, что сначала надо посмотреть, что существует, а не сразу бросаться программировать. Посмотрели, да. Велосипедов много, у каждого свои достоинства, только вот целиком ни на один садиться не хочется: у этого рама неудобная, у другого руль не туда повёрнут, у третьего навешано столько всего, что уже непонятно, где педали.
А если взять велосипед и прикрутить к нему ракетный двигатель?
Пошли по старой схеме: ресерч-фирст. Ну а что там ресерчить-то? Есть Т. W. и S. (ну, чтоб никто не догадался, кого именно я дальше хаять буду) и к каждому были свои вопросики.
Правда, вопросы эти уже были немножко другие, чем у человека, которому надо просто позвонить маме. Я смотрел на привычные приложения и привычно ловил себя на мысли: вот это сделано хорошо, вот это удобно, а вот здесь почему такая фигня? Я бы сделал по-другому))
Опасная мысль, особенно когда рядом есть ИИ, который на слова «я бы сделал» вполне может ответить: «Сейчас сделаем»))
У Т. мне нравилась сама идея большого пространства для общения: личная переписка, группы, каналы, цирк с конями. Облачная история, доступ с разных устройств — очень удобно, я это прекрасно понимаю. Но мне не нравилось, что переписка живёт где-то вне моего телефона и сервис потенциально имеет весьма широкий доступ к этой истории. Да, там есть отдельные секретные чаты ("секретность" которых тоже вызывала вопросики, на самом деле), а мне бы хотелось, чтобы приватность личного разговора была обычным состоянием, без необходимости дополнительных тыков в кнопочки. Ну ок, скажет пытливый читатель - есть же W.?
С W. была другая история: привычный бытовой инструмент, удобный и понятный, но я не хотел просто воспроизвести его у себя под другой иконкой. Я ж, блин, теперь разработчик! Хотелось и личного общения, и публичных каналов в том виде, который мне нравился у Т., и собственного интерфейса, и возможности переделать то, что меня раздражало, и вот тут еще кнопочку добавить, а вон там - удалить. Чужая аппка на такие пожелания реагирует довольно предсказуемо: никак. Пользуйся тем, что дали.
А S. я рассматривал уже с интересом к тому, как там устроена безопасность. И некоторые решения казались мне избыточными для того продукта, который я уже собрался сделать. Именно казались, с моим тогдашним пониманием и моими задачами: я не приехал в интернет на белом коне, с дипломом «проверил всю криптографию мира». Пока только с шестизнаком, который к тому же потерял))
Про шифрование мы ещё отдельно поговорим, там мне хватило материала и для размышлений и для переделок. Здесь важнее то, как из недовольства чужими приложениями постепенно складывался замысел своего. Взять удобное, выкинуть лишнее, переделать неудобное, добавить недостающее. Логично же! Ну и сохранить приватность там, где надо, и не навешивать на пользователя сложность просто потому, что я теперь умею попросить агента её написать.
Ну вот, уже интереснее. Уже хочется хотя бы попробовать. А почему бы и да?
Так семейная задача «сделай, чтобы можно было нормально общаться» начала превращаться в MangoConnect. Я сразу осознавал, что просто маленькую говорилку на двоих делать мне будет неинтересно: если уж браться за мессенджер, то за настоящий, с нормальными чатами, группами, звонками, фотографиями и всеми теми вещами, которые любой человек в нём ожидает увидеть.
Со всеми функциями, короче. Очень хорошая формулировка для начала проекта, особенно если не пытаться сразу разобраться, сколько именно функций помещается в слове «все».
Но сначала надо было определиться с несколькими вещами, от которых зависело всё остальное. Одна из главных — что мы вообще обещаем человеку насчёт его переписки?
Мне хотелось, чтобы личные разговоры шифровались на устройствах участников и сервер занимался доставкой, а не чтением. До этого я уже был знаком с шифрованием, но совершенно не представлял, сколько привычных удобств мессенджера придётся заново обдумать, если последовательно держаться этой идеи.
На уровне желания всё просто: пусть будет безопасно и удобно. Очень желательно одновременно, без дополнительных вопросов, кнопок и необходимости прочитать перед первым сообщением учебник. Вот примерно настолько подробно я сначала и представлял себе эту часть задачи))
Вру конечно, у меня даже диплом есть "Защита информации от средств технической разведки". Красный. Ну, чтоб вы не подумали "Полез чайник в болото"))
Итак, безопасность для меня оказалась чуть важнее, но и удобство хотелось подтягивать настолько, насколько возможно. Одним из решений стало «один аккаунт — одно активное устройство»: мне не хотелось сценария, когда к одной переписке постоянно имеют доступ ещё несколько подключённых клиентов. У такого решения есть своя цена для пользователя, конечно, поэтому его пришлось выбирать осознанно, а не просто записать в список преимуществ.
Ещё я не хотел делать номер телефона обязательным условием регистрации. Зачем он мне нужен, если задача — дать людям возможность общаться? Даже у ориентированного на приватность S. номер для регистрации остаётся необходимым, хотя собеседнику его можно не показывать; мне же хотелось обойтись без этой привязки, да и вообще как-то поменьше знать о конечном юзере.
При этом публичный канал и личный разговор для меня были совершенно разными вещами. Если человек публикует что-то для открытой аудитории, у этого другой смысл, другие правила и другие задачи, чем у сообщения жене. В итоге я выбрал гибридную модель: личное общение и закрытые группы, звонки и групповые звонки — со сквозным шифрованием, публичные группы и каналы — отдельный открытый режим.
То есть универсальность устройства, как вы помните, я люблю, а вот одинаково обращаться со всеми его функциями совершенно не обязательно. В одном приложении могут жить разные сценарии, главное — самому понимать, где у них границы, и суметь объяснить это и пользователю и агенту.
Последнее, как выяснилось - отдельный квест. Но об этом позже.
К этому времени я уже мог нормально обсуждать с агентами устройство приложения: из каких частей оно будет состоять, что должен делать сервер, что остаётся на телефоне, как всё это связывается. Опыт ManiTalk и EasyStayTH никуда не делся, я по дороге действительно учился, поэтому разговор уже не сводился к «нарисуй мне экранчик, а дальше посмотрим».
Но знать в общих чертах, как устроено приложение, и заранее представить все последствия своих пожеланий — это, оказывается, две большие разницы. Особенно когда пожелание звучит как «обычный мессенджер, ток там с шифрованием немного, ну ты понял, DO NO MISTAKES».
Возьмём хотя бы моё бодрое «отправил сообщение — принял сообщение». Для пользователя это действительно два действия, а внутри между ними ещё очень много жизни. Получатель может быть без интернета, приложение может быть закрыто, соединение может оборваться как раз в тот момент, когда уже непонятно, успело сообщение уйти или ещё нет. Человек жмёт повторно, потому что ему надо отправить, а не изучать состояние твоего соединения. А всё это должно выглядеть для юзера совершенно обыденно: написал — дошло. Никто не обязан восхищаться тем, сколько ты предусмотрел вариантов между этими двумя событиями. Всем пофиг, на самом деле.
Со звонком та же история. «Позвонил — ответил» прекрасно звучит, пока не начинаешь раскладывать, что должно происходить на каждом телефоне до ответа, во время разговора и после того, как один из участников неожиданно пропал из сети. А ведь мы вообще начали с того, что семье надо нормально звонить, поэтому сказать «ну сообщения уже ходят, а звонки потом как-нибудь» было бы довольно странным результатом всей затеи. Мне вообще сказали, что без видеозвонков работу не примут))
И это мы ещё даже не добрались до смайликов, которые я так бодро записал в «фигню делов». Просто начали раскладывать, что именно прячется за словом «мессенджер». На словах-то я все эти вещи знал, я же тыщу лет ими пользовался, а теперь приходилось превращать привычки пользователя в решения разработчика. Реверс инжиниринг типа, ток без кода.
И вот тут агент действительно был очень полезен. Можно было сесть и обсуждать: я объясняю, как представляю себе поведение, он раскладывает, что для этого потребуется, я смотрю, уточняю, что-то меняю. Так из идеи постепенно появлялась конструкция, про которую уже можно говорить предметно, а потом и писать код. Да, я в курсе про гитхаб и гитлаб, и что там есть репы с открытым кодом. Но вы же знаете: гордыня - самый страшный грех, зато самый сладкий по отдаче ))
Вместе с конструкцией опять росло количество всего того, что надо помнить. Это решение мы выбрали вот поэтому, здесь решили сделать иначе, такую возможность пока отложили, а вот эту часть нельзя менять отдельно от соседней. Вчера мы с одним агентом всё это прекрасно обсудили, сегодня я открываю новую сессию — и опять становлюсь главным носителем истории проекта.
Тут очень хотелось достать тот самый волшебный промпт из предыдущей статьи. Но мы его, как вы помните, не нашли.
Я реально какое-то время прям боялся начать новую сессию, потому что потеря контекста - это боль в том же месте, где и шило. А контекст теряется и по ходу сессии - сюрприз-сюрприз! - при "compacting..."! Одно время даже заводил практику, что в сессии просил у агента её саммари, открывал новую сессию, вставлял саммари туда, убеждался, что новый агент вроде понял, и только тогда закрывал старую сессию. Эх, юность ИИ-разработки ))
При работе над Mango я уже сознательно старался оставлять контекст в самом проекте. Начали со списка задач и описания идеи, потом стали добавлять другие документы. Не было такого, что я однажды проснулся и сразу нарисовал какую-то систему: очередная необходимость возникала в работе, мы придумывали, куда её записать и как потом найти.
Позже понадобилось место, через которое агенты могли передавать друг другу незаконченные дела. Потому что «я тут кое-что попробовал, не получилось, но я уже почти понял» — очень ценная информация, особенно если она не исчезает вместе с закрытой сессией. И совсем не хочется оплачивать временем и лимитами ещё одно такое же «почти понял» от следующего агента.
Вот так у проекта, который начинался с просьбы наладить семейные звонки, постепенно появлялась ещё и собственная память. А у меня — новая задача: сделать так, чтобы агенты этой памятью наконец пользовались, а не каждый раз приходили в проект как в первый раз.
Мессенджер написать — фигня делов, мы же договорились. Осталось объяснить нескольким очень умным железякам, что именно мы пишем, и добиться, чтобы завтра они это всё ещё знали))
В следующих сериях: «Прочитай доки». Как я начал выносить собственную голову в файлы и почему просто завести папку с документами оказалось недостаточно.
Источники и подробности:
