Руководство по AI-модерации контента
Discuse проверяет текст и изображения на тональность/токсичность, спам, нежелательный язык, ненормативную лексику, ссылки и откровенные изображения, а затем возвращает результат по каждой категории, чтобы ваш код мог автоматически одобрять, помечать или отклонять контент. Вы отправляете контент на один endpoint, POST https://api.discuse.com/api/v2/check, и получаете в ответ структурированные оценки. В этом руководстве описано, как работают проверки, какие паттерны модерации можно выстроить вокруг них и как подключить Discuse API к вашему пайплайну.
Что такое AI-модерация контента?
AI-модерация контента использует модели машинного обучения, чтобы автоматически выявлять и классифицировать потенциально вредный контент. Если модератор-человек просматривает материалы по одному, то такие модели оценивают контент сразу при поступлении, поэтому публикации можно проверить до того, как их увидят другие пользователи.
Как это работает?
- Отправьте контент: Передайте текст и/или URL медиафайлов в API модерации.
- Запустите проверки: API выполнит включённые проверки (тональность, язык, спам, запрещённые слова, изображения, ссылки, антивирус).
- Оцените каждую категорию: Каждая проверка возвращает оценки и флаг
hit, показывающий, был ли превышен настроенный вами порог. - Примите решение: Используйте
has_violations(а также оценки по отдельным проверкам), чтобы одобрить, пометить или отклонить контент.
В Discuse запрос выглядит так:
const response = await fetch('https://api.discuse.com/api/v2/check', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.DISCUSE_API_KEY
},
body: JSON.stringify({
content: { text: 'message to check', image_urls: ['https://...'] },
settings: { check_sentiment: true, check_spam: true, check_images: true }
})
});
const result = await response.json(); // { has_violations, results: { sentiment, spamfinder, images, ... }, usage }
Что охватывает каждая проверка Discuse?
Проверка (переключатель settings) |
Что она охватывает | Ключевые поля результата |
|---|---|---|
check_sentiment |
Негатив, токсичность, ненормативную лексику, угрозы и оскорбления в тексте | sentiment.is_toxic, sentiment.toxicity, sentiment.score, sentiment.hit |
check_spam |
Классификацию текста как спама | spamfinder.label, spamfinder.confidence, spamfinder.is_spam, spamfinder.hit |
check_language |
Соответствие текста ожидаемому языку | language.language, language.confidence, language.hit |
check_badwords |
Совпадения с пользовательским списком запрещённых слов | badwords.hit, badwords.matched_words |
check_images |
Откровенный визуальный контент по URL изображений | images.porn, images.sexual, images.neutral, images.hit |
check_links |
Репутацию ссылок | links.status, links.hit |
check_antivirus |
Вредоносное ПО в URL документов/файлов | antivirus.status, antivirus.hit |
Каждый переключатель имеет логический тип. Числовые пороги, при которых оценка превращается в hit, настраиваются отдельно для каждого проекта в панели управления и не передаются в запросе — см. руководство по настройке порогов.
Преимущества AI-модерации
Масштабируемость
AI обрабатывает такие объёмы контента, с которыми не справятся команды модераторов. Один вызов API возвращает результат за миллисекунды, поэтому модерация успевает за новыми публикациями, а не накапливает очередь на проверку. Сочетайте автоматические проверки с очередью для ручной модерации пограничных случаев (об этом ниже).
Скорость
Проверки в реальном времени позволяют отсеивать контент ещё до публикации:
// Pre-moderation: Check content before publishing
async function publishPost(content) {
const moderation = await checkContent(content);
if (moderation.has_violations) {
return { published: false, reason: moderation.message };
}
// Content passes moderation
return await saveAndPublish(content);
}
Согласованность
AI применяет одни и те же правила ко всему контенту — без усталости и различий между модераторами. Решения воспроизводимы: один и тот же ввод при одинаковых порогах проекта даёт одинаковые флаги hit, что делает применение правил проверяемым.
Архитектура модерации
Поток премодерации
User Submits → AI Check → Decision
↓
┌───────────┼───────────┐
↓ ↓ ↓
Allow Review Block
↓ ↓ ↓
Publish Human Queue Reject
Поток постмодерации
User Submits → Publish → AI Check → Action
↓
┌────────────┼────────────┐
↓ ↓ ↓
Safe Borderline Violation
↓ ↓ ↓
Keep Flag/Review Remove
Гибридный подход (рекомендуется)
Ответ Discuse устанавливает has_violations, как только любая включённая проверка превышает настроенный для неё порог, и передаёт базовые оценки по категориям, чтобы вы могли добавить поверх них собственный диапазон уверенности:
async function moderateContent(content) {
const result = await checkContent(content);
// Build a confidence figure from the scores you care about.
// e.g. the toxicity score and the spam classifier confidence.
const confidence = Math.max(
result.results?.sentiment?.toxicity ?? 0,
result.results?.spamfinder?.confidence ?? 0,
result.results?.images?.porn ?? 0
);
// High confidence: automate.
if (confidence > 0.95) {
return result.has_violations
? { action: 'auto_remove', reason: result.message }
: { action: 'auto_approve' };
}
// Medium confidence: route to a human.
if (confidence > 0.5) {
await addToReviewQueue(content, result);
return { action: 'pending_review' };
}
// Low confidence: approve, keep watching.
return { action: 'approve_with_monitoring' };
}
Реализация AI-модерации
Шаг 1: Определите свою политику
Прежде чем вызывать API, решите, какой контент считается допустимым и какое действие выполнять для каждой категории. В Discuse числовой порог для каждой категории задаётся в настройках проекта (в панели управления), поэтому политика вашего приложения сопоставляет результат API с действием, а не заново определяет порог:
const MODERATION_POLICY = {
// What to do when a given Discuse check reports a hit.
// Thresholds themselves are configured per project in the dashboard.
actions: {
sentiment: 'block', // toxic / threatening text
spam: 'block',
badwords: 'flag',
images: 'block', // explicit imagery
links: 'flag'
}
};
Шаг 2: Интегрируйте API
Отправьте контент и проверки, которые нужно включить для этого запроса. Каждый переключатель check_* — это необязательное логическое значение, которое переопределяет настройку проекта по умолчанию для данного вызова:
async function checkContent(content) {
const response = await fetch('https://api.discuse.com/api/v2/check', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.DISCUSE_API_KEY
},
body: JSON.stringify({
content: {
text: content.text,
image_urls: content.images
},
settings: {
check_sentiment: true,
check_spam: true,
check_images: true
}
})
});
if (!response.ok) {
throw new Error(`Discuse API returned ${response.status}`);
}
return response.json();
}
Шаг 3: Примените решения
Сопоставьте каждую проверку, которая возвращает hit, с заданным вами действием:
function applyModerationDecision(result) {
const r = result.results || {};
if (r.sentiment?.hit) return { action: MODERATION_POLICY.actions.sentiment, category: 'sentiment' };
if (r.spamfinder?.hit) return { action: MODERATION_POLICY.actions.spam, category: 'spam' };
if (r.images?.hit) return { action: MODERATION_POLICY.actions.images, category: 'images' };
if (r.badwords?.hit) return { action: MODERATION_POLICY.actions.badwords, category: 'badwords' };
if (r.links?.hit) return { action: MODERATION_POLICY.actions.links, category: 'links' };
return { action: 'allow' };
}
Шаг 4: Обработайте пограничные случаи
async function handleModerationResult(content, result) {
switch (result.action) {
case 'block':
await notifyUser(content.author, 'content_blocked', result);
await logModeration(content, result);
return false;
case 'flag':
await addToReviewQueue(content, result);
await publishWithWarning(content);
return true;
case 'allow':
await publish(content);
return true;
default:
// Unknown action - fail safe by blocking
await logError('unknown_moderation_action', result);
return false;
}
}
Рекомендации
Начинайте осторожно и корректируйте со временем
Начните с более строгих порогов для проекта и постепенно смягчайте их по мере того, как будете измерять ложные срабатывания. В Discuse эти пороги задаются в настройках проекта, поэтому настройка выполняется в панели управления (или через API обновления настроек), а не в каждом отдельном запросе. Рабочий процесс описан в руководстве по настройке порогов.
Поддерживайте очередь для проверки человеком
AI должен дополнять человеческое суждение в пограничных случаях, а не заменять его:
async function processReviewQueue() {
const items = await getReviewQueue();
for (const item of items) {
// Present to human reviewer with AI context
const reviewUI = {
content: item.content,
ai_scores: item.moderation_result,
similar_decisions: await getSimilarPreviousDecisions(item)
};
// Human makes final decision
const decision = await presentToReviewer(reviewUI);
// Log for model improvement
await logHumanDecision(item, decision);
}
}
Отслеживайте и улучшайте
Отслеживайте ключевые метрики, чтобы улучшать систему модерации:
const METRICS = {
// Accuracy metrics
false_positive_rate: 'Content incorrectly blocked',
false_negative_rate: 'Harmful content missed',
// Operational metrics
average_response_time: 'API latency',
review_queue_depth: 'Human review backlog',
// User impact
appeal_rate: 'Users appealing decisions',
appeal_success_rate: 'Appeals overturned'
};
Корректно обрабатывайте апелляции
Когда пользователь подает апелляцию, передавайте материал на проверку человеку, а не принимайте повторное решение автоматически. Предоставьте проверяющему исходные оценки Discuse и историю пользователя в качестве контекста:
async function handleAppeal(contentId, userId) {
const original = await getContentWithModeration(contentId);
await addToReviewQueue(contentId, {
type: 'appeal',
original_decision: original.moderation, // Discuse `results` saved at decision time
author_history: await getAuthorHistory(userId)
});
return { status: 'pending', message: 'Under review' };
}
В самом API нет параметра «контекст» или «история автора» для каждого запроса — контекст вы применяете на своей стороне, когда выбираете пороги и направляете материалы на проверку.
Распространённые ошибки
Чрезмерная зависимость от AI
Автоматизируя каждое решение, вы автоматизируете и каждую ошибку. Оставляйте человека в процессе для:
- Сложных решений, зависящих от контекста
- Контента с высокими рисками (юридические вопросы, безопасность)
- Апелляций и пограничных случаев
Игнорирование контекста
Одни и те же слова могут быть вредоносными или допустимыми в зависимости от контекста:
"I'm going to kill it at this interview!" // Positive
"I'm going to kill you" // Threat
Discuse оценивает каждое сообщение отдельно; у него нет параметра «контекста» на уровне запроса. Учитывайте контекст на своей стороне: выбирайте более строгие или более мягкие пороги проекта для разных поверхностей (публичная публикация или личное сообщение) и направляйте пограничные hit на проверку человеком.
Настроил и забыл
Модерация контента требует постоянной настройки:
- Отслеживайте долю ложноположительных и ложноотрицательных срабатываний
- Обновляйте пороги на основе данных
- Анализируйте новые паттерны контента
- Переобучайте или обновляйте модели
Непоследовательное применение правил
Применяйте политику по правилам, а не в зависимости от того, кто опубликовал контент. Задавайте пороги на основе документированного уровня доверия, а не разовых исключений:
// Avoid: per-person exceptions
if (user.isInfluencer) { /* lenient */ }
// Prefer: thresholds keyed to a documented trust level,
// configured the same way for everyone in that level.
const action = MODERATION_POLICY.actions[category];
Дальнейшие шаги
- Настройка порогов - Точно настройте модерацию
- Масштабирование модерации контента - Работайте с большими объёмами
- Анализ текста - Подробно разберите модерацию текста
- Обнаружение NSFW на изображениях - Защита визуального контента