Docs

Generacion con IA

Documento tecnico que describe el sistema de generacion de invitaciones con Inteligencia Artificial en Nvito: proveedores, flujo de generacion, analisis de vision, cuotas por plan, tracking de uso y cache.

CampoValor
Version1.0
FechaFebrero 2026
EstadoEn revision
AudienciaEquipo de desarrollo, arquitectos, stakeholders

1. Proveedores de IA

Nvito implementa un sistema multi-proveedor con seleccion automatica y fallback. Ambos proveedores se gestionan a traves de la interfaz comun AIProvider y estan protegidos por circuit breakers individuales (libreria opossum).

1.1 Proveedores Disponibles

ProveedorModelo por defectoSDKTimeoutUso principal
OpenAIgpt-4oopenai30sGeneracion de textos, extraccion de colores (Vision)
Anthropicclaude-sonnet-4-5-20250929@anthropic-ai/sdk120sGeneracion de textos, analisis de diseno (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 generacion (GenerationResult) incluye:

CampoTipoDescripcion
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 esta logica implementada en selectProvider():

  1. Si el usuario elige openai y esta disponible, se usa OpenAI.
  2. Si el usuario elige claude y esta disponible, se usa Claude.
  3. Si el modo es auto (por defecto), se prefiere OpenAI; si no esta disponible, se usa Claude.
  4. Si ningun proveedor esta 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 configuracion:

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 (mas 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 Generacion

El flujo principal de generacion 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 informacion enriquecida incluye:

  • Datos del evento: nombre, tipo, fecha, hora, descripcion, codigo de vestimenta, ubicacion.
  • Conteo de invitados: total de guests registrados o maxCapacity.
  • Secciones a generar: determinadas dinamicamente segun 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 espanol (Mexico/Latinoamerica).
  • No generar colores, fuentes ni aspectos de diseno.
  • Para hero, generar solo subtitle (el titulo es el nombre real del evento).
  • Para event_details y location, generar solo titulo de seccion (datos reales se inyectan automaticamente).

2.3 Validacion y Construccion del Schema

Despues de recibir la respuesta de la IA:

  1. Validacion: ValidationService.validateTextsJSON() valida la estructura del JSON generado usando schemas Zod (invitation-schema.zod.ts).
  2. Construccion: buildSchemaV2() combina los textos generados con datos reales del evento para crear el InvitationSchemaV2 final.
  3. Persistencia: El schema se guarda en la invitacion y se crea un registro de version via VersionManagerService.

2.4 Calculo de Costo

Los costos se calculan por millon de tokens segun 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 diseno para enriquecer la generacion.

3.1 Proveedores de Vision

El modulo de Vision opera independientemente del modulo de generacion de texto, con tres proveedores:

ProveedorTipoModeloUso
OpenAI VisionIAgpt-4oExtraccion de colores y analisis de diseno
Claude VisionIAclaude-sonnet-4-5-20250929Extraccion de colores y analisis de diseno
LocalLibrerianode-vibrant / sharpExtraccion basica de colores sin IA

El VisionProviderService gestiona la seleccion y el fallback entre proveedores de vision:

  • Modo auto: cascada segun el orden configurado (openai -> claude -> local).
  • Modo explicito: el usuario selecciona un proveedor especifico.
  • Fallback automatico: 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. Validacion: formato permitido (JPEG, PNG, WebP, GIF), tamano maximo 20 MB.
  2. Optimizacion: redimensionamiento a 1920x1920 max (sin ampliacion) y compresion JPEG al 85% usando sharp.
  3. Extraccion de colores: retorna ColorPalette con colors[], dominantColor, y palette (primary, secondary, accent, background, text).
  4. Analisis de diseno: 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 organizacion, con limites mensuales y diarios segun el plan contratado.

4.1 Limites por Plan

PlanGeneraciones/mesGeneraciones/diaNotas
Free52Ideal para prueba
Starter2010Eventos pequenos
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 organizacion.
  2. Reset automatico: si el mes o dia cambio respecto al registro, los contadores se reinician a cero (medianoche UTC).
  3. Validacion 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 facilitar pruebas.
  6. Super Admins: las organizaciones sin organizationId (Super Admins) no tienen restriccion de cuota.

4.3 Incremento de Uso

Despues de cada generacion 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 informacion 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 generacion se registra en el modelo AIGeneration de Prisma, proporcionando un historial completo de uso, costos y rendimiento.

5.1 Modelo AIGeneration

CampoTipoDescripcion
idstringIdentificador unico
organizationIdstring?Organizacion que genero (null para Super Admins)
userIdstringUsuario que solicito la generacion
invitationIdstring?Invitacion asociada
providerstringProveedor usado (openai, claude, cache)
modelstringModelo exacto (gpt-4o, claude-sonnet-4-5-20250929, cached)
promptstringPrompt original del usuario
designInputJSON?Input de diseno (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 generacion
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. Creacion: al iniciar la generacion, 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

MetodoEndpointDescripcion
GET/ai-generation/generations/:idObtener detalle de una generacion
GET/ai-generation/generations?limit=20&offset=0Listar generaciones de la organizacion (paginado)

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 automatico.

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 generacion normal y al completarse, se almacena con cacheService.set(prompt, content, designInput).
  4. Invalidacion: disponible via invalidate(prompt, designInput) para forzar regeneracion.
  5. Limpieza total: clearAll() elimina todas las claves con prefijo ai:generation:*.

6.3 Configuracion

Variable de entornoDescripcionDefault
AI_CACHE_ENABLEDHabilitar/deshabilitar cachetrue
AI_CACHE_TTLTiempo de vida en segundos3600 (1 hora)

Si Redis no esta disponible, el cache se deshabilita automaticamente y todas las peticiones se procesan directamente contra los proveedores de IA.

7. Configuracion

Toda la configuracion del modulo de IA se centraliza en src/config/ai.config.ts y se inyecta via ConfigService de NestJS.

7.1 Variables de Entorno - Proveedores de Generacion

VariableDescripcionDefault
OPENAI_API_KEYAPI key de OpenAIRequerido
OPENAI_DEFAULT_MODELModelo de generacion OpenAIgpt-4o
OPENAI_MAX_TOKENSTokens maximos de respuesta OpenAI4000
OPENAI_TEMPERATURETemperatura de generacion OpenAI0.7
ANTHROPIC_API_KEYAPI key de AnthropicRequerido
CLAUDE_DEFAULT_MODELModelo de generacion Claudeclaude-sonnet-4-5-20250929
CLAUDE_MAX_TOKENSTokens maximos de respuesta Claude4000
CLAUDE_TEMPERATURETemperatura de generacion Claude0.7

7.2 Variables de Entorno - Vision

VariableDescripcionDefault
VISION_PROVIDER_DEFAULTProvider de vision por defectoauto
VISION_AUTO_FALLBACKHabilitar fallback automaticotrue
VISION_FALLBACK_ORDEROrden de fallback (separado por comas)openai,claude,local
VISION_MAX_IMAGE_SIZE_MBTamano maximo 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 extraccion 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

VariableDescripcionDefault
AI_CACHE_ENABLEDHabilitar cache de generaciontrue
AI_CACHE_TTLTTL del cache en segundos3600

Las cuotas se configuran directamente en ai.config.ts bajo la clave quotas (ver seccion 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 generacion
  cache.service.ts                # Cache Redis para generaciones
  quota.service.ts                # Control de cuotas por plan
  dto/
    generate-from-prompt.dto.ts   # DTO para generacion desde prompt
    generate-from-design.dto.ts   # DTO para generacion desde diseno
    modify-invitation.dto.ts      # DTO para modificacion conversacional
    generation-result.dto.ts      # DTO de respuesta
  interfaces/
    vision-provider.interface.ts  # Interfaz para proveedores de vision
  providers/
    ai-provider.interface.ts      # Interfaz comun de proveedores IA
    openai.provider.ts            # Proveedor OpenAI (generacion + colores)
    claude.provider.ts            # Proveedor Claude (generacion + 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 generacion
  schemas/
    invitation-schema.zod.ts      # Schema Zod de validacion
    validation.service.ts         # Servicio de validacion de respuestas
  services/
    design-extraction.service.ts  # Extraccion de contexto de diseno
    enrich-prompt.service.ts      # Enriquecimiento de prompt con evento
    vision-provider.service.ts    # Orquestador de proveedores de vision

7.5 Endpoints Disponibles

MetodoEndpointDescripcionAuth
POST/ai-generation/generateGenerar invitacion desde promptClerkAuth
POST/ai-generation/generate-from-designGenerar desde imagen de referenciaClerkAuth
POST/ai-generation/modifyModificar invitacion existente con IAClerkAuth
GET/ai-generation/generations/:idObtener detalle de generacionClerkAuth
GET/ai-generation/generationsListar generaciones (paginado)ClerkAuth
GET/ai-generation/quotaConsultar cuota de la organizacionClerkAuth
Esta pagina fue util?