Когда вокруг постоянно говорят про искусственный интеллект, трудно остаться в стороне. Куда ни посмотри — везде нейросети: от фильтров в соцсетях до сложных аналитических систем. Мне как начинающему специалисту эта тема особенно близка — не просто наблюдаю за трендами, а пробую их на практике.
Недавно я решил создать небольшой, но полезный проект — Telegram-бота, который умеет определять эмоциональный окрас сообщений. Не суперсложное приложение, а скорее практика: проверить, как можно быстро собрать рабочее AI-решение, не погружаясь в тонны серверных настроек и не тратя недели на разработку.
До этого я уже сталкивался с задачами по работе с облачными сервисами, но именно этот эксперимент стал для меня наглядным примером, как много сегодня можно сделать «из коробки». Нужно было лишь придумать задачу (в моем случае — анализ эмоций в тексте), выбрать инструменты и собрать все в единый рабочий процесс.
Дальше началось самое интересное — подготовка среды, развертывание и настройка бота. Ниже расскажу, как именно это происходило.

Настраиваем и запускаем бота
Начнем с подготовки среды:
1. Регистрируемся на платформе Cloud.ru Evolution.
2. Активируем Evolution Foundation Models и создаем реестр в Evolution Artifact Registry.
3. Получаем API-ключи — один обычный для доступа к реестру, второй специальный для ML-сервисов с параметром ml_inference_ai_marketplace
.
4. Дальше нужно подготовить Docker-образ с n8n. Проходим аутентификацию в реестре и загружаем образ:
docker login <registry_name>.cr.cloud.ru -u <key_id> -p <key_secret>
docker pull docker.n8n.io/n8nio/n8n:1.86.0 --platform linux/amd64
docker tag docker.n8n.io/n8nio/n8n:1.86.0 <registry_name>.cr.cloud.ru/n8n:1.86.0
docker push <registry_name>.cr.cloud.ru/n8n:1.86.0

5. Теперь создаем бакет в Evolution Object Storage — он нам понадобится для постоянного хранения данных n8n. После этого запускаем Evolution Container Apps, выбираем наш образ из реестра, указываем порт 5678 и настраиваем несколько переменных окружения:
N8N_PROTOCOL=https
N8N_HOST=<container_app_name>.containerapps.ru
WEBHOOK_URL=https://<container_app_name>.containerapps.ru
GENERIC_TIMEZONE=Europe/Moscow
Выглядит это следующим образом:

6. Создаем постоянный том, привязываем к нашему бакету и указываем путь /home/node/.n8n. Минимум экземпляров ставим 1, чтобы бот был всегда доступен:

7. Пока контейнер разворачивается, регистрируем бота через @BotFather — тут все стандартно.
Настройка workflow в n8n
Сразу прикрепляю ссылку на json workflow, кому лень повторять инструкцию и уже сильно хочется посмотреть:)
Когда Evolution Container Apps покажет статус «Выполняется», переходим по публичному URL, регистрируемся в n8n и создаем первый workflow.
Начинаем с создания Telegram API credentials — просто указываем токен бота. Затем добавляем триггер Telegram — On message, который будет ловить входящие сообщения. Нажимаем test step. Слева появится всплывающее уведомление о том, что n8n отслеживает сообщения, отправленные в Telegram-бота:

Следующий узел — OpenAI. Здесь создаем новые credentials: API-ключ от Evolution Foundation Models и базовый URL https://foundation-models.api.cloud.ru/v1. Я выбрал модель OPENAI/GPT-OSS-120B.
В настройках промпта делаем две части. Первая берет текст сообщения:
{{ $('Telegram Trigger').item.json.message.text }}
Вторая — системная инструкция, которая учит модель анализировать эмоции:
You are an expert in text sentiment analysis. When solving a task, FIRST think step-by-step in private to reach your answer. Do NOT reveal these private thoughts. Instead, output ONLY a JSON object with three keys: 1. "result" – one of: "positive", "negative", "neutral" 2. "confidence" – number between 0 and 1 (e.g. 0.87). Calibrate it so the three classes are equally likely a priori. 3. "explanation" – a brief, public rationale (1-3 sentences) that cites the pivotal phrases. Use Russian language to provide explanation. Follow the format of the few-shot examples exactly:
Пользователь: "Я очень рад, что сегодня такой отличный день!"
{"result": "positive", "confidence": 0.93, "explanation": "Фразы 'рад' и 'отличный день' явно выражают положительные эмоции."}
Пользователь: "Меня сильно расстроило поведение коллеги, сегодня был тяжелый день."
{"result": "negative", "confidence": 0.88, "explanation": "Слова 'расстроило' и 'тяжелый день' указывают на негативный эмоциональный окрас."}
Пользователь: "Сегодня ничего особенного не произошло, обычный день."
{"result": "neutral", "confidence": 0.85, "explanation": "Отсутствуют ярко выраженные эмоциональные слова, текст нейтральный."}.
Nothing before or after the JSON. Don’t mark or label your answer as 'json', just output the object.
Немного разберем наш запрос. В его основе лежит требование о структуре ответа «output ONLY a JSON object with three keys:» - три ключа (result, confidence, explanation) все в одном и том же формате. И ничего более.
Техника «think-step-by-step in private to reach your answer, do NOT reveal these private thoughts» - это Chain of Thought. Она вдохновляет модель на более глубокие рассуждения, но при этом оставляет ответ лаконичным.
Инструкция «Follow the format of the few-shot examples exactly:» относится к технике few-shot prompting — т. е. дается несколько примеров в самом начале промпта либо, как в нашем случае, внутри системного промпта. После чего модель понимает, какой формат вывода требуется и подстраивается под него для генерации ответа. Это повышает точность и стабильность формата.

«Don’t mark or label your answer as 'json', just output the object.». Эта инструкция нужна для корректного вывода ответа модели, без всяких кавычек и скобок как в json.
Включаем Output Content as JSON, чтобы n8n правильно парсил ответ:

Последний узел — Telegram Send a text message. В Chat ID указываем {{ $('Telegram Trigger').item.json.message.chat.id }}
, а в тексте сообщения формируем читаемый ответ:
Эмоциональный окрас сообщения — {{ $json.message.content.result }}
Уверенность в ответе — {{ $json.message.content.confidence }}
Объяснение решения — {{ $json.message.content.explanation }}
Добавляем Reply To Message ID, перетаскивая message id из триггера — так бот будет отвечать на конкретное сообщение.

Активируем workflow, переключателем в Active, и всё готово:

На скрине добавлены еще несколько блоков, не описанных в инструкции. Их я добавил в процессе написания самой статьи, поэтому решил оставить. Блок if проверяет входящее сообщение. Если оно является /start, то бот выдает описание своего функционала пользователю. Это полезно, так как многие, заходя первый раз в бота, сразу жмут кнопку /start, еще не понимая, для чего этот бот создан.

Сервисы Cloud.ru Evolution в работе как они на фоне «старого» метода
Когда начал собирать проект, заметил, что почти все инфраструктурные задачи берет на себя платформа. Evolution Container Apps — это, по сути, умное облако для контейнеров, где не нужно лезть в администрирование. Приложение живет в своем контейнере, а платформа позволяет выбрать, сколько экземпляров держать в онлайне. Если нагрузка падает — все сворачивается до нуля, а если растет — довольно быстро масштабируется. С точки зрения затрат это спасение: нет бессмысленных трат на простаивающие серверы.
Evolution Artifact registry пригодился как аккуратное хранилище образов. Да, можно было бы выгрузить все в сторонний публичный сервис, но приватный реестр внутри Cloud.ru удобнее — быстрее загружается, есть контроль версий и автоматическая проверка на уязвимости. Плюс все в одной экосистеме, без лишних интеграций.
Отдельно стоит сказать про Evolution Foundation Models. Они дают доступ к крупным языковым моделям сразу из облака, и можно общаться с ними через API, полностью совместимый с OpenAI. Это избавляет от мороки с отдельными аккаунтами и ключами на сторонних сервисах. Модель понимает контекст на русском, корректно выделяет эмоции и вполне уверенно классифицирует сообщения.
Если бы я делал всё по классической схеме, пришлось бы арендовать VPS, настраивать окружение с нуля, устанавливать Docker или Python, настраивать вебхуки и мониторинг, писать и отлаживать код бота — обрабатывать сообщения, взаимодействовать с OpenAI, устранять ошибки. Всё это требовало бы времени и внимания, а каждый сбой ложился бы на меня.
Сейчас же всё намного проще: контейнер разворачивается за минуты, обновления выкатываются из реестра одной кнопкой, масштабирование и перезапуск при ошибках проходят автоматически. Почти не нужно писать код — n8n позволяет собрать логику визуально, добавляя скрипты только при необходимости.
В итоге, вместо длинного списка рутинных задач я работаю только над тем, что реально важно — логикой бота и взаимодействием с моделью.
Как можно улучшить бота
Сам бот — это только база. При желании можно настроить алерты о негативных сообщениях в корпоративный чат, расширить анализ с помощью других AI-моделей или интегрировать с внешними системами через webhook'и. Для хранения данных можно использовать Evolution Object Storage или внешние базы данных.
Для более сложных production-сценариев стоит обратить внимание на Evolution AI Agents — новый сервис Cloud.ru Evolution, который находится в публичном превью. Он позволяет создавать мультиагентные системы с автономными AI-агентами, способными принимать решения и выполнять сложные задачи без постоянного вмешательства разработчика.
Заключение
Этот проект показал, что при правильном подборе инструментов можно собрать рабочее AI-решение буквально за вечер, без погружения в серверную рутину. Для экспериментов и быстрых MVP это идеальный вариант: все под рукой, нет лишней возни с инфраструктурой, а результат — уже завтра в рабочем виде.
Если же вы совсем новичок, то рекомендую начать с лабораторных работ на Cloud.ru — там есть пошаговые инструкции по интеграции различных сервисов платформы (включая лабу по созданию Telegram-бота с AI-функциональностью).
alcanoid
День назерокоженных телеграм-ботов на хабре. Налетай, торопись!