Перейти к содержанию
AM
← Все статьи

Личный ИИ-агент на n8n: четыре воркфлоу, один бот

Опубликовано · 5 мин чтения

Большая часть моей работы связана с платформами данных: конвейеры, lakehouse, вся инфраструктура, на которой стоят аналитика и ML. Поэтому, когда в Школе 21 мне дали проект личного ИИ-агента, я подошёл к нему как к любому конвейеру данных. Откуда приходят данные, что их преобразует, что может сломаться и сколько стоит один запуск?

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

Задача

Студент Школы 21 снова и снова задаёт себе одни и те же вопросы. Какое направление выбрать? Что происходит в моей области на этой неделе? Какие навыки на самом деле нужны работодателям? Что учить дальше и в каком порядке?

Каждый такой вопрос требует маленького исследования. Вручную это значит открыть чат с LLM, снова объяснить свою ситуацию, копировать результаты из одного места в другое и всё проверять самому. Цель была заменить это агентом, который уже знает контекст, сам запускается по расписанию там, где это имеет смысл, и присылает результаты в одно место: в Telegram.

Стек

  • n8n в Docker на Cloud.ru Container Apps. Развернуть его самому, а не взять n8n Cloud, требовало задание, и это правильный подход в любом случае: когда разворачиваешь сам, понимаешь, из каких частей всё состоит.
  • GigaChat 2 Max через Cloud.ru Foundation Models, подключённый в n8n через узел OpenAI Chat Model. API совместим с OpenAI, но с одной оговоркой: переключатель Responses API должен быть выключен.
  • Telegram как единственный интерфейс: бот для диалогов и закрытый канал для дайджестов.
  • Tavily для веб-поиска, API HH.ru для вакансий и RSS как мост к публичным Telegram-каналам.

Четыре воркфлоу

1. Консультант

Бот для диалога, который помогает выбрать направление: data science, DevOps, QA, аналитика, безопасность, UX/UI, управление проектами, биоинформатика или разработка.

Telegram Trigger → AI Agent (GigaChat 2) → Send message
                      ↑
               Simple Memory (keyed by chat ID)

Агент живёт в своём системном промпте. У него одна роль (карьерный консультант для студентов Школы 21), одна цель (рекомендация) и чёткий сценарий: восемь вопросов по одному, с ожиданием ответа на каждый. Интересы, предыдущий опыт, удобный темп, удалёнка или офис, сильные и слабые стороны и так далее. После последнего ответа агент пишет рекомендацию.

Две детали важнее, чем кажутся:

  • Память привязана к ID чата в Telegram. Без этого все пользователи делили бы один диалог.
  • Сценарий строгий намеренно. Открытый промпт вроде «помоги выбрать профессию» даёт приятную беседу, которая никогда не заканчивается. Пронумерованный список вопросов даёт решение.

2. Ежедневный дайджест новостей

Каждое утро в 9:00 воркфлоу забирает свежие посты из трёх публичных Telegram-каналов, делает краткое содержание и публикует один дайджест в мой закрытый канал.

Schedule (09:00) → RSS × 3 → Limit 5 each → Merge → Aggregate → AI Agent → Telegram channel

Бот не может читать публичный канал, в котором он не администратор, поэтому каждый канал сначала проходит через RSS-сервис. Узлы Limit отвечают за расходы: не больше пяти постов с канала, как бы активно он ни писал за ночь. Один общий запрос к модели дешевле и связнее, чем пятнадцать отдельных.

У результата фиксированный формат: абзац с кратким итогом, затем каждый канал с числом постов и строкой описания и ссылкой на каждый пост.

3. Еженедельный дайджест рынка труда

Каждую субботу воркфлоу запрашивает в API HH.ru свежие вакансии ML-инженеров в Москве, просит модель извлечь и привести к единому виду требования и публикует пятнадцать самых частых.

Schedule (Sat 09:00) → HTTP Request (HH.ru) → AI Agent → Telegram channel

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

Этому воркфлоу я доверяю меньше всего, и следующий пост целиком о том, почему: LLM плохо считает, и результат это показал.

4. Ментор

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

Telegram Trigger → AI Agent (+ Tavily, + memory) → Code (state machine) → Send message

Самое интересное здесь в узле Code. Вместо того чтобы надеяться, что история диалога помнит, где находится пользователь, он хранит явное состояние для каждого чата в статических данных воркфлоу n8n: спрашиваем цель, спрашиваем уровень, ждём план, отправляем уроки, готово. LLM пишет содержание, а код решает, что происходит дальше. Об этом я написал отдельно, потому что этот приём полезен далеко за пределами одного бота.

Решения, которые стоит объяснить

Своё развёртывание вместо n8n Cloud. Для игрушки Cloud быстрее. Для того, что будет работать месяцами, свой контейнер означает контроль над версиями, секретами и тем, куда уходят данные.

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

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

Небольшие лимиты везде. Посты с канала, вакансии за запуск, пользователи в состоянии. Агент по расписанию тратит деньги, пока вы спите, поэтому лимиты входят в архитектуру.

Анонимизация перед отправкой. Всё уходит во внешний API и может там логироваться, поэтому в промпт не попадает ничего, что позволяет узнать человека. «По времени на платформе я в топ-5%» работает так же хорошо, как имя и место в рейтинге.

Что я бы изменил для продакшена

  • Забрать подсчёт у модели. Извлекать навыки из каждой вакансии в виде структурированного JSON, нормализовать их по словарю и считать в коде. Модель пишет только итоговую фразу.
  • Вынести состояние из статических данных воркфлоу. Для одного пользователя и пары друзей это работает. Для большего числа состояние должно жить в Postgres или Redis со сроком хранения, а не в блоке данных, который может стереть повторный деплой.
  • Проверять каждый ответ модели до отправки в Telegram: разобрать, проверить формат, при ошибке повторить запрос или использовать запасной вариант.
  • Логировать запуски и расходы. Токены за запуск, сбои за неделю. Если это не измерять, система тихо станет дорогой или тихо перестанет работать.
  • Зафиксировать версию модели. Обновление у провайдера может за ночь изменить поведение; зафиксированная версия и несколько сохранённых тестовых промптов заметят это раньше пользователей.

Что я вынес

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

Дальше в серии (пока на английском): почему я больше никогда не дам LLM считать, и небольшой конечный автомат, который не даёт чат-боту потерять нить разговора.