Skip to main content
डॉक्यूमेंटेशन
लर्निंग सेंटर

विस्तृत गाइड, ट्यूटोरियल और API डॉक्यूमेंटेशन के साथ कंटेंट मॉडरेशन में महारत हासिल करें

क्विक लिंक

कंटेंट मॉडरेशन को स्केल करना

जो मॉडरेशन सेटअप रोज़ 1,000 संदेशों पर काम करता है, वह दस लाख पर टूटने लगता है: रेट लिमिट अड़चन बनती है, हर कॉल की लेटेंसी जुड़ती जाती है, और लागत तेज़ी से बढ़ती है। यह गाइड दिखाती है कि Discuse मॉडरेशन को हाई-थ्रूपुट पाइपलाइनों में कैसे जोड़ा जाए — कब ब्लॉक करना है, कब बैकग्राउंड में जाँच करनी है, क्या कैश करना है, और पीक लोड के दौरान ट्रैफ़िक को कैसे रूट करना है।

मॉडरेशन के बड़े पैमाने पर बढ़ने पर क्या टूटता है?

हर स्केलिंग समस्या का एक खास कारण और एक खास समाधान होता है:

चुनौती प्रभाव समाधान
वॉल्यूम में बढ़ोतरी API रेट लिमिट, बढ़ी हुई लागत एसिंक्रोनस प्रोसेसिंग, कैशिंग
लेटेंसी की आवश्यकताएँ खराब उपयोगकर्ता अनुभव प्री-मॉडरेशन, क्यूइंग
लागत प्रबंधन बजट की सीमाएँ स्मार्ट रूटिंग, कैशिंग
निरंतरता असमान प्रवर्तन केंद्रीकृत कॉन्फ़िगरेशन
पीक हैंडलिंग सेवा की गुणवत्ता में गिरावट ऑटो-स्केलिंग, क्यू

मुझे कौन-सा आर्किटेक्चर पैटर्न इस्तेमाल करना चाहिए?

पैटर्न 1: सिंक्रोनस प्री-मॉडरेशन

इनके लिए सबसे उपयुक्त: कम मात्रा वाला, उच्च-जोखिम कंटेंट (भुगतान, कानूनी)

User Input → API Call → Moderation → Decision → Response
                ↓
           (Blocking call)
// Simple synchronous flow
async function createPost(content) {
  // Check moderation before saving
  const result = await checkModeration(content);

  if (result.has_violations) {
    throw new ModerationError(result.message);
  }

  // Safe to publish
  return await savePost(content);
}

फ़ायदे: सरल, तुरंत फ़ीडबैक कमियाँ: विलंब बढ़ाता है, थ्रूपुट सीमित करता है

पैटर्न 2: असिंक्रोनस पोस्ट-मॉडरेशन

इनके लिए सबसे उपयुक्त: अधिक मात्रा वाला, कम-जोखिम कंटेंट (टिप्पणियाँ, संदेश)

User Input → Save (Pending) → Publish → Background Check → Action
                                              ↓
                                    ┌────────┴────────┐
                                    ↓                 ↓
                                  Safe            Violation
                                    ↓                 ↓
                                  Keep             Remove
// Async flow with queue
async function createPost(content) {
  // Save immediately with pending status
  const post = await savePost(content, { status: 'pending' });

  // Queue for async moderation
  await moderationQueue.add('check-content', {
    postId: post.id,
    content: content
  });

  return post;
}

// Background worker
moderationQueue.process('check-content', async (job) => {
  const result = await checkModeration(job.data.content);

  if (result.has_violations) {
    await removePost(job.data.postId);
    await notifyUser(job.data.postId, 'content_removed');
  } else {
    await updatePost(job.data.postId, { status: 'approved' });
  }
});

फ़ायदे: नॉन-ब्लॉकिंग, अधिक मात्रा संभालता है कमियाँ: हानिकारक कंटेंट थोड़े समय के लिए दिखाई दे सकता है

पैटर्न 3: टियरड मॉडरेशन

इनके लिए सबसे उपयुक्त: लागत अनुकूलन के साथ संतुलित तरीका

User Input → Quick Check → High Confidence? ──Yes──► Auto-decision
                              │
                              No
                              ↓
                         Full Analysis ──► Decision
async function tieredModeration(content) {
  // Tier 1: Fast local checks (regex, blocklists)
  const localResult = await quickLocalCheck(content);
  if (localResult.definiteViolation) {
    return { action: 'block', source: 'local' };
  }

  // Tier 2: Cached API results
  const cacheKey = hashContent(content);
  const cached = await cache.get(cacheKey);
  if (cached) {
    return { action: cached.action, source: 'cache' };
  }

  // Tier 3: Full API check
  const apiResult = await checkModeration(content);
  await cache.set(cacheKey, apiResult, TTL);

  return { action: determineAction(apiResult), source: 'api' };
}

पैटर्न 4: एग्रीगेशन के साथ फैन-आउट

इनके लिए सबसे उपयुक्त: स्वतंत्र रूप से स्केल होने वाली कई तरह की जाँचें

                    ┌──► Text Check ──┐
                    │                  │
User Input ──► Router ──► Image Check ──► Aggregator ──► Decision
                    │                  │
                    └──► Link Check ──┘
async function parallelModeration(content) {
  const checks = [];

  if (content.text) {
    checks.push(checkText(content.text));
  }

  if (content.images?.length) {
    checks.push(checkImages(content.images));
  }

  if (content.links?.length) {
    checks.push(checkLinks(content.links));
  }

  // Run all checks in parallel
  const results = await Promise.all(checks);

  // Aggregate results
  return aggregateResults(results);
}

function aggregateResults(results) {
  // Most severe result wins
  const hasViolation = results.some(r => r.has_violations);
  const maxScore = Math.max(...results.map(r => r.max_score || 0));

  return {
    has_violations: hasViolation,
    max_score: maxScore,
    details: results
  };
}

कैशिंग रणनीतियाँ

सामग्री-आधारित कैशिंग

एक जैसी सामग्री के लिए परिणाम कैश करें:

const cache = new Redis();

async function checkWithCache(content) {
  const hash = crypto.createHash('sha256')
    .update(content.text || '')
    .update(JSON.stringify(content.images || []))
    .digest('hex');

  // Check cache first
  const cached = await cache.get(`mod:${hash}`);
  if (cached) {
    return { ...JSON.parse(cached), cached: true };
  }

  // API call
  const result = await callModerationAPI(content);

  // Cache for 24 hours
  await cache.setex(`mod:${hash}`, 86400, JSON.stringify(result));

  return { ...result, cached: false };
}

उपयोगकर्ता-आधारित कैशिंग

बार-बार उल्लंघन करने वालों के लिए निर्णय कैश करें:

async function checkUserHistory(userId) {
  const recentViolations = await cache.get(`violations:${userId}`);

  if (recentViolations > 5) {
    // Flag for enhanced scrutiny
    return { enhancedModeration: true };
  }

  return { enhancedModeration: false };
}

async function recordViolation(userId) {
  await cache.incr(`violations:${userId}`);
  await cache.expire(`violations:${userId}`, 86400 * 7); // 7 days
}

कतार प्रबंधन

प्राथमिकता कतारें

अलग-अलग प्रकार की सामग्री को अलग-अलग प्राथमिकताओं के साथ संभालें:

const queues = {
  critical: new Queue('moderation-critical'),  // Reports, appeals
  high: new Queue('moderation-high'),          // Public posts
  normal: new Queue('moderation-normal'),      // Comments, DMs
  low: new Queue('moderation-low')             // Profile updates
};

async function queueForModeration(content, priority = 'normal') {
  const queue = queues[priority] || queues.normal;

  return queue.add('check', {
    contentId: content.id,
    type: content.type,
    data: content
  }, {
    priority: getPriorityNumber(priority),
    timeout: getTimeout(priority)
  });
}

रेट लिमिट का सम्मान करना

हर API कुंजी की प्रति मिनट अनुरोधों की एक सीमा होती है; इसे पार करने पर API कॉल को "rate limit exceeded" त्रुटि के साथ अस्वीकार कर देता है। उस सीमा के भीतर रहने और अनावश्यक कॉल पर कोटा खर्च होने से बचने के लिए अपनी तरफ से थ्रॉटलिंग करें। लिमिटर की प्रति-मिनट अधिकतम सीमा को अपनी कुंजी के कॉन्फ़िगर किए गए RPM से मिलाएँ:

const Bottleneck = require('bottleneck');

const limiter = new Bottleneck({
  maxConcurrent: 50,                   // Cap parallel requests
  minTime: 20,                         // Min 20ms between requests
  reservoir: YOUR_KEY_RPM,             // Match your API key's per-minute limit
  reservoirRefreshAmount: YOUR_KEY_RPM,
  reservoirRefreshInterval: 60 * 1000  // Refill each minute
});

async function rateLimitedCheck(content) {
  return limiter.schedule(() => checkModeration(content));
}

कोटा रेट लिमिट से अलग होता है: हर कॉल आपके प्लान की मासिक API-अनुरोध सीमा में गिना जाता है, और प्रतिक्रिया का usage ऑब्जेक्ट api_requests_used, api_requests_limit, और api_requests_remaining रिपोर्ट करता है, ताकि आप बची हुई क्षमता पर नज़र रख सकें।

डेड-लेटर कतारें

विफल मॉडरेशन प्रयासों को संभालें:

moderationQueue.process('check-content', async (job) => {
  try {
    const result = await checkModeration(job.data.content);
    await applyDecision(job.data.contentId, result);
  } catch (error) {
    if (job.attemptsMade < 3) {
      throw error; // Retry
    }

    // Move to dead letter queue after 3 attempts
    await deadLetterQueue.add('failed-moderation', {
      ...job.data,
      error: error.message,
      attempts: job.attemptsMade
    });

    // Apply safe default (hold for review)
    await holdForManualReview(job.data.contentId);
  }
});

लागत अनुकूलन

स्मार्ट रूटिंग

भुगतान वाले APIs को केवल ज़रूरत पड़ने पर ही कॉल करें:

async function smartModeration(content) {
  // Step 1: Free local checks
  const localResult = runLocalFilters(content);
  if (localResult.isDefinitelySpam) {
    return { action: 'block', cost: 0 };
  }

  // Step 2: Check cache (free)
  const cached = await getCachedResult(content);
  if (cached) {
    return { action: cached.action, cost: 0 };
  }

  // Step 3: Risk-based API call
  const riskScore = calculateRiskScore(content, localResult);

  if (riskScore < 0.2) {
    // Low risk: approve without API call
    return { action: 'approve', cost: 0 };
  }

  // Step 4: API call for uncertain content
  const apiResult = await checkModeration(content);
  return {
    action: determineAction(apiResult),
    cost: calculateApiCost(content)
  };
}

कन्करेंसी नियंत्रण

/api/v2/check एंडपॉइंट हर कॉल में एक सबमिशन को स्कोर करता है। काम को "बैच" करने के लिए, एक ही मल्टी-आइटम अनुरोध की अपेक्षा करने के बजाय, अपने वर्कर में आइटमों को समूहित करें और उन्हें सीमित पूल के तहत समानांतर रूप से फैला दें। कई मीडिया URLs शामिल करने वाला एक चेक अपने आप में एक कॉल होता है जो उन सभी को कवर करता है — एक इमेज-भारी कॉल, कई सिंगल-इमेज कॉल्स से सस्ती पड़ती है।

// Bounded concurrency: many items, capped parallel calls.
async function processBatch(items, concurrency = 10) {
  const results = [];
  for (let i = 0; i < items.length; i += concurrency) {
    const slice = items.slice(i, i + concurrency);
    const settled = await Promise.allSettled(
      slice.map(item => checkModeration(item.content))
    );
    results.push(...settled);
  }
  return results;
}

एक ही अनुरोध में अधिकतम 10 इमेज URLs, 5 GIF URLs, 3 वीडियो URLs, 5 डॉक्यूमेंट URLs, और 20 लिंक, साथ ही 10,000 अक्षरों तक का टेक्स्ट भेजा जा सकता है — इसलिए किसी सबमिशन के मीडिया को अलग-अलग करने के बजाय एक ही कॉल में समेकित करें।

मॉनिटरिंग और अलर्टिंग

मुख्य मेट्रिक्स डैशबोर्ड

const metrics = {
  // Volume metrics
  total_requests: new Counter('moderation_requests_total'),
  requests_per_second: new Gauge('moderation_rps'),

  // Latency metrics
  latency_p50: new Histogram('moderation_latency_p50'),
  latency_p99: new Histogram('moderation_latency_p99'),

  // Queue metrics
  queue_depth: new Gauge('moderation_queue_depth'),
  processing_time: new Histogram('moderation_processing_time'),

  // Cost metrics
  api_calls: new Counter('moderation_api_calls'),
  estimated_cost: new Counter('moderation_estimated_cost'),

  // Accuracy metrics
  violations_detected: new Counter('moderation_violations'),
  false_positives: new Counter('moderation_false_positives')
};

अलर्टिंग नियम

# Alert on queue backup
- alert: ModerationQueueBackup
  expr: moderation_queue_depth > 10000
  for: 5m
  labels:
    severity: warning
  annotations:
    summary: Moderation queue backing up

# Alert on high latency
- alert: ModerationLatencyHigh
  expr: moderation_latency_p99 > 5000
  for: 2m
  labels:
    severity: critical
  annotations:
    summary: Moderation latency exceeding 5 seconds

# Alert on high error rate
- alert: ModerationErrorRate
  expr: rate(moderation_errors_total[5m]) / rate(moderation_requests_total[5m]) > 0.01
  for: 5m
  labels:
    severity: critical
  annotations:
    summary: Moderation error rate above 1%

इन्फ्रास्ट्रक्चर स्केलिंग

हॉरिज़ॉन्टल स्केलिंग

# Kubernetes HPA for moderation workers
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: moderation-worker
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: moderation-worker
  minReplicas: 3
  maxReplicas: 50
  metrics:
  - type: External
    external:
      metric:
        name: queue_depth
      target:
        type: AverageValue
        averageValue: 100

वैश्विक उपयोगकर्ताओं के लिए लेटेंसी कम करना

Discuse API एक ही बेस URL, https://api.discuse.com पर उपलब्ध है। वैश्विक ट्रैफ़िक के लिए लेटेंसी कम रखने के लिए, अपने मॉडरेशन वर्कर्स को अपने उपयोगकर्ताओं के पास चलाएँ और उन्हें API कॉल करने दें, बजाय इसके कि किसी दूरस्थ क्षेत्र में उपयोगकर्ता-सामने वाले रिक्वेस्ट पाथ से इसे सिंक्रोनस तरीके से कॉल किया जाए। इसे ऊपर दिए गए async पोस्ट-मॉडरेशन और कैशिंग पैटर्न के साथ मिलाएँ, ताकि धीमा राउंड-ट्रिप कभी भी किसी उपयोगकर्ता को ब्लॉक न करे।

सर्वोत्तम प्रथाओं का सारांश

  1. आक्रामक रूप से कैश करें: समान सामग्री कैश किया हुआ परिणाम लौटाती है। API भी किसी प्रोजेक्ट में थोड़े समय के भीतर समान सामग्री को डीडुप्लिकेट करता है और cached: true लौटाता है।
  2. क्यू का उपयोग करें: अधिक मात्रा के लिए async प्रोसेसिंग।
  3. टियर लागू करें: स्थानीय → कैश → API।
  4. हर चीज़ मॉनिटर करें: क्यू की गहराई, विलंबता, और अपने कोटा के मुकाबले उपयोग।
  5. विफलता के लिए योजना बनाएं: डेड-लेटर क्यू और सुरक्षित फ़ॉलबैक।
  6. क्षैतिज रूप से स्केल करें: बड़ी मशीनों के बजाय अधिक वर्कर।
  7. लागत अनुकूलित करें: स्मार्ट रूटिंग, कम अनावश्यक कॉल, और प्रति अनुरोध समेकित मीडिया।

अगले कदम

Discuse टीम द्वारा लिखा गया · अंतिम अपडेट June 2026

संबंधित लेख

AI Content Moderation Guide

Machine learning आधुनिक content moderation systems को कैसे सक्षम बनाती है

Detection Thresholds कॉन्फ़िगर करना

अपने use case के लिए false positives और negatives का संतुलन बनाएँ