Visita nuestro libro de recetas de moderación de contenido para ver un ejemplo de implementación de moderación de contenido usando Claude.

Esta guía está enfocada en moderar contenido generado por usuarios dentro de tu aplicación. Si buscas orientación sobre cómo moderar interacciones con Claude, consulta nuestra guía de barreras de protección.

Antes de construir con Claude

Decide si usar Claude para la moderación de contenido

Aquí hay algunos indicadores clave de que deberías usar un LLM como Claude en lugar de un enfoque tradicional basado en ML o reglas para la moderación de contenido:

Anthropic ha entrenado todos los modelos de Claude para ser honestos, útiles e inofensivos. Esto puede resultar en que Claude modere contenido considerado particularmente peligroso (en línea con nuestra Política de Uso Aceptable), independientemente del prompt utilizado. Por ejemplo, un sitio web para adultos que quiere permitir a los usuarios publicar contenido sexual explícito puede encontrar que Claude aún marca el contenido explícito como que requiere moderación, incluso si especifican en su prompt que no modere contenido sexual explícito. Recomendamos revisar nuestra AUP antes de construir una solución de moderación.

Genera ejemplos de contenido para moderar

Antes de desarrollar una solución de moderación de contenido, primero crea ejemplos de contenido que debería ser marcado y contenido que no debería ser marcado. Asegúrate de incluir casos límite y escenarios desafiantes que puedan ser difíciles de manejar efectivamente para un sistema de moderación de contenido. Después, revisa tus ejemplos para crear una lista bien definida de categorías de moderación. Por ejemplo, los ejemplos generados por una plataforma de redes sociales podrían incluir lo siguiente:

allowed_user_comments = [
    'Esta película fue genial, realmente la disfruté. ¡El actor principal realmente la mató!',
    'Odio los lunes.',
    '¡Es un buen momento para invertir en oro!'
]

disallowed_user_comments = [
    'Borra esta publicación ahora o mejor escóndete. Voy por ti y tu familia.',
    '¡Mantente alejado de los teléfonos celulares 5G! Están usando el 5G para controlarte.',
    '¡Felicidades! Has ganado una tarjeta de regalo de $1,000. Haz clic aquí para reclamar tu premio.'
]

# Comentarios de usuario de muestra para probar la moderación de contenido
user_comments = allowed_user_comments + disallowed_user_comments

# Lista de categorías consideradas inseguras para la moderación de contenido
unsafe_categories = [
    'Explotación Infantil',
    'Teorías de Conspiración',
    'Odio',
    'Armas Indiscriminadas', 
    'Propiedad Intelectual',
    'Crímenes No Violentos', 
    'Privacidad',
    'Autolesión',
    'Crímenes Sexuales',
    'Contenido Sexual',
    'Asesoramiento Especializado',
    'Crímenes Violentos'
]

Moderar efectivamente estos ejemplos requiere una comprensión matizada del lenguaje. En el comentario, Esta película fue genial, realmente la disfruté. ¡El actor principal realmente la mató!, el sistema de moderación de contenido necesita reconocer que “la mató” es una metáfora, no una indicación de violencia real. Por el contrario, a pesar de la falta de menciones explícitas de violencia, el comentario Borra esta publicación ahora o mejor escóndete. Voy por ti y tu familia. debería ser marcado por el sistema de moderación de contenido.

La lista unsafe_categories puede ser personalizada para adaptarse a tus necesidades específicas. Por ejemplo, si deseas evitar que menores creen contenido en tu sitio web, podrías añadir “Publicación de Menores de Edad” a la lista.


Cómo moderar contenido usando Claude

Selecciona el modelo Claude adecuado

Al seleccionar un modelo, es importante considerar el tamaño de tus datos. Si los costos son una preocupación, un modelo más pequeño como Claude Haiku 3 es una excelente opción debido a su rentabilidad. A continuación se muestra una estimación del costo para moderar texto para una plataforma de redes sociales que recibe mil millones de publicaciones por mes:

  • Tamaño del contenido

    • Publicaciones por mes: 1bn
    • Caracteres por publicación: 100
    • Total de caracteres: 100bn
  • Tokens estimados

    • Tokens de entrada: 28.6bn (asumiendo 1 token por cada 3.5 caracteres)
    • Porcentaje de mensajes marcados: 3%
    • Tokens de salida por mensaje marcado: 50
    • Total de tokens de salida: 1.5bn
  • Costo estimado de Claude Haiku 3

    • Costo de tokens de entrada: 2,860 MTok * $0.25/MTok = $715
    • Costo de tokens de salida: 1,500 MTok * $1.25/MTok = $1,875
    • Costo mensual: $715 + $1,875 = $2,590
  • Costo estimado de Claude Sonnet 4

    • Costo de tokens de entrada: 2,860 MTok * $3.00/MTok = $8,580
    • Costo de tokens de salida: 1,500 MTok * $15.00/MTok = $22,500
    • Costo mensual: $8,580 + $22,500 = $31,080
Los costos reales pueden diferir de estas estimaciones. Estas estimaciones se basan en el prompt destacado en la sección sobre procesamiento por lotes. Los tokens de salida pueden reducirse aún más eliminando el campo explanation de la respuesta.

Construye un prompt sólido

Para usar Claude para la moderación de contenido, Claude debe entender los requisitos de moderación de tu aplicación. Comencemos escribiendo un prompt que te permita definir tus necesidades de moderación:

import anthropic
import json

# Inicializa el cliente de Anthropic
client = anthropic.Anthropic()

def moderate_message(message, unsafe_categories):
    # Convierte la lista de categorías inseguras en una cadena, con cada categoría en una nueva línea
    unsafe_category_str = '\n'.join(unsafe_categories)
    
    # Construye el prompt para Claude, incluyendo el mensaje y las categorías inseguras
    assessment_prompt = f"""
    Determina si el siguiente mensaje requiere moderación, 
    basado en las categorías inseguras descritas a continuación.
    
    Mensaje:
    <message>{message}</message>

    Categorías Inseguras:
    <categories>
    {unsafe_category_str}
    </categories>

    Responde SOLO con un objeto JSON, utilizando el formato a continuación:
    {{
    "violation": <Campo booleano que indica si el mensaje debe ser moderado>,
    "categories": [Lista separada por comas de categorías violadas],
    "explanation": [Opcional. Solo incluir si hay una violación.]
    }}"""

    # Envía la solicitud a Claude para la moderación de contenido
    response = client.messages.create(
        model="claude-3-haiku-20240307",  # Usando el modelo Haiku para costos más bajos
        max_tokens=200,
        temperature=0,   # Usa temperatura 0 para mayor consistencia
        messages=[
            {"role": "user", "content": assessment_prompt}
        ]
    )
    
    # Analiza la respuesta JSON de Claude
    assessment = json.loads(response.content[0].text)
    
    # Extrae el estado de violación de la evaluación
    contains_violation = assessment['violation']
    
    # Si hay una violación, obtén las categorías y la explicación; de lo contrario, usa valores predeterminados vacíos
    violated_categories = assessment.get('categories', []) if contains_violation else []
    explanation = assessment.get('explanation') if contains_violation else None
    
    return contains_violation, violated_categories, explanation

# Procesa cada comentario e imprime los resultados
for comment in user_comments:
    print(f"\nComentario: {comment}")
    violation, violated_categories, explanation = moderate_message(comment, unsafe_categories)
    
    if violation:
        print(f"Categorías Violadas: {', '.join(violated_categories)}")
        print(f"Explicación: {explanation}")
    else:
        print("No se detectaron problemas.")

En este ejemplo, la función moderate_message contiene un prompt de evaluación que incluye las categorías de contenido inseguro y el mensaje que deseamos evaluar. El prompt le pide a Claude que evalúe si el mensaje debe ser moderado, basado en las categorías inseguras que definimos.

La evaluación del modelo se analiza luego para determinar si hay una violación. Si hay una violación, Claude también devuelve una lista de categorías violadas, así como una explicación de por qué el mensaje es inseguro.

Evalúa tu prompt

La moderación de contenido es un problema de clasificación. Por lo tanto, puedes usar las mismas técnicas descritas en nuestro libro de recetas de clasificación para determinar la precisión de tu sistema de moderación de contenido.

Una consideración adicional es que en lugar de tratar la moderación de contenido como un problema de clasificación binaria, puedes crear múltiples categorías para representar varios niveles de riesgo. Crear múltiples niveles de riesgo te permite ajustar la agresividad de tu moderación. Por ejemplo, es posible que desees bloquear automáticamente las consultas de usuarios que se consideren de alto riesgo, mientras que los usuarios con muchas consultas de riesgo medio son marcados para revisión humana.

import anthropic
import json

# Inicializa el cliente de Anthropic
client = anthropic.Anthropic()

def assess_risk_level(message, unsafe_categories):
    # Convierte la lista de categorías inseguras en una cadena, con cada categoría en una nueva línea
    unsafe_category_str = '\n'.join(unsafe_categories)
    
    # Construye el prompt para Claude, incluyendo el mensaje, las categorías inseguras y las definiciones de nivel de riesgo
    assessment_prompt = f"""
    Evalúa el nivel de riesgo del siguiente mensaje que requiere moderación, 
    basado en las categorías inseguras enumeradas a continuación.
    
Mensaje:
<message>{message}</message>

Categorías Inseguras:
<categories>
{unsafe_category_str}
</categories>

Asigna un nivel de riesgo basado en tu confianza de que el mensaje del usuario debe ser moderado 
según las categorías inseguras definidas:

0 - Sin riesgo
1 - Riesgo bajo
2 - Riesgo medio
3 - Riesgo alto

Responde SOLO con un objeto JSON, utilizando el formato a continuación:
{{
  "risk_level": <Campo numérico que denota el nivel de riesgo>,
  "categories": [Lista separada por comas de categorías violadas],
  "explanation": <Opcional. Solo incluir si el nivel de riesgo es mayor que 0>
}}"""

    # Envía la solicitud a Claude para la evaluación de riesgo
    response = client.messages.create(
        model="claude-3-haiku-20240307",  # Usando el modelo Haiku para costos más bajos
        max_tokens=200,
        temperature=0,   # Usa temperatura 0 para mayor consistencia
        messages=[
            {"role": "user", "content": assessment_prompt}
        ]
    )
    
    # Analiza la respuesta JSON de Claude
    assessment = json.loads(response.content[0].text)
    
    # Extrae el nivel de riesgo, las categorías violadas y la explicación de la evaluación
    risk_level = assessment["risk_level"]
    violated_categories = assessment["categories"]
    explanation = assessment.get("explanation")
    
    return risk_level, violated_categories, explanation

# Procesa cada comentario e imprime los resultados
for comment in user_comments:
    print(f"\nComentario: {comment}")
    risk_level, violated_categories, explanation = assess_risk_level(comment, unsafe_categories)
    
    print(f"Nivel de Riesgo: {risk_level}")
    if violated_categories:
        print(f"Categorías Violadas: {', '.join(violated_categories)}")
    if explanation:
        print(f"Explicación: {explanation}")

Este código implementa una función assess_risk_level que utiliza Claude para evaluar el nivel de riesgo de un mensaje. La función acepta un mensaje y una lista de categorías inseguras como entradas.

Dentro de la función, se genera un prompt para Claude, que incluye el mensaje a evaluar, las categorías inseguras e instrucciones específicas para evaluar el nivel de riesgo. El prompt instruye a Claude a responder con un objeto JSON que incluye el nivel de riesgo, las categorías violadas y una explicación opcional.

Este enfoque permite una moderación de contenido flexible mediante la asignación de niveles de riesgo. Se puede integrar perfectamente en un sistema más grande para automatizar el filtrado de contenido o marcar comentarios para revisión humana según su nivel de riesgo evaluado. Por ejemplo, al ejecutar este código, el comentario Borra esta publicación ahora o mejor escóndete. Voy por ti y tu familia. se identifica como de alto riesgo debido a su peligrosa amenaza. Por el contrario, el comentario ¡Mantente alejado de los teléfonos celulares 5G! Están usando el 5G para controlarte. se categoriza como de riesgo medio.

Implementa tu prompt

Una vez que estés seguro de la calidad de tu solución, es hora de implementarla en producción. Aquí hay algunas mejores prácticas a seguir cuando se usa la moderación de contenido en producción:

  1. Proporciona retroalimentación clara a los usuarios: Cuando la entrada del usuario es bloqueada o una respuesta es marcada debido a la moderación de contenido, proporciona retroalimentación informativa y constructiva para ayudar a los usuarios a entender por qué su mensaje fue marcado y cómo pueden reformularlo adecuadamente. En los ejemplos de código anteriores, esto se hace a través de la etiqueta explanation en la respuesta de Claude.

  2. Analiza el contenido moderado: Mantén un registro de los tipos de contenido que está marcando tu sistema de moderación para identificar tendencias y áreas potenciales de mejora.

  3. Evalúa y mejora continuamente: Evalúa regularmente el rendimiento de tu sistema de moderación de contenido utilizando métricas como el seguimiento de precisión y exhaustividad. Utiliza estos datos para refinar iterativamente tus prompts de moderación, palabras clave y criterios de evaluación.


Mejora el rendimiento

En escenarios complejos, puede ser útil considerar estrategias adicionales para mejorar el rendimiento más allá de las técnicas estándar de ingeniería de prompts. Aquí hay algunas estrategias avanzadas:

Define temas y proporciona ejemplos

Además de enumerar las categorías inseguras en el prompt, se pueden realizar mejoras adicionales proporcionando definiciones y frases relacionadas con cada categoría.

import anthropic
import json

# Inicializa el cliente de Anthropic
client = anthropic.Anthropic()

# Diccionario de categorías consideradas inseguras para la moderación de contenido, con sus definiciones
unsafe_category_definitions = {
    'Explotación Infantil': 'Contenido que muestra desnudez infantil o que permite, fomenta, excusa o representa el abuso sexual de niños.',
    'Teorías de Conspiración': """Contenido que promueve o respalda teorías infundadas, falsas o engañosas sobre eventos, situaciones o individuos, 
        que pueden incitar daño o socavar la confianza pública en instituciones o hechos.""",
    'Odio': """Contenido que es odioso hacia personas en base a sus características protegidas 
        (raza, color, etnia, origen nacional, discapacidad, afiliación religiosa, casta, orientación sexual, sexo, identidad de género y enfermedades graves), 
        o contenido que perpetúa estereotipos negativos.""",
    'Armas Indiscriminadas': 'Contenido que permite la creación de armas de destrucción masiva.', 
    'Propiedad Intelectual': 'Contenido que viola los derechos de propiedad intelectual de terceros.',
    'Crímenes No Violentos': 'Contenido que permite, fomenta o excusa la comisión de crímenes no violentos.', 
    'Privacidad': 'Contenido que contiene información personal sensible sobre individuos privados.',
    'Autolesión': 'Contenido que permite, fomenta o excusa actos de autolesión intencional.',
    'Crímenes Sexuales': 'Contenido que permite, fomenta o excusa la comisión de crímenes sexuales.',
    'Contenido Sexual': 'Contenido que contiene descripciones eróticas o representaciones explícitas de actos sexuales.',
    'Asesoramiento Especializado': """Contenido que contiene asesoramiento financiero, médico o legal. 
        El asesoramiento financiero incluye orientación sobre inversiones, acciones, bonos o cualquier planificación financiera.""",
    'Crímenes Violentos': 'Contenido que permite, fomenta o excusa la comisión de crímenes violentos.', 
}


def moderate_message_with_definitions(message, unsafe_category_definitions):
    # Formatea la cadena de categorías inseguras, con cada categoría y su definición en una nueva línea
    unsafe_category_str = '\n'.join(f'{category}: {definition}' 
        for category, definition in unsafe_category_definitions.items()
    )
    
    # Construye el prompt para Claude, incluyendo el mensaje y las categorías inseguras
    assessment_prompt = f"""Determina si el siguiente mensaje requiere moderación, basado en las categorías inseguras descritas a continuación.

Mensaje:
<message>{message}</message>

Categorías Inseguras y Sus Definiciones:
<categories>
{unsafe_category_str}
</categories>

Es importante que recuerdes todas las categorías inseguras y sus definiciones.

Responde SOLO con un objeto JSON, utilizando el formato a continuación:
{{
  "violation": <Campo booleano que indica si el mensaje debe ser moderado>,
  "categories": [Lista separada por comas de categorías violadas],
  "explanation": [Opcional. Solo incluir si hay una violación.]
}}"""

    # Envía la solicitud a Claude para la moderación de contenido
    response = client.messages.create(
        model="claude-3-haiku-20240307",  # Usando el modelo Haiku para costos más bajos
        max_tokens=200,
        temperature=0,   # Usa temperatura 0 para mayor consistencia
        messages=[
            {"role": "user", "content": assessment_prompt}
        ]
    )
    
    # Analiza la respuesta JSON de Claude
    assessment = json.loads(response.content[0].text)
    
    # Extrae el estado de violación de la evaluación
    contains_violation = assessment['violation']
    
    # Si hay una violación, obtén las categorías y la explicación; de lo contrario, usa valores predeterminados vacíos
    violated_categories = assessment.get('categories', []) if contains_violation else []
    explanation = assessment.get('explanation') if contains_violation else None
    
    return contains_violation, violated_categories, explanation


# Procesa cada comentario e imprime los resultados
for comment in user_comments:
    print(f"\nComentario: {comment}")
    violation, violated_categories, explanation = moderate_message_with_definitions(comment, unsafe_category_definitions)
    
    if violation:
        print(f"Categorías Violadas: {', '.join(violated_categories)}")
        print(f"Explicación: {explanation}")
    else:
        print("No se detectaron problemas.")

La función moderate_message_with_definitions amplía la función anterior moderate_message al permitir que cada categoría insegura se empareje con una definición detallada. Esto ocurre en el código al reemplazar la lista unsafe_categories de la función original con un diccionario unsafe_category_definitions. Este diccionario mapea cada categoría insegura a su definición correspondiente. Tanto los nombres de las categorías como sus definiciones se incluyen en el prompt.

Notablemente, la definición para la categoría Asesoramiento Especializado ahora especifica los tipos de asesoramiento financiero que deberían estar prohibidos. Como resultado, el comentario ¡Es un buen momento para invertir en oro!, que anteriormente pasó la evaluación de moderate_message, ahora desencadena una violación.

Considera el procesamiento por lotes

Para reducir costos en situaciones donde la moderación en tiempo real no es necesaria, considera moderar mensajes en lotes. Incluye múltiples mensajes dentro del contexto del prompt y pide a Claude que evalúe qué mensajes deben ser moderados.

import anthropic
import json

# Inicializa el cliente de Anthropic
client = anthropic.Anthropic()

def batch_moderate_messages(messages, unsafe_categories):
    # Convierte la lista de categorías inseguras en una cadena, con cada categoría en una nueva línea
    unsafe_category_str = '\n'.join(unsafe_categories)
    
    # Formatea la cadena de mensajes, con cada mensaje envuelto en etiquetas tipo XML y con un ID
    messages_str = '\n'.join([f'<message id={idx}>{msg}</message>' for idx, msg in enumerate(messages)])
    
    # Construye el prompt para Claude, incluyendo los mensajes y las categorías inseguras
    assessment_prompt = f"""Determina los mensajes a moderar, basado en las categorías inseguras descritas a continuación.

Mensajes:
<messages>
{messages_str}
</messages>

Categorías inseguras y sus definiciones:
<categories>
{unsafe_category_str}
</categories>

Responde SOLO con un objeto JSON, utilizando el formato a continuación:
{{
  "violations": [
    {{
      "id": <id del mensaje>,
      "categories": [lista de categorías violadas],
      "explanation": <Explicación de por qué hay una violación>
    }},
    ...
  ]
}}

Notas Importantes:
- Recuerda analizar cada mensaje para detectar una violación.
- Selecciona cualquier número de violaciones que se apliquen razonablemente."""

    # Envía la solicitud a Claude para la moderación de contenido
    response = client.messages.create(
        model="claude-3-haiku-20240307",  # Usando el modelo Haiku para costos más bajos
        max_tokens=2048,  # Aumenta el recuento máximo de tokens para manejar lotes
        temperature=0,    # Usa temperatura 0 para mayor consistencia
        messages=[
            {"role": "user", "content": assessment_prompt}
        ]
    )
    
    # Analiza la respuesta JSON de Claude
    assessment = json.loads(response.content[0].text)
    return assessment


# Procesa el lote de comentarios y obtén la respuesta
response_obj = batch_moderate_messages(user_comments, unsafe_categories)

# Imprime los resultados para cada violación detectada
for violation in response_obj['violations']:
    print(f"""Comentario: {user_comments[violation['id']]}
Categorías Violadas: {', '.join(violation['categories'])}
Explicación: {violation['explanation']}
""")

En este ejemplo, la función batch_moderate_messages maneja la moderación de un lote completo de mensajes con una sola llamada a la API de Claude. Dentro de la función, se crea un prompt que incluye la lista de mensajes a evaluar, las categorías de contenido inseguro definidas y sus descripciones. El prompt dirige a Claude a devolver un objeto JSON que enumera todos los mensajes que contienen violaciones. Cada mensaje en la respuesta se identifica por su id, que corresponde a la posición del mensaje en la lista de entrada. Ten en cuenta que encontrar el tamaño de lote óptimo para tus necesidades específicas puede requerir algo de experimentación. Si bien los tamaños de lote más grandes pueden reducir los costos, también podrían conducir a una ligera disminución en la calidad. Además, es posible que debas aumentar el parámetro max_tokens en la llamada a la API de Claude para acomodar respuestas más largas. Para obtener detalles sobre el número máximo de tokens que tu modelo elegido puede generar, consulta la página de comparación de modelos.