Deploy de Agentes — Módulo 14: rollout y confiabilidad
Módulo final del Curso de Deploy de Agentes: cómo cambiar tu agente en producción sin caídas. Versionar prompts y modelos, canary y feature flags, blue-green, rollback rápido. Confiabilidad con retries con backoff, timeouts, circuit breaker y fallbacks. El runbook, el checklist de producción completo y el mapa de los 14 módulos.
☰ Índice del contenido
En el módulo anterior le pusimos ojos y candados a tu agente: ya ves lo que pasa y proteges lo que corre. Queda lo último — y lo más delicado de todo el curso. Tu agente está en producción, usuarios reales dependen de él, y necesitas cambiarlo: ajustar un prompt, subir de modelo, corregir un bug. En un prototipo eso es guardar el archivo. En producción, un cambio a ciegas puede tumbar el servicio para todos a la vez. Este módulo cierra el curso enseñando lo que separa a un equipo que despliega con miedo de uno que despliega los viernes: rollout controlado y confiabilidad.
La tesis del módulo
En producción no existe “guardar el archivo”: existe liberar de a poco y poder volver atrás en segundos. La confiabilidad no es que nada falle — es que cuando algo falla, tu agente degrada con gracia en vez de morir. Cambiar con red y fallar con red: ese es el oficio.
Rollout seguro: versionar, liberar de a poco, volver atrás
1. Versiona prompts y modelos. Este es el punto que más gente ignora: un prompt es código, y cambiar de modelo cambia el comportamiento (glosado: el prompt del sistema y el modelo que usas definen cómo responde tu agente tanto como tu .py; por eso ambos van versionados y con capacidad de volver atrás, igual que cualquier commit). Si cambiaste el prompt el martes y el agente empeoró el miércoles, sin versión no sabes qué tocaste. Un prompt vive en el repositorio, con su número de versión, no pegado en el código a mano.
import os
# Prompts versionados como artefacto, no como string suelto en el código.
# Cambiar de versión es explícito, auditable y reversible: si la v3
# empeora las respuestas, vuelves a la v2 cambiando una variable.
PROMPTS = {
"v2": "Eres un asistente de soporte. Responde breve y con datos.",
"v3": "Eres un asistente de soporte. Responde breve, con datos, "
"y cita la fuente cuando exista.",
}
# La versión activa se controla por entorno (o por feature flag), no
# editando código. Así el rollout y el rollback son cambiar un valor.
PROMPT_ACTIVO = os.environ.get("PROMPT_VERSION", "v2")
def system_prompt() -> str:
return PROMPTS[PROMPT_ACTIVO]
2. Libera de a poco. Nadie sensato manda un cambio al 100% de los usuarios de golpe. Tres técnicas, de menor a mayor infraestructura:
- Feature flags (glosado: interruptores que encienden o apagan una función sin volver a desplegar; cambias un valor y la nueva conducta entra o sale al instante). El control más fino: activas el prompt v3 solo para el 5% de los usuarios, miras las métricas, subes si va bien.
- Canary (glosado: liberar la versión nueva a una fracción pequeña del tráfico — el “canario en la mina” — y vigilar; si las métricas empeoran, cortas antes de que afecte a todos). El nombre viene de los canarios que los mineros bajaban para detectar gas: si el pájaro sufría, salían a tiempo.
- Blue-green (glosado: mantener dos entornos idénticos — blue el actual, green el nuevo; despliegas y pruebas en green, y cuando está listo rediriges todo el tráfico de golpe; si algo falla, vuelves a blue al instante). Cero downtime y rollback inmediato, a costa de correr dos entornos.
3. Rollback rápido. Rollback (glosado: volver a la versión anterior conocida-buena en cuanto la nueva da problemas). La métrica que importa no es “cuánto tardas en desplegar” sino “cuánto tardas en volver atrás”. Si tu rollback toma media hora, media hora estuviste roto. Un buen rollback es cambiar una variable o reapuntar el tráfico: segundos.
liberación gradual con canary
┌──────────────────────┐
│ despliegas v_nueva │
│ 5% tráfico / 95% v. │
└──────────┬───────────┘
▼
¿métricas ok?
│
┌─────┴─────┐
▼ ▼
┌─────┐ ┌────────────────┐
│ NO │ │ SÍ │
│ │ │ sube a 50%, │
│roll-│ │ luego a 100% │
│back │ └────────────────┘
└─────┘
vuelve a v_actual
Confiabilidad: degradar con gracia, no morir
El rollout es cómo cambias sin romper. La confiabilidad es cómo sigues en pie cuando algo externo falla — el LLM tarda, la API cae, una tool no responde. Cuatro herramientas que se combinan.
Retries con backoff (glosado: reintentar una llamada que falló, pero esperando cada vez más entre intentos — backoff exponencial — para no golpear un servicio ya caído). Reintentar de inmediato y en bucle es echarle gasolina al fuego; esperar 1 s, 2 s, 4 s le da aire al servicio para recuperarse.
Timeouts (glosado: un tope de tiempo para cada llamada; si se pasa, se corta). Sin timeout, una API colgada deja a tu agente esperando para siempre y arrastra a todos los requests detrás. Todo lo que sale a la red lleva timeout, sin excepción.
Circuit breaker (glosado: un “cortacircuitos” que, tras varios fallos seguidos de un servicio, deja de llamarlo por un rato y responde al tiro con el fallback; así no gastas tiempo ni dinero golpeando algo que ya sabes que está caído). Cuando el servicio se recupera, el breaker vuelve a dejar pasar.
Fallbacks (glosado: degradar a otro modelo o a una respuesta más simple cuando algo falla — mejor una respuesta modesta que un error). Si el modelo principal cae, caes a uno más barato; si ese también, respondes un mensaje honesto de “no disponible” en vez de un error 500.
import time
import random
def llamar_con_resiliencia(fn, *, intentos=3, timeout=20, fallback=None):
# Retries con backoff exponencial + jitter (un poco de azar para que
# mil clientes no reintenten todos en el mismo milisegundo).
for i in range(intentos):
try:
return fn(timeout=timeout) # timeout en CADA llamada
except (TimeoutError, ConnectionError) as e:
if i == intentos - 1: # último intento fallido
break
espera = (2 ** i) + random.uniform(0, 0.5) # 1s, 2s, 4s + jitter
time.sleep(espera)
# Se agotaron los reintentos: degradamos con gracia en vez de morir.
if fallback is not None:
return fallback() # otro modelo, o una respuesta más simple
raise RuntimeError("servicio no disponible y sin fallback")
# Uso: modelo principal con red; si se cae del todo, cae a uno de respaldo
respuesta = llamar_con_resiliencia(
lambda timeout: modelo_principal(prompt, timeout=timeout),
fallback=lambda: modelo_barato(prompt), # degradación elegante
)
Runbook (glosado: un documento con los pasos exactos para responder a cada incidente conocido — “si el agente responde lento, revisa X; si falla la tool Y, haz Z”). Es la diferencia entre improvisar a las 3 AM y seguir una lista probada. Sumado a un turno de on-call (alguien de guardia que recibe las alertas), convierte un incidente de crisis en procedimiento.
| Herramienta | Contra qué protege | Qué hace |
|---|---|---|
| Retries + backoff | Fallos transitorios de red/API | Reintenta espaciando, no en bucle |
| Timeout | Servicio colgado | Corta y libera en vez de esperar infinito |
| Circuit breaker | Servicio caído sostenido | Deja de golpearlo, responde con fallback |
| Fallback | Cualquiera de los anteriores agotado | Degrada a otro modelo o respuesta simple |
| Runbook + on-call | El factor humano del incidente | Procedimiento probado en vez de improvisar |
Ojo: reintentar sin backoff es un ataque a ti mismo. Mil clientes reintentando de inmediato contra una API que titubea la terminan de tumbar — es una estampida. El backoff exponencial con jitter es lo que evita que tu solución sea peor que el problema.
El checklist de producción de un agente
Todo el curso, condensado en una lista. Si puedes marcar todas, tu agente está listo para el mundo.
- Git y convenciones de equipo respetadas; historia legible (M2–M3)
- Secretos fuera del código, por entorno (M4)
- Imagen de contenedor reproducible, con
.dockerignorey sin secretos (M5) - Tests unitarios con el LLM mockeado (M6)
- Evals corriendo como tests en cada cambio (M7)
- CI que corre tests, evals y checks en cada PR (M8–M9)
- Infraestructura como código versionada (Terraform) (M10–M11)
- Deploy automatizado a la plataforma elegida (M12)
- Observabilidad: logs estructurados, traces, métricas p95/p99, alertas (M13)
- Seguridad: auth, rate limiting, defensas de prompt injection, tope de gasto (M13)
- Rollout: prompts y modelos versionados, canary/flags, rollback en segundos
- Confiabilidad: retries con backoff, timeouts, circuit breaker, fallbacks
- Runbook escrito y turno de on-call definido
El mapa de los 14 módulos
bloque básico bloque intermedio bloque avanzado
Git y proyecto tests, CI y brechas IaC, deploy y op.
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ qué cambia │ │ testing unit │ │ Terraform │
│ Git esencial │ ──► │ evals-tests │ ──► │ deploy GCP │
│ convenciones │ │ CI Actions │ │ Railway │
│ entornos │ │ checks y │ │ observab. │
│ Docker │ │ brechas │ │ rollout │
└──────────────┘ └──────────────┘ └──────────────┘
lo haces bien lo automatizas lo operas
La progresión completa del curso: primero escribes el agente como profesional (Git, convenciones, entornos, contenedor); luego blindas cada cambio con tests, evals y CI que atrapan las brechas antes de producción; y por fin lo llevas al mundo con infraestructura como código, lo despliegas, lo observas y lo liberas con red. Del “funciona en mi máquina” del módulo 1 al “sigue funcionando aunque yo no esté mirando” de hoy.
Errores comunes
- Desplegar al 100% de golpe. Un cambio para todos a la vez es una caída para todos a la vez. Canary o feature flag, siempre.
- No versionar el prompt ni el modelo. El día que el agente empeora, sin versión no sabes qué cambiaste ni cómo volver. El prompt es código.
- Optimizar el tiempo de deploy e ignorar el de rollback. Lo que importa cuando estás roto es cuán rápido vuelves atrás, no cuán rápido rompiste.
- Reintentar sin backoff. Reintentos inmediatos en bucle rematan un servicio que titubeaba. Backoff exponencial con jitter, o nada.
- Correr sin timeouts. Una sola llamada colgada arrastra a todos los requests detrás. Todo lo que sale a la red lleva tope de tiempo.
- No tener fallback. Sin degradación elegante, cualquier caída externa es un error 500 para el usuario. Un modelo de respaldo o una respuesta honesta siempre gana.
- Manejar incidentes de memoria. Sin runbook, cada incidente se improvisa a las 3 AM. Escríbelo cuando estás tranquilo, úsalo cuando estás en crisis.
La frase para llevarse
“Desplegar bien no es no fallar nunca: es liberar de a poco, volver atrás en segundos y degradar con gracia cuando el mundo se porta mal. El que despliega tranquilo es el que tiene red debajo.”
Qué viene: fin del curso
Catorce módulos: del “¿qué cambia en producción?” al agente que se libera con canary, degrada con fallbacks y vuelve atrás en segundos. Recorriste el pipeline completo de una empresa de verdad — Git y convenciones, tests y evals, CI con checks y brechas, contenedor, infraestructura como código, deploy, observabilidad, seguridad y rollout — el contrato que pusimos sobre la mesa en el módulo 1, cumplido.
Si completaste los 14 módulos con tu cuenta de la academia, el certificado es tuyo. El glosario de Deploy queda como referencia permanente para cuando necesites recordar qué era un circuit breaker o un canary a mitad de un incidente.
Y este curso es una pieza de un cuadro más grande. Aquí aprendiste a operar el agente; los puentes hacia el resto:
- Construir el agente por dentro — su lógica, su grafo, su memoria: el Curso de LangGraph.
- Servir el modelo que lo alimenta, con la cuenta de costos clara: el Curso de GPU para IA.
- Evaluarlo con rigor, para saber si de verdad mejora: Evaluación de agentes.
Construir, servir, evaluar, operar. Con eso, tu agente deja de ser un demo bonito y se vuelve un producto en el que alguien confía. Ese siempre fue el punto.
Material relacionado
Preguntas sobre este curso
Regístrate gratis para hacer preguntas y guardar tu progreso.
✉ Entérate de lo nuevo
Recibe un aviso cuando publique nuevos cursos, workshops o investigaciones. Sin spam.