Cuando la Inteligencia Artificial No Responde: Patrones de Resiliencia para Aplicaciones con IA en Producción

Llevas semanas construyendo tu asistente inteligente. Los demos funcionan a la perfección. El modelo responde con precisión, el tiempo de respuesta es aceptable y el cliente está emocionado. Llega el día del despliegue en producción… y tres horas después recibes una llamada: «El sistema de IA no responde».

Bienvenido a la realidad de operar inteligencia artificial en entornos empresariales.

El Problema que Nadie Menciona en los Demos

Cuando hablamos de IA en producción — ya sea un modelo desplegado en Red Hat OpenShift AI, un servicio externo como Amazon Bedrock, Azure OpenAI o cualquier otro proveedor — tendemos a asumir que el modelo siempre va a estar disponible, que siempre va a responder en tiempo razonable y que siempre va a devolver algo útil.

Esa suposición es el primer error.

Los modelos de lenguaje (LLMs) y los servicios de IA en general fallan de formas muy distintas a los servicios tradicionales:

  • Timeouts por carga elevada: Un pico de tráfico puede hacer que el modelo tarde 30, 60 o más segundos en responder — o que simplemente no responda.
  • Respuestas degradadas: El modelo responde, pero con alucinaciones, con formato incorrecto o con contenido fuera del contexto esperado.
  • Límites de tasa (rate limiting): Los proveedores externos imponen cuotas. Cuando las alcanzas, el servicio devuelve errores 429 sin previo aviso.
  • Ventana de contexto excedida: Envías un prompt demasiado largo y el modelo rechaza la solicitud.
  • Indisponibilidad total: El servicio externo tiene una interrupción. Ocurre más seguido de lo que aparece en los SLAs.

El problema no es que la IA falle. El problema es no estar preparado para cuando falle.

Resiliencia en Aplicaciones con IA: Los Patrones que Necesitas

Los mismos patrones que llevan décadas aplicándose en microservicios son perfectamente válidos — y necesarios — en aplicaciones con IA. La diferencia está en cómo se implementan y qué constituye una «respuesta de fallback» cuando el componente que falla es un modelo de lenguaje.

1. Circuit Breaker: Protege el Sistema Aguas Arriba

El Circuit Breaker es quizás el patrón más importante cuando integras servicios de IA. Si el modelo está tardando demasiado o devolviendo errores repetidamente, el circuito se «abre» y las solicitudes subsiguientes no llegan al modelo — evitando que el problema se propague a toda la aplicación.

En Quarkus, con SmallRye Fault Tolerance, esto es directo:

@POST
@Path("/analizar")
@CircuitBreaker(
    requestVolumeThreshold = 10,
    failureRatio = 0.5,
    delay = 5000,
    successThreshold = 2
)
@Fallback(fallbackMethod = "respuestaManual")
public AnalisisRiesgo analizarSolicitudCredito(SolicitudCredito solicitud) {
    return modeloRiesgo.evaluar(solicitud);
}

public AnalisisRiesgo respuestaManual(SolicitudCredito solicitud) {
    // Fallback: reglas determinísticas o respuesta de degradación controlada
    return AnalisisRiesgo.evaluacionManual(solicitud);
}

Lo clave aquí es el método respuestaManual. No es un error — es una degradación controlada. El sistema sigue funcionando, aunque de forma más limitada.

2. Timeout + Retry con Backoff Exponencial

Los LLMs tienen latencias variables. Una respuesta que normalmente llega en 2 segundos puede tardar 20 bajo carga. Sin un timeout explícito, tu hilo queda bloqueado indefinidamente.

@Timeout(value = 8, unit = ChronoUnit.SECONDS)
@Retry(
    maxRetries = 2,
    delay = 1000,
    delayUnit = ChronoUnit.MILLIS,
    jitter = 200,
    retryOn = { TimeoutException.class, ModelUnavailableException.class }
)
public String generarResumen(String texto) {
    return llmClient.completar(texto);
}

El jitter es importante: evita que todos los reintentos simultáneos golpeen el servicio exactamente al mismo tiempo (el llamado «efecto tormenta»).

3. Bulkhead: Aísla el Impacto

Si tienes múltiples flujos que usan IA — procesamiento de documentos, atención al cliente, análisis de riesgo — un problema en uno no debería derribar los otros. El patrón Bulkhead limita el número de llamadas concurrentes por funcionalidad:

@Bulkhead(value = 5, waitingTaskQueue = 10)
public ClasificacionDocumento clasificarDocumento(byte[] documento) {
    return modeloDocumentos.clasificar(documento);
}

Esto es especialmente crítico en contextos bancarios, donde el procesamiento de documentos regulatorios y la atención al cliente deben operar de forma independiente.

4. Fallback Estratégico: No Todos los Fallbacks Son Iguales

Un fallback no siempre es un mensaje de error genérico. Dependiendo del contexto, puede ser:

Contexto Fallback Adecuado
Asistente de atención al cliente Derivar a agente humano
Análisis de riesgo crediticio Aplicar reglas determinísticas del motor legacy
Generación de resúmenes Devolver el texto original sin procesar
Clasificación de documentos Marcar como «requiere revisión manual»
Detección de fraude Aplicar modelo estadístico tradicional (no LLM)

El diseño del fallback es una decisión de negocio, no solo técnica. Involucra a los equipos funcionales.

IA Local vs. IA en la Nube: Implicancias de Disponibilidad

Uno de los argumentos más sólidos para desplegar modelos on-premise — usando, por ejemplo, Red Hat OpenShift AI con modelos servidos a través de vLLM o OpenVINO Model Server — es precisamente el control sobre la disponibilidad.

Con un proveedor externo como OpenAI o Amazon Bedrock:

  • No controlas las ventanas de mantenimiento.
  • No controlas la degradación del servicio.
  • Los datos salen de tu infraestructura (relevante para bancos bajo la supervisión de la SBS en Perú).

Con un modelo desplegado en tu propio clúster OpenShift:

  • Controlas el escalado (puedes configurar HPA sobre las réplicas del servidor de inferencia).
  • Controlas la disponibilidad con múltiples réplicas y readiness probes.
  • Los datos nunca salen de tu infraestructura.

La contrapartida es la responsabilidad operativa: tú gestionas los recursos de GPU, los modelos, las actualizaciones. No hay almuerzo gratis.

Observabilidad: No Puedes Mejorar Lo que No Mides

Cuando la IA falla, ¿cómo te enteras? ¿Por una llamada del cliente? ¿Por un ticket de soporte? Eso es inaceptable en producción.

Las métricas mínimas que deberías tener en cualquier integración con IA:

# Tasa de éxito de llamadas al modelo
ia_llamadas_total{estado="exitoso|fallido|timeout"}

# Latencia por percentil
ia_latencia_segundos_p50
ia_latencia_segundos_p95
ia_latencia_segundos_p99

# Estado del Circuit Breaker
ia_circuit_breaker_estado{servicio="modelo-riesgo", estado="cerrado|abierto|semiabierto"}

# Activaciones de fallback
ia_fallback_activaciones_total{motivo="timeout|error|circuito_abierto"}

# Calidad de respuesta (si aplica scoring)
ia_respuesta_confianza_promedio

En OpenShift, estas métricas pueden exponerse a través de Micrometer y ser recolectadas por el stack de Prometheus + Grafana que ya tienes en tu clúster — o integrarse con Red Hat OpenShift Monitoring.

El Caso de los Bancos y Aseguradoras

Las instituciones financieras tienen un contexto particular:

Regulación: La SBS en Perú — y reguladores equivalentes en la región — exigen que los sistemas críticos tengan planes de continuidad. Un sistema de IA que no tiene fallback no cumple con los requisitos de un BCP (Business Continuity Plan).

Auditoría: Si tu modelo de scoring o clasificación falla y no tienes registro de qué pasó, cuándo pasó y qué hizo el sistema en su lugar, tienes un problema de auditoría — no solo técnico.

Confianza del usuario final: En un contexto de banca digital, si el asistente inteligente falla y el usuario no recibe ninguna respuesta útil, la percepción es que el banco falló — no que la IA falló. La experiencia de degradación controlada debe ser indistinguible de la operación normal para el usuario final.

Lista de Verificación: ¿Tu Aplicación con IA Está Lista para Producción?

Antes de desplegar cualquier integración con IA en un entorno productivo, revisa esto:

  • [ ] ¿Tienes timeout configurado? Ninguna llamada a un LLM debe ser indefinida.
  • [ ] ¿Tienes Circuit Breaker? El modelo puede fallar en cascada. Protege el resto del sistema.
  • [ ] ¿Tienes fallback definido con el equipo de negocio? No improvises el fallback en el código.
  • [ ] ¿Estás midiendo latencia, tasa de error y calidad de respuesta?
  • [ ] ¿Tu fallback está auditado y registrado? Cada activación del fallback debe quedar en el log.
  • [ ] ¿Tienes pruebas de caos? Deshabilita el servicio de IA en staging y verifica que el fallback funciona como se espera.
  • [ ] ¿El equipo de operaciones sabe qué hacer cuando el modelo falla? Un runbook no es opcional.

La inteligencia artificial no es diferente a cualquier otro componente de software distribuido: fallará. La pregunta no es si va a fallar, sino cuándo, y si tu aplicación está diseñada para manejar ese momento con elegancia.

Los patrones que hemos revisado — Circuit Breaker, Timeout, Retry, Bulkhead, Fallback estratégico — no son nuevos. Lo que es nuevo es aplicarlos conscientemente en el contexto de sistemas de IA, donde las formas de fallo son más variadas y a veces más sutiles que en los servicios tradicionales.

La resiliencia no es una característica que se agrega al final. Es una decisión de arquitectura que se toma desde el primer día.

 

 

Añadir un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *