Модерация контента в онлайн-сообществах — одна из самых сложных задач для администраторов Discord-серверов. Традиционные решения либо полагаются на сторонние API с непрозрачной логикой (так называемые «чёрные ящики»), либо требуют ручного труда модераторов. В недавней публикации на Habr автор делится опытом создания OmniBot — бота для Discord, который использует локальную NLP-модель ruBERT для анализа сообщений, работает в формате Discord Activity и предоставляет полную прозрачность модерационных решений. Разберём технические детали этого проекта, его архитектуру и применимые выводы для разработчиков.
Что такое Discord Activity и почему это важно?
Discord Activity — это функция платформы, позволяющая запускать интерактивные приложения прямо в голосовых каналах (например, игры, стриминг или опросы). Однако автор пошёл дальше: он реализовал модерацию в формате Activity, чтобы бот мог работать в реальном времени, не покидая канал, и обрабатывать сообщения без задержек, связанных с внешними вызовами. Такой подход снижает latency и даёт пользователям мгновенную обратную связь — например, предупреждение о нарушении правил появляется в чате канала через 0.5–1 секунду после отправки сообщения.
Локальный ruBERT: почему не ChatGPT и не сторонние API?
Одна из ключевых проблем современных модерационных систем — это зависимость от внешних сервисов, таких как OpenAI, Perspective API или Azure Content Moderator. Они работают по принципу «чёрного ящика»: вы отправляете текст, получаете оценку токсичности, но не знаете, на основе каких признаков было принято решение. Кроме того, такие API требуют оплаты за каждый запрос, а передача данных третьей стороне поднимает вопросы конфиденциальности.
Вместо этого автор OmniBot выбрал локальную NLP-модель ruBERT — русскоязычную версию BERT (Bidirectional Encoder Representations from Transformers), разработанную DeepPavlov и SberDevices. Модель была дообучена на датасетах с разметкой токсичности (например, RuSentiment и собственных корпусах). Преимущества:
- Прозрачность: можно видеть, какие токены (слова и фразы) модель считает токсичными, с помощью механизма attention maps.
- Скорость: инференс на CPU (Intel Xeon) занимает ~50 мс на одно сообщение, что быстрее вызова внешнего API.
- Стоимость: нулевые затраты на API — только электроэнергия.
Однако есть и ограничения: модель обучалась на относительно небольшом объёме данных (порядка 100 000 размеченных сообщений), поэтому она может ошибаться на сарказме или контекстных шутках. Автор признаёт, что точность составляет около 85% на тестовой выборке, что приемлемо для базовой модерации, но требует доработки под конкретное сообщество.
Архитектура и стек технологий
OmniBot построен на Node.js с использованием библиотеки discord.js для работы с Discord API. Discord Activity реализован через WebSocket-соединение, которое позволяет боту получать события в реальном времени без polling. Модель ruBERT запускается через ONNX Runtime — это кроссплатформенный движок для инференса, который оптимизирует модель для работы на CPU. Весь код и модель хранятся локально на сервере автора (Linux VPS с 4 ядрами и 8 ГБ RAM).
Сравнение подходов к модерации:
| Критерий | Локальный ruBERT (OmniBot) | Сторонние API (Perspective, OpenAI) |
|---|---|---|
| Прозрачность | Полная (видно веса токенов) | Чёрный ящик (только итоговый скор) |
| Задержка | 50–100 мс | 200–500 мс (включая сетевые задержки) |
| Стоимость | 0 руб./1000 запросов | ~$0.01–0.05/1000 запросов |
| Конфиденциальность | Данные не покидают сервер | Данные передаются провайдеру |
| Точность | ~85% (дообученная) | 90–95% (большие корпуса) |
Таблица наглядно показывает, что локальное решение выигрывает в скорости, стоимости и приватности, но уступает в точности. Для сообществ с низкой толерантностью к ложным срабатываниям можно комбинировать оба подхода: локальный быстрый фильтр + ручная проверка модераторами для пограничных случаев.
Настройка и кастомизация под сообщество
Автор отмечает, что универсальной модели не существует. Для каждого Discord-сервера требуется донастройка порогов чувствительности. Например, в сообществе по киберспорту допустимы более жёсткие выражения, чем в образовательном чате. OmniBot позволяет администраторам регулировать три параметра:
- threshold_toxic — порог вероятности токсичности (по умолчанию 0.7);
- threshold_spam — порог спам-детекции (на основе частоты сообщений);
- action — что делать: предупреждение, временный мут или кик.
Эти параметры задаются через команды в Discord (например, /config threshold_toxic 0.8), что делает систему гибкой без необходимости переписывать код.
Практические примеры и кейсы
В статье приводится тестовый запуск OmniBot на сервере с 500 активными пользователями. За неделю бот обработал около 15 000 сообщений, из которых:
- 120 были помечены как токсичные (0.8% от общего числа);
- 40 — как спам;
- 15 ложных срабатываний (в основном из-за сарказма и мемов).
Ложные срабатывания были проанализированы вручную, и автор добавил их в датасет для дообучения модели. Это демонстрирует цикл непрерывного улучшения, недоступный для «чёрных ящиков».
Выводы и рекомендации
Проект OmniBot — это пример того, как современные open-source NLP-модели можно развернуть локально для решения конкретных задач, не жертвуя производительностью или конфиденциальностью. Основные уроки для разработчиков:
- Не бойтесь локальных моделей: ONNX Runtime и подобные инструменты делают инференс на CPU быстрым и доступным.
- Прозрачность — конкурентное преимущество: пользователи доверяют системе, если видят, как она работает.
- Гибкость настройки критична: одна модель не подходит для всех сообществ — дайте администраторам возможность регулировать параметры.
- Собирайте данные для дообучения: каждое ложное срабатывание — это возможность улучшить модель.
Для тех, кто хочет углубиться в тему, ASI Biont поддерживает подключение к Discord через API — подробнее на asibiont.com/courses. А полный код и инструкции по развёртыванию OmniBot доступны в оригинальной статье на Habr.
В эпоху, когда AI-модерация стала стандартом, важно помнить: лучший инструмент — тот, который вы понимаете и можете контролировать.
Комментарии