Я ненавижу пет-проекты

Да, я НЕНАВИЖУ их всей своей душой. Ровно с тех пор, как получил свою первую фул-тайм работу разработчиком. Я ненавижу приходить с работы и вставать перед выбором - работать в рамках привычного мне фронтенда, которым я занимаюсь на моей “с 9 до 5” и от которого к концу рабочей недели уже тошнит.

…или с головой погружаться в новые технологии, медленно и мучительно прогрызаясь через них, прежде, чем у тебя получится сделать нечто чуть лучше условного Hello world. Если ты, конечно, не готов жертвовать сном, другими хобби или временем, проведенным с любимыми людьми.

Выбирай свою отраву.

Как человек, для кого программирование лишь один из многих интересов, которым, по совпадению, оказалось проще всего заработать на жизнь - я предпочитал не выбирать вовсе.

Как-то так, да
Как-то так, да

Первые эксперименты с агентным программированием

Где-то во второй половине 2024 года - чуть больше чем за год до написания этой статьи - начался главный хайп по «агентному программированию». LLM теперь не просто могла подкидывать полезные сниппеты, а научилась реально вникать в контекст проекта, сам изменять код, писать тесты и оставлять коммиты.

Долгое время я не обращал на это внимания. К моей работе это не прикрутишь - у агентов были и остаются проблемы с безопасностью, если ты не готов вкладывать миллионы зелени в личный сервер. А пет-проекты я, как можно догадаться, не делал.

Но в какой-то момент я приобрёл подписку на ChatGpt, чью помощь, несмотря на все косяки, я уже успел оценить в задачах из области поиска или исследования. А вместе с ChatGpt шел и Codex.

И это было…вау. Полчаса продумывания архитектуры на салфетке, 10–15 минут на формирование промпта, немного ожидания и… бум, у тебя есть первый драфт проекта. Кривой, косой и вообще тебе придётся потом много чего допиливать руками, НО ОН РАБОТАЕТ. Не через месяц, не через неделю, не в выходные, когда ты выгрызешь немного времени, получше подразберёшься в технологии и вставишь несколько сниппетов со стак-оверфлоу, которые всё починят.

СЕЙЧАС.

И это был тот момент, когда я понял, что крепко на это подсел. Внезапно, программировать стало так же весело, как в годы студенчества. И это было офигенно.

Продумывание стека и архитектуры

Погоняв Codex на простеньких задачках для сайтика-портфолио, который я себе потихоньку любовно собираю - я решил сделать шаг дальше. И использовать его для того, чего раньше я никогда ни в каком виде не делал.

Достаточно скоро в голову пришла хулиганская идея написать AI-чатбота для телеги. Такая AI-girlfriend на минималках. Но это звучало простой задачкой и без всяких агентов, даже если я ботов и не делал. Поэтому я решил немного усложнить себе жизнь и подумал, что теоретически, к такому боту можно прикрепить какую-нибудь базу данных, которая будет хранить чат и прикреплять к контексту для генерации ответа наиболее релевантные этого чата.

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

И вот этот пробел я в первую очередь и решил заполнить. Спустя некоторое время приблизительный стек выглядел вот так.

  • Python в качестве ЯП.

  • telethon — для взаимодействия с телегой. Изначально я прикола ради хотел сделать именно юзер‑бота, отсюда и такой выбор. Его чуть позже сменит python‑telegram‑bot.

  • Milvus — векторная база данных как раз для задач, где нужно без мороки вытащить релевантную информацию.

  • Langchain — опен‑сорсный фреймворк для интеграции LLM в приложение. В основном выступает в роли саппорта, упрощающего взаимодействие с Milvus. Позднее я осознал, что мог бы вообще Langchain не использовать, но тогда я совершенно не понимал, чем я занимаюсь.

  • И API от Deepseek.

Структурно я решил разбить проект на несколько модулей.

  • Memory — отвечает за долгосрочную память.

  • Persona — за персону бота и генерацию ответов.

  • Metadata — за хранение информации о юзерах, подписках и прочих вспомогательных данных.

  • Messenger — за взаимодействие с API мессенджера, то есть отправку сообщений, подписку на новые сообщения юзеров, изменение статуса «печатает» и получение истории сообщений.

  • и Agent — чтобы связать остальные модули в цельную систему.

Скрытый текст

На более поздних этапах список дополнили:

Payments - будет отвечать отправку инвойсов, выдачу подписок, списание токенов и т.п.

Timezone - мини-модуль, отвечающий за инфу о том, в какой таймзоне находится юзер

Не могу сказать, что сильно оглядывался на какие-то паттерны проектирования, но для модулей metamemory, messenger и persona я исходил из идеи отделения бизнес-логики от логики взаимодействия с конкретными инструментами (учитывая мои переобувания со стеком в процессе - чертовски верное решение). Для Messenger это будут, соответственно, обёртки вокруг разных API разных приложений. Для Metamemory - обёртки вокруг разных баз данных. А для persona - разные провайдеры LLM (например, кроме оф. API Deepseek я рассматривал Nlpcloud и их ChatDolphin).

Посчитаю, что я так реализовал паттерн “Стратегия” и буду невероятно горд собой, ха-ха.

Реализация

Забавно, но мне даже нечего сказать в этом разделе. Если раньше этот этап был безграничным источником драмы даже на таком незамысловатом пет-проекте как этот (ЪУЪ), то с агентом за спиной это было почти буднично, и даже не потому, что агент держал у моей головы пистолет.

По крайней мере, я приложил определенные усилия, чтобы все было максимально буднично, и у меня был для этого план. И я его придерживался.

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

Все началось с промпта, где я детально описывал структуру, названия классов и что конкретно должна уметь первая версия приложения. Вместо Memory - заглушка, от Agent и Messenger - небольшие функциональные огрызки. Все, что я от него хотел - чтобы он отправлял статичное сообщение в ответ на сообщение пользователя.

Напишу основу для приложения чат-бота. На текущем этапе у него будет два модуля. 

1) Модуль Messenger: 
a) Предназначен для взаимодействия с мессенджерами. 
б) На текущем этапе достаточно следующего функционала: возможность подписаться на получение сообщений (в событии должны быть следующие данные: uid [id пользователя, отправившего сообщение], message [сообщение пользователя].), возможность отправки сообщения пользователю (sendMessage(uid, messages)), возможность получения истории переписки с пользователем (getConversationHistory(uid, messagesAmount = 20)). 
в) Есть интерфейс IMessangerApp, который должны реализовать все классы, которые осуществляют работу уже с конкретными мессенджерами. 
г) Реализован класс TelegramApp, который реализует интерфейс IMessangerApp и позволяет взаимодействовать с юзер-аккаунтом Telegram через Telethon.
д) Класс TelegramApp подключен к модулю Messenger.
е) Метод sendMessage работает следующим образом: он создает очередь из сообщений, которые нужно отправить. Пачку сообщений для одного пользователя он отправляет сразу, между разными пользователями (например при рассылке пожеланий доброго утра) делает паузу в 15 секунд. 

2) Модуль Memory: 
а) Занимается сохранением долгосрочных воспоминаний
б) На текущим этапе сохраняет только uid пользователей. 

2) Модуль Agent:
а) Предназначен для связывания остальных модулей и координации работы чат-бота. 
б) Подписан на событие получения сообщения и отправляет в ответ сообщение ("Сообщение сохранено!"). При этом, если uid пользователя ранее не было в Memory, добавляет uid пользователя. 
в) В 7:00 отправляет всем пользователям, чьи uid он сохранил сообщение "С добрым утром!",  в 21:00 - "Доброй ночи".

Вот и весь промпт. Немного подшаманить, получить ключики от API-телеграма. Глупая болванка, но она уже имела кое-что от желаемой структуры и успешно запускалась. Моему счастью не было предела.

Дальше пошло без особых проблем. Обдумываю, как сформулировать следующую фичу, засовываю промпт в codex, немного довожу до ума итоговый результат и готово.

А затем ещё одну, и ещё одну.

И так ровно до момента, пока я не уткнулся в наиболее сложный аспект всего бота вообще. Долговременную память. Код вроде был написан, pymilvus установлен, а ничего не работало. Даже неправильно не работало. Небольшой поиск и я выяснил, что в некоторых местах использовался вообще нерабочий код, который обращался к несуществующим конструкторам и свойствам классов. Не уверен был ли это устаревший код или вообще галлюцинация, но снова быстро поправил, запустил и… ничего.

Что. За. Фигня.

Проверил всё ещё раз, проверил синтаксис, проверил, не нужно ли мне что-нибудь доустановить и-и-и, в итоге нашёл подлянку. Всё это время я пытался использовать Milvus-lite (что-то вроде SQLite, только Milvus), чтобы не париться с разворачиванием серьёзной БД и уж тем более не покупать доступ к cloud-версии. Но, как оказалось, она… не поддерживается на Windows. Модули для неё просто не ставится и говорится об этом в маленькой сноске на PyPi.

Пришлось разворачивать через Docker standalone-версию и в этот раз всё, вот чудо, сразу заработало.

 Админ-панель на Milvus ставится отдельно и называется Attu
Админ-панель на Milvus ставится отдельно и называется Attu

Где-то в этот момент появилось спонтанное желание прикрутить ко всему этому делу монетизацию. Над способом долго не думал - возиться с платежными процессорами не хотелось, поэтому просто подрубил оплату telegram-звёздами. Ну и так как юзер-бот не мог отправлять инвойсы, то перешел на бота обычного, плюс сменил telethon на python-telegram-bot.

Coding-agent не предупредит вас о проблемах с совместимостью, ему абсолютно точно все равно на актуальную документацию пакетов и он точно будет предлагать вам различные deprecated решения или вообще выдавать галлюцинации. Очевидные штуки, но с современными ИИшками забываешь иногда, что косяки у них все те же, что и во времена GPT-3.

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

Деплой (╯°□°)╯︵┻━┻

О-о-о да, это было больно. Чертовски-чертовски больно. Нет, большого ума запустить пяток докер-контейнеров не нужно - тут даже достаточно далекий от DevOps человек, вроде меня, вполне себе смог разобраться. И с консольным серверным Debian я разобрался, хотя линуксоиды я стараюсь не трогать даже шестифутовой палкой, только если от этого не зависит моя жизнь.

КТО ЖЕ МОГ ПОДУМАТЬ, что сервер с доменом (который нужен для вебхуков) будет так отвратительно сложно получить.

Просто так вышло, что я сразу нацелился на две вещи - арендовать сервер в ЕС и сделать это у провайдера, а не у наших кабанчиков-реселлеров, чтобы сэкономить в долгосроке. Тем более я хотел арендовать что-то более менее шустрое - пригодится и захостить что-нибудь еще, и использовать как плейграунд, и развернуть фаундри для игры в днд с друзьями.

Первым делом я пошел к Hetzner и… получил отказ по причине национальности. Причем возможность оплатить их сервера у меня есть, и я на момент создания бота не находился на территории РФ, просто… вот.

 Remember, no russian
Remember, no russian

Вторыми были DigitalOcean и… моментальный бан до выяснения причин аренды. Проблему удалось разрешить через поддержку, но настроение уже было испорчено.

В общем, спустя энное число попыток и поиска я остановился на Netcup, которых с чистой душой могу посоветовать, если у вас есть карта, которую принимают за рубежом. У них же я арендовал и домен сроком на год. За примерно 8.75 EUR в месяц я получил следующий пакет:

  • AMD EPYC™ 9645 от которого мне дали 4 ядра.

  • 8 ГБ ОЗУ DDR5.

  • NVMe SSD на 256 Гб.

 Контрольная панелька не особо блещет изысками, но да и черт с ним
Контрольная панелька не особо блещет изысками, но да и черт с ним

После получение сервера остальное было делом техники, и очень скоро бот на этом сервере уже крутился. Успех… или?

Принятие и дальнейшие планы

Ну, раз я уже прикрутил монетизацию и меня ничего не останавливало от того, чтобы заработать на западных товарищах, то почему бы не поделиться проектом на каком-нибудь сабреддите? Я придумал боту имя - Foxy Roxy, выбрал парочку подходящих сообществ и вкинул несколько постов.

Результаты были интересные. Во первых, реддит ненавидит прямые ссылки на телеграм и автоматом банит посты с ними. Учитывая, что это все таки телеграм-бот, это точно повлияло плачевно. Но! В остальном бот получил достаточно хорошие отзывы и чувствовался определенный интерес к теме, если бы не одно но.

 Всем очень нравится идея, но мало кто реально зашел и попробовал бота судя по моим логам. Несколько комментаторов подсказали мне причину.
Всем очень нравится идея, но мало кто реально зашел и попробовал бота судя по моим логам. Несколько комментаторов подсказали мне причину.

Нафиг там никому не сдался ваш телеграм. Я не уверен, почему я считал иначе - вопрос инерции похоже, но на западе это в общем-то не самая популярная штука, а ее мощь как платформы для ботов (а в этом плане у телеги из конкурентов разве что Дискорд) и даром никому не сдалась.

Поэтому ту дорожную карту, что я строил у себя в голове, я немного достроил под актуальные реалии и получил примерно следующую картину.

  1. Сделать обертку в виде веб или мобильного приложения.

  2. Добавить возможность изменять системный промпт - люди это любят, плюс с текущим промптом Рокси слишком...кхм, слишком. Даже для подвального обитателя типа меня.

  3. Отполировать работу векторной памяти - мне бы хотелось, чтобы подтягивались не только актуальные саммари, но и наиболее релевантные сообщения из переписки, плюс отдельно отбирались важные факты, даты и т.д.

  4. Добавить поддержку распознания изображений - чтобы можно было кидать Рокси мемов.

  5. …на самом деле идей еще много, но меня, пожалуй, и это займет на неплохой промежуток времени.

Кстати, моей любимой мелочью, которую я добавил стало то, что Рокси нормально обрабатывает кейс, где прилетает много мелких сообщений подряд - как мы делаем в обычных переписках.

Те же, кто хотят опробовать бота как есть, могут сделать это тут

Либо взять его отсюда и собрать ручками

АХТУНГ! Я не поправлял набросанный на коленке промпт, поэтому она может быть слишком флиртующей и надоедливой.

 Оно работает! Грейт саксесс!
Оно работает! Грейт саксесс!

Выводы

А не будет их.

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

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

Так что я хочу сказать даже самым лютым скептикам и тем, кто просто не успел опробовать новые инструменты как следует. Попробуйте.

Может они сделают то же самое для вас.

Комментарии (1)


  1. blackyblack
    30.11.2025 15:05

    Наконец-то хоть кто-то написал о том, как правильно пользоваться агентской разработкой. А то сплошняком идут статьи, где пишут на Курсоре или через ЧатГПТ.

    Codex после обновления стал чуть похуже работать. Я попеременно делаю через Codex и Github Copilot агента. У них схожие принципы работы, но копилот более "разговорчивый": сразу пишет план работ, добавляет сам тесты и рассуждения более детальные.