erp-core/docs/00-vision-general/ARQUITECTURA-IA.md
rckrdmrd 0086695b4c
Some checks failed
ERP Core CI / Backend Lint (push) Has been cancelled
ERP Core CI / Backend Unit Tests (push) Has been cancelled
ERP Core CI / Backend Integration Tests (push) Has been cancelled
ERP Core CI / Frontend Lint (push) Has been cancelled
ERP Core CI / Frontend Unit Tests (push) Has been cancelled
ERP Core CI / Frontend E2E Tests (push) Has been cancelled
ERP Core CI / Database DDL Validation (push) Has been cancelled
ERP Core CI / Backend Build (push) Has been cancelled
ERP Core CI / Frontend Build (push) Has been cancelled
ERP Core CI / CI Success (push) Has been cancelled
Performance Tests / Lighthouse CI (push) Has been cancelled
Performance Tests / Bundle Size Analysis (push) Has been cancelled
Performance Tests / k6 Load Tests (push) Has been cancelled
Performance Tests / Performance Summary (push) Has been cancelled
[SIMCO-V38] feat: Actualizar a SIMCO v3.8.0 + cambios backend
- HERENCIA-SIMCO.md actualizado con directivas v3.7 y v3.8
- Actualizaciones en modulos CRM y OpenAPI

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 08:53:05 -06:00

794 lines
19 KiB
Markdown

---
id: ARQUITECTURA-IA-ERP-CORE
title: Arquitectura IA - ERP Core
type: Architecture
status: Published
version: 1.0.0
created_date: 2026-01-10
updated_date: 2026-01-10
---
# Arquitectura IA - ERP Core
> Detalle de la arquitectura de inteligencia artificial
## Resumen
ERP Core implementa una arquitectura de IA que permite integracion con multiples modelos de lenguaje (LLM), herramientas de negocio via MCP, y comunicacion inteligente a traves de WhatsApp.
---
## 1. Diagrama de Arquitectura
```mermaid
graph TB
subgraph "Clientes"
WA[WhatsApp]
WEB[Web Chat]
MOB[Mobile App]
API[API REST]
end
subgraph "Capa de Orquestacion"
WAS[WhatsApp Service]
MCP[MCP Server]
end
subgraph "Gateway LLM"
OR[OpenRouter]
subgraph "Modelos"
CL[Claude 3]
GPT[GPT-4]
GEM[Gemini]
MIS[Mistral]
end
end
subgraph "Herramientas MCP"
T1[Products Tools]
T2[Inventory Tools]
T3[Orders Tools]
T4[Customers Tools]
T5[Fiados Tools]
end
subgraph "Backend"
BE[Express API]
PRED[Prediction Service]
end
subgraph "Database"
PG[(PostgreSQL)]
MSG[messaging schema]
AI[ai schema]
end
WA --> WAS
WEB --> MCP
MOB --> MCP
API --> MCP
WAS --> MCP
MCP --> OR
OR --> CL
OR --> GPT
OR --> GEM
OR --> MIS
MCP --> T1
MCP --> T2
MCP --> T3
MCP --> T4
MCP --> T5
T1 --> BE
T2 --> BE
T3 --> BE
T4 --> BE
T5 --> BE
BE --> PG
WAS --> MSG
MCP --> AI
PRED --> PG
```
---
## 2. MCP Server (Model Context Protocol)
### 2.1 Concepto
El MCP Server implementa el protocolo Model Context Protocol de Anthropic, que permite exponer herramientas (tools) de negocio a los modelos de lenguaje de manera estandarizada.
### 2.2 Herramientas Disponibles
#### 2.2.1 Products Tools
```typescript
// Herramientas de productos
const productTools = {
list_products: {
description: 'Lista productos filtrados por categoria, nombre o precio',
parameters: {
category?: string,
search?: string,
min_price?: number,
max_price?: number,
limit?: number
},
returns: 'Array de productos con id, nombre, precio, stock'
},
get_product_details: {
description: 'Obtiene detalles completos de un producto',
parameters: {
product_id: string
},
returns: 'Producto con todos sus atributos, variantes y precios'
},
check_product_availability: {
description: 'Verifica si hay stock suficiente de un producto',
parameters: {
product_id: string,
quantity: number
},
returns: '{ available: boolean, current_stock: number }'
}
};
```
#### 2.2.2 Inventory Tools
```typescript
const inventoryTools = {
check_stock: {
description: 'Consulta el stock actual de productos',
parameters: {
product_ids?: string[],
warehouse_id?: string
},
returns: 'Array de { product_id, quantity, location }'
},
get_low_stock_products: {
description: 'Lista productos que estan por debajo del minimo',
parameters: {
threshold?: number
},
returns: 'Array de productos con stock bajo'
},
record_inventory_movement: {
description: 'Registra un movimiento de inventario',
parameters: {
product_id: string,
quantity: number,
movement_type: 'in' | 'out' | 'adjustment',
reason?: string
},
returns: 'Movimiento registrado'
},
get_inventory_value: {
description: 'Calcula el valor total del inventario',
parameters: {
warehouse_id?: string
},
returns: '{ total_value: number, items_count: number }'
}
};
```
#### 2.2.3 Orders Tools
```typescript
const orderTools = {
create_order: {
description: 'Crea un nuevo pedido',
parameters: {
customer_id: string,
items: Array<{ product_id: string, quantity: number }>,
payment_method?: string,
notes?: string
},
returns: 'Pedido creado con id y total'
},
get_order_status: {
description: 'Consulta el estado de un pedido',
parameters: {
order_id: string
},
returns: 'Estado del pedido y detalles'
},
update_order_status: {
description: 'Actualiza el estado de un pedido',
parameters: {
order_id: string,
status: 'pending' | 'confirmed' | 'preparing' | 'ready' | 'delivered' | 'cancelled'
},
returns: 'Pedido actualizado'
}
};
```
#### 2.2.4 Customers Tools
```typescript
const customerTools = {
search_customers: {
description: 'Busca clientes por nombre, telefono o email',
parameters: {
query: string,
limit?: number
},
returns: 'Array de clientes encontrados'
},
get_customer_balance: {
description: 'Obtiene el saldo actual de un cliente',
parameters: {
customer_id: string
},
returns: '{ balance: number, credit_limit: number }'
}
};
```
#### 2.2.5 Fiados Tools (Credito)
```typescript
const fiadoTools = {
get_fiado_balance: {
description: 'Consulta el saldo de credito de un cliente',
parameters: {
customer_id: string
},
returns: '{ balance: number, available_credit: number }'
},
create_fiado: {
description: 'Registra una venta a credito',
parameters: {
customer_id: string,
amount: number,
order_id?: string,
description?: string
},
returns: 'Registro de fiado creado'
},
register_fiado_payment: {
description: 'Registra un abono a la cuenta de credito',
parameters: {
customer_id: string,
amount: number,
payment_method?: string
},
returns: 'Pago registrado y nuevo saldo'
},
check_fiado_eligibility: {
description: 'Verifica si un cliente puede comprar a credito',
parameters: {
customer_id: string,
amount: number
},
returns: '{ eligible: boolean, reason?: string }'
}
};
```
### 2.3 Recursos MCP
```typescript
const mcpResources = {
'erp://config/business': {
description: 'Configuracion del negocio',
returns: '{ name, address, phone, hours, policies }'
},
'erp://catalog/categories': {
description: 'Categorias de productos',
returns: 'Array de categorias'
},
'erp://inventory/summary': {
description: 'Resumen de inventario',
returns: '{ total_products, total_value, low_stock_count }'
}
};
```
---
## 3. Gateway LLM (OpenRouter)
### 3.1 Arquitectura
```mermaid
graph LR
APP[Aplicacion] --> OR[OpenRouter API]
OR --> |"Route"| M1[Claude 3 Haiku]
OR --> |"Route"| M2[Claude 3 Sonnet]
OR --> |"Route"| M3[GPT-4o-mini]
OR --> |"Route"| M4[GPT-3.5 Turbo]
OR --> |"Route"| M5[Mistral 7B]
OR --> |"Route"| M6[Llama 3]
```
### 3.2 Modelos Soportados
| Modelo | ID | Input/1M | Output/1M | Uso Recomendado |
|--------|----|---------:|----------:|-----------------|
| Claude 3 Haiku | anthropic/claude-3-haiku | $0.25 | $1.25 | Default (rapido) |
| Claude 3 Sonnet | anthropic/claude-3-sonnet | $3.00 | $15.00 | Premium |
| GPT-4o-mini | openai/gpt-4o-mini | $0.15 | $0.60 | Fallback economico |
| GPT-3.5 Turbo | openai/gpt-3.5-turbo | $0.50 | $1.50 | Fallback |
| Mistral 7B | mistralai/mistral-7b | $0.06 | $0.06 | Ultra-economico |
| Llama 3 | meta-llama/llama-3-8b | $0.20 | $0.20 | Open source |
### 3.3 Configuracion por Tenant
```typescript
interface TenantLLMConfig {
provider: 'openrouter' | 'openai' | 'anthropic' | 'ollama';
api_key: string; // encriptada
model: string;
max_tokens: number;
temperature: number;
system_prompt: string;
}
// Ejemplo de configuracion
const config: TenantLLMConfig = {
provider: 'openrouter',
api_key: 'sk-or-v1-...',
model: 'anthropic/claude-3-haiku',
max_tokens: 1000,
temperature: 0.7,
system_prompt: 'Eres un asistente de ventas amigable...'
};
```
### 3.4 Estrategia de Fallback
```typescript
async function callLLM(messages: Message[]): Promise<Response> {
const models = [
config.model, // Modelo preferido del tenant
'anthropic/claude-3-haiku', // Fallback 1
'openai/gpt-3.5-turbo' // Fallback 2
];
for (const model of models) {
try {
const response = await openrouter.chat({
model,
messages,
max_tokens: config.max_tokens,
temperature: config.temperature
});
return response;
} catch (error) {
if (error.code === 'rate_limit_exceeded') {
continue; // Intentar siguiente modelo
}
throw error;
}
}
// Si todos fallan, respuesta predefinida
return { content: 'Lo siento, no puedo procesar tu solicitud ahora.' };
}
```
### 3.5 Tracking de Tokens
```sql
-- Schema: ai
CREATE TABLE ai.configs (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
tenant_id UUID NOT NULL REFERENCES tenants.tenants(id),
provider VARCHAR(20) NOT NULL,
model VARCHAR(100) NOT NULL,
temperature DECIMAL(3,2) DEFAULT 0.7,
max_tokens INTEGER DEFAULT 1000,
system_prompt TEXT,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE ai.usage (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
tenant_id UUID NOT NULL,
model VARCHAR(100) NOT NULL,
operation VARCHAR(50), -- chat, completion, embedding
input_tokens INTEGER NOT NULL,
output_tokens INTEGER NOT NULL,
cost_usd DECIMAL(10,6),
latency_ms INTEGER,
success BOOLEAN DEFAULT true,
error_message TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Indice para reportes de uso
CREATE INDEX idx_ai_usage_tenant_date
ON ai.usage(tenant_id, created_at DESC);
```
---
## 4. WhatsApp Service con IA
### 4.1 Flujo de Mensaje
```mermaid
sequenceDiagram
participant C as Cliente
participant WA as WhatsApp
participant META as Meta API
participant WS as WhatsApp Service
participant LLM as LLM Service
participant MCP as MCP Server
participant BE as Backend
C->>WA: Envia mensaje
WA->>META: Webhook
META->>WS: POST /webhook
WS->>WS: Verificar firma
WS->>WS: Extraer tenant
WS->>LLM: Procesar mensaje
LLM->>LLM: Cargar contexto
LLM->>MCP: Llamar con tools
alt Necesita datos
MCP->>BE: Ejecutar tool
BE-->>MCP: Resultado
end
MCP-->>LLM: Respuesta con datos
LLM-->>WS: Texto de respuesta
WS->>META: Enviar mensaje
META->>WA: Entrega
WA->>C: Muestra mensaje
```
### 4.2 Tipos de Mensaje Soportados
#### Entrantes
| Tipo | Descripcion | Procesamiento |
|------|-------------|---------------|
| text | Texto simple | Directo a LLM |
| audio | Nota de voz | Whisper -> LLM |
| image | Imagen | Vision/OCR -> LLM |
| location | Ubicacion | Extraer coords -> LLM |
| interactive | Respuesta de botones | Mapear a accion |
#### Salientes
| Tipo | Uso |
|------|-----|
| text | Respuestas de texto |
| template | Templates pre-aprobados |
| interactive | Botones o listas |
| media | Imagenes, documentos |
### 4.3 Contexto de Conversacion
```typescript
interface ConversationContext {
tenant_id: string;
customer_id?: string;
customer_name: string;
phone_number: string;
history: Message[]; // Ultimos 20 mensajes
pending_action?: string;
cart?: CartItem[];
}
// Sistema mantiene contexto por 30 minutos de inactividad
```
### 4.4 System Prompts
#### Para Clientes
```
Eres el asistente virtual de {{BUSINESS_NAME}},
una tienda de barrio en Mexico.
Ayudas a los clientes con:
- Informacion sobre productos y precios
- Hacer pedidos
- Consultar su cuenta de fiado
- Estado de sus pedidos
Reglas:
1. Responde en espanol mexicano casual y amigable
2. Se breve pero calido
3. Nunca inventes precios, usa las herramientas
4. Para fiados, siempre verifica primero el saldo
5. Se proactivo sugiriendo opciones
```
#### Para Duenos
```
Eres el asistente de negocios de {{BUSINESS_NAME}}.
Ayudas al dueno con:
- Analisis de ventas y tendencias
- Gestion de inventario
- Recordatorios de cobranza
- Sugerencias de negocio
Se directo, profesional y accionable.
Proporciona numeros concretos siempre.
Sugiere acciones si detectas problemas.
```
---
## 5. Prediccion de Inventario
### 5.1 Algoritmo de Demanda
```typescript
// Promedio movil ponderado (4 semanas)
function predictDemand(salesHistory: WeeklySales[]): number {
const weights = [0.40, 0.30, 0.20, 0.10];
// Ultimas 4 semanas
const recentWeeks = salesHistory.slice(-4).reverse();
let weightedSum = 0;
for (let i = 0; i < weights.length; i++) {
weightedSum += (recentWeeks[i]?.quantity ?? 0) * weights[i];
}
return Math.ceil(weightedSum);
}
```
### 5.2 Punto de Reorden
```typescript
function calculateReorderPoint(
dailyDemand: number,
leadTimeDays: number = 3,
safetyStockDays: number = 2
): number {
const safetyStock = dailyDemand * safetyStockDays;
const reorderPoint = (dailyDemand * leadTimeDays) + safetyStock;
return Math.ceil(reorderPoint);
}
// Ejemplo:
// dailyDemand = 10 unidades/dia
// leadTime = 3 dias
// safetyStock = 10 * 2 = 20 unidades
// reorderPoint = (10 * 3) + 20 = 50 unidades
```
### 5.3 Dias de Inventario
```typescript
function daysOfInventory(currentStock: number, dailyDemand: number): number {
if (dailyDemand === 0) return Infinity;
return Math.floor(currentStock / dailyDemand);
}
// Alertas
// < 3 dias: CRITICO
// < 7 dias: BAJO
// > 30 dias: EXCESO
```
### 5.4 Endpoints de Prediccion
```typescript
// GET /inventory/predictions
{
products: [
{
product_id: 'uuid',
name: 'Coca-Cola 600ml',
current_stock: 24,
predicted_weekly_demand: 50,
reorder_point: 30,
days_of_inventory: 3.4,
suggested_order: 50,
urgency: 'HIGH'
}
]
}
// GET /inventory/low-stock
{
products: [
{
product_id: 'uuid',
name: 'Coca-Cola 600ml',
current_stock: 5,
minimum_stock: 20,
shortage: 15
}
]
}
// GET /inventory/slow-moving
{
products: [
{
product_id: 'uuid',
name: 'Cafe Premium',
current_stock: 10,
days_without_sale: 45,
last_sale_date: '2025-11-25'
}
]
}
```
---
## 6. Modelo de Datos IA
### 6.1 Schema: messaging
```sql
CREATE TABLE messaging.conversations (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
tenant_id UUID NOT NULL,
phone_number VARCHAR(20) NOT NULL,
contact_name VARCHAR(100),
conversation_type VARCHAR(20) DEFAULT 'general',
status VARCHAR(20) DEFAULT 'active',
last_message_at TIMESTAMPTZ,
last_message_preview TEXT,
unread_count INTEGER DEFAULT 0,
wa_conversation_id VARCHAR(100),
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE messaging.messages (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
conversation_id UUID NOT NULL REFERENCES messaging.conversations(id),
direction VARCHAR(10) NOT NULL, -- in, out
message_type VARCHAR(20) NOT NULL, -- text, audio, image, template
content TEXT,
media_url TEXT,
media_mime_type VARCHAR(50),
-- IA Processing
processed_by_llm BOOLEAN DEFAULT false,
llm_model VARCHAR(100),
tokens_used INTEGER,
tool_calls JSONB,
-- WhatsApp
wa_message_id VARCHAR(100),
wa_status VARCHAR(20), -- sent, delivered, read, failed
wa_timestamp TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
```
### 6.2 Indices
```sql
-- Busqueda rapida de conversaciones
CREATE INDEX idx_conversations_tenant_phone
ON messaging.conversations(tenant_id, phone_number);
CREATE INDEX idx_conversations_last_message
ON messaging.conversations(tenant_id, last_message_at DESC);
-- Busqueda de mensajes
CREATE INDEX idx_messages_conversation
ON messaging.messages(conversation_id, created_at DESC);
```
---
## 7. Patrones de Extension IA
### 7.1 Agregar Herramientas MCP
```typescript
// En vertical: erp-construccion
// Registrar herramientas adicionales
mcpServer.registerTool('construction.get_budget', {
description: 'Obtiene presupuesto de construccion',
parameters: {
budget_id: { type: 'string', required: true }
},
handler: async ({ budget_id }) => {
return constructionService.getBudget(budget_id);
}
});
mcpServer.registerTool('construction.estimate_materials', {
description: 'Estima materiales para un proyecto',
parameters: {
area_m2: { type: 'number', required: true },
project_type: { type: 'string', required: true }
},
handler: async ({ area_m2, project_type }) => {
return constructionService.estimateMaterials(area_m2, project_type);
}
});
```
### 7.2 System Prompts por Vertical
```typescript
// Configuracion por vertical
const systemPrompts = {
'erp-core': 'Eres un asistente de negocios general...',
'erp-construccion': 'Eres un asistente especializado en construccion...',
'erp-retail': 'Eres un asistente de punto de venta...'
};
```
### 7.3 Modelos por Caso de Uso
```typescript
// Diferentes modelos para diferentes tareas
const modelConfig = {
chat_simple: 'anthropic/claude-3-haiku', // Rapido y economico
chat_complex: 'anthropic/claude-3-sonnet', // Alta calidad
analysis: 'openai/gpt-4o', // Analisis profundo
embedding: 'openai/text-embedding-3-small' // Embeddings
};
```
---
## 8. Seguridad IA
### 8.1 Checklist
- [ ] API keys encriptadas en base de datos
- [ ] Rate limiting por tenant
- [ ] Limite de tokens por request
- [ ] Logs de todas las llamadas LLM
- [ ] Sanitizacion de inputs
- [ ] No exponer datos sensibles a LLM
### 8.2 Rate Limiting
```typescript
// Limites por plan
const rateLimits = {
free: { tokensPerDay: 1000, requestsPerMinute: 5 },
starter: { tokensPerDay: 10000, requestsPerMinute: 20 },
pro: { tokensPerDay: 100000, requestsPerMinute: 60 },
enterprise: { tokensPerDay: -1, requestsPerMinute: 200 }
};
```
---
## Referencias
- [VISION-ERP-CORE.md](VISION-ERP-CORE.md) - Vision general
- [INTEGRACIONES-EXTERNAS.md](INTEGRACIONES-EXTERNAS.md) - Integraciones
- [Anthropic MCP](https://github.com/anthropics/anthropic-cookbook) - Documentacion MCP
- [OpenRouter](https://openrouter.ai/docs) - Documentacion API
---
*Actualizado: 2026-01-10*