Para desplegar microservicios de FastAPI (procesamiento rápido de solicitudes) y LangChain (orquestación de LLMs, intensiva y lenta) en Google Kubernetes Engine (GKE), la mejor práctica es utilizar un patrón asíncrono basado en eventos.
Este diseño garantiza que las llamadas de Inteligencia Artificial no bloqueen el tráfico web, permitiendo que cada componente escale de manera 100% independiente.

Diagrama de Arquitectura




Estrategia de Configuración en GKE

1. Escalabilidad Independiente (Autoscaling)

  • FastAPI: Debe configurarse con un Horizontal Pod Autoscaler (HPA) estándar. Escala rápidamente basándose en la utilización de CPU o en el número de solicitudes HTTP entrantes.
  • LangChain Workers: Deben escalar utilizando KEDA (Kubernetes Event-driven Autoscaling). Escalar los workers por CPU o Memoria es un error común: cuando un worker está esperando la respuesta de la API de un LLM externo, su consumo de CPU es casi nulo, pero sigue estando ocupado. KEDA permite escalar los pods basándose directamente en el número de mensajes pendientes en la cola.

2. Aislamiento y Separación de Nodos (Node Pools)

  • Node Pool Estándar: Destinado a la API de FastAPI. Utiliza tipos de máquina de propósito general y económicos (ej. familia e2-standard).
  • Node Pool Optimizado / GPU: Destinado a los Workers de LangChain.
    • Si ejecutas modelos de lenguaje de forma local (ej. Llama 3 mediante vLLM o Hugging Face), este pool requiere GPUs dedicadas (ej. NVIDIA L4 o T4).
    • Si consumes LLMs mediante APIs externas (OpenAI, Anthropic, Vertex AI), utiliza máquinas optimizadas para computación (c3) o memoria (m3) para gestionar con solvencia las operaciones pesadas de chunks de texto y generación de embeddings.

3. Asignación de Recursos (Requests & Limits)

Es crítico definir límites estrictos para evitar que un bucle infinito en una cadena o agente de LangChain consuma los recursos de todo el clúster:
  • FastAPI:
    • requests: CPU: 200m | Memoria: 256Mi
    • limits: CPU: 1000m | Memoria: 512Mi
  • LangChain Workers:
    • requests: CPU: 1000m | Memoria: 2Gi
    • limits: CPU: 2000m | Memoria: 4Gi (Ajustar según la complejidad de los prompts y agentes)

🛠️ Manifiestos de Kubernetes (Ejemplo Base)

FastAPI: Despliegue y Servicio

apiVersion: apps/v1
kind: Deployment
metadata:
  name: fastapi-api
  namespace: ai-apps
spec:
  replicas: 2
  selector:
    matchLabels:
      app: fastapi-api
  template:
    metadata:
      labels:
        app: fastapi-api
    spec:
      containers:
      - name: fastapi
        image: gcr.io/[PROJECT_ID]/fastapi-app:latest
        ports:
        - containerPort: 8000
        resources:
          requests:
            cpu: "250m"
            memory: "256Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"
---
apiVersion: v1
kind: Service
metadata:
  name: fastapi-service
  namespace: ai-apps
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8000
  selector:
    app: fastapi-api

LangChain Worker: Despliegue de Procesamiento Async

apiVersion: apps/v1
kind: Deployment
metadata:
  name: langchain-worker
  namespace: ai-apps
spec:
  replicas: 1 # Controlado dinámicamente si se usa KEDA o HPA por colas
  selector:
    matchLabels:
      app: langchain-worker
  template:
    metadata:
      labels:
        app: langchain-worker
    spec:
      containers:
      - name: langchain
        image: gcr.io/[PROJECT_ID]/langchain-worker:latest
        env:
        - name: OPENAI_API_KEY
          valueFrom:
            secretKeyRef:
              name: ai-secrets
              key: openai-key
        resources:
          requests:
            cpu: "1000m"
            memory: "2Gi"
          limits:
            cpu: "2000m"
            memory: "4Gi"