AI-модерація текстового контенту в мобільних додатках
Текстова модерація обов'язкова для будь-якого додатка з UGC: чат, коментарі, відзиви, описи. Без неї App Store Review Guideline 1.2 (User Generated Content) відхиляє додатки або вимагає негайних змін. Технічно завдання ділиться на клієнтську (базову) та серверну (основну) модерацію.
Клієнтська модерація: перша лінія
На клієнті — швидка перевірка без мережі. Мета: запобігти очевидним порушенням до відправки, зменшити навантаження на сервер.
Два інструменти на iOS:
-
NaturalLanguageframework зNLTaggerдля базового аналізу тональності - Локальний список заборонених слів (скомпільований regex)
import NaturalLanguage
class LocalTextModerator {
private let forbiddenPatterns: NSRegularExpression
init() {
// Компілюємо паттерн один раз під час ініціалізації
let patterns = ["word1", "word2"].joined(separator: "|")
forbiddenPatterns = try! NSRegularExpression(
pattern: "\\b(\(patterns))\\b",
options: [.caseInsensitive]
)
}
func quickCheck(_ text: String) -> ModerationResult {
let range = NSRange(text.startIndex..., in: text)
if forbiddenPatterns.firstMatch(in: text, range: range) != nil {
return .blocked(reason: .explicitContent)
}
return .passed
}
}
Не тримайте список слів у бінарнику в открытом виді — ревьюери Apple іноді перевіряють. Краще: зашифрований список, розшифровується при першому запуску, або завантажується з сервера під час ініціалізації.
Серверна модерація: основний шар
OpenAI Moderation API — безплатна (на березень 2025) та точна:
POST https://api.openai.com/v1/moderations
Authorization: Bearer <key>
{
"input": "текст для перевірки",
"model": "omni-moderation-latest"
}
Відповідь містить categories та category_scores:
{
"results": [{
"flagged": false,
"categories": {
"hate": false,
"harassment": false,
"sexual": false,
"violence": false,
"self-harm": false
},
"category_scores": {
"hate": 0.0023,
"harassment": 0.0156,
"sexual": 0.0001
}
}]
}
Ніколи не викликайте OpenAI Moderation з клієнта — API ключ на клієнті. Завжди через backend-proxy.
Архітектура модераційного pipeline
Користувач вводить текст
↓
[Клієнт] Локальна перевірка (миттєво)
↓ пройшла
[Backend] OpenAI Moderation API (100–300 мс)
↓ пройшла
[Backend] Користувальницькі правила (regex, domain-specific)
↓ пройшла
Публікація контенту
↓ паралельно
[Backend] Асинхронна повторна перевірка (дорожча модель)
Двохрівнева перевірка: синхронна (для негайної відповіді) та асинхронна (для глибокого аналізу). Асинхронний результат може привести до ретроактивного видалення.
Робота з пограничними випадками
OpenAI Moderation не дає бінарну відповідь — це вероятності. Потрібна бізнес-логіка для "сірої зони":
// Android: обробка результатів модерації
fun evaluateModerationResult(result: ModerationResult): ContentDecision {
return when {
result.flagged -> ContentDecision.BLOCK
result.categoryScores["harassment"]!! > 0.7 -> ContentDecision.BLOCK
result.categoryScores["harassment"]!! > 0.3 -> ContentDecision.REQUIRE_REVIEW
result.categoryScores["sexual"]!! > 0.4 -> ContentDecision.REQUIRE_REVIEW
else -> ContentDecision.ALLOW
}
}
REQUIRE_REVIEW — контент попадає в очередь ручної модерації. Публікується з затримкою або сразу з пониженою видимістю.
Багатомовна модерація
OpenAI Moderation працює з російською мовою, але якість на нестандартних формах (транслітерація, навмисні опечатки, leetspeak) — гірша. Додатковий шар: нормалізація тексту перед перевіркою.
func normalizeText(_ text: String) -> String {
var result = text.lowercased()
// Транслітерація до кирилиці
let translitMap: [String: String] = ["a": "а", "e": "е", "o": "о", "p": "р", "c": "с"]
for (latin, cyrillic) in translitMap {
result = result.replacingOccurrences(of: latin, with: cyrillic)
}
// Видаляємо повторювані символи: "приивет" → "привет"
result = result.replacingOccurrences(of: "(.)\\1{2,}", with: "$1", options: .regularExpression)
return result
}
Перевіряємо як нормалізований, так й оригінальний текст.
Rate limiting та зловживання
Якщо модерація платна або дорога — потрібна захист від флуду:
- Rate limiting на backend: 20 публікацій/хвилину на користувача
- Shadowban: користувач з історією порушень проходить більш жорстку перевірку автоматично
- Тимчасова блокування: при 3 порушеннях за 24 години — тимчасова блокування публікацій
Логування для аппеляцій
Користувачі оскаржують блокування. Потрібно логувати: оригінальний текст, результат модерації, причину, timestamp, версію моделі. Це також допомагає поліпшувати пороги з часом.
Часові рамки
Backend з OpenAI Moderation + базовий клієнтський фільтр — 2–3 дні. Повна система з pipeline, ручною модерацією, нормалізацією, аналітикою та аппеляціями — 2–3 тижні. Вартість розраховується індивідуально.







