Desplegar un agente de IA en producción es el salto que separa un experimento que funciona en tu portátil de un servicio que responde a usuarios reales, día y noche, sin que tengas que estar delante. El agente deja de ser un script que lanzas a mano y se convierte en un proceso contenedorizado, con estado guardado fuera del contenedor, observabilidad de cada llamada al modelo, secretos bien gestionados y una estrategia clara para los fallos. En esta guía empaquetas un agente construido con el SDK de agentes de OpenAI dentro de una imagen Docker mínima, lo expones con FastAPI y lo preparas para el tráfico real. La misma explicación está disponible en inglés.

Puntos clave

  • Un agente en producción es un servicio HTTP contenedorizado, no un script: se empaqueta en una imagen Docker mínima (base python:3.13-slim, sobre Debian 13) y se ejecuta como un proceso sin estado.
  • El SDK de agentes de OpenAI (paquete openai-agents, versión 0.18.2 del 11 de julio de 2026) es compatible con más de 100 modelos, así que el mismo servicio sirve para un modelo propietario o para uno abierto.
  • El estado (memoria de conversación, puntos de control) vive fuera del contenedor, en Postgres y Redis, para que puedas escalar a varias réplicas detrás de un balanceador.
  • La observabilidad no es opcional: cada llamada al modelo se traza con su coste, su latencia y su resultado, y las peticiones al proveedor llevan reintentos con espera exponencial y límites de tasa.
  • Los secretos nunca se hornean en la imagen (quedarían en las capas): se inyectan por variables de entorno o por un gestor de secretos, y el agente se ejecuta con un usuario sin privilegios.

¿Por qué un script no basta en producción?

Durante el desarrollo, un agente es un archivo de Python que ejecutas en la terminal: lee una pregunta, llama al modelo unas cuantas veces, imprime la respuesta y termina. Ese modelo funciona para una demo, pero se rompe en cuanto lo tienen que usar otras personas. Un servicio en producción debe estar siempre encendido, atender varias peticiones a la vez, sobrevivir a un reinicio sin perder datos, registrar qué hizo y por qué, y no exponer tus claves de API a quien inspeccione el sistema.

El primer paso es dejar de pensar en un script y empezar a pensar en un servicio. En la práctica eso significa envolver la lógica del agente en un servidor web que reciba peticiones HTTP. Con FastAPI (versión 0.139.0) y el servidor Uvicorn (versión 0.51.0) bastan unas pocas líneas para exponer dos rutas: una de salud, que un orquestador consulta para saber si el proceso está vivo, y otra que recibe el mensaje del usuario y devuelve la respuesta del agente.

# servicio.py
from fastapi import FastAPI
from pydantic import BaseModel
from agents import Agent, Runner

app = FastAPI(title="Agente de soporte")
agente = Agent(
    name="Soporte",
    instructions="Responde en espanol, con concision y citando la fuente.",
)

class Peticion(BaseModel):
    mensaje: str

@app.get("/health")
def salud():
    return {"estado": "ok"}

@app.post("/responder")
async def responder(p: Peticion):
    resultado = await Runner.run(agente, p.mensaje)
    return {"respuesta": resultado.final_output}

Con esas dos rutas ya tienes un agente que habla HTTP. El manejador es asíncrono (async def) porque la mayor parte del tiempo el proceso está esperando la respuesta del modelo, no calculando, de modo que un solo trabajador puede atender muchas peticiones concurrentes sin bloquearse.

¿Cómo empaquetar el agente en un contenedor?

El contenedor es la unidad que despliegas: encapsula tu código, sus dependencias exactas y el intérprete de Python, y garantiza que se ejecute igual en tu equipo, en la integración continua y en el servidor. Fija siempre las versiones en un requirements.txt; nunca dependas de la última versión sin fijar, porque una actualización silenciosa puede romper el servicio.

# requirements.txt
openai-agents==0.18.2
fastapi==0.139.0
uvicorn[standard]==0.51.0

La imagen se construye en dos etapas (patrón «multi-stage» de Docker). La primera instala las dependencias; la segunda copia solo el resultado a una imagen limpia, sin compiladores ni caché de pip, de forma que la imagen final es pequeña y tiene menos superficie de ataque. Este Dockerfile funciona con Docker Engine 29.6.1, la versión estable de junio de 2026:

# Etapa 1: instala las dependencias en un prefijo aislado
FROM python:3.13-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt

  # Etapa 2: imagen final minima, como usuario sin privilegios
FROM python:3.13-slim
RUN useradd --create-home --uid 10001 agente
WORKDIR /app
COPY --from=builder /install /usr/local
COPY . .
USER agente
EXPOSE 8000
HEALTHCHECK CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"
CMD ["uvicorn", "servicio:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "2"]

Construyes y arrancas la imagen con dos órdenes; las claves entran por un archivo de entorno que nunca se copia a la imagen:

docker build -t agente-soporte:1.0.0 .
docker run -p 8000:8000 --env-file .env agente-soporte:1.0.0

Si usas un framework con grafos de estado como LangGraph, te ahorras escribir el Dockerfile a mano: la utilidad langgraph-cli (versión 0.4.30) lee tu archivo langgraph.json y genera el Dockerfile por ti con langgraph dockerfile Dockerfile, incluyendo el servidor y los almacenes de estado.

¿Dónde vive el estado y cómo gestionar la concurrencia?

Un agente es intrínsecamente stateful: recuerda el hilo de la conversación, guarda resultados intermedios y, si es un grafo, mantiene puntos de control para reanudar tareas largas. La regla de oro es que ese estado no puede vivir dentro del contenedor, porque un contenedor es efímero: se reinicia, se reemplaza y se replica sin previo aviso. Si guardas la memoria en una variable de Python, la pierdes en el primer reinicio y dos réplicas distintas tendrán historias distintas.

La solución es externalizar el estado a servicios pensados para ello. El SDK de agentes de OpenAI ofrece el extra openai-agents[redis] para guardar las sesiones en Redis; LangGraph guarda sus puntos de control en Postgres y usa Redis para la transmisión de eventos. Con el estado fuera, el contenedor queda sin estado y puedes lanzar varias réplicas idénticas detrás de un balanceador de carga, que reparte las peticiones entre ellas.

Para la concurrencia conviene separar dos casos. Las respuestas rápidas (unos segundos) se atienden dentro de la propia petición HTTP, con manejadores asíncronos y varios trabajadores de Uvicorn. Las tareas largas (un agente que investiga durante minutos) no deben bloquear la petición: encolas el trabajo en una cola de tareas, devuelves de inmediato un identificador de trabajo y el cliente consulta el resultado más tarde. El cuello de botella real casi nunca es tu CPU, sino la latencia del modelo y sus límites de tasa, así que se escala en horizontal añadiendo réplicas, no comprando una máquina más grande.

¿Cómo observar el agente y resistir los fallos?

Un agente en producción falla de formas que un script no conoce: el proveedor devuelve un error 429 por exceso de peticiones, una llamada tarda demasiado, el modelo alucina una herramienta que no existe. Sin observabilidad, esos fallos son invisibles hasta que un usuario se queja. Por eso cada llamada al modelo debe trazarse con su prompt exacto, sus tokens, su coste y su latencia. Una plataforma como Langfuse, que puedes autoalojar con Docker, graba ese árbol de ejecución completo y te deja depurar con datos en lugar de a ciegas.

La resiliencia se construye con tres piezas. Primero, tiempos de espera en toda llamada externa, para que una petición colgada no bloquee un trabajador indefinidamente. Segundo, reintentos con espera exponencial y una pequeña aleatoriedad (jitter): ante un 429 o un 503 transitorio, esperas 1, 2 y 4 segundos antes de rendirte, en vez de martillear al proveedor. Tercero, un cortacircuitos que, si el proveedor lleva un rato caído, deja de intentarlo durante unos segundos y devuelve un error controlado. Y como tú también tienes un presupuesto que cuidar, conviene imponer límites de tasa por usuario y un tope de gasto diario, para que un bucle descontrolado no te vacíe la cuenta. El mismo rigor que aplicarías al servir el modelo con vLLM va, aquí, dirigido a la fiabilidad del agente que lo consume.

Seguridad y gestión de secretos

El error más común y más caro es hornear la clave de API dentro de la imagen. Cualquier ENV OPENAI_API_KEY=sk-... en el Dockerfile queda grabado en una capa de la imagen para siempre, y quien pueda descargarla la lee en claro. Los secretos se inyectan en tiempo de ejecución: con --env-file en Docker, con secretos de Docker o de Kubernetes, o desde un gestor dedicado como Vault. En el repositorio de código nunca hay claves, solo un .env.example con marcadores.

El resto de la seguridad son buenas costumbres que ya viste en el Dockerfile. El contenedor se ejecuta con un usuario sin privilegios (useradd --uid 10001), no como root, para que un fallo del proceso no comprometa el anfitrión. Conviene montar el sistema de archivos como solo lectura y limitar la salida de red a los dominios que el agente necesita de verdad, de modo que, si el agente ejecuta código o herramientas, no pueda filtrar datos a cualquier destino. Si el agente sí ejecuta código generado, hazlo en un entorno aislado (una sandbox), nunca en el propio contenedor del servicio.

Preguntas frecuentes

¿Necesito un framework o me basta un contenedor con FastAPI?

Depende de la complejidad. Para un agente de un solo bucle, un contenedor con FastAPI que envuelva el SDK de agentes de OpenAI es suficiente y te da control total. Cuando el agente crece hacia un grafo con varios pasos, ramas y reanudación de tareas largas, un framework como LangGraph aporta los puntos de control y la gestión de estado ya resueltos, y su CLI genera el Dockerfile y el despliegue por ti. La recomendación práctica es empezar simple y adoptar el framework cuando el estado se te complique.

¿Cómo escalo el agente cuando llega más tráfico?

En horizontal. Como el contenedor no guarda estado (vive en Postgres y Redis), lanzas más réplicas idénticas de la imagen detrás de un balanceador de carga, que reparte las peticiones. El límite superior no suele ser tu servidor, sino los límites de tasa del proveedor del modelo: revisa cuántas peticiones por minuto te permite y pide una ampliación de cuota antes de que el tráfico la alcance. Para picos irregulares, un autoescalado por número de peticiones en cola funciona bien.

¿Puedo desplegar el agente sin depender de una API de pago?

Sí. El SDK de agentes de OpenAI es compatible con más de 100 modelos, incluidos los que sirves en tu propio servidor. Puedes ejecutar el modelo de forma local con Ollama o con vLLM, exponer su API compatible con OpenAI y apuntar el agente a esa URL. Así el mismo contenedor del servicio funciona igual con un modelo propietario en la nube o con uno abierto que corre en tu infraestructura, sin cambiar el código del agente.

Conclusión

Llevar un agente a producción es, sobre todo, un cambio de mentalidad: pasar del script que ejecutas a mano al servicio que se ejecuta solo. El camino tiene cinco tramos claros. Envuelves la lógica en un servidor HTTP con FastAPI; la empaquetas en una imagen Docker mínima y reproducible; sacas el estado a Postgres y Redis para poder replicar; instrumentas cada llamada al modelo y la proteges con tiempos de espera, reintentos y límites; y gestionas los secretos fuera de la imagen, con el contenedor corriendo sin privilegios. Con esas cinco piezas, tu agente deja de ser una demo y se convierte en un servicio en el que puedes confiar. El siguiente paso es coger el Dockerfile de arriba, fijar tus dependencias, construir la imagen y desplegar la primera versión.

Fuentes: [1] Documentación del SDK de agentes de OpenAI[1], [2] Despliegue de LangGraph[2], [3] Construcciones multietapa en Docker[3], [4] Paquete openai-agents en PyPI[4].

Fuentes

  1. Documentación del SDK de agentes de OpenAI
  2. Despliegue de LangGraph
  3. Construcciones multietapa en Docker
  4. Paquete openai-agents en PyPI

Ruta: Agentes de IA en producción: evaluación y fiabilidad