Я уже не помню, в какой момент экспериментирования с ИИ у меня щёлкнуло, и я решил, что теперь-то уж точно пора делать все свои задвинутые в «когда-нибудь» проекты.
До этого у меня был опыт использования агентской разработки для создания специализированного ЯП, но это был узконаправленный исследовательский интерес. Кроме того, я достаточно активно использую ИИ на работе и успешно способствую распространению этой практики на всю мою команду: агенты помогают нам с анализом, тестированием, кодингом и на самом деле ещё много с чем, но это тема отдельной статьи. Для текущей важно то, что теоретический и практический опыт у меня какой-никакой есть. При этом такого, что нужно в одиночку пилить целое приложение и проектировать UX/UI/CUI, чат-бота, безопасность, расписывать пользовательские сценарии и реализовывать различные схемы работы с моделью, ещё не было. Время не резиновое, а бюджета нет вообще. В общем, залетел я во всё это на голом энтузиазме.
Мечта об умном чате для планирования рутины возникла ещё до массового распространения ИИ и ждала, а возможно, ещё подождёт, оптимального отношения цены, скорости и зрелости моделей. Я даже подговорил товарища участвовать в проекте, но коллаборации особо не вышло: мы много разговаривали о проекте, но в основном я работал над всем один.
Нет фантазии, скажете вы, ведь каждый второй пилит какой-то свой планер, и вообще сколько можно? В этой статье я коснусь ответа на этот вопрос, но всё же больше буду концентрироваться на специфике продуктовой агентской разработки. Спойлер: много что получилось, до MVP доехал, сейчас еду в сторону MWP — minimal wowable product. Для меня это про историю, когда не нужно задумываться как именно формулировать задачи. Если что-то будет не понятно, агент уточнит, а если понятно — поймает намерение и зафиксирует его в планах.
Расскажу про саму решаемую задачу
Если простой TODO-лист пишется не приходя в сознание минут за 15 на любом современном фреймворке, то как только мы пытаемся сделать что-то более сложное и минимизировать когнитивную нагрузку на пользователя, то будто бы утыкаемся в бетонную стену. Моя проблема со всеми приложениями, которые я пробовал, заключается в том, что в какой-то момент мне нужно тратить слишком много времени на поддержание запланированного. Я же хочу планировать так, будто я общаюсь с ассистентом, причём в тех каналах, где я уже привык общаться текстом или голосом. В моём случае это Telegram и Алиса. Пользовательский интерфейс нужен скорее для того, чтобы проконтролировать, посмотреть прогресс или эпизодически, когда есть подходящее настроение, плотно поработать над планами.
Тут вы можете сказать: возьми OpenClaw или другого агента и общайся сколько хочешь. Я соглашусь, но частично. Действительно, возможность вести личные дела в Obsidian и подключить к агенту Telegram многое решает. У меня всё это и так настроено. Но такое взаимодействие нельзя назвать полноценным продуктом. Это скорее некий DIY-проект, который может дать впечатляющие результаты, но требует времени на настройку и вовлечение. В продукте можно задать онтологию предметной области, закрепить интеграции и контракты, сделать специализированный UI и разбор сложных кейсов. В общем, нарастить обвязку, целиком заточенную под решение конкретных продуктовых задач. Например, мне важно, чтобы приложение обеспечивало быстрые и правильные ответы, точно ловило мои интенции и имело при этом низкую себестоимость.
Если смотреть под таким углом, то планировщик, который я задумал, должен дополнять вещи типа Claw, а не конкурировать с ними: персональный ИИ-помощник может использовать API планера для создания задач, загружать и выгружать сущности, и это, на мой взгляд, только дополняет картину. Но и без ассистента у меня должна быть возможность быстро запланировать задачу, скорректировать планы и получить о них детальную информацию.
Мне нравится начинать любой проект с построения модели предметной области. Раньше это были формальные и не очень OWL-онтологии, сейчас — просто некая вспомогательная конструкция, которая помогает понять, что есть, что можно получить из того, что есть, и даёт дополнительные ограничения для кодирующих агентов. На картинке не полная онтология, но показательная. Отличается она в основном тем, что сфера — отдельная сущность, и кроме неизменной сферы «Жизнь», которая есть у всех изначально, пользователи могут добавить другие сферы, например «Работа».
Процесс проектирования был непростым, так как, с одной стороны, хотелось опираться на понятные метафоры — путь / шаг / цель, а с другой — я совершенно не привык к неймингу сущностей на русском, и это оказалась одна из плохо делегируемых LLM тем. Я до конца так и не уверен, что преуспел, но на текущий момент все мои дела вписываются в придуманный каркас.
Далее я хотел, чтобы у приложения была возможность:
-
создавать планы с привязкой к дате и без неё;
-
задавать минимальный интервал между событиями («переворачивать матрас каждые две недели»);
-
привязываться к порядковому номеру временной сущности («последнюю субботу месяца планировать вылазки на следующий месяц»);
-
создавать события, которые длятся несколько дней, и при этом я могу быть занят постоянно в эти дни (командировка) или частично (фестиваль/конференция в моём городе), а расписание занятости может изменяться в зависимости от дня;
-
записывать рутины — действия, которые должны повторяться, о которых нужно помнить, но для которых история не важна. Например, планировать еду на неделю по субботам;
-
записывать практики — действия, для которых важны непрерывность и отслеживаемость. Например, занятия йогой;
-
связывать планы с людьми и местами. Например: «Пойти с женой в кино»;
-
создавать текстовые заметки, связанные с планами;
-
использовать русский язык со всей его вариативностью.
Наглядный пример:
Раз в две недели по средам вечером созваниваться с мамой
В этой фразе есть несколько разных смысловых слоёв:
-
это регулярное действие, а не разовая задача;
-
интервал — раз в две недели;
-
день недели — среда;
-
время — вечер, то есть мягкое окно, а не точное
19:30; -
человек — мама, и это может быть важным контекстом для будущих запросов;
-
действие относится к личной сфере, а не к работе;
-
если пользователь пропустит созвон и сделает его позже, возможно, следующий повтор должен считаться от фактического выполнения.
Задача планировщика — превратить бытовую фразу в связку устойчивых сущностей так, чтобы с этой связкой можно было работать в дальнейшем: исправлять, планировать, переносить и использовать через API.
Ещё несколько примеров:
|
Фраза пользователя |
Наивная трактовка |
Что нужно хранить на самом деле |
|---|---|---|
|
|
Ежемесячная задача |
Рутину с правилом «первая суббота месяца» и отдельный подготовительный шаг «проверить остатки», потому что порядок действий важен. |
|
|
Событие в октябре или заметка |
Обслуживающую рутину или запланированное дело с неточной датой: месяц известен, день может потребовать уточнения, следующий цикл должен считаться от фактического выполнения. |
|
|
Календарное событие с точным временем |
Дело, а не событие: дата «завтра», мягкое время «вечером», без фиксации точного начала и конца. |
|
|
Текстовая заметка или простой reminder |
Событие: точное начало, длительность 2 часа, человек |
|
|
Создать новое событие «встреча с Сергеем» |
Обновить уже существующее событие, найденное по названию и человеку; сохранить идентичность, не делать дубль. |
|
|
Создать новую встречу в офисе |
Обновить место существующей встречи, не потеряв время и участника. |
|
|
Человек |
Дело или событие с ролью/командой в тексте; |
Реализация
При таком подходе нужно будет сразу отдавать LLM весь контекст, из-за чего сразу понятно, что он не годится. Но он позволяет собрать контур тестирования, посмотреть на ответы разных LLM-моделей и понять, какие промпты для чего лучше подходят. Следующий шаг — сделать так, чтобы функционал приложения был доступен для модели в виде описанного набора возможных вызовов.
Очень быстро я пришёл к тому, что мне нужна качественная обвязка — то, что в статьях по ИИ называется harness. Тащить LangChain/Graph казалось усложнением, и я решил сделать узкозаточенный инструмент — так появился PromptStudio. Это админка, которая позволяет динамически задавать промпты, работать с моделью напрямую, смотреть трейсы, работать с инструментами, задавать сценарии для проверки и вести статистику по связкам «модель + промпт». Всё это можно было собрать из открытых решений, но это казалось и до сих пор кажется сложнее, чем завайбкодить за пару дней своё решение.
Существенный фактор в пользу вайбкодинга — я сразу понимал, что нужно и что я собираюсь делать: хранить в YAML весь пайплайн, редактировать его в UI, иметь возможность варьировать запросы к моделям в пайплайнах и прогонять разные пайплайны на разных моделях с наборами тестов, чтобы в итоге автоматически получить скор. Также студия умеет использовать сервисы планера как инструменты модели и привязывать пайплайны к API.
Я загрузил в неё набор из 64 базовых сценариев и стал проверять их на бесплатных моделях (локально и через OpenRouter) и яндексовских моделях. Само облако мне знакомо по прошлым проектам, плюс есть начальный грант. Так я определил круг моделей, которые достаточно выразительны, чтобы пройти все кейсы без ошибок.
Сценарии устроены следующим образом: они определяют, что отсылать и какой дополнительный контекст передавать, а затем проверяются статус ответа, тип сущности, действие, ключевые поля, отсутствие лишних уточнений, сохранение в БД, отсутствие дублей, чистота контракта и иногда задержка с токенами. Сейчас всё устроено так, что почти каждая найденная ошибка автоматически превращается в сценарий, в котором выделяются части, отличающие его от существующих сценариев, и таким образом база проверок ежедневно растёт.
Пример простого сценария — один запрос + немного контекста:
{ "text": "Встретиться с Сергеем сегодня в 19:00", "quick_add": true, "user_context": { "language": "ru", "timezone": "Europe/Moscow", "known_spheres": [ "Жизнь", "Работа", "Здоровье" ] }, "shortlists": { "goals": [ "Запустить MVP продукта", "Ремонт" ], "milestones": [ "Согласовать словарь", "Разработка" ], "people": [ "Сергей — коллега", "Сергей — тренер", "Мария", "Анна" ], "locations": [ "Офис", "Namastation" ] }, "context_ids": {}}
Есть более сложные варианты, где пользователь может уточнить уже сделанный запрос и, например, отметить прогресс. Для каждого варианта можно оценить, насколько модель справилась: вызвала ли нужный инструмент, смогла ли заполнить итоговую структуру. Баллы за каждый пункт проставляет SOTA-модель. Я пока не встречал кейс, где она бы ошиблась и сделала что-то неправильное.
Когда я только начал экспериментировать, наиболее комфортной из открытых моделей была Qwen 235B A22B. Какое-то время я был ею доволен: модель прощала много ошибок, на моих тестах с отрывом набирала большое количество очков, и в целом выглядело так, что по соотношению цены и качества — самое то. Минуса было два:
-
Цену хотелось ещё ниже: эксперименты быстро высасывают выданный грант, а мне хотелось проверить как можно больше гипотез за как можно меньше денег. Один прогон на всех сценариях выходил в 500–800 рублей, в зависимости от количества пайплайнов.
-
Скорость. Модель работала сильно медленно, около 30 секунд на ответ, и это ставило саму идею проекта под угрозу. Дело в том, что основной интерфейс должен быть чат/войсы, а в таком режиме 30 секунд — слишком ощутимая задержка.
Тогда я стал исследовать быстрые модели и смотреть, кто что предлагает на российском рынке, и быстро обнаружил, что довольно неплохие результаты показывает яндексовская Alice AI LLM Flash, которую я отмёл на первом отсеве из-за того, что она стабильно игнорировала часть инструкций. Но к этому моменту я наигрался с бесплатными и локальными моделями, и у меня был развитый repair-слой, который позволял не замечать некоторые вольности в формировании JSON и доводил вывод модели до необходимого контракта. При этом «флешка» отвечала остальным критериям: низкая цена и высокая скорость работы. Большая часть ответов укладывалась в 5 секунд даже с корректирующими запросами.
Обнаружив, что мои базовые кейсы проходят, я решил остановить дальнейшие поиски — по крайней мере пока не упрусь в какой-нибудь нерешаемый кейс. А там, глядишь, кто-нибудь выпустит более подходящую «флешку».
Нужно сказать, что в некоторых случаях для классификации намерения модель вообще не нужна: справляются комбинация dateparse, pymorph3 и rapidfuzz. Были большие надежды на Natasha, но они не оправдались: тесты сходу не показали качественного улучшения, и я отложил эту идею, по крайней мере на время.
Процесс регистрации для упрощения сделан вокруг Telegram. Почему нет MAX? Я скажу. Признаюсь, подумал, что сделать поддержку MAX было бы разумно: это потенциально увеличит охваты. Но внезапно оказалось, что национальный мессенджер надёжно защищен от таких опасных мыслей: физическому лицу делать ботов не положено. Не буду это комментировать тут, попридержу для тг.
Вынос проекта за пределы личного ноутбука
Мне хотелось выкатываться сразу в что-то публичное, но при этом хочется чтобы это был сразу MWP. С другой стороны, психологически хотелось иметь доказательство что это всё может быть выкачено. В итоге я остановился на публичной бете — так я контролирую свои расходы с одной стороны и могу собрать обратную связь от заинтересованных людей с другой. Пару вечеров потратил на то чтобы понять как именно выкатывать и… долгожданный первый деплой.
Прохожу регистрацию, сам себя апрувлю и создаю первую задачу. Чувствую радость и гордость. Радость была недолгой, но это ожидаемо: мои сценарии бот проходил с лёгкостью, но в первый же день я столкнулся с осознанием того, что много реальных запросов не учтено и нужно ещё изрядно поработать, прежде чем вывести всё это в публичную историю. При этом сам я уже вовсю пользуюсь своим детищем: переношу туда планы и заодно добираю тестовые сценарии.
Про деплой особо нечего рассказывать: попросил нейронку сгенерировать мне Ansible и, собственно, им и деплою. На текущем этапе за глаза.
Монетизация и юридическая сторона
Как подключать платежи, я разузнал, но перспектив по монетизации особо не вижу. Я буду рад, если проект будет отбивать себестоимость облака и токенов. С другой стороны, есть несколько идей для развития: совместное планирование, покупки, голосовое общение. Я допускаю, что в какой-то момент это может вырасти в классный подписочный сервис.
Юридический вопрос — отдельная неувлекательная история. Мы отсылаем персональные данные в LLM и Telegram, и это могут быть довольно чувствительные данные, если кто-то захочет запланировать врача и прикрепить к плану заметку с детальными вопросами. На все такие операции нужны явные согласия. А ещё нужно стать оператором ПДн. Кроме того, недавно принятый 149-ФЗ тоже потенциально осложняет жизнь. Потихоньку читаю законы и пытаюсь понять, можно ли в этой стране вообще делать такие сервисы.
—
Если вдруг есть желание помочь или узнать больше о проекте, то самый простой способ — написать об этом мне в Telegram
ссылка на оригинал статьи https://habr.com/ru/articles/1047364/