NorthTec AI Backend
Plataforma SaaS multi-tenant de agentes de IA conversacionales. Cada cliente (tenant) configura su propio asistente con personalidad, herramientas (tools) y base de conocimiento (RAG). Los usuarios finales interactúan por Widget web, WhatsApp o API.
Arquitectura del Sistema
┌─────────────────────────────────────────────────────────────┐
│ CANALES │
│ Widget (SSE stream) │ WhatsApp (non-stream) │ API │
└──────────────┬────────────────┬─────────────────┬───────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ FASTIFY SERVER │
│ Guards: widgetSession | whatsappKey | apiKey | firebaseToken│
└──────────────────────────┬──────────────────────────────────┘
│
┌────────────────┼────────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ OpenAI │ │ MCP │ │ RAG │
│ gpt-5-mini │ │ Tools │ │ Pinecone │
│ Responses │ │ Handlers │ │ + Gemini │
└──────────────┘ └──────────────┘ └──────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ FIRESTORE │
│ clients/{id}/private/manifest │ conversations │ usage │
└─────────────────────────────────────────────────────────────┘
Repositorios
| Repo | Descripción |
|---|---|
northtec-ai-backend |
Fastify + TypeScript. API principal, WhatsApp webhook, RAG, MCP tools |
northtec-fb |
Firebase Functions + Admin dashboard |
Modelos de IA
| Uso | Modelo | Costo (per 1M tokens) |
|---|---|---|
| Chat (todos los canales) | gpt-5-mini | $0.25 / $2.00 |
| Análisis de docs (RAG) | gemini-2.5-flash-lite con fallback a flash | $0.10 / $0.40 |
| Embeddings | text-embedding-3-small | $0.02 |
| PDF con imágenes | gemini-2.5-flash (multimodal) | $0.15 / $0.60 |
Estructura de Archivos Clave
northtec-ai/src/
├── agents/
│ ├── assistant/
│ │ ├── stream.ts # Chat runner con streaming (Widget/API)
│ │ └── buildSystemPrompt.ts # Construye prompt del sistema
│ ├── whatsapp/
│ │ ├── handleWhatsAppWebhook.ts # Webhook de Meta
│ │ └── chat.ts # Chat runner non-stream (WhatsApp)
│ └── utils/
│ ├── usageCounter.ts # Contador mensual de mensajes por canal
│ └── locks.ts # Conversation locking
├── mcp/
│ ├── index.ts # runMcpTool dispatcher
│ ├── tools.handlers.ts # Handlers de cada tool (RAG, etc)
│ └── types.ts # McpContext, manifest types
├── rag/
│ ├── docs-indexer.ts # Indexa documentos a Pinecone
│ ├── services/gemini.ts # Análisis con Gemini
│ └── utils/textSplitter.ts # Chunking (800 words max)
├── integrations/
│ ├── openai.client.ts # Cliente OpenAI
│ ├── pinecone.ts # Cliente Pinecone
│ ├── embeddingService.ts # Genera embeddings
│ └── whatsapp.client.ts # API de WhatsApp Business
├── security/
│ ├── widgetSession.guard.ts # Auth para widget
│ ├── apiKey.guard.ts # Auth por API key
│ ├── whatsappKey.guard.ts # Auth para webhooks WA
│ └── whatsappRateLimit.ts # Rate limiting WhatsApp
└── config/
├── firebase.ts # Firestore init
└── logger.ts # Pino logger
Firestore Collections
clients/{clientId}/
├── private/
│ ├── manifest # Config del agente (tools, rag, persona, rules)
│ └── usage # Contadores: messages.2025-01, whatsapp.2025-01, etc
├── conversations/{convId}/
│ └── messages/{msgId} # Historial de chat
└── documents/{docId} # Documentos para RAG
whatsapp_keys/{hash} # Claves de WhatsApp por cliente
plans/{planId} # Planes de suscripción
Manifest (config por cliente)
{
"mcpId": string,
"scopes": string[],
"tools": ToolDefinition[],
"rules": { maxTokens?, allowedDomains?, etc },
"defaults": { greeting?, language? },
"persona": { assistantName, role, tone },
"rag": { enabled, namespace, pineconeIndex },
"businessContext": string,
"onboardingConfig": object,
"requestedCapabilities": object
}
Planes de Suscripción
Estructura de Planes
| Categoría | Planes | Canales |
|---|---|---|
| Personal | free, starter, pro | Widget |
| PyME | starter, business, scale | Widget, WhatsApp, API |
Cada plan define:
category: "personal" | "pyme"channels: ["widget"] o ["widget", "whatsapp", "api"]limits: { messages, documents, conversations }features: string[]capabilities: { rag, customPersona, analytics, etc }
Flujo de Mensaje (WhatsApp)
Meta envía webhook → handleWhatsAppWebhook
Valida whatsappKey + rate limit
Busca/crea conversación en Firestore
Carga manifest del cliente
buildSystemPrompt() + reglas de formato WhatsApp
runChatWithTools() → OpenAI gpt-5-mini
Si hay tool calls → runMcpTool() (puede hacer RAG query)
Loop hasta respuesta final (max 6 loops)
Envía mensaje por WhatsApp API
Guarda en Firestore + incrementa contador de uso
Observabilidad (Logs Estructurados)
| Log | Significado |
|---|---|
[Gemini] flash-lite fallback |
Modelo lite falló estructura JSON, usó flash |
[Embedding] chunk excede límite |
Chunk > 2048 tokens, posible truncamiento |
[AI] respuesta vacía/corta |
Posible problema de prompt o contexto |
[RAG] 0 chunks encontrados |
Query no matcheó documentos en Pinecone |
[AI] tool loop exhausted |
6 loops sin respuesta final |
Costos Estimados por Mensaje
| Componente | Costo/mensaje |
|---|---|
| OpenAI gpt-5-mini (~2K tokens) | ~$0.0045 |
| Embedding (1 query) | ~$0.00002 |
| Pinecone (5 chunks) | ~$0.00008 |
| Firestore (3 writes) | ~$0.00001 |
| Total | ~$0.005/mensaje |
Stack Tecnológico
| Runtime | Node.js + TypeScript |
| Server | Fastify |
| Database | Firestore (Firebase) |
| Vector DB | Pinecone |
| AI | OpenAI (chat), Google Gemini (docs/embeddings) |
| Messaging | WhatsApp Business API (Meta Cloud) |
| Deploy | Firebase Functions / Cloud Run |
Prompt para Usar con IA
Copia este prompt para dar contexto a cualquier IA sobre el sistema:
📋 Prompt de Contexto
Eres un asistente experto en el sistema NorthTec AI Backend.
**Stack:** Node.js + TypeScript, Fastify, Firestore, Pinecone, OpenAI (gpt-5-mini), Gemini (embeddings/docs).
**Arquitectura:** Plataforma SaaS multi-tenant de agentes IA. Canales: Widget (SSE stream), WhatsApp (non-stream), API.
**Archivos clave:**
- agents/assistant/stream.ts → Chat streaming para Widget/API
- agents/whatsapp/chat.ts → Chat non-stream para WhatsApp
- agents/whatsapp/handleWhatsAppWebhook.ts → Webhook de Meta
- mcp/tools.handlers.ts → Handlers de tools (RAG, etc)
- rag/docs-indexer.ts → Indexación a Pinecone
- security/*.guard.ts → Auth por canal
**Firestore:**
- clients/{id}/private/manifest → Config del agente
- clients/{id}/private/usage → Contadores mensuales
- clients/{id}/conversations → Historial de chats
**Modelos:**
- Chat: gpt-5-mini ($0.25/$2.00 per 1M)
- Docs: gemini-2.5-flash-lite con fallback
- Embeddings: text-embedding-3-small
- PDF vision: gemini-2.5-flash
**Costo por mensaje:** ~$0.005
Responde preguntas sobre este sistema con precisión técnica.