- BrainTools - https://www.braintools.ru -

Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1

Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 1

Привет! Если ты, как и я, держишь инфраструктуру небольшой команды, наверняка знаком с ситуацией: разработчиков становится больше, а DevOps-отдел при этом не растёт. С приходом vibe-coding’а эта диспропорция стала особенно заметной — у нас в студии команда разработки выросла раза в полтора буквально за пару месяцев, потому что каждый продакт-менеджер захотел свой мини-аппликейшен. Параллельно подкинули головной боли [1] участившиеся проблемы с доступностью приложения из ряда регионов.

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

Так появилась идея переложить первую линию на AI-агента. К тому моменту мы уже автоматизировали анализ инцидентов по сработавшему алерту [2] (об этом я писал в предыдущей статье), и опыт [3] показал, что подход рабочий. Логичным продолжением стало расширение схемы на ручные обращения в чате.

В этой статье — первой из двух — расскажу, как мы:

  • классифицировали поток обращений за последний год и выделили категории, которые имеет смысл автоматизировать;

  • реализовали классификатор на n8n с интеграцией Mattermost через MCP;

  • построили ассистента по CI/CD-инцидентам как первую боевую ветку обработки;

  • научились разбирать вложения (скриншоты ошибок, файлы с логами);

  • настроили нормальную отчётность об ошибках в самих workflow.

Во второй части разберём оставшиеся ветки: помощник по инцидентам в инфраструктуре, ассистент по типовым вопросам и обработка задач на модификацию.

Все workflow и системные промпты выложены отдельно — ссылка в конце статьи.

Подготовка: классификация обращений

Прежде чем что-то автоматизировать, нужно понять, что именно. Я выгрузил историю обращений из каналов Mattermost за последний год и разнёс их по категориям. Получилась такая классификация:

  1. Модификация инфраструктуры — изменения в текущей инфраструктуре, добавление типовых ресурсов.

  2. Новая инсталляция — развёртывание новых систем и интеграций, которых раньше не было.

  3. Инцидент — что-то перестало работать в текущей инфраструктуре.

  4. CI/CD — падающие сборки, неудачные тесты и деплои.

  5. Вопрос — общие вопросы по нашей инфраструктуре.

  6. Анонс — сообщения информационного характера: например, о плановых техработах.

  7. Другое — всё, что не попало ни в одну из категорий выше.

Основная масса запросов оказалась в категориях 3–5 — именно их мы и взяли в работу в первую очередь. Категории 1–2 требуют согласований и почти всегда участия инженера, так что автоматизировать их смысла нет. Анонсы агенту обрабатывать не нужно — достаточно корректно их распознавать и не дёргать дежурного.

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

Классификатор

Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 2

На первый взгляд всё выглядело просто: создаём бота в Mattermost, настраиваем webhook в n8n на сообщения с упоминанием этого бота, прогоняем через LLM, получаем категорию.

Пример
Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 3

Но дальше всплыл первый нюанс: пришедшее сообщение может быть как стартовым в новом треде, так и репликой внутри уже существующего. И во втором случае без контекста треда классификатор будет ошибаться — например, уточнение «а у меня та же проблема» вне контекста выглядит как нечто бессмысленное.

Вместо того чтобы дёргать Mattermost API напрямую из n8n, я переложил эту задачу на агента — благо у нас уже есть mattermost-mcp [4], который умеет читать сообщения в каналах и тредах. Агент сам решает, нужно ли подтянуть историю треда, и подтягивает её, если контекст того требует. В системном промпте необходимо описать как это сделать, а также еще несколько моментов

  • Описания категорий и примеры.

  • Ожидаемый формат выходных данных

{
  "category": "<category_key>",
  "confidence": <0.0-1.0>,
  "summary": "<one sentence summary in the same language as the user message>",
  "acknowledge": "<a short response that you accepted the request and started working on it>",
  "is_thread": <true|false>,
  "parent_post": "<post_id to use as root_id when replying — ALWAYS set>"
}

В user промпте я дополнительно передаю channel_id, channel_name, post_id, user_name это поможет классификатору лучше ориентироваться в сообщениях

В качестве модели использую Sonnet или GPT-5 Codex — на классификации обе показывают сопоставимое качество.

На этом этапе я ещё не подключал разбор вложений — скриншоты и файлы с логами появятся дальше, в логике [5] конкретных веток.

После того как ответ агента получен и провалидирован на корректность полей, нужно определить дежурного инженера — он может понадобиться, если автоматизированная обработка не справится. Дежурства у нас ведутся в Google Calendar, поэтому пришлось настроить OAuth2-доступ к нему по документации n8n [6].

Пример
Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 4
Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 5

После определения категории и дежурного запускается соответствующий sub-workflow. Параллельно с этим в Mattermost уходит сообщение-acknowledge, чтобы автор обращения видел: запрос принят и обрабатывается. Это важная деталь — без неё человек продолжает писать в тред «эй, кто нибудь смотрит?», что портит всю задумку.

Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 6

Помощник по CI/CD

CI/CD — одна из самых частых категорий обращений, поэтому с неё и начал. Внушительная доля таких проблем решается без участия инженера: упавшие из-за временной недоступности репозитория сборки, флаки-тесты, неправильно сконфигурированные пайплайны, истёкшие токены.

Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 7

На входе sub-workflow ожидает структуру с данными об обращении:

{
  "message": "Запрос в чате",
  "post_id": "id поста в Mattermost",
  "channel_id": "id канала в Mattermost",
  "channel_name": "Название канала в Mattermost",
  "user_name": "Имя отправителя",
  "user_id": "id отправителя",
  "file_ids": ["Список id вложений"],
  "category": "Одна из категорий",
  "confidence": "Уровень уверенности в выборе",
  "summary": "Краткое описание обращения",
  "is_thread": "Сообщение пришло из треда или нет",
  "thread_root_id": "Начальное сообщение в треде, если оно есть",
  "on_call_user": "Имя дежурного"
}

Разбор вложений

Чаще всего обращение по CI приходит в формате «упала сборка» + скриншот ошибки [7]. Такого описания явно недостаточно, чтобы найти конкретную сборку, поэтому перед вызовом основного агента стартует вспомогательный sub-workflow — attachmentsAnalyzer.

Он разбирает прикреплённые файлы:

  • Изображения (скриншоты ошибок) — отправляются в gpt-4o-mini для извлечения текста и описания контекста.

  • Текстовые файлы (логи) — если размер не превышает заданный в Config-ноде лимит, содержимое прокидывается дальше как дополнительный контекст.

На выходе формируется компактный текстовый блок:

{
  "attachments_context": "...human-readable block...",
  "attachments_count": 1
}

Я вынес этот функционал в отдельный workflow намеренно — он переиспользуется и в других ветках обработки. Если attachmentsAnalyzer падает с ошибкой, основной workflow продолжает работу без доп. контекста, а не валится целиком.

Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 8

Сбор контекста и вызов агента

Перед формированием запроса к LLM в ноде SetVars собираю всё необходимое:

  • исходные данные обращения;

  • результат работы attachmentsAnalyzer;

  • вспомогательный контекст для системного промпта: имена организаций в GitHub, контексты и namespace’ы в Kubernetes, названия источников данных в Grafana.

Сам агент работает с набором MCP-инструментов:

  • GitHub MCP — доступ к логам сборок в Actions, PR, исходному коду.

  • Mattermost MCP — чтение сообщений в треде (если контекста изначального запроса недостаточно).

  • Grafana / Kubernetes MCP — поиск логов и событий кластера при проблемах с деплоем.

Что следует осветить в системном промпте:

  • Какие есть команды и какие группы репозиториев им принадлежат – это поможет быстрее определить репозиторий с ошибкой

  • Как искать дополнительный контекст в треде Mattermost

  • Описание зоны ответственности DevOps отдела – если ошибка попадает в эту зону ассистент будет дополнительно тэгать дежурного инженера в конце расследования

  • Общее описание доступных инструментов и когда их использовать.

  • Несколько примеров

  • Формат выходных данных

В качестве пользовательского промпта используется конструкция

Расследуй проблему от {{ $json.user_name }} в канале {{ $json.channel_name }}{{ $json.is_thread ? ' (сообщение в треде, thread_root_id=' + $json.thread_root_id + ' — сначала прочитай историю через Mattermost get_thread)' : '' }}
{{ $json.message }}{{ $json.attachments_context && $json.attachments_context.trim().length > 0 ? 'nnДополнительная информация из вложений:n' + $json.attachments_context : '' }}

Здесь помимо самого сообщения передается от кого и в каком канале пришло сообщение, пришло ли сообщение из треда, а также вложения, если они есть.

Костыль с HTTP-проверками

Одна из частых причин падения сборок — недоступность внешнего ресурса: репозитория с зависимостями, прокси, registry. Логично было бы дать агенту встроенный HTTP Request-tool и попросить проверить доступность. На практике это не сработало: встроенная нода n8n не умеет нормально обрабатывать таймауты и сетевые ошибки — в случае проблем она роняет всю цепочку с агентом.

Пришлось обернуть проверку в отдельный sub-workflow httpProbeTool, который всегда возвращает структурированный результат: успешно, неуспешно с описанием причины, или таймаут. Агент использует его как обычный инструмент.

Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 9

После получения ответа от агента идёт короткая валидация формата, и сообщение уходит в тред Mattermost.

Обработка ошибок самого workflow

Когда строишь систему, через которую идут реальные обращения, надёжность критична. Если workflow упадёт по любой причине — закончилась квота у LLM, отвалился MCP-сервер, прилетел невалидный JSON — никто в чате об этом не узнает, и обращение зависнет в подвешенном состоянии.

Особенно это актуально в первые недели после запуска, когда постоянно что-то правишь и докручиваешь. Решение простое: отдельный workflow, который указан в настройках основных workflow как Error Workflow.

Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 10

Что он делает:

  1. Получает информацию о сломавшемся execution от n8n API (для этого надо сгенерировать API-ключ).

  2. Через ноду Extract Thread Context определяет channel_id и root_id исходного сообщения.

  3. Отправляет краткое сообщение об ошибке прямо в тред обращения, чтобы автор не висел в неведении.

Пример
Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 11
Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 12
Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 13

Дополнительно в более развёрнутом виде ошибка летит в служебный канал DevOps-команды — это позволяет быстро реагировать [8] на регрессии.

Что получилось

После пары месяцев тестирования в боевом режиме картина такая:

  • Среднее время ответа — до 3 минут с момента появления сообщения в канале.

  • ~25% обращений закрываются полностью без участия инженера.

  • ~40% обращений решаются быстрее обычного — агент проводит предварительную диагностику, дежурный получает уже готовый контекст.

  • Стоимость при нашем потоке (несколько десятков обращений в неделю) — до 250$ в месяц на оплату LLM.

Расследование упавшего билда
Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 14
Расследование инцидента по скриншоту
Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 15
Ответ на вопрос об инфраструктуры
Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 16
Создание задачи по запросу
Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 17
Строим первую линию техподдержки на n8n за 250$ в месяц. Часть 1 - 18

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

Чего пока не удалось

  • Агент иногда «теряется» в длинных тредах с десятками сообщений — приходится в системном промпте отдельно ограничивать глубину контекста.

  • Категория Инцидент пока даёт самый низкий процент автономного разрешения — там слишком много нестандартных ситуаций. Работаем над расширением набора MCP-инструментов.

  • Сложно объективно оценить качество ответов на «вопросы по инфраструктуре» — нужен механизм фидбэка от инженеров (планирую реакции в Mattermost как простейший сигнал).

Во второй части разберём оставшиеся ветки обработки обращений: ассистента по инфраструктурным инцидентам, ассистента по типовым вопросам с RAG-поиском по нашей документации, и обработку задач на модификацию инфраструктуры с автоматическим заведением тикетов.


Репозиторий с workflow: https://github.com/javdet/automagicops-workflows [9]

А как вы у себя разгружаете первую линию? Используете готовые продукты или строите своё? Какие категории обращений у вас лучше всего автоматизируются — поделитесь в комментариях, очень интересно сравнить распределение.

Автор: javdet12

Источник [10]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/30219

URLs in this post:

[1] боли: http://www.braintools.ru/article/9901

[2] автоматизировали анализ инцидентов по сработавшему алерту: https://habr.com/ru/articles/1011352/

[3] опыт: http://www.braintools.ru/article/6952

[4] mattermost-mcp: https://github.com/cloud-ru-tech/mcp-server-mattermost

[5] логике: http://www.braintools.ru/article/7640

[6] документации n8n: https://docs.n8n.io/integrations/builtin/credentials/google/oauth-single-service/

[7] ошибки: http://www.braintools.ru/article/4192

[8] реагировать: http://www.braintools.ru/article/1549

[9] https://github.com/javdet/automagicops-workflows: https://github.com/javdet/automagicops-workflows

[10] Источник: https://habr.com/ru/articles/1034370/?utm_campaign=1034370&utm_source=habrahabr&utm_medium=rss

www.BrainTools.ru

Rambler's Top100