Skip to main content
Документация
Центр обучения

Освойте модерацию контента с подробными руководствами, обучающими материалами и документацией API

Быстрые ссылки

Настройка порогов обнаружения

Пороги обнаружения задают уровень уверенности, при котором Discuse помечает контент, позволяя найти баланс между ложными срабатываниями и пропущенными нарушениями. В Discuse эти пороги являются настройками проекта, которые задаются в панели управления (или через API настроек), а запрос к API только включает или отключает нужные проверки — числовые значения порогов в нём не передаются. В этом руководстве объясняется, как работает этот компромисс и как выбрать подходящие значения для вашей платформы.

Как работают пороги Discuse

Каждая проверка возвращает оценку уверенности от 0.0 до 1.0 и флаг hit. Флаг hit устанавливается, когда оценка достигает порога, заданного для этой категории в вашем проекте, или превышает его. Настраиваемые пороги:

Порог (настройка проекта) К чему применяется
threshold_sentiment Общая граница негативной тональности
threshold_toxicity Токсичный текст
threshold_profanity Нецензурная лексика
threshold_threat Угрозы
threshold_insult Оскорбления
threshold_spam Уверенность классификатора спама
threshold_images Откровенные изображения (в целом)
threshold_images_porn Порнографические изображения
threshold_images_sexual Изображения сексуального характера

Именно эти названия доступны через API настроек проекта; объект settings в отдельном запросе содержит только переключатели включения/выключения check_*, а также expected_language. Пороги меняются в панели управления, а не для каждого запроса отдельно.

Компромисс

Lower Threshold = More Strict
├── More content flagged
├── Higher false positive rate
├── Fewer harmful posts slip through
└── More user friction

Higher Threshold = More Permissive
├── Less content flagged
├── Lower false positive rate
├── More harmful posts may slip through
└── Better user experience

Визуализация компромисса

                False Positives ─────────────────────────►
                     Few                              Many
               ┌─────────────────────────────────────────┐
False      Few │   ◄─── Ideal Zone                      │
Negatives      │        (High threshold,                │
               │         low false rates)               │
      │        │                                        │
      │        │              Your platform's           │
      │        │              optimal point →  ●        │
      ▼        │                                        │
          Many │                      Too permissive ──►│
               └─────────────────────────────────────────┘
                       Threshold: 0.3   0.5   0.7   0.9

Какие пороги подходят для разных платформ?

Значения ниже — это отправные точки, выраженные через названия порогов в Discuse (threshold_toxicity, threshold_images_porn и так далее). Используйте их как базовый ориентир для дальнейшей настройки на основе собственных данных о ложных срабатываниях, а не как гарантированно точные значения. Чем ниже порог, тем строже срабатывает проверка.

Социальные платформы

Универсальным социальным платформам нужна сбалансированная модерация:

const SOCIAL_MEDIA_THRESHOLDS = {
  threshold_toxicity: 0.7,
  threshold_profanity: 0.6,
  threshold_threat: 0.5,        // Lower (stricter) for threats
  threshold_insult: 0.7,
  threshold_spam: 0.75,
  threshold_images_porn: 0.6,
  threshold_images_sexual: 0.8  // More permissive for suggestive content
};

Профессиональные и бизнес-платформы

В деловой среде обычно требуется более строгая модерация:

const PROFESSIONAL_THRESHOLDS = {
  threshold_toxicity: 0.5,
  threshold_profanity: 0.4,
  threshold_threat: 0.3,
  threshold_insult: 0.5,
  threshold_spam: 0.6,
  threshold_images_porn: 0.3,
  threshold_images_sexual: 0.5
};

Игровые сообщества

Игровые платформы могут допускать больше дружеских подколов, но при этом должны строго реагировать на реальные угрозы:

const GAMING_THRESHOLDS = {
  threshold_toxicity: 0.8,
  threshold_profanity: 0.85,    // Banter allowed
  threshold_threat: 0.5,        // Still strict on real threats
  threshold_insult: 0.8,
  threshold_spam: 0.8,
  threshold_images_porn: 0.6,
  threshold_images_sexual: 0.9
};

Детские платформы

Платформам для несовершеннолетних нужны самые строгие настройки:

const CHILDRENS_THRESHOLDS = {
  threshold_toxicity: 0.3,
  threshold_profanity: 0.2,
  threshold_threat: 0.2,
  threshold_insult: 0.3,
  threshold_spam: 0.5,
  threshold_images_porn: 0.1,   // Maximum strictness
  threshold_images_sexual: 0.2
};

Можно ли динамически менять пороги?

Discuse хранит один набор порогов для каждого проекта, поэтому вариативность по пользователям или контексту должна обрабатываться в вашем приложении. В приведённых ниже шаблонах эффективный порог рассчитывается на вашей стороне; затем вы либо направляете запросы в разные проекты (у каждого из которых настроены свои пороги), либо самостоятельно выполняете сравнение с оценками, которые возвращает Discuse.

Уровни доверия пользователей

Настраивайте эффективные пороги с учётом репутации пользователя:

function getThresholds(user) {
  const baseThresholds = PLATFORM_THRESHOLDS;

  const trustMultipliers = {
    new_user: 0.8,       // Stricter (lower effective threshold)
    basic_user: 1.0,     // Standard
    verified_user: 1.15, // Slightly more permissive
    trusted_user: 1.3,   // More permissive
    moderator: 1.5       // Most permissive
  };

  const multiplier = trustMultipliers[user.trustLevel] || 1.0;

  return Object.fromEntries(
    Object.entries(baseThresholds).map(([key, value]) => [
      key,
      typeof value === 'number'
        ? Math.min(value * multiplier, 0.95)
        : adjustNestedThresholds(value, multiplier)
    ])
  );
}

Пороги с учётом контекста

Для разных типов контента могут потребоваться разные пороги:

const CONTEXT_THRESHOLDS = {
  // Public posts visible to everyone
  public_post: {
    toxic: 0.6,
    profanity: 0.5
  },

  // Direct messages between users
  direct_message: {
    toxic: 0.7,      // Slightly more permissive
    profanity: 0.6
  },

  // Comments on public content
  comment: {
    toxic: 0.55,     // Stricter than posts
    profanity: 0.5
  },

  // Profile information
  profile: {
    toxic: 0.5,      // Strict for public-facing content
    profanity: 0.4
  }
};

function getContextThresholds(contentType) {
  return CONTEXT_THRESHOLDS[contentType] || CONTEXT_THRESHOLDS.public_post;
}

Корректировки по времени

Корректируйте пороги в периоды повышенного риска:

function getTimeAdjustedThresholds(baseThresholds) {
  const hour = new Date().getHours();
  const dayOfWeek = new Date().getDay();

  // Stricter during off-hours when fewer moderators available
  const isOffHours = hour < 6 || hour > 22;
  const isWeekend = dayOfWeek === 0 || dayOfWeek === 6;

  let multiplier = 1.0;

  if (isOffHours) multiplier *= 0.85;
  if (isWeekend) multiplier *= 0.9;

  return adjustThresholds(baseThresholds, multiplier);
}

Реализация настройки порогов

Централизованная конфигурация

// config/moderation.js — mirrors your Discuse project thresholds so app-side
// routing stays in sync with the values configured in the dashboard.
export const ModerationConfig = {
  thresholds: {
    threshold_toxicity:      parseFloat(process.env.THRESHOLD_TOXICITY || '0.7'),
    threshold_profanity:     parseFloat(process.env.THRESHOLD_PROFANITY || '0.6'),
    threshold_threat:        parseFloat(process.env.THRESHOLD_THREAT || '0.5'),
    threshold_insult:        parseFloat(process.env.THRESHOLD_INSULT || '0.7'),
    threshold_spam:          parseFloat(process.env.THRESHOLD_SPAM || '0.75'),
    threshold_images_porn:   parseFloat(process.env.THRESHOLD_IMAGES_PORN || '0.6'),
    threshold_images_sexual: parseFloat(process.env.THRESHOLD_IMAGES_SEXUAL || '0.8')
  },

  actions: {
    high_confidence: 'auto_block',     // score > 0.95
    medium_confidence: 'human_review', // 0.7 - 0.95
    low_confidence: 'allow_with_flag'  // threshold - 0.7
  }
};

Обновление порогов во время выполнения

Разрешите изменять пороги без повторного развертывания:

class ModerationService {
  constructor() {
    this.thresholds = defaultThresholds;
    this.loadRemoteConfig();
  }

  async loadRemoteConfig() {
    try {
      const config = await fetch('/api/admin/moderation-config');
      const data = await config.json();
      this.thresholds = data.thresholds;
      console.log('Loaded remote moderation config');
    } catch (error) {
      console.warn('Using default thresholds:', error);
    }
  }

  async checkContent(content, context) {
    const result = await callModerationAPI(content);
    const thresholds = this.getThresholdsForContext(context);

    return this.applyThresholds(result, thresholds);
  }
}

Оценка эффективности пороговых значений

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

const MODERATION_METRICS = {
  // Accuracy
  precision: 'True positives / (True positives + False positives)',
  recall: 'True positives / (True positives + False negatives)',
  f1_score: 'Harmonic mean of precision and recall',

  // User impact
  block_rate: 'Content blocked / Total content',
  appeal_rate: 'Appeals filed / Content blocked',
  appeal_success: 'Appeals won / Appeals filed',

  // Operational
  review_queue_size: 'Items waiting for human review',
  review_time: 'Average time to human decision'
};

A/B-тестирование пороговых значений

Проверяйте изменения порогов на части трафика:

async function moderateWithExperiment(content, userId) {
  const experiment = getExperiment(userId, 'threshold_test');

  const thresholds = experiment === 'control'
    ? CURRENT_THRESHOLDS
    : EXPERIMENTAL_THRESHOLDS;

  const result = await checkContent(content);
  const decision = applyThresholds(result, thresholds);

  // Log for analysis
  await logExperiment({
    experiment: 'threshold_test',
    variant: experiment,
    content_id: content.id,
    scores: result,
    decision: decision,
    timestamp: Date.now()
  });

  return decision;
}

Анализ результатов

-- Calculate precision and recall for each threshold variant
SELECT
  variant,
  COUNT(*) as total_decisions,
  SUM(CASE WHEN blocked AND actually_harmful THEN 1 ELSE 0 END) as true_positives,
  SUM(CASE WHEN blocked AND NOT actually_harmful THEN 1 ELSE 0 END) as false_positives,
  SUM(CASE WHEN NOT blocked AND actually_harmful THEN 1 ELSE 0 END) as false_negatives,
  SUM(CASE WHEN blocked AND actually_harmful THEN 1 ELSE 0 END) * 1.0 /
    NULLIF(SUM(CASE WHEN blocked THEN 1 ELSE 0 END), 0) as precision,
  SUM(CASE WHEN blocked AND actually_harmful THEN 1 ELSE 0 END) * 1.0 /
    NULLIF(SUM(CASE WHEN actually_harmful THEN 1 ELSE 0 END), 0) as recall
FROM moderation_decisions
WHERE experiment = 'threshold_test'
GROUP BY variant;

Рабочий процесс настройки порогов

Шаг 1: Задайте базовые значения

// Start with conservative thresholds
const INITIAL_THRESHOLDS = {
  threshold_toxicity: 0.5,
  threshold_profanity: 0.5,
  threshold_spam: 0.6
};

Шаг 2: Соберите данные

async function logModerationDecision(content, result, decision) {
  await db.insert('moderation_log', {
    content_id: content.id,
    content_hash: hashContent(content.text),
    scores: result.results,
    thresholds_used: currentThresholds,
    decision: decision,
    user_trust_level: content.author.trustLevel,
    created_at: Date.now()
  });
}

Шаг 3: Проанализируйте долю ошибок

Просмотрите заблокированный контент и обращения пользователей, чтобы выявить:

  • Ложные срабатывания: безопасный контент был ошибочно заблокирован
  • Пропуски: вредоносный контент, который не удалось обнаружить

Шаг 4: Скорректируйте настройки и повторите

// Based on analysis, raise thresholds that fire too often
const ADJUSTED_THRESHOLDS = {
  threshold_toxicity: 0.65,  // Raised after false positives
  threshold_profanity: 0.55,
  threshold_spam: 0.7
};

Шаг 5: Ведите постоянный мониторинг

Настройте оповещения об эффективности порогов:

async function checkModerationHealth() {
  const stats = await getModerationStats(last24Hours);

  // Alert if false positive rate too high
  if (stats.appealSuccessRate > 0.3) {
    alert('High appeal success rate - thresholds may be too strict');
  }

  // Alert if harmful content is getting through
  if (stats.reportedAfterApproval > threshold) {
    alert('Increase in reported content - thresholds may be too permissive');
  }
}

Краткое изложение лучших практик

  1. Начинайте консервативно: сперва задайте более строгие пороги и ослабляйте их на основе данных.
  2. Учитывайте контекст: разные поверхности (публичные публикации, личные сообщения, профили) требуют разных порогов.
  3. Уровни доверия важны: корректируйте фактический порог с учетом репутации пользователя в вашем приложении.
  4. Измеряйте всё: отслеживайте точность, полноту и влияние на пользователей.
  5. Постоянно улучшайте: модерация никогда не бывает «завершена».
  6. Документируйте решения: ведите записи о том, почему менялись пороги.
  7. Предусмотрите запасные варианты: направляйте пограничные случаи на проверку модератором.

Помните: в Discuse эти пороги задаются в настройках проекта. Изменяйте их в панели управления или через API настроек; объект settings в отдельном запросе лишь включает или отключает выполнение проверок check_*.

Следующие шаги

Автор: Команда Discuse · Обновлено June 2026

Похожие статьи

Руководство по модерации контента с AI

Как машинное обучение обеспечивает работу современных систем модерации контента

Масштабирование модерации контента

Архитектурные шаблоны для модерации больших объёмов контента