- PVSM.RU - https://www.pvsm.ru -

OpenAI ModerationAPI: примеры использования

Всем привет!

В последнее время всё чаще появляются новости о том, что искусственный интеллект (ИИ) удалось взломать или обойти его защитные механизмы. Это действительно актуальная проблема — особенно для тех, кто занимается разработкой ИИ‑агентов и интеграцией языковых моделей в продукты.

Чтобы понять суть проблемы, представим ИИ в виде ребёнка, который знает правила, но может поддаться на уговоры. Злоумышленник здесь выступает в роли «дяди с конфеткой»: он находит способы убедить модель нарушить установленные ограничения.

Недавно в нашем Telegram‑канале «Код на салфетке» [1] мы опубликовали подробный разбор [2] того, как можно попытаться обойти встроенные ограничения ИИ. Такие попытки обхода называют джейлбрейком (jailbreak). Это термин из сферы IT, который изначально использовался для обозначения взлома защитных механизмов мобильных устройств, а теперь применяется и к ИИ.

Существует множество техник джейлбрейка — от простых манипуляций с формулировками до сложных многоэтапных схем. Однако разработчики не стоят на месте: для каждой атаки создаются соответствующие защитные механизмы.

В этой статье мы сосредоточимся на одном из ключевых инструментов защиты — модерации контента. Разберём, как с помощью Moderation API автоматически фильтровать вредоносные или некорректные запросы, настроим пакетную проверку и логирование, а также рассмотрим практические примеры интеграции модерации в реальные сервисы.

Важно: вопросы джейлбрейка мы детально разберём в следующей статье — здесь же фокусируемся исключительно на механизмах модерации.

А уже в это воскресенье на канале [1] выйдет пост о защите системных промптов — не пропустите!


Модерация

OpenAI Moderation API — бесплатный инструмент для автоматической проверки текста и изображений на потенциально вредоносный контент. Он реализован в виде отдельной модели omni-moderation-latest и позволяет оперативно выявлять нарушения политики использования OpenAI как в пользовательских запросах, так и в ответах ИИ‑агента.

О модели omni-moderation-latest

omni-moderation-latest — новейшая мультимодальная модель на базе GPT‑4o. Её ключевые особенности:

  • поддерживает анализ текста и изображений.

  • охватывает 13 категорий нарушений (см. ниже).

  • обеспечивает точность классификации до 95 %.

  • работает с контентом на 40 языках.

Сценарии использования

Moderation API предназначен для двух основных задач:

  1. Input Moderation — проверка пользовательского ввода до его обработки ИИ‑агентом. Позволяет:

    • блокировать попытки джейлбрейка.

    • предотвращать ввод вредоносного или незаконного контента.

    • снижать нагрузку на основную модель за счёт отсева некорректных запросов.

  2. Output Moderation — валидация ответов агента перед отображением пользователю. Обеспечивает:

    • контроль качества и безопасности генерируемого контента.

    • соответствие ответа этическим и юридическим нормам.

    • защиту репутации сервиса.

Категории модерации

API классифицирует контент по 13 категориям. Ниже — подробный разбор каждой с примерами и ограничениями.

Категория

Описание

Поддержка

harassment

Язык, выражающий, подстрекающий или продвигающий домогательства (например, оскорбительные высказывания в адрес группы лиц)

Только текст

harassment/threatening

Домогательства с угрозами насилия или серьёзного вреда (например, «я найду тебя и…»)

Только текст

hate

Контент, выражающий ненависть по признаку расы, пола, этнической принадлежности, религии и т. д. (например, ксенофобские лозунги)

Только текст

hate/threatening

Контент ненависти, включающий угрозы насилия (например, призывы к расправе)

Только текст

illicit

Советы или инструкции по совершению незаконных действий (например, «как изготовить взрывчатое вещество»)

Только текст

illicit/violent

Незаконный контент, связанный с насилием (например, руководство по изготовлению оружия)

Только текст

self-harm

Контент, продвигающий или изображающий акты самоповреждения (например, фото порезов)

Текст и изображения

self-harm/intent

Выражение намерения совершить акт самоповреждения (например, «я собираюсь…»)

Текст и изображения

self-harm/instructions

Инструкции по совершению актов самоповреждения (например, пошаговые руководства)

Текст и изображения

sexual

Сексуально возбуждающий контент или продвижение сексуальных услуг (например, откровенные изображения)

Текст и изображения

sexual/minors

Сексуальный контент с участием лиц младше 18 лет (например, намеки на педофилию)

Только текст

violence

Контент, изображающий смерть, насилие или физические повреждения (например, описание драки)

Текст и изображения

violence/graphic

Контент с графическими изображениями насилия (например, фото травм)

Текст и изображения

Важные примечания:

  • Для изображений анализ доступен только по категориям, где указана поддержка «Текст и изображения».

  • Модель не заменяет юридическую экспертизу: её решения носят рекомендательный характер.

  • Точность 95 % достигнута на тестовых наборах данных; в реальных условиях показатель может варьироваться.

  • API не хранит обрабатываемый контент — данные удаляются после модерации.

Принцип работы

Moderation API использует классификаторы на базе технологий, аналогичных GPT, для комплексной оценки контента по всем 13 категориям нарушений.

Работа сервиса выстроена в чёткую последовательность этапов:

  1. Отправка запроса. Клиент передаёт на анализ текст или изображение через API‑запрос. Допустимые форматы:

    • текст — в виде строки.

    • изображения — в формате URL или base64‑кодировке.

  2. Анализ контента. Модель omni-moderation-latest обрабатывает входные данные:

    • для текста — применяет лингвистический анализ, выявляя семантические паттерны и контекстные сигналы.

    • для изображений — использует компьютерное зрение для распознавания объектов, сцен и текстовых элементов на картинке. Для каждой из 13 категорий нарушений вычисляется вероятность соответствия.

  3. Генерация оценок. Модератор формирует структурированный ответ, включающий:

    • булевы флаги (flaggedcategories) — чёткие «да/нет» по категориям.

    • числовые оценки уверенности (category_scores) — вероятность нарушения в диапазоне от 0 до 1.

    • метаданные о типах входных данных (category_applied_input_types).

  4. Принятие решения. Приложение интерпретирует ответ API и выполняет действия по сценарию:

    • блокировка контента (если flagged = true).

    • передача на ручную модерацию.

    • логирование инцидента.

Структура ответа

Ответ возвращается в формате JSON. Ниже — пример с пояснениями.

{
  "id": "modr-970d409ef3bef3b70c73d8232df86e7d",
  "model": "omni-moderation-latest",
  "results": [
    {
      "flagged": true,
      "categories": {
        "sexual": false,
        "hate": false,
        "violence": true,
        "self-harm": false,
        ...
      },
      "category_scores": {
        "sexual": 2.34135824776394e-7,
        "hate": 3.1999824407395835e-7,
        "violence": 0.8599265510337075,
        "self-harm": 0.0011175734280627694,
        ...
      },
      "category_applied_input_types": {
        "violence": ["image"],
        "sexual": ["image"],
        ...
      }
    }
  ]
}

Поля ответа и их значение:

  • id — уникальный идентификатор запроса для отслеживания и аудита.

  • model — название используемой модели модерации (omni-moderation-latest).

  • results — массив объектов с результатами анализа. Даже для одного входного элемента возвращается массив (может расширяться в будущих версиях).

Внутри объекта results:

  • flagged — булево значение (true/false). Указывает, обнаружен ли хотя бы один тип нарушения. Если true, контент требует внимания.

  • categories — словарь булевых флагов по каждой из 13 категорий. true означает, что модель идентифицировала нарушение в этой категории.

  • category_scores — словарь числовых оценок уверенности модели для каждой категории. Значение от 0 (нет нарушения) до 1 (высокая вероятность нарушения). Позволяет настраивать пороги срабатывания (например, блокировать только при оценке > 0.8).

  • category_applied_input_types — словарь, указывающий, какой тип входных данных (текст/изображение) был проанализирован для каждой категории. Помогает понять, на чём основано решение (например, нарушение категории violence обнаружено на изображении).

Практические рекомендации:

  1. Используйте category_scores для гибкой настройки чувствительности. Например:

    • 0.0–0.3 — низкий риск, можно пропустить.

    • prepared 0.3–0.7 — отправить на ручную модерацию.

    • 0.7–1.0 — автоматически блокировать.

  2. Проверяйте category_applied_input_types, чтобы понимать, какой компонент контента вызвал срабатывание (текст или изображение).

  3. Логируйте id для аудита и разбора инцидентов.

  4. Обрабатывайте массив results в цикле, даже если ожидаете один элемент — это обеспечит совместимость с будущими версиями API.

Практическая реализация в Python

Рассмотрим, как интегрировать OpenAI Moderation API в реальные проекты. Ниже — рабочие примеры с пояснениями и рекомендациями по безопасности.

Базовая проверка текста

Простейший сценарий: проверка текстового ввода на нарушения.

from openai import OpenAI

# Инициализация клиента (ключ API должен быть в переменной окружения OPENAI_API_KEY)
client = OpenAI()

# Текст для проверки
text_to_check = "Текст для проверки"

# Отправка запроса в Moderation API
response = client.moderations.create(
    model="omni-moderation-latest",
    input=text_to_check
)

# Получение результата
result = response.results[0]

# Анализ ответа
if result.flagged:
    print("Контент нарушает политику!")
    # Выводим список категорий, где обнаружено нарушение
    violated_categories = [
        cat for cat, flagged in result.categories.items() if flagged
    ]
    print("Категории нарушений:", violated_categories)
else:
    print("Контент безопасен")

Пояснение:

  1. client = OpenAI() — инициализация клиента. Ключ API автоматически берётся из переменной окружения OPENAI_API_KEY. Также можно использовать ваш объект клиента в проекте.

  2. model="omni-moderation-latest" — явное указание модели модерации.

  3. input=text_to_check — передаваемый на анализ текст.

  4. result.flagged — главный флаг: True, если обнаружено хотя бы одно нарушение.

  5. Перебор result.categories.items() — получение списка нарушенных категорий.

Проверка с учётом пороговых значений

В реальных проектах часто требуется не просто «да/нет» по факту нарушения, а гибкая настройка чувствительности системы. Например, явно оскорбительные высказывания стоит блокировать при уверенности модели от 0,5, а контент с намёками на насилие — только при оценке выше 0,8.

Для этого используют пороговые значения (threshold) — минимальный уровень уверенности модели (category_scores), при котором нарушение считается подтверждённым.

Как это работает

  1. Модель возвращает числовую оценку уверенности для каждой из 13 категорий (от 0 до 1).

  2. Функция сравнивает каждую оценку с заданным порогом.

  3. Если оценка ≥ порога, категория попадает в список нарушений.

  4. Итоговый флаг flagged устанавливается в True, если есть хотя бы одно нарушение.

Реализация на Python

def moderate_with_threshold(text: str, threshold: float = 0.7) -> dict[str, bool | dict[str, float]]:
    """
    Модерация с настраиваемым порогом для категорий.

    :param text: Текст для проверки
    :type text: str
    :param threshold: Минимальная оценка для блокировки (0.0–1.0)
    :type threshold: float

    :returns: Результаты модерации с деталями:
        - flagged: True, если найдены нарушения ≥ порога
        - violations: словарь категорий и их оценок (только превысившие порог)
        - all_scores: полные оценки по всем категориям
    :rtype: dict[str, bool | dict[str, float]]
    """
    response = client.moderations.create(
        model="omni-moderation-latest",
        input=text
    )

    result = response.results[0]
    violations = {}

    # Сравниваем оценки с порогом
    for category, score in result.category_scores.items():
        if score >= threshold:
            violations[category] = score

    return {
        "flagged": len(violations) > 0,
        "violations": violations,
        "all_scores": result.category_scores
    }

Пример использования

# Проверяем текст с пониженным порогом (0.6)
moderation = moderate_with_threshold(
    text="Потенциально вредный текст с намёками на нарушение",
    threshold=0.6
)

if moderation["flagged"]:
    print(f"Найдены нарушения: {moderation['violations']}")
else:
    print("Контент безопасен")

# Вывод (пример):
# Найдены нарушения: {'violence': 0.68, 'harassment': 0.72}

Практические сценарии настройки порога

  1. Строгая фильтрация (threshold = 0.5):

    • Подходит для детских приложений или соцсетей с нулевой терпимостью к токсичности.

    • Блокирует даже слабые намёки на нарушения.

    • Риск ложных срабатываний выше.

  2. Баланс точности и охвата (threshold = 0.7–0.8):

    • Оптимально для большинства коммерческих сервисов.

    • Снижает ложные срабатывания, сохраняя защиту.

  3. Минимальная фильтрация (threshold = 0.9):

    • Для платформ с высокой терпимостью к спорному контенту (например, дискуссионные форумы).

    • Блокирует только очевидные нарушения.

Важные замечания

  1. Пороги для отдельных категорий. В продвинутых системах пороги задают индивидуально для каждой категории (например, violence ≥ 0.8, а hate ≥ 0.6). Это требует дополнительной логики вне базовой функции.

  2. Интерпретация оценок

    • 0.0–0.3: Низкая вероятность нарушения.

    • 0.3–0.7: Зона неопределённости (рекомендуется ручная модерация).

    • 0.7–1.0: Высокая вероятность нарушения.

  3. Обновление модели. Значения category_scores могут меняться при обновлении omni-moderation-latest. Тестируйте пороги после анонсов OpenAI.

  4. Локализация. Пороги могут требовать корректировки для разных языков, так как модель может демонстрировать разную точность в зависимости от языковой пары.

Модерация изображений

Moderation API от OpenAI поддерживает мультимодальную модерацию — одновременный анализ текста и изображений. Это критически важно для платформ, где пользователи комбинируют разные типы контента (соцсети, форумы, маркетплейсы).

Как работает мультимодальная модерация

  1. Единый запрос — текст и изображения передаются в одном вызове API.

  2. Кросс‑модальный анализ — модель учитывает взаимосвязи (например, текст может «смягчать» шокирующее изображение или, наоборот, усиливать его эффект).

  3. Общие категории нарушений — результаты объединяются по 13 стандартным категориям (см. раздел «Категории модерации»).

  4. Метаданные о типе данных — поле category_applied_input_types показывает, какой компонент (текст/изображение) спровоцировал срабатывание.

Реализация на Python

def moderate_multimodal(text: str = None, image_url: str = None) -> dict[str, bool | dict[str, list[str] | bool]]:
    """
    Модерация текста и/или изображений.

    :param text: Текстовый контент (опционально)
    :type text: str
    :param image_url: URL изображения или base64 строка (опционально)
    :type image_url: str

    :returns: Результаты модерации:
        - flagged: True, если найдено хотя бы одно нарушение
        - categories: словарь нарушенных категорий (только с flagged=True)
        - applied_to: типы данных, вызвавшие срабатывание (текст/изображение)
    :rtype: dict[str, bool | dict[str, list[str] | bool]]
    """
    input_data = []

    # Добавляем текст, если передан
    if text:
        input_data.append({"type": "text", "text": text})

    # Добавляем изображение по URL
    if image_url:
        input_data.append({
            "type": "image_url",
            "image_url": {"url": image_url}
        })

    # Отправка запроса в API
    response = client.moderations.create(
        model="omni-moderation-latest",
        input=input_data
    )

    result = response.results[0]

    return {
        "flagged": result.flagged,
        "categories": {
            cat: flagged
            for cat, flagged in result.categories.items()
            if flagged  # Оставляем только нарушенные категории
        },
        "applied_to": result.category_applied_input_types  # Какие типы данных затронуты
    }

Пример использования

# Проверка комбинации текста и изображения
result = moderate_multimodal(
    text="Смотрите, как это работает!",
    image_url="https://example.com/shocking_image.png"
)

if result["flagged"]:
    print("Найдены нарушения:")
    for category, flagged in result["categories"].items():
        print(f"  - {category} (затронуто: {result['applied_to'].get(category, [])})")
else:
    print("Контент безопасен")

Возможный вывод:

Найдены нарушения:
  - violence (затронуто: ['image'])
  - harassment (затронуто: ['text', 'image'])

Поддерживаемые форматы изображений

  • URL — прямая ссылка на файл (HTTP/HTTPS).

  • Base64 — закодированное изображение (передайте в поле image_url["url"] как строку data:image/png;base64,...).

Требования:

  • Форматы: JPEG, PNG, GIF, WebP.

  • Максимальный размер: 4 МБ.

  • URL должен быть публично доступен для робота OpenAI.

Важные нюансы

  1. Обязательная проверка входных данных. Перед вызовом функции убедитесь, что:

    • text не превышает лимит символов (рекомендуется ≤ 4000 знаков).

    • image_url корректен и доступен.

  2. Интерпретация applied_to. Поле показывает, какой тип данных спровоцировал срабатывание:

    • ["text"] — нарушение найдено только в тексте.

    • ["image"] — только в изображении.

    • ["text", "image"] — комбинация компонентов усилила риск.

  3. Ограничения мультимодального анализа

    • Модель может не распознать текст на изображении (используйте OCR отдельно, если это критично).

    • Для сложных сцен (например, мемов) точность ниже, чем для явных нарушений.

Рекомендации по внедрению

  1. Тестируйте на реальных данных. Соберите набор примеров из вашего домена (соцсеть, чат, маркетплейс) и проверьте, как модель реагирует на пограничные случаи.

  2. Комбинируйте с ручной модерацией. Для категорий с высокой ценой ошибки (например, sexual/minors) настройте эскалацию на человека при flagged = True.

  3. Логируйте ID запросов. Добавляйте response.id [3] в логи для аудита и разбора спорных случаев.

  4. Учитывайте контекст. Для узкоспециализированных платформ (например, медицинские изображения) дополняйте API собственными правилами фильтрации.

Интеграция с обработчиком запросов

Рассмотрим, как внедрить автоматическую модерацию в реальный обработчик пользовательских запросов — например, в API‑сервис или чат‑бота.

Суть решения

Представленный декоратор moderate_input позволяет:

  • прозрачно добавить проверку контента перед обработкой.

  • настраивать чувствительность (порог срабатывания).

  • выбирать категории для контроля (например, только «hate» и «violence»).

  • логировать нарушения для последующего анализа.

  • блокировать запросы, нарушающие политику.

Как это работает

  1. Вы декорируете функцию обработки ввода (process_user_message) декоратором moderate_input.

  2. При вызове функции сначала выполняется модерация переданного текста.

  3. Если найдены нарушения (с оценкой ≥ порога), выбрасывается исключение ValueError.

  4. Если контент безопасен, вызывается оригинальная логика функции.

Разбор кода

import logging
from functools import wraps
from typing import Callable, Any

logger = logging.getLogger(name=__name__)

def moderate_input(
    threshold: float = 0.7, categories: list[str] | None = None
) -> CallableCallable[..., Any, Callable[..., Any]]:
    """
    Декоратор для автоматической модерации входных данных.

    :param threshold: Порог для блокировки (0.0–1.0). По умолчанию 0.7.
    :type threshold: float
    :param categories: Список категорий для проверки. Если None — проверяются все категории.
    :type categories: list[str] | None

    :returns: Декоратор, оборачивающий функцию с проверкой входных данных.
    :rtype: CallableCallable[..., Any, Callable[..., Any]]
    """
    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        @wraps(func)  # Сохраняет метаданные оригинальной функции (имя, докстринг и т.п.)
        def wrapper(user_input: str, *args: Any, **kwargs: Any) -> Any:
            # Отправляем текст на модерацию
            response = client.moderations.create(
                model="omni-moderation-latest",
                input=user_input
            )
            result = response.results[0]

            # Определяем, какие категории проверяем
            check_categories = categories or result.category_scores.keys()

            # Собираем нарушения, превышающие порог
            violations = {
                cat: score
                for cat, score in result.category_scores.items()
                if cat in check_categories and score >= threshold
            }

            # Если есть нарушения — логируем и блокируем
            if violations:
                logger.warning(f"Заблокирован вход с нарушениями: {violations}")
                raise ValueError(f"Контент нарушает политику: {list(violations.keys())}")

            # Если всё ок — вызываем оригинальную функцию
            return func(user_input, *args, **kwargs)

        return wrapper

    return decorator

Пример использования

# Декоратор: проверяем на «hate» и «violence» с порогом 0.6
@moderate_input(threshold=0.6, categories=["hate", "violence"])
def process_user_message(message: str) -> str:
    """Обработка сообщения пользователя."""
    return f"Обработано: {message}"

# Вызов
try:
    result = process_user_message("Безопасное сообщение")
    print(result)  # Обработано: Безопасное сообщение
except ValueError as e:
    print(f"Ошибка модерации: {e}")

# Пример с нарушением
try:
    result = process_user_message("Оскорбительное сообщение с признаками ненависти")
    print(result)
except ValueError as e:
    print(f"Ошибка модерации: {e}")  # Ошибка модерации: Контент нарушает политику: ['hate']

Важные детали реализации

  1. Тип входного параметра. Декоратор ожидает строку (user_input: str). Для других типов (например, списка сообщений) потребуется доработка.

  2. Обработка ошибок API. В примере не учтена возможность ошибок сети или превышения лимитов. В продакшене добавьте обработку ошибок.

  3. Логирование. Убедитесь, что логгер настроен.

  4. Производительность. Каждый вызов добавляет задержку на запрос к API. Для высоконагруженных систем:

    • кэшируйте результаты модерации для повторяющихся текстов.

    • группируйте запросы.

Рекомендации по внедрению

  1. Тестирование Проверьте на наборах данных:

    • безопасные тексты.

    • пограничные случаи (оценки 0.5–0.7).

    • явные нарушения для всех целевых категорий.

  2. Гибкость конфигурации. Храните threshold и categories в настройках приложения, а не в коде:

  3. Аудит и мониторинг Логируйте:

    • ID запроса (из response.id [3]).

    • текст запроса (опционально, с учётом конфиденциальности).

    • найденные нарушения и оценки.

Пакетная модерация с логированием

В реальных проектах часто требуется обрабатывать множество запросов одновременно — например, при модерации чата, комментариев или пользовательского контента в соцсетях. Для таких сценариев удобна пакетная обработка с централизованным логированием и аналитикой.

Ключевые задачи решения

  1. Пакетная проверка — массовая отправка текстов в Moderation API.

  2. Логирование результатов — запись каждого решения для аудита.

  3. Аналитика — сбор статистики по нарушениям (общее число, категории, динамика).

  4. Прозрачность действий — фиксация принятых мер (allowed / blocked).

Реализация

import json
from datetime import datetime
from openai.types import Moderation

class ModerationLogger:
    """Класс для логирования и анализа результатов модерации."""

    def __init__(self, log_file="moderation.log") -> None:
        self.log_file = log_file

    def log_result(self, input_text: str, result: Moderation, action_taken: str) -> None:
        """
        Логирование результата модерации.

        :param input_text: Входной текст (первые 100 символов)
        :type input_text: str
        :param result: Результат модерации от API
        :type result: Moderation
        :param action_taken: Принятое действие ('allowed' / 'blocked')
        :type action_taken: str
        """
        log_entry = {
            "timestamp": datetime.now().isoformat(),
            "input": input_text[:100],  # Ограничиваем длину для компактности
            "flagged": result.flagged,
            "categories": dict(result.categories),
            "scores": dict(result.category_scores),
            "action": action_taken,
        }

        with open(self.log_file, "a", encoding="utf-8") as f:
            f.write(json.dumps(log_entry, ensure_ascii=False) + "n")

    def get_statistics(self) -> dict[str, int | dict[str, int]]:
        """
        Получение статистики модерации.

        :returns: Словарь с:
            - total: общее число проверенных текстов
            - flagged: число заблокированных
            - by_category: статистика по категориям нарушений
        :rtype: dict[str, int | dict[str, int]]
        """
        stats = {"total": 0, "flagged": 0, "by_category": {}}

        try:
            with open(self.log_file, "r", encoding="utf-8") as f:
                for line in f:
                    entry = json.loads(line)
                    stats["total"] += 1

                    if entry["flagged"]:
                        stats["flagged"] += 1
                        for cat, flagged in entry["categories"].items():
                            if flagged:
                                stats["by_category"][cat] = stats["by_category"].get(cat, 0) + 1
        except FileNotFoundError:
            pass  # Если файл лога не существует

        return stats



def batch_moderate(
    texts: list[str], logger: ModerationLogger | None = None
) -> list[dict[str, str | bool | dict[str, bool]]]:
    """
    Пакетная модерация текстов.

    :param texts: Список текстов для проверки
    :type texts: list[str]
    :param logger: Экземпляр ModerationLogger для логирования (опционально)
    :type logger: ModerationLogger | None

    :returns: Список результатов модерации с полями:
        - text: исходный текст
        - flagged: True, если найдено нарушение
        - action: 'allowed' или 'blocked'
        - details: словарь категорий нарушений
    :rtype: list[dict[str, str | bool | dict[str, bool]]]
    """
    results = []

    for text in texts:
        response = client.moderations.create(
            model="omni-moderation-latest",
            input=text
        )
        result = response.results[0]

        # Определяем действие
        action = "blocked" if result.flagged else "allowed"

        # Логируем результат, если передан логгер
        if logger:
            logger.log_result(input_text=text, result=result, action_taken=action)

        results.append({
            "text": text,
            "flagged": result.flagged,
            "action": action,
            "details": result.categories
        })

    return results

Пример использования

# Инициализация логгера
logger = ModerationLogger()

# Список сообщений для проверки
messages = [
    "Привет, как дела?",
    "Потенциально вредное сообщение с угрозами",
    "Ещё один безопасный текст"
]

# Пакетная модерация
results = batch_moderate(texts=messages, logger=logger)

# Вывод результатов
for res in results:
    print(f"Текст: {res['text']}")
    print(f"Статус: {res['action']}")
    if res["flagged"]:
        print(f!Нарушения: {list(res['details'].keys())}")
    print("---")

# Получение статистики
stats = logger.get_statistics()
print(f"nСтатистика:")
print(f"Всего проверено: {stats['total']}")
print(f"Заблокировано: {stats['flagged']}")
print(f"По категориям: {stats['by_category']}")

Вывод (пример):

Текст: Привет, как дела?
Статус: allowed
---
Текст: Потенциально вредное сообщение с угрозами
Статус: blocked
Нарушения: ['harassment/threatening']
---
Текст: Ещё один безопасный текст
Статус: allowed
---

Статистика:
Всего проверено: 3
Заблокировано: 1
По категориям: {'harassment/threatening': 1}

Структура лог‑файла (moderation.log)

Каждая запись — JSON‑строка:

{"timestamp": "2025-11-06T14:15:35.123456", "input": "Привет, как дела?", "flagged": false, "categories": {"hate": false, ...}, "scores": {"hate": 0.001, ...}, "action": "allowed"}

Рекомендации по применению

  1. Ротация логов Для больших объёмов данных:

    • используйте logging.handlers.RotatingFileHandler.

    • настраивайте ротацию по размеру/времени.

  2. Асинхронность В высоконагруженных системах:

    • обрабатывайте пакеты в фоновых задачах (Celery, asyncio, Taskiq).

    • объединяйте запросы в bulk‑вызовы (если API поддерживает).

  3. Конфиденциальность

    • Не логируйте полные тексты, если они содержат персональные данные.

    • Используйте input_text[:N] для ограничения объёма.

  4. Мониторинг Добавляйте метрики в системы мониторинга (Prometheus, Grafana):

    • moderation_total_requests.

    • moderation_blocked_percent.

    • moderation_violations_by_category.

  5. Резервное копирование Регулярно архивируйте лог‑файлы для аудита и расследований.


Заключение

Модерация — отличный (и, что особенно приятно, бесплатный!) инструмент для контроля контента. Она надёжно ограждает систему от нежелательных запросов и ответов агента. Правда, стоит понимать: сама по себе модерация не даёт безграничных возможностей по фильтрации. Её задача — проверять соответствие политике использования OpenAI. Но на основе её результатов можно выстроить гибкую и продуманную систему оценки сообщений.

Помните нашу аналогию с ребёнком, которого пытаются уговорить нарушить правила? Модерация в этой истории — как заботливый родитель, который вовремя говорит «стоп». Она не даёт чужим уловкам сбить систему с пути и сохраняет границы безопасности.

Важные мысли, которые стоит запомнить:

  • Модерация — не рубильник «вкл/выкл», а тонкий инструмент. Это как настройка громкости музыки: если сделать слишком тихо — не услышите угрозы, если слишком громко — будете вздрагивать от каждого шороха. Найдите свой баланс.

  • Логи — ваша суперсила. Они не просто фиксируют нарушения, а рисуют полную картину: показывают, какие темы «болят», какие категории требуют повышенного внимания. Используйте эту информацию на полную.

  • Защита — это марафон, а не забег. Модели постоянно обновляются, злоумышленники изобретают новые трюки. Ваша система защиты тоже должна развиваться — регулярно пересматривайте настройки и стратегии.

Что дальше?

В следующей части мы познакомимся с более гибким и мощным инструментом. Он не просто фильтрует контент — он умеет распознавать атаки на модель и противостоять им. Будет интересно!

Если вам интересны подобные материалы и проекты, подписывайтесь на Telegram-канал «Код на салфетке» [4] — там я делюсь гайдами для новичков и полезными инструментами.

Автор: proDream

Источник [5]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/python/435816

Ссылки в тексте:

[1] «Код на салфетке»: https://t.me/+ltLKpJRXd89lY2Vi

[2] подробный разбор: https://t.me/press_any_button/1341

[3] response.id: http://response.id

[4] «Код на салфетке»: https://t.me/+RuW6ly2M-jg0ZDdi

[5] Источник: https://habr.com/ru/articles/963698/?utm_campaign=963698&utm_source=habrahabr&utm_medium=rss