# Módulos de Inteligencia Artificial y NLP Local 🧠
`bgustscraper` destaca por ser una solución **100% offline y de ejecución local**, diseñada con un pipeline híbrido en el que Node.js y Rust cooperan para vectorizar, agrupar (clustering) y extraer información sin depender de APIs de pago externas.
---
## 🗺️ 1. Generación de Embeddings Vectoriales
Para lograr que el scraper "entienda" el contexto semántico de una página y de las búsquedas, inyectamos un pipeline vectorial local:
* **Modelo de Embeddings:** `Xenova/all-MiniLM-L6-v2` (ONNX). Es un modelo bi-encoder súper ligero (22 millones de parámetros, ~80MB en disco).
* **Lógica en Node.js:**
1. Toma el Markdown de la página y lo segmenta en oraciones individuales.
2. Llama al pipeline local de Hugging Face en ONNX Runtime.
3. Aplica **Mean Pooling** y **Normalización L2** sobre los tensores de salida.
4. Esto genera un vector de **384 dimensiones** por oración.
---
## 📈 2. Compresión Extractiva K-Means (El Filtro de Rust)
Pasar todo el Markdown ruidoso de una página web directamente a un LLM en CPU local saturará el contexto del modelo, ralentizará la ejecución y provocará alucinaciones.
Para solucionar esto, Rust implementa un filtro de **Clustering K-Means** utilizando la librería de Machine Learning **`linfa`**:
1. Rust recibe todas las frases y sus vectores del worker de Node.js.
2. Construye una matriz bidimensional `ndarray` de precisión de 64 bits (`ndarray::Array2<f64>`).
3. Aplica **K-Means** (configurado por defecto con $K=12$ clusters de significado y $100$ iteraciones máximas).
4. Para cada cluster calculado, Rust localiza la oración **más cercana a su centroide semántico** (utilizando la distancia euclidiana espacial).
5. **Beneficio:** Filtra de forma inmediata la paja textual, menús de navegación, barras laterales e información redundante, reduciendo el texto en un **80%-90%** y conservando únicamente los núcleos densos de información semántica de la página.
---
## 🔮 3. Generador Estructurado local (`Qwen2.5-0.5B-Instruct`)
Una vez comprimido el texto semánticamente en Rust, la cadena se envía de vuelta al worker de Node.js para la inferencia de lenguaje estructurado:
* **El Modelo:** `onnx-community/Qwen2.5-0.5B-Instruct` cuantizado en precisión **Q4** (~350MB en disco). Es increíblemente veloz en CPUs comerciales y posee un soporte multilingüe en español soberbio.
* **Asegurando Salida JSON:**
* Utilizamos prompts de sistema estrictos indicando que **únicamente** se debe responder con un objeto JSON válido que cumpla el esquema.
* Configuramos una **temperatura ultra-baja (0.1)** para mitigar la creatividad del modelo y forzar consistencia de tipo.
* Node.js procesa el resultado crudo, limpia posibles bloques markdown y parsea el objeto de forma nativa. Si falla, propaga el error estructurado a la CLI.