# Discord + AI ассистент для модераторов

Модерация Discord серверов — это рутинная, но критически важная задача. С ростом сообщества нагрузка на модераторов растёт экспоненциально. AI-ассистент может автоматизировать до 80% рутинных задач модерации, освобождая время модераторов для более важных решений.

## Содержание

- [Проблема: перегрузка модераторов](#проблема-перегрузка-модераторов)
- [Что может автоматизировать AI](#что-может-автоматизировать-ai)
- [Архитектура AI-модератора](#архитектура-ai-модератора)
- [Реализация на Python](#реализация-на-python)
- [Интеграция с Discord](#интеграция-с-discord)
- [Обучение модели](#обучение-модели)
- [Метрики эффективности](#метрики-эффективности)
- [Лучшие практики](#лучшие-практики)
- [Примеры использования](#примеры-использования)

## Проблема: перегрузка модераторов

### Статистика

- **Средний Discord сервер:** 1000-5000 участников
- **Активных модераторов:** 2-5 человек
- **Сообщений в день:** 500-2000
- **Время на модерацию:** 2-4 часа в день на модератора
- **Рутинных задач:** 70-80% от общего времени

### Типичные задачи модератора

1. **Модерация контента**
- Проверка на спам
- Обнаружение оскорблений
- Контроль NSFW контента
- Проверка ссылок

2. **Управление участниками**
- Выдача предупреждений
- Временные муты
- Кики и баны
- Восстановление прав

3. **Ответы на вопросы**
- Частые вопросы (FAQ)
- Техническая поддержка
- Разрешение конфликтов

4. **Мониторинг активности**
- Отслеживание подозрительной активности
- Выявление рейдов
- Контроль ботов

## Что может автоматизировать AI

### ✅ Высокая эффективность (80-95%)

**1. Обнаружение спама**
- Повторяющиеся сообщения
- Ссылки на фишинговые сайты
- Массовые упоминания
- Подозрительные паттерны

**2. Модерация контента**
- Оскорбления и токсичность
- NSFW контент в SFW каналах
- Политически некорректные высказывания
- Дискриминация

**3. Автоматические ответы**
- FAQ вопросы
- Стандартные команды
- Информационные запросы

**4. Предупреждения и муты**
- Автоматические предупреждения
- Временные муты за нарушения
- Эскалация к модераторам

### ⚠️ Средняя эффективность (50-70%)

**1. Разрешение конфликтов**
- Требует контекста
- Нужна человеческая оценка
- Может эскалировать ситуацию

**2. Сложные случаи модерации**
- Спорные ситуации
- Граничные случаи
- Требуют суждения

### ❌ Низкая эффективность (<50%)

**1. Творческие решения**
- Уникальные ситуации
- Требуют креативности
- Человеческое понимание

**2. Стратегические решения**
- Политика сервера
- Долгосрочное планирование
- Сообщество-билдинг

## Архитектура AI-модератора

### Компоненты системы

```
┌─────────────────┐
│ Discord Bot │
│ (discord.py) │
└────────┬────────┘


┌─────────────────┐
│ Event Handler │
│ (on_message) │
└────────┬────────┘


┌─────────────────┐
│ AI Analyzer │
│ (OpenAI/LLM) │
└────────┬────────┘


┌─────────────────┐
│ Action Handler │
│ (mute/ban/warn)│
└─────────────────┘
```

### Поток обработки сообщения

1. **Получение сообщения** → Discord Bot
2. **Предобработка** → Извлечение текста, метаданных
3. **AI анализ** → Классификация, оценка токсичности
4. **Принятие решения** → Автоматическое действие или эскалация
5. **Логирование** → Сохранение для обучения

## Реализация на Python

### Базовая структура проекта

```python
# requirements.txt
discord.py>=2.3.0
openai>=1.0.0
python-dotenv>=1.0.0
aiohttp>=3.9.0
```

### Основной код бота

```python
import discord
from discord.ext import commands
import openai
import os
from dotenv import load_dotenv
import asyncio
from typing import Optional, Dict, List

load_dotenv()

# Инициализация
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix='!', intents=intents)

# OpenAI клиент
openai.api_key = os.getenv('OPENAI_API_KEY')

class AIModerator:
def __init__(self):
self.openai_client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
self.warning_threshold = 0.7 # Порог для предупреждения
self.mute_threshold = 0.85 # Порог для мута
self.ban_threshold = 0.95 # Порог для бана

async def analyze_message(self, message: str, author_id: int) -> Dict:
"""
Анализирует сообщение на токсичность, спам и нарушения
"""
try:
# Используем GPT-4 для анализа
response = self.openai_client.chat.completions.create(
model="gpt-4",
messages=[
{
"role": "system",
"content": """Ты AI-модератор Discord сервера.
Анализируй сообщения на:
1. Токсичность (0-1)
2. Спам (0-1)
3. NSFW контент (0-1)
4. Оскорбления (0-1)
5. Нарушение правил (0-1)

Верни JSON с оценками и рекомендацией действия:
- none: нет действия
- warn: предупреждение
- mute: временный мут
- ban: бан
"""
},
{
"role": "user",
"content": f"Проанализируй сообщение: {message}"
}
],
response_format={"type": "json_object"},
temperature=0.3
)

result = json.loads(response.choices[0].message.content)

# Вычисляем общий score
total_score = (
result.get('toxicity', 0) * 0.3 +
result.get('spam', 0) * 0.25 +
result.get('nsfw', 0) * 0.2 +
result.get('offensive', 0) * 0.15 +
result.get('rule_violation', 0) * 0.1
)

result['total_score'] = total_score
return result

except Exception as e:
print(f"Ошибка анализа: {e}")
return {'total_score': 0, 'action': 'none'}

def determine_action(self, score: float, recommendation: str) -> str:
"""
Определяет действие на основе score и рекомендации AI
"""
if score >= self.ban_threshold:
return 'ban'
elif score >= self.mute_threshold:
return 'mute'
elif score >= self.warning_threshold:
return 'warn'
else:
return 'none'

# Инициализация модератора
moderator = AIModerator()

# История нарушений пользователей
user_violations = {}

@bot.event
async def on_ready():
print(f'{bot.user} подключён и готов к модерации!')

@bot.event
async def on_message(message):
# Игнорируем сообщения от ботов
if message.author.bot:
return

# Игнорируем команды
if message.content.startswith('!'):
await bot.process_commands(message)
return

# Анализируем сообщение
analysis = await moderator.analyze_message(
message.content,
message.author.id
)

score = analysis.get('total_score', 0)
action = moderator.determine_action(
score,
analysis.get('recommendation', 'none')
)

# Выполняем действие
if action != 'none':
await handle_moderation_action(
message,
action,
analysis,
score
)

# Логируем для обучения
await log_message_analysis(message, analysis)

await bot.process_commands(message)

async def handle_moderation_action(
message: discord.Message,
action: str,
analysis: Dict,
score: float
):
"""
Обрабатывает действие модерации
"""
author = message.author
channel = message.channel

# Увеличиваем счётчик нарушений
if author.id not in user_violations:
user_violations[author.id] = {
'count': 0,
'last_violation': None
}

user_violations[author.id]['count'] += 1
user_violations[author.id]['last_violation'] = message.created_at

if action == 'warn':
# Удаляем сообщение
try:
await message.delete()
except:
pass

# Отправляем предупреждение
warning_embed = discord.Embed(
title="⚠️ Предупреждение",
description=f"{author.mention}, ваше сообщение было удалено за нарушение правил.",
color=discord.Color.orange()
)
warning_embed.add_field(
name="Причина",
value=analysis.get('reason', 'Нарушение правил сервера'),
inline=False
)
warning_embed.add_field(
name="Оценка",
value=f"{score:.2%}",
inline=True
)

await channel.send(embed=warning_embed, delete_after=10)

# Логируем в канал модерации
await log_to_mod_channel(message, action, analysis)

elif action == 'mute':
# Удаляем сообщение
try:
await message.delete()
except:
pass

# Выдаём мут на 1 час
mute_role = discord.utils.get(message.guild.roles, name="Muted")
if mute_role:
await author.add_roles(mute_role)

mute_embed = discord.Embed(
title="🔇 Временный мут",
description=f"{author.mention} получил мут на 1 час.",
color=discord.Color.red()
)
await channel.send(embed=mute_embed, delete_after=10)

# Автоматически снимаем мут через час
await asyncio.sleep(3600)
await author.remove_roles(mute_role)

await log_to_mod_channel(message, action, analysis)

elif action == 'ban':
# Удаляем сообщение
try:
await message.delete()
except:
pass

# Эскалируем к модераторам для бана
ban_embed = discord.Embed(
title="🚨 Требуется действие модератора",
description=f"Сообщение от {author.mention} требует бана.",
color=discord.Color.dark_red()
)
ban_embed.add_field(
name="Сообщение",
value=message.content[:500],
inline=False
)
ban_embed.add_field(
name="Оценка",
value=f"{score:.2%}",
inline=True
)
ban_embed.add_field(
name="Причина",
value=analysis.get('reason', 'Серьёзное нарушение'),
inline=False
)

await log_to_mod_channel(message, 'ban_request', analysis, embed=ban_embed)

async def log_to_mod_channel(
message: discord.Message,
action: str,
analysis: Dict,
embed: Optional[discord.Embed] = None
):
"""
Логирует действие в канал модерации
"""
mod_channel = discord.utils.get(
message.guild.channels,
name='mod-logs'
)

if not mod_channel:
return

if not embed:
embed = discord.Embed(
title=f"Действие: {action}",
description=f"Сообщение от {message.author.mention}",
color=discord.Color.blue()
)
embed.add_field(name="Канал", value=message.channel.mention)
embed.add_field(name="Оценка", value=f"{analysis.get('total_score', 0):.2%}")

await mod_channel.send(embed=embed)

async def log_message_analysis(
message: discord.Message,
analysis: Dict
):
"""
Логирует анализ для обучения модели
"""
# Здесь можно сохранять в базу данных для последующего обучения
pass

# Команды для управления

@bot.command(name='set_threshold')
@commands.has_permissions(administrator=True)
async def set_threshold(ctx, action: str, value: float):
"""
Устанавливает порог для действий
!set_threshold warn 0.7
"""
if action == 'warn':
moderator.warning_threshold = value
elif action == 'mute':
moderator.mute_threshold = value
elif action == 'ban':
moderator.ban_threshold = value
else:
await ctx.send("Неизвестное действие. Используйте: warn, mute, ban")
return

await ctx.send(f"Порог для {action} установлен: {value}")

@bot.command(name='mod_stats')
@commands.has_permissions(administrator=True)
async def mod_stats(ctx):
"""
Показывает статистику модерации
"""
total_violations = sum(v['count'] for v in user_violations.values())
unique_violators = len(user_violations)

embed = discord.Embed(
title="📊 Статистика модерации",
color=discord.Color.blue()
)
embed.add_field(
name="Всего нарушений",
value=str(total_violations),
inline=True
)
embed.add_field(
name="Уникальных нарушителей",
value=str(unique_violators),
inline=True
)
embed.add_field(
name="Пороги",
value=f"Warn: {moderator.warning_threshold}\n"
f"Mute: {moderator.mute_threshold}\n"
f"Ban: {moderator.ban_threshold}",
inline=False
)

await ctx.send(embed=embed)

bot.run(os.getenv('DISCORD_BOT_TOKEN'))
```

## Интеграция с Discord

### Настройка прав бота

Бот должен иметь следующие права:
- **Управление сообщениями** — удаление нарушающих сообщений
- **Управление ролями** — выдача/снятие мута
- **Чтение истории сообщений** — анализ контекста
- **Отправка сообщений** — предупреждения и логи

### Создание роли "Muted"

```python
@bot.command(name='setup_muted_role')
@commands.has_permissions(administrator=True)
async def setup_muted_role(ctx):
"""
Создаёт роль Muted для мута пользователей
"""
guild = ctx.guild

# Проверяем, существует ли роль
muted_role = discord.utils.get(guild.roles, name="Muted")

if muted_role:
await ctx.send("Роль Muted уже существует!")
return

# Создаём роль
muted_role = await guild.create_role(
name="Muted",
color=discord.Color.dark_grey(),
reason="Роль для автоматического мута"
)

# Отключаем все права для роли
for channel in guild.channels:
if isinstance(channel, discord.TextChannel):
await channel.set_permissions(
muted_role,
send_messages=False,
add_reactions=False
)
elif isinstance(channel, discord.VoiceChannel):
await channel.set_permissions(
muted_role,
speak=False,
connect=False
)

await ctx.send(f"✅ Роль {muted_role.mention} создана и настроена!")

@bot.command(name='setup_mod_channel')
@commands.has_permissions(administrator=True)
async def setup_mod_channel(ctx):
"""
Создаёт канал для логов модерации
"""
guild = ctx.guild

# Проверяем, существует ли канал
mod_channel = discord.utils.get(guild.channels, name='mod-logs')

if mod_channel:
await ctx.send("Канал mod-logs уже существует!")
return

# Создаём канал
mod_channel = await guild.create_text_channel(
'mod-logs',
reason="Канал для логов AI-модерации"
)

# Ограничиваем доступ
await mod_channel.set_permissions(
guild.default_role,
read_messages=False
)

await ctx.send(f"✅ Канал {mod_channel.mention} создан!")
```

## Обучение модели

### Сбор данных

```python
import sqlite3
from datetime import datetime

class ModerationDatabase:
def __init__(self, db_path='moderation.db'):
self.conn = sqlite3.connect(db_path)
self.create_tables()

def create_tables(self):
cursor = self.conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
message_id TEXT,
author_id TEXT,
content TEXT,
channel_id TEXT,
created_at TIMESTAMP,
toxicity_score REAL,
spam_score REAL,
nsfw_score REAL,
action_taken TEXT,
moderator_feedback TEXT
)
''')
self.conn.commit()

def log_message(self, message: discord.Message, analysis: Dict, action: str):
cursor = self.conn.cursor()
cursor.execute('''
INSERT INTO messages
(message_id, author_id, content, channel_id, created_at,
toxicity_score, spam_score, nsfw_score, action_taken)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
''', (
str(message.id),
str(message.author.id),
message.content,
str(message.channel.id),
message.created_at,
analysis.get('toxicity', 0),
analysis.get('spam', 0),
analysis.get('nsfw', 0),
action
))
self.conn.commit()

def add_feedback(self, message_id: str, feedback: str):
"""
Добавляет обратную связь от модератора
"""
cursor = self.conn.cursor()
cursor.execute('''
UPDATE messages
SET moderator_feedback = ?
WHERE message_id = ?
''', (feedback, message_id))
self.conn.commit()
```

### Fine-tuning модели

```python
async def prepare_training_data(db: ModerationDatabase):
"""
Подготавливает данные для fine-tuning модели
"""
cursor = db.conn.cursor()
cursor.execute('''
SELECT content, toxicity_score, spam_score, nsfw_score,
action_taken, moderator_feedback
FROM messages
WHERE moderator_feedback IS NOT NULL
''')

training_data = []
for row in cursor.fetchall():
content, tox, spam, nsfw, action, feedback = row

# Создаём промпт для обучения
training_data.append({
"messages": [
{
"role": "system",
"content": "Ты AI-модератор Discord сервера."
},
{
"role": "user",
"content": f"Проанализируй: {content}"
},
{
"role": "assistant",
"content": f"Токсичность: {tox}, Спам: {spam}, NSFW: {nsfw}, Действие: {action}. {feedback}"
}
]
})

return training_data
```

## Метрики эффективности

### Ключевые метрики

**1. Автоматизация**
- Процент сообщений, обработанных автоматически
- Цель: > 80%

**2. Точность**
- Процент правильных решений
- Цель: > 90%

**3. Снижение нагрузки**
- Время, сэкономленное модераторами
- Цель: > 70% времени

**4. Ложные срабатывания**
- Процент неправильных действий
- Цель: < 5%

### Отслеживание метрик

```python
class ModerationMetrics:
def __init__(self):
self.total_messages = 0
self.auto_processed = 0
self.human_reviewed = 0
self.false_positives = 0
self.true_positives = 0

def log_auto_action(self, correct: bool):
self.auto_processed += 1
if correct:
self.true_positives += 1
else:
self.false_positives += 1

def get_metrics(self) -> Dict:
accuracy = (self.true_positives / self.auto_processed * 100) if self.auto_processed > 0 else 0
automation_rate = (self.auto_processed / self.total_messages * 100) if self.total_messages > 0 else 0

return {
'total_messages': self.total_messages,
'auto_processed': self.auto_processed,
'automation_rate': f"{automation_rate:.2f}%",
'accuracy': f"{accuracy:.2f}%",
'false_positives': self.false_positives
}
```

## Лучшие практики

### 1. Начинайте с простого

Не пытайтесь автоматизировать всё сразу:
- Начните с обнаружения спама
- Добавьте токсичность
- Постепенно расширяйте функционал

### 2. Всегда оставляйте эскалацию

Сложные случаи должны попадать к модераторам:
- Высокий score → эскалация
- Неопределённость → эскалация
- Первое нарушение → предупреждение, не бан

### 3. Собирайте обратную связь

Модераторы должны оценивать решения AI:
- Правильно ли было действие?
- Нужно ли было действие?
- Как улучшить?

### 4. Настраивайте пороги

Пороги должны быть гибкими:
- Начинайте с консервативных значений
- Адаптируйте под ваше сообщество
- Регулярно пересматривайте

### 5. Прозрачность

Пользователи должны понимать, почему их замутили:
- Объясняйте причину
- Показывайте оценку
- Давайте возможность апелляции

## Примеры использования

### Пример 1: Обнаружение спама

```python
async def detect_spam(message: discord.Message) -> bool:
"""
Обнаруживает спам по паттернам
"""
content = message.content.lower()

# Проверка на повторяющиеся символы
if len(set(content)) < len(content) * 0.3:
return True

# Проверка на массовые упоминания
mentions = len(message.mentions)
if mentions > 5:
return True

# Проверка на подозрительные ссылки
suspicious_domains = ['bit.ly', 'tinyurl.com', 't.co']
if any(domain in content for domain in suspicious_domains):
return True

return False
```

### Пример 2: Автоматические ответы на FAQ

```python
faq_responses = {
"как создать бота": "Для создания бота используйте команду !create_bot",
"правила": "Правила сервера: https://example.com/rules",
"поддержка": "Обратитесь в канал #support"
}

@bot.event
async def on_message(message):
if message.author.bot:
return

content = message.content.lower()

# Проверяем FAQ
for question, answer in faq_responses.items():
if question in content:
await message.channel.send(answer)
return

await bot.process_commands(message)
```

### Пример 3: Умные предупреждения

```python
async def smart_warning(message: discord.Message, violation_type: str):
"""
Отправляет умное предупреждение с объяснением
"""
explanations = {
'toxicity': "Ваше сообщение содержало токсичный контент. Пожалуйста, будьте уважительны к другим участникам.",
'spam': "Ваше сообщение было расценено как спам. Избегайте повторяющихся сообщений и массовых упоминаний.",
'nsfw': "NSFW контент разрешён только в канале #nsfw. Пожалуйста, используйте правильный канал."
}

embed = discord.Embed(
title="⚠️ Предупреждение",
description=explanations.get(violation_type, "Нарушение правил сервера"),
color=discord.Color.orange()
)
embed.add_field(
name="Ваше сообщение",
value=message.content[:200],
inline=False
)
embed.add_field(
name="Что делать?",
value="Пожалуйста, ознакомьтесь с правилами сервера и будьте внимательнее в будущем.",
inline=False
)

await message.author.send(embed=embed)
```

## Заключение

AI-ассистент для модерации Discord серверов может значительно снизить нагрузку на модераторов, автоматизируя до 80% рутинных задач. Ключ к успеху — правильная настройка, постоянное обучение и баланс между автоматизацией и человеческим контролем.

**Ключевые выводы:**

1. ✅ **Начните с простого** — автоматизируйте очевидные случаи
2. ✅ **Собирайте данные** — для обучения и улучшения
3. ✅ **Оставляйте эскалацию** — сложные случаи к модераторам
4. ✅ **Мониторьте метрики** — отслеживайте эффективность
5. ✅ **Будьте прозрачны** — объясняйте действия пользователям

**Результаты:**
- ⏱️ Снижение нагрузки на модераторов: 70-80%
- 🎯 Точность автоматических действий: 90%+
- ⚡ Скорость реакции: мгновенно
- 📊 Покрытие автоматизацией: 80%+ сообщений

Успехов в создании эффективного AI-модератора! 🤖

315 просмотров
0 лайков
0 комментариев