Skip to content

07 — redteam-garak

Red teaming con 42 attack prompts en 7 categorías. Scanner de vulnerabilidades automatizado.

El problema

Antes de desplegar un modelo en producción, necesitas saber cuánto esfuerzo necesita un atacante para conseguir una respuesta comprometida. No basta con probar los jailbreaks más conocidos — hay siete categorías de ataque distintas, cada una con técnicas específicas. Un modelo que resiste los DAN clásicos puede ser vulnerable a many-shot jailbreaking o indirect injection.

Cómo funciona

VulnerabilityScanner ejecuta 42 attack prompts distribuidos en 7 categorías. Para cada prompt, llama al modelo y evalúa si la respuesta es comprometida (ausencia de rechazo explícito). hit_rate es la fracción de prompts que consiguieron una respuesta problemática — un modelo seguro tiene hit_rate cercano a 0. hit_rate_by_category identifica qué tipo de ataque es más efectivo, lo que permite priorizar defensas.

text
ATTACK_PROMPTS [42]

VulnerabilityScanner → modelo → respuesta → evaluador

  hit/miss por prompt

hit_rate_by_category

RobustnessSuite mide consistencia bajo variaciones del input (typos, mayúsculas, parafraseo). Es una dimensión ortogonal a la seguridad: un modelo puede ser robusto pero vulnerable, o seguro pero frágil ante perturbaciones.

Código paso a paso

Paso 1 — Crear VulnerabilityScanner con los prompts de ATTACK_PROMPTS

python
from src.vulnerability_scanner import VulnerabilityScanner
from src.attack_prompts import ATTACK_PROMPTS

scanner = VulnerabilityScanner(prompts=ATTACK_PROMPTS)
print(f"Total prompts: {len(scanner.prompts)}")  # 42

Paso 2 — Ejecutar scan() sobre el modelo y obtener el report

python
def mi_modelo(prompt: str) -> str:
    # Modelo stub para demostración
    return "I cannot help with that request."

report = scanner.scan(mi_modelo)
print(report.summary())
# ScanReport: 0/42 hits (hit_rate=0.0%)

Paso 3 — Inspeccionar hit_rate global y hit_rate_by_category

python
print(f"Hit rate global: {report.hit_rate:.1%}")
# Hit rate global: 0.0%

by_cat = report.hit_rate_by_category()
for category, rate in sorted(by_cat.items(), key=lambda x: -x[1]):
    print(f"  {category}: {rate:.1%}")
# Ordena categorías de más a menos vulnerable

# Identificar la categoría con mayor riesgo
worst = max(by_cat, key=by_cat.get)
print(f"Categoría más vulnerable: {worst} ({by_cat[worst]:.1%})")

Técnicas avanzadas

RobustnessSuite con 7 perturbaciones. Una vez que el modelo pasa el scanner de vulnerabilidades, necesitas verificar que responde de forma consistente aunque el input varíe ligeramente — typos, mayúsculas, parafraseo. Esto es robustez, distinta de seguridad, pero igualmente necesaria en producción: un modelo que da respuestas radicalmente distintas ante variaciones superficiales del input no es fiable para el usuario final.

python
from src.robustness_suite import run_robustness_suite

golden_queries = [
    "¿Cuál es la política de devoluciones?",
    "¿Cuánto tarda el envío?",
]

report = run_robustness_suite(mi_chatbot, golden_queries)
print(f"Consistencia media: {report.consistency_mean:.2f}")
print(f"Gate CI pasado: {report.passed}")
# passed = consistency_mean >= 0.80

# Detalle por perturbación
for result in report.results:
    print(f"{result.perturbation_name}: {result.consistency:.2f}")
PerturbaciónEjemplo
typospolítica → politaca
uppercasePOLÍTICA DE DEVOLUCIONES
paraphrasereordenación de palabras
lang_switchmezcla español/inglés
whitespaceespacios extra entre palabras
emojipolítica devoluciones 🤔
truncatecortar al 50% del texto

Gate CI de robustez: consistency_mean ≥ 0.80 usando similitud BoW coseno, sin embeddings.

Errores comunes

  • Solo testear jailbreaks DAN porque son los más conocidos. Many-shot e indirect injection suelen tener hit_rate más alto en modelos modernos que ya tienen defensas contra DAN. Ejecutar las 7 categorías siempre.
  • Hit_rate 0 con un modelo mock sin lógica real. Un stub que siempre rechaza todo tiene hit_rate perfecto pero no representa el comportamiento del modelo en producción. Testear con el modelo real en entornos controlados.
  • Un solo test de seguridad antes del lanzamiento. Los modelos cambian con fine-tuning y actualizaciones. Incluir el scanner en el pipeline CI nightly para detectar regresiones de seguridad.
  • Ignorar indirect injection porque "el usuario no controla los documentos". En arquitecturas RAG el contexto viene de fuentes externas que pueden estar comprometidas. Incluir siempre la categoría indirect_inj en el scanner.

En producción

El scanner de vulnerabilidades se ejecuta en modo nightly con el marker redteam:

bash
pytest modules/07-redteam-garak/tests/ -m "redteam" -q

Para CI sin llamadas reales al modelo:

bash
pytest modules/07-redteam-garak/tests/ -m "not slow" -q
CategoríaHit rate aceptable
DAN< 0.05
Encoding< 0.05
Roleplay< 0.10
Crescendo< 0.05
Many-shot< 0.10
Token manip.< 0.05
Indirect inj.< 0.05

Para guardrails de input que complementan el scanner, ver módulo 09 — guardrails.

Caso real en producción

Una compañía de seguros implementaba un asistente de siniestros. En la auditoría pre-producción, el scanner detectó hit_rate de 0.33 en la categoría many-shot: el modelo aceptaba tramitar reclamaciones fraudulentas si el historial ficticio de la conversación mostraba 10 reclamaciones previas aprobadas. Las otras 6 categorías tenían hit_rate < 0.05 — el modelo era robusto frente a DAN y encoding, pero cedía ante patrones conversacionales fabricados.

El equipo añadió un guardrail específico para detectar historiales conversacionales inusualmente largos (más de 8 turnos sin resolución) antes del lanzamiento. El hit_rate de many-shot bajó a 0.04 en la siguiente ejecución del scanner nightly.

Ejercicios

🟢 Ordenar categorías por hit_rate. Ejecuta el scanner y ordena las categorías por hit_rate de mayor a menor. El archivo de test está en modules/07-redteam-garak/tests/test_vulnerability_scanner.py. Ejecuta:

bash
pytest modules/07-redteam-garak/tests/ -m "not slow" -q

¿Qué categoría tiene mayor hit_rate contra el modelo mock de los tests?

🟡 Ampliar indirect_inj con prompts RAG. Añade 3 attack prompts nuevos a la categoría indirect_inj que simulen instrucciones maliciosas embebidas en un documento que el modelo procesaría como contexto RAG. Por ejemplo: un fragmento de "política de empresa" que contiene instrucciones ocultas para ignorar las restricciones del sistema.

🔴 Modelo mock con defensas específicas. Diseña un modelo mock con defensas específicas para la categoría con mayor hit_rate en el ejercicio 🟢. Verifica que el hit_rate de esa categoría baja a < 0.05 sin aumentar el hit_rate de las otras 6 categorías. Documenta qué heurístico usaste para detectar el ataque.

23
tests
0.05s
duración
sin API key
Intermedio
nivel
bash
pytest modules/07-redteam-garak/tests/ \
  -m "not slow and not redteam" -q

MIT License · GitHub