Реализация AI-модерации пользовательского контента на сайте
Пользовательский контент — комментарии, отзывы, изображения, сообщения в чате — требует модерации. Ручная проверка не масштабируется: при 10 000 публикаций в сутки команда из пяти модераторов физически не справится. AI-модерация решает задачу автоматически, оставляя человеку только спорные случаи.
Что именно поддаётся автоматической модерации
Текстовый контент: спам, нецензурная лексика, разжигание ненависти, угрозы, персональные данные в открытом виде. Изображения: откровенные материалы, насилие, нарушение авторских прав (через перцептивное хэширование). Ссылки: фишинг, вредоносные домены. Тональность: токсичные комментарии без явных запрещённых слов.
Каждая категория требует отдельной модели или отдельного API-эндпоинта — универсального решения нет.
Архитектура системы модерации
Синхронная проверка перед публикацией — пользователь отправляет контент, сервер проверяет его до сохранения. Задержка 200–800 мс. Подходит для критичных сценариев: оплата отзывов, юридически значимые публикации.
Асинхронная очередь — контент сохраняется со статусом pending, фоновый воркер проверяет через очередь (RabbitMQ, SQS, Redis Streams). Публикация происходит после одобрения или через N минут, если нарушений нет. Подходит для высоконагруженных форумов и чатов.
Гибридная схема — быстрая синхронная проверка по простым правилам (стоп-слова, длина, паттерны) + асинхронная ML-проверка для прошедшего первичный фильтр.
POST /api/comment
→ sync: banned words check (< 5ms)
→ sync: OpenAI Moderation API (< 300ms)
→ save with status=published/flagged
→ async: image scan if attachments
Инструменты и API
OpenAI Moderation API — бесплатный эндпоинт /v1/moderations. Возвращает категории: hate, hate/threatening, self-harm, sexual, violence, harassment. Работает только с текстом. Не требует промпта — отдельная специализированная модель.
import openai
def moderate_text(content: str) -> dict:
response = openai.moderations.create(input=content)
result = response.results[0]
if result.flagged:
categories = {k: v for k, v in result.categories.__dict__.items() if v}
return {"allowed": False, "categories": categories}
return {"allowed": True}
Google Perspective API — анализ токсичности с оценкой от 0 до 1. Атрибуты: TOXICITY, SEVERE_TOXICITY, IDENTITY_ATTACK, INSULT, PROFANITY, THREAT. Поддерживает русский язык. Квота: 1 QPS бесплатно, платный тариф от $0.25 за 1000 запросов.
AWS Rekognition — модерация изображений. API DetectModerationLabels возвращает иерархию меток с confidence score. Категории: Explicit Nudity, Violence, Visually Disturbing, Hate Symbols.
Azure Content Safety — текст и изображения в одном API. Категории: hate, sexual, violence, self-harm. Каждая оценивается по шкале 0–6. Есть Groundedness Detection для проверки фактичности ответов.
Собственная модель на базе fine-tuning
Для специфичного контента (профессиональный форум с технической лексикой, медицинская платформа) сторонние API дают много ложных срабатываний. Выход — fine-tuning на своих данных.
Процесс: собрать датасет из 2000–5000 размеченных примеров (одобренные/отклонённые), дообучить distilbert-base-multilingual-cased через Hugging Face Transformers, развернуть как отдельный сервис.
from transformers import pipeline
classifier = pipeline(
"text-classification",
model="./moderation-model",
device=0 # GPU
)
def classify_content(text: str) -> tuple[str, float]:
result = classifier(text, truncation=True, max_length=512)[0]
return result["label"], result["score"]
Inference на CPU — ~50 мс на текст до 512 токенов. На GPU (T4) — ~5 мс.
Обработка изображений
Перед отправкой в API нужна предобработка: изменение размера до 2048px по длинной стороне, конвертация в JPEG с качеством 85%, удаление EXIF-метаданных. Это снижает стоимость и ускоряет ответ.
Для защиты от загрузки заранее известного запрещённого контента — PhotoDNA (Microsoft) или pHash-сравнение с базой хэшей. PhotoDNA интегрируется через Azure, pHash реализуется самостоятельно:
import imagehash
from PIL import Image
def compute_phash(image_path: str) -> str:
img = Image.open(image_path)
return str(imagehash.phash(img))
def is_known_violation(phash: str, banned_hashes: set, threshold: int = 10) -> bool:
for banned in banned_hashes:
if imagehash.hex_to_hash(phash) - imagehash.hex_to_hash(banned) < threshold:
return True
return False
Dashboard для ручной модерации
Автоматика не принимает решения по пограничным случаям — их нужно показать модератору. Очередь ручной модерации содержит:
- контент с confidence 0.4–0.7 (неуверенный результат)
- контент, на который пожаловались пользователи
- контент от новых аккаунтов без истории
Интерфейс: список с фильтрами, горячие клавиши для быстрых решений (approve/reject/escalate), история решений с привязкой к оператору, метрики точности по каждому оператору.
Обратная связь и переобучение
Модель деградирует, если контент-паттерны меняются. Цикл улучшения:
- Сохранять все решения (автоматические и ручные) с метками
- Еженедельно анализировать расхождения: где автоматика ошиблась, модератор исправил
- Раз в месяц дообучать модель на накопленных исправлениях
- A/B тестировать новую версию на 10% трафика перед полным переключением
Мониторинг
Метрики для Grafana/Datadog:
-
moderation.requests.total— общий объём -
moderation.latency.p99— задержка 99-го перцентиля -
moderation.flagged.rate— доля заблокированного контента -
moderation.false_positive.rate— доля ошибочных блокировок (по апелляциям) -
moderation.queue.depth— глубина очереди ручной модерации
Алерт: если false_positive.rate > 5% за 24 часа — модель нужно проверить.
Сроки реализации
| Этап | Срок |
|---|---|
| Интеграция OpenAI Moderation API + базовые правила | 3–5 дней |
| Асинхронная очередь + статусы контента | 3–4 дня |
| Dashboard ручной модерации | 5–7 дней |
| Модерация изображений (AWS Rekognition) | 2–3 дня |
| Fine-tuning собственной модели | 10–15 дней |
| Цикл переобучения + мониторинг | 3–5 дней |
Базовая интеграция с OpenAI Moderation API и очередью ручной проверки — 2 недели. Полная система с собственной моделью, мониторингом и dashboard — 5–6 недель.







