Docs

Generación con IA

Sistema de generación de invitaciones con Inteligencia Artificial en Nvito - proveedores multi-modelo, flujo de generación, analisis de vision, cuotas por plan.

PublicadoFebrero 2026Equipo de desarrollo, arquitectos, stakeholders

1. Proveedores de IA

Nvito implementa un sistema multi-proveedor con seleccion automática y fallback. Ambos proveedores se gestiónan a traves de la interfaz común AIProvider y estan protegidos por circuit breakers individuales (libreria opossum).

1.1 Proveedores Disponibles

ProveedorModelo por defectoSDKTimeoutUso principal
OpenAIgpt-4oopenai30sGeneración de textos, extracción de colores (Vision)
Anthropicclaude-sonnet-4-5-20250929@anthropic-ai/sdk120sGeneración de textos, analisis de diseño (Vision)

1.2 Interfaz Comun (AIProvider)

Ambos proveedores implementan la interfaz AIProvider definida en providers/ai-provider.interface.ts:

interface AIProvider {
  generate(options: GenerationOptions): Promise<GenerationResult>;
  extractColors(imageUrl: string): Promise<ColorExtractionResult>;
  getModelName(): string;
  getProviderName(): string;
  isAvailable(): boolean;
}

El resultado de cada generación (GenerationResult) incluye:

CampoTipoDescripción
contentstringJSON con los textos generados
tokensUsednumberTotal de tokens consumidos (input + output)
modelstringModelo exacto utilizado
latencyMsnumberTiempo de respuesta en milisegundos

1.3 Sistema de Fallback

La seleccion de proveedor sigue está lógica implementada en selectProvider():

  1. Si el usuario elige openai y está disponible, se usa OpenAI.
  2. Si el usuario elige claude y está disponible, se usa Claude.
  3. Si el modo es auto (por defecto), se prefiere OpenAI; si no está disponible, se usa Claude.
  4. Si ningún proveedor está disponible, se lanza BadRequestException.

La disponibilidad se verifica con isAvailable(), que comprueba la existencia del API key configurado.

1.4 Circuit Breaker

Cada proveedor implementa un circuit breaker con la siguiente configuración:

ParametroOpenAIClaude
Timeout30,000 ms120,000 ms
Error Threshold50%50%
Reset Timeout60,000 ms60,000 ms
Volume Threshold5 requests5 requests

Cuando el circuit breaker se abre (más del 50% de errores en las ultimas 5 peticiones), todas las llamadas fallan inmediatamente durante 60 segundos, permitiendo la recuperacion del servicio.

2. Flujo de Generación

El flujo principal de generación se ejecuta a traves del endpoint POST /ai-generation/generate. La IA genera exclusivamente textos emotivos (v2: text-only). Estos textos se combinan con datos reales del evento para construir un InvitationSchemaV2 que los templates artesanales consumen.

2.1 Diagrama de Secuencia

2.2 Enriquecimiento de Prompt

El servicio EnrichPromptService inyecta contexto del evento antes de enviar el prompt al proveedor de IA. La información enriquecida incluye:

  • Datos del evento: nombre, tipo, fecha, hora, descripción, código de vestimenta, ubicación.
  • Conteo de invitados: total de guests registrados o maxCapacity.
  • Secciones a generar: determinadas dinámicamente según los servicios habilitados en serviceConfig.enabledServices.
  • Secciones opcionales: gallery, itinerary, accommodation, registry, sponsors, prayer, thankYou, dressCode.
  • Secciones por tipo de evento: story (bodas, XV), faq (eventos grandes o formales).

El prompt enriquecido incluye instrucciones estrictas:

  • Generar solo textos emotivos en español (Mexico/Latinoamerica).
  • No generar colores, fuentes ni aspectos de diseño.
  • Para hero, generar solo subtitle (el título es el nombre real del evento).
  • Para event_details y location, generar solo título de sección (datos reales se inyectan automáticamente).

2.3 Validación y Construcción del Schema

Después de recibir la respuesta de la IA:

  1. Validación: ValidationService.validateTextsJSON() valida la estructura del JSON generado usando schemas Zod (invitation-schema.zod.ts).
  2. Construcción: buildSchemaV2() combina los textos generados con datos reales del evento para crear el InvitationSchemaV2 final.
  3. Persistencia: El schema se guarda en la invitación y se crea un registro de versión via VersiónManagerService.

2.4 Calculo de Costo

Los costos se calculan por millon de tokens según la tabla de precios:

ModeloInput (USD/1M tokens)Output (USD/1M tokens)
gpt-4o$2.50$10.00
gpt-4o-mini$0.15$0.60
claude-sonnet-4-5-20250929$3.00$15.00

3. Analisis de Vision

El sistema permite generar invitaciones a partir de imagenes de referencia. El usuario sube un archivo (imagen o PDF) y el sistema extrae colores, estilos y elementos de diseño para enriquecer la generación.

3.1 Proveedores de Vision

El módulo de Vision opera independientemente del módulo de generación de texto, con tres proveedores:

ProveedorTipoModeloUso
OpenAI VisionIAgpt-4oExtracción de colores y analisis de diseño
Claude VisionIAclaude-sonnet-4-5-20250929Extracción de colores y analisis de diseño
LocalLibrerianode-vibrant / sharpExtracción básica de colores sin IA

El VisionProviderService gestióna la seleccion y el fallback entre proveedores de vision:

  • Modo auto: cascada según el orden configurado (openai -> claude -> local).
  • Modo explicito: el usuario selecciona un proveedor específico.
  • Fallback automático: si un proveedor falla y el modo no es explicito, se intenta el siguiente en la lista.

3.2 Diagrama de Secuencia - Analisis de Vision

3.3 Pipeline de Procesamiento de Imagen

El DesignExtractionService ejecuta el siguiente pipeline:

  1. Validación: formato permitido (JPEG, PNG, WebP, GIF), tamano máximo 20 MB.
  2. Optimizacion: redimensionamiento a 1920x1920 max (sin ampliacion) y compresion JPEG al 85% usando sharp.
  3. Extracción de colores: retorna ColorPalette con colors[], dominantColor, y palette (primary, secondary, accent, background, text).
  4. Analisis de diseño: retorna DesignAnalysis con colorScheme (vibrant/muted/monochrome/pastel), styleHints[] (modern, elegant, romantic, etc.) y typography.
  5. Analisis de esquema de color: determina tipo (monocromatico, analogo, complementario, triadico), armonia, contraste y temperatura (calido/frio/neutro).
  6. Sugerencia de fuentes: mapeo de estilos a familias tipograficas:
Estilo detectadoHeadingBodyAccent
Elegant / FormalPlayfair DisplayLoraGreat Vibes
Modern / MinimalistMontserratInterRaleway
Playful / FunQuicksandNunitoPacifico
RomanticDancing ScriptCrimson TextTangerine
DefaultPoppinsOpen SansSatisfy
  1. Prompt enriquecido: se construye con la paleta exacta, esquema de color, hints de estilo y tipografia sugerida.

4. Cuotas por Plan

El sistema de cuotas (QuotaService) controla la cantidad de generaciones permitidas por organización, con limites mensuales y diarios según el plan contratado.

4.1 Limites por Plan

PlanGeneraciones/mesGeneraciones/díaNotas
Free52Ideal para prueba
Starter2010Eventos pequeños
Pro10030Eventos frecuentes
VIPIlimitado (-1)Ilimitado (-1)Sin restricciones

4.2 Mecanismo de Control

El flujo de verificacion de cuotas es:

  1. Verificacion: checkQuotaOrThrow(organizationId) consulta el registro AIQuota de la organización.
  2. Reset automático: si el mes o día cambio respecto al registro, los contadores se reinician a cero (medianoche UTC).
  3. Validación de limites: se compara monthlyUsed < monthlyLimit y dailyUsed < dailyLimit.
  4. Excepcion controlada: si se excede el limite diario, se lanza ForbiddenException con mensaje indicando que se reinicia a medianoche UTC. Si se excede el mensual, se sugiere actualizar el plan.
  5. Ambiente de desarrollo: en NODE_ENV=development, la verificacion de cuotas se omite para fácilitar pruebas.
  6. Super Admins: las organizaciones sin organizationId (Super Admins) no tienen restriccion de cuota.

4.3 Incremento de Uso

Después de cada generación exitosa:

await quotaService.incrementUsage(organizationId, costUsd);

Esto incrementa monthlyUsed, dailyUsed, totalCostUsd y monthCostUsd de forma atomica en la base de datos.

4.4 Endpoint de Consulta

El endpoint GET /ai-generation/quota retorna la información completa de cuota:

interface QuotaInfo {
  canGenerate: boolean;
  monthlyLimit: number;
  monthlyUsed: number;
  monthlyRemaining: number;
  dailyLimit: number;
  dailyUsed: number;
  dailyRemaining: number;
  totalCostUsd: number;
  monthCostUsd: number;
}

5. Tracking de Generaciones

Cada generación se registra en el modelo AIGeneration de Prisma, proporcionando un historial completo de uso, costos y rendimiento.

5.1 Modelo AIGeneration

CampoTipoDescripción
idstringIdentificador único
organizationIdstring?Organización que género (null para Super Admins)
userIdstringUsuario que solicito la generación
invitationIdstring?Invitación asociada
providerstringProveedor usado (openai, claude, cache)
modelstringModelo exacto (gpt-4o, claude-sonnet-4-5-20250929, cached)
promptstringPrompt original del usuario
designInputJSON?Input de diseño (colores, URL de referencia, estilo)
generatedSchemaJSON?Schema generado (InvitationSchemaV2 o textos)
statusstringEstado: pending, completed, failed
tokensUsednumber?Total de tokens consumidos
costUsdDecimal?Costo en USD de la generación
latencyMsnumber?Tiempo de respuesta en milisegundos
errorMessagestring?Mensaje de error si fallo
startedAtDateTimeTimestamp de inicio
completedAtDateTime?Timestamp de finalizacion

5.2 Ciclo de Vida del Registro

  1. Creación: al iniciar la generación, se crea con status: pending.
  2. Exito: se actualiza con status: completed, el schema generado, tokens, costo y latencia.
  3. Fallo: se actualiza con status: failed y el errorMessage.
  4. Cache: si se sirve desde cache, se registra con provider: cache, model: cached, costUsd: 0, tokensUsed: 0.

5.3 Endpoints de Consulta

MetodoEndpointDescripción
GET/ai-generation/generations/:idObtener detalle de una generación
GET/ai-generation/generations?limit=20&offset=0Listar generaciones de la organización (páginado)

6. Cache

El servicio AiCacheService implementa un cache en Redis para evitar llamadas repetidas a los proveedores de IA cuando se reciben prompts similares.

6.1 Funcionamiento

  • Clave de cache: hash SHA-256 del JSON compuesto por { prompt, designInput }.
  • Prefijo: ai:generation:.
  • TTL: 3600 segundos (1 hora) por defecto, configurable via AI_CACHE_TTL.
  • Almacenamiento: Redis con SETEX para TTL automático.

6.2 Flujo de Cache

  1. Consulta: antes de llamar al proveedor de IA, se busca en cache con cacheService.get(prompt, designInput).
  2. Cache hit: se valida el JSON cacheado, se construye el schema, se crea registro con provider: cache y costo $0.
  3. Cache miss: se procede con la generación normal y al completarse, se almacena con cacheService.set(prompt, content, designInput).
  4. Invalidación: disponible via invalidate(prompt, designInput) para forzar regeneración.
  5. Limpieza total: clearAll() elimina todas las claves con prefijo ai:generation:*.

6.3 Configuración

Variable de entornoDescripciónDefault
AI_CACHE_ENABLEDHabilitar/deshabilitar cachetrue
AI_CACHE_TTLTiempo de vida en segundos3600 (1 hora)

Si Redis no está disponible, el cache se deshabilita automáticamente y todas las peticiones se procesan directamente contra los proveedores de IA.

7. Configuración

Toda la configuración del módulo de IA se centraliza en src/config/ai.config.ts y se inyecta via ConfigService de NestJS.

7.1 Variables de Entorno - Proveedores de Generación

VariableDescripciónDefault
OPENAI_API_KEYAPI key de OpenAIRequerido
OPENAI_DEFAULT_MODELModelo de generación OpenAIgpt-4o
OPENAI_MAX_TOKENSTokens máximos de respuesta OpenAI4000
OPENAI_TEMPERATURETemperatura de generación OpenAI0.7
ANTHROPIC_API_KEYAPI key de AnthropicRequerido
CLAUDE_DEFAULT_MODELModelo de generación Claudeclaude-sonnet-4-5-20250929
CLAUDE_MAX_TOKENSTokens máximos de respuesta Claude4000
CLAUDE_TEMPERATURETemperatura de generación Claude0.7

7.2 Variables de Entorno - Vision

VariableDescripciónDefault
VISION_PROVIDER_DEFAULTProvider de vision por defectoauto
VISION_AUTO_FALLBACKHabilitar fallback automáticotrue
VISION_FALLBACK_ORDEROrden de fallback (separado por comas)openai,claude,local
VISION_MAX_IMAGE_SIZE_MBTamano máximo de imagen en MB10
VISION_OPENAI_ENABLEDHabilitar OpenAI Visiontrue
OPENAI_VISION_MODELModelo de vision OpenAIgpt-4o
VISION_CLAUDE_ENABLEDHabilitar Claude Visiontrue
CLAUDE_VISION_MODELModelo de vision Claudeclaude-sonnet-4-5-20250929
VISION_LOCAL_ENABLEDHabilitar procesamiento localtrue
VISION_LOCAL_QUALITYCalidad de extracción local5
VISION_LOCAL_COLOR_COUNTCantidad de colores a extraer (local)64
VISION_LOCAL_MAX_IMAGE_SIZETamano max imagen local (px)800

7.3 Variables de Entorno - Cache y Cuotas

VariableDescripciónDefault
AI_CACHE_ENABLEDHabilitar cache de generacióntrue
AI_CACHE_TTLTTL del cache en segundos3600

Las cuotas se configuran directamente en ai.config.ts bajo la clave quotas (ver sección 4.1).

7.4 Estructura del Modulo

src/modules/ai-generation/
  ai-generation.module.ts         # Modulo NestJS
  ai-generation.controller.ts     # Endpoints REST
  ai-generation.service.ts        # Servicio principal de generación
  cache.service.ts                # Cache Redis para generaciones
  quota.service.ts                # Control de cuotas por plan
  dto/
    generate-from-prompt.dto.ts   # DTO para generación desde prompt
    generate-from-design.dto.ts   # DTO para generación desde diseño
    modify-invitation.dto.ts      # DTO para modificación conversacional
    generation-result.dto.ts      # DTO de respuesta
  interfaces/
    vision-provider.interface.ts  # Interfaz para proveedores de vision
  providers/
    ai-provider.interface.ts      # Interfaz común de proveedores IA
    openai.provider.ts            # Proveedor OpenAI (generación + colores)
    claude.provider.ts            # Proveedor Claude (generación + colores)
    openai-vision.provider.ts     # Proveedor OpenAI Vision
    claude-vision.provider.ts     # Proveedor Claude Vision
    local-vision.provider.ts      # Proveedor local (node-vibrant)
  prompts/
    invitation-system-prompt.ts   # System prompt para generación
  schemas/
    invitation-schema.zod.ts      # Schema Zod de validación
    validation.service.ts         # Servicio de validación de respuestas
  services/
    design-extraction.service.ts  # Extracción de contexto de diseño
    enrich-prompt.service.ts      # Enriquecimiento de prompt con evento
    vision-provider.service.ts    # Orquestador de proveedores de vision

7.5 Endpoints Disponibles

MetodoEndpointDescripciónAuth
POST/ai-generation/generateGenerar invitación desde promptClerkAuth
POST/ai-generation/generate-from-designGenerar desde imagen de referenciaClerkAuth
POST/ai-generation/modifyModificar invitación existente con IAClerkAuth
GET/ai-generation/generations/:idObtener detalle de generaciónClerkAuth
GET/ai-generation/generationsListar generaciones (páginado)ClerkAuth
GET/ai-generation/quotaConsultar cuota de la organizaciónClerkAuth
Esta pagina fue util?