miinventario-v2/docs/97-adr/ADR-0003-abstraccion-proveedores-ia.md
rckrdmrd 1a53b5c4d3 [MIINVENTARIO] feat: Initial commit - Sistema de inventario con análisis de video IA
- Backend NestJS con módulos de autenticación, inventario, créditos
- Frontend React con dashboard y componentes UI
- Base de datos PostgreSQL con migraciones
- Tests E2E configurados
- Configuración de Docker y deployment

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 02:25:48 -06:00

7.6 KiB

ADR-0003: Abstraccion de Proveedores IA


id: ADR-0003 type: ADR status: Aceptado created_date: 2026-01-10 updated_date: 2026-01-10 decision_date: 2026-01-10 deciders: ["Tech Lead", "ML Engineer"]

Estado

Aceptado


Contexto

El procesamiento de imagenes para deteccion de productos puede usar diferentes proveedores de IA:

  • OpenAI GPT-4 Vision
  • Anthropic Claude 3 Vision
  • Google Cloud Vision
  • Modelo custom/fine-tuned

Cada proveedor tiene:

  • Diferentes APIs y formatos
  • Diferentes costos por imagen/token
  • Diferentes capacidades y precision
  • Diferentes limites de rate

Necesitamos poder:

  • Cambiar de proveedor sin modificar codigo
  • Usar multiples proveedores (fallback)
  • Comparar precision y costos
  • Escalar con nuevos proveedores

Decision

Implementar una capa de abstraccion de proveedores con:

  1. Interface comun

    • Todos los proveedores implementan la misma interface
    • Metodos estandar: detectProducts, getCost, isAvailable
  2. Adapter pattern

    • Cada proveedor tiene su propio adapter
    • El adapter traduce requests/responses al formato comun
  3. Configuracion dinamica

    • Proveedor activo configurable por variable de entorno
    • Cambio en runtime via admin panel
  4. Fallback automatico

    • Si proveedor principal falla, usar secundario
    • Reintentar con diferentes proveedores
  5. Registro de COGS

    • Cada request registra proveedor y costo
    • Permite analisis de costos por proveedor

Opciones Consideradas

Opcion A: Acoplamiento directo a OpenAI

Aspecto Valor
Complejidad Baja
Flexibilidad Nula
Riesgo Alto (vendor lock-in)
Velocidad Rapida

Descartada: Lock-in inaceptable, no permite optimizar costos.

Opcion B: Servicio de IA externo (AWS Rekognition)

Aspecto Valor
Complejidad Media
Flexibilidad Baja
Costo Fijo por imagen
Precision Generica

Descartada: Precision insuficiente para productos de tienda.

Opcion C: Abstraccion multi-proveedor (Seleccionada)

Aspecto Valor
Complejidad Alta inicial
Flexibilidad Maxima
Escalabilidad Alta
Mantenimiento Medio

Seleccionada: Flexibilidad maxima y proteccion contra cambios de precios/disponibilidad.


Consecuencias

Positivas

  • Sin vendor lock-in: Cambiar proveedor facilmente
  • Optimizacion de costos: Comparar y elegir el mejor
  • Resiliencia: Fallback a otro proveedor
  • A/B testing: Comparar precision entre proveedores
  • Futuro-proof: Agregar nuevos proveedores facilmente

Negativas

  • Complejidad inicial: Mas codigo para abstraer
  • Mantenimiento: Actualizar adapters si APIs cambian
  • Testing: Probar cada adapter
  • Potencial inconsistencia: Resultados pueden variar entre proveedores

Arquitectura

┌─────────────────────────────────────────────────────────────────┐
│                    ABSTRACCION IA PROVIDER                       │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │                  IAProviderService                       │    │
│  │  ─────────────────────────────────────────────────────  │    │
│  │  - activeProvider: string                                │    │
│  │  - providers: Map<string, IAProvider>                    │    │
│  │                                                          │    │
│  │  + detectProducts(frames): Detection[]                   │    │
│  │  + getActiveProvider(): IAProvider                       │    │
│  │  + switchProvider(name): void                            │    │
│  │  + calculateCOGS(session): number                        │    │
│  └────────────────────────┬────────────────────────────────┘    │
│                           │ implements IAProvider               │
│            ┌──────────────┼──────────────┐                      │
│            ▼              ▼              ▼                      │
│      ┌──────────┐  ┌──────────┐  ┌──────────┐                  │
│      │  OpenAI  │  │  Claude  │  │  Custom  │                  │
│      │ Adapter  │  │ Adapter  │  │ Adapter  │                  │
│      │─────────-│  │─────────-│  │─────────-│                  │
│      │GPT-4V API│  │Claude API│  │Local/API │                  │
│      └──────────┘  └──────────┘  └──────────┘                  │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Interface

interface IAProvider {
  readonly name: string;

  // Core functionality
  detectProducts(
    frames: Buffer[],
    options?: DetectionOptions
  ): Promise<Detection[]>;

  // Cost tracking
  getCostPerFrame(): number;
  getCostPerToken(): number;

  // Health check
  isAvailable(): Promise<boolean>;

  // Optional: identification
  identifyProduct?(
    image: Buffer,
    detection: Detection
  ): Promise<ProductMatch>;
}

interface Detection {
  frameNumber: number;
  boundingBox: BoundingBox;
  confidence: number;
  label?: string;
  embedding?: number[];
  metadata?: Record<string, any>;
}

interface DetectionOptions {
  minConfidence?: number;
  maxProducts?: number;
  categories?: string[];
}

Configuracion

# Proveedor activo
IA_ACTIVE_PROVIDER=openai

# OpenAI
OPENAI_API_KEY=sk-...
OPENAI_MODEL=gpt-4-vision-preview
OPENAI_COST_PER_FRAME=0.02

# Claude
ANTHROPIC_API_KEY=sk-ant-...
CLAUDE_MODEL=claude-3-opus
CLAUDE_COST_PER_FRAME=0.015

# Fallback
IA_FALLBACK_PROVIDER=claude
IA_RETRY_WITH_FALLBACK=true

Metricas por Proveedor

Proveedor Precision Latencia Costo/frame Disponibilidad
OpenAI 87% 2.5s $0.02 99.5%
Claude 85% 3.0s $0.015 99.8%
Custom 82% 0.5s $0.005 99.9%

Estrategia de Migracion

  1. Fase 1: Implementar con OpenAI como unico proveedor
  2. Fase 2: Agregar adapter de Claude como fallback
  3. Fase 3: Comparar precision y costos en produccion
  4. Fase 4: Evaluar modelo custom si volumen lo justifica

Referencias


Ultima Actualizacion: 2026-01-10