LLPY-04: Vectorización y Embeddings – Preparando Datos para RAG




🎯 Introducción

En el mundo de los sistemas RAG (Retrieval-Augmented Generation), la vectorización es el proceso crítico que convierte texto no estructurado en representaciones numéricas que las máquinas pueden entender y comparar. Después de haber procesado y estructurado nuestros datos legales en el post anterior, ahora necesitamos transformarlos en embeddings que permitan búsquedas semánticas precisas.

Este post documenta nuestra exploración exhaustiva de 11 modelos de embedding diferentes para encontrar el óptimo para nuestro sistema RAG de consultas sobre la ley laboral paraguaya. No se trata solo de elegir el modelo más rápido o el más preciso, sino de encontrar el balance perfecto entre calidad, velocidad y recursos computacionales.



🔍 El Desafío



¿Por Qué Vectorización es Crítica?

Los sistemas RAG dependen de la capacidad de encontrar información relevante basándose en el significado semántico de las consultas, no en coincidencias exactas de palabras. Para esto necesitamos:

  • Representaciones vectoriales que capturen el significado semántico
  • Modelos de embedding optimizados para español y contenido legal
  • Velocidad de búsqueda que permita respuestas en tiempo real
  • Calidad de resultados que encuentre la información más relevante



Nuestro Dataset de Prueba

  • 413 artículos del Código del Trabajo paraguayo
  • 29 artículos seleccionados representativos de 8 capítulos diferentes
  • 16 consultas semánticas generadas con GPT-4o-mini
  • Datos reales con metadatos enriquecidos (libro, título, capítulo, artículo)



La Solución: Evaluación Sistemática de Modelos



Arquitectura de Evaluación

📊 DATASET DE PRUEBA
├── 29 artículos legales estructurados
├── 16 consultas semánticas específicas
└── Metadatos enriquecidos por artículo

🔬 EVALUACIÓN DE MODELOS
├── 11 modelos de embedding diferentes
├── Métricas de rendimiento (velocidad)
├── Métricas de calidad (similitud)
└── Integración con Qdrant vector database

📈 ANÁLISIS COMPARATIVO
├── Normalización de puntuaciones
├── Sistema de pesos configurables
├── Ranking final basado en criterios
└── Recomendaciones específicas por caso de uso
Enter fullscreen mode

Exit fullscreen mode



Modelos Evaluados

Modelo Dimensiones Especialización Descripción
multilingual-e5-small 384 Multilingüe · Rápido Modelo ligero y eficiente
paraphrase-multilingual-MiniLM-L12-v2 384 Multilingüe · Ligero Balanceado para múltiples idiomas
sentence_similarity_spanish_es 768 Español · Optimizado Especializado en español
jina-embeddings-v2-base-es 768 Español · Última generación Modelo de nueva generación
multilingual-e5-base 768 Multilingüe · Robusto Versión base más robusta
gte-multilingual-base 768 Multilingüe · Generalista Modelo general de alta calidad
paraphrase-multilingual-mpnet-base-v2 768 Multilingüe · MPNet Alta precisión con MPNet
distiluse-base-multilingual-cased-v2 512 Multilingüe · Compacto Versión compacta balanceada
LaBSE 768 Multilingüe · Confiable Amplio soporte multilingüe
snowflake-arctic-embed-l-v2.0 1024 Multilingüe · Large Modelo grande de alto rendimiento
bge-m3-korean 1024 Multilingüe · BGE Optimizado para múltiples idiomas



🛠️ Implementación Técnica



1. Configuración del Entorno

# Importaciones necesarias
import os
import time
import json
import re
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import string
import seaborn as sns
from itables import init_notebook_mode, show
from typing import List, Dict, Any, Tuple
from pathlib import Path
from dotenv import load_dotenv

# OpenAI para generación de consultas
from openai import OpenAI

# Qdrant y modelos de embedding
from qdrant_client import QdrantClient
from qdrant_client.http.models import Distance, VectorParams, PointStruct
from sentence_transformers import SentenceTransformer

# Configuración de visualizaciones
plt.style.use('seaborn-v0_8')
sns.set_palette("husl")
init_notebook_mode(all_interactive=True)

print("Librerías importadas exitosamente")
Enter fullscreen mode

Exit fullscreen mode



2. Carga de Variables de Entorno

def load_env_from_parent(levels_up=1, env_filename=".env"):
    """
    Carga un archivo .env ubicado varios niveles arriba de este script.
    """
    # Obtener ruta actual de trabajo
    current_path = Path.cwd()

    # Subir 'levels_up' niveles
    env_path = current_path
    for _ in range(levels_up):
        env_path = env_path.parent
    env_path = env_path / env_filename

    if env_path.exists():
        load_dotenv(dotenv_path=env_path)
        print(f"Variables de entorno cargadas desde: {env_path}")
    else:
        print(f"Archivo {env_filename} no encontrado en: {env_path}")

# Cargar variables de entorno
load_env_from_parent()

# Configuración de conexión a Qdrant
QDRANT_URL = os.getenv('QDRANT_URL')
QDRANT_API_KEY = os.getenv('QDRANT_API_KEY')

print(f"Conectando a Qdrant en: {QDRANT_URL}")
Enter fullscreen mode

Exit fullscreen mode



3. Configuración de Modelos de Embedding

Configuramos un diccionario con 11 modelos de embedding a evaluar. Cada modelo incluye:

  • name: Nombre completo del modelo en HuggingFace
  • description: Características principales
  • dimension: Dimensiones del vector de salida

Ejemplo de configuración:

MODELS_TO_TEST = dict()

# Modelo 1: Ligero y rápido (384 dimensiones)
MODELS_TO_TEST['multilingual-e5-small'] = dict(
    name='intfloat/multilingual-e5-small',
    description='Multilingüe · Small · Rápido',
    dimension=384
)

# Modelo 2: Español optimizado (768 dimensiones)
MODELS_TO_TEST['sentence_similarity_spanish_es'] = dict(
    name='hiiamsid/sentence_similarity_spanish_es',
    description='Español · Optimizado · Preciso',
    dimension=768
)

# ... 9 modelos más ...
Enter fullscreen mode

Exit fullscreen mode

Total configurado: 11 modelos de embedding

💡 Lista completa: Ver variable MODELS_TO_TEST en el notebook con los 11 modelos



4. Carga de Datos Legales

# Cargar datos reales de la ley laboral paraguaya
def load_labor_law_data(json_path="../data/processed/codigo_trabajo_articulos.json"):
    """Cargar y procesar los datos reales de la ley laboral"""
    try:
        with open(json_path, 'r', encoding='utf-8') as f:
            law_data = json.load(f)

        print(f"Datos cargados exitosamente desde: {json_path}")
        print(f"Metadatos de la ley: {law_data['meta']}")
        print(f"Total de artículos: {len(law_data['articulos'])}")

        return law_data
    except Exception as e:
        print(f"Error cargando datos: {e}")
        return None

# Cargar datos reales
law_data = load_labor_law_data()
Enter fullscreen mode

Exit fullscreen mode



5. Selección de Artículos y Generación de Consultas

Para crear un dataset de prueba representativo, implementamos dos funciones clave:

Función 1: select_representative_articles()

  • Agrupa artículos por capítulo
  • Selecciona 1-4 artículos por capítulo de los primeros 8 capítulos
  • Formatea el texto como: "capítulo: artículo"
  • Resultado: 29 artículos representativos

Función 2: generate_semantic_questions()

  • Usa GPT-4o-mini para generar 2 preguntas por capítulo
  • Cada pregunta apunta a artículos específicos del capítulo
  • Prompt estructurado que solicita formato JSON
  • Resultado: 16 consultas semánticas de prueba

Ejemplos de consultas generadas:

1. "¿Cuál es el objetivo principal del código en relación con las relaciones laborales?"
   → Apunta al Artículo 1 (Objeto y aplicación del código)

2. "¿Qué tipos de trabajadores están sujetos a las disposiciones de este código?"
   → Apunta al Artículo 2 (Objeto y aplicación del código)

3. "¿Qué debe prevalecer en caso de dudas sobre la interpretación de normas?"
   → Apunta al Artículo 1 (Del trabajo y sus garantías)
Enter fullscreen mode

Exit fullscreen mode

Dataset final:

  • ✅ 29 textos legales seleccionados
  • ✅ 16 consultas de prueba
  • ✅ 8 capítulos representados

💡 Código completo: Ver notebooks/02_vectorstore_embedding_exploration.ipynb secciones “Selecting Sample Articles” y “Generate Semantic Questions”



6. Clase Evaluadora de Modelos

Creamos una clase EmbeddingModelEvaluator que encapsula toda la lógica de evaluación:

Métodos principales:

  1. connect_qdrant() – Establece conexión con Qdrant vector database

  2. load_model_and_measure_time(model_name) – Carga el modelo y mide el tiempo

   model = SentenceTransformer(model_name, trust_remote_code=True)
   load_time = time.time() - start_time
Enter fullscreen mode

Exit fullscreen mode

  1. create_embeddings_and_measure_time(model, texts) – Genera embeddings y mide rendimiento
   embeddings = model.encode(texts, convert_to_tensor=False)
   embedding_time = time.time() - start_time
Enter fullscreen mode

Exit fullscreen mode

Métricas capturadas:

  • ⏱️ Tiempo de carga del modelo
  • ⏱️ Tiempo de generación de embeddings
  • 📊 Dimensiones de los vectores
  • 🎯 Calidad de similitud semántica

💡 Código completo: Ver clase EmbeddingModelEvaluator en notebooks/02_vectorstore_embedding_exploration.ipynb



7. Evaluación de Calidad de Búsqueda

Implementamos dos funciones para medir la calidad de los modelos:

Función 1: calculate_cosine_similarity()

  • Calcula la similitud coseno entre dos embeddings
  • Fórmula: dot_product / (norm1 * norm2)
  • Rango: 0.0 (sin similitud) a 1.0 (idénticos)

Función 2: evaluate_search_quality()

  • Para cada consulta:
    1. Genera embedding de la consulta
    2. Calcula similitud con todos los textos
    3. Ordena por similitud descendente
    4. Mide tiempo de búsqueda
  • Retorna:
    • Similitud promedio del mejor resultado
    • Tiempo promedio de búsqueda
    • Resultados detallados por consulta

Ejemplo de flujo:

# 1. Generar embedding de consulta
query_embedding = model.encode(["¿Cuáles son los derechos del trabajador?"])

# 2. Calcular similitudes
for text_embedding in text_embeddings:
    similarity = calculate_cosine_similarity(query_embedding, text_embedding)

# 3. Ordenar y retornar top resultados
similarities.sort(key=lambda x: x[2], reverse=True)
Enter fullscreen mode

Exit fullscreen mode

💡 Código completo: Ver funciones de evaluación en notebooks/02_vectorstore_embedding_exploration.ipynb



8. Evaluación Completa de Modelos

El proceso de evaluación itera sobre los 11 modelos configurados:

Flujo de evaluación por modelo:

for model_key, model_config in MODELS_TO_TEST.items():
    # 1. Cargar modelo y medir tiempo
    model, load_time = evaluator.load_model_and_measure_time(model_config['name'])

    # 2. Generar embeddings y medir tiempo
    embeddings, embedding_time = evaluator.create_embeddings_and_measure_time(
        model, SAMPLE_LEGAL_TEXTS
    )

    # 3. Almacenar resultados con todas las métricas
    model_performance[model_key] = create_performance_dict(
        model_config, load_time, embedding_time, embeddings, model
    )
Enter fullscreen mode

Exit fullscreen mode

Métricas capturadas por modelo:

  • ⏱️ Tiempo de carga del modelo
  • ⏱️ Tiempo de generación de embeddings (29 artículos)
  • 📊 Dimensiones de los vectores
  • 🎯 Embeddings generados para búsquedas

Resultado: 11 modelos evaluados con métricas completas de rendimiento

💡 Código completo: Ver sección “Model Loading and Evaluation” en el notebook



9. Evaluación de Calidad de Búsqueda

Para cada modelo evaluado, medimos la calidad de búsqueda:

for model_key, model_data in model_performance.items():
    # Evaluar calidad con las 16 consultas de prueba
    quality_results = evaluate_search_quality(
        model_data, SAMPLE_LEGAL_TEXTS, SAMPLE_QUERIES
    )

    # Almacenar resultados
    search_quality_results[model_key] = quality_results
Enter fullscreen mode

Exit fullscreen mode

Métricas obtenidas por modelo:

  • 📊 Similitud promedio del mejor resultado
  • ⏱️ Tiempo promedio de búsqueda
  • 🎯 Resultados detallados por cada consulta

💡 Código completo: Ver sección “Search Quality Evaluation” en el notebook



10. Análisis Comparativo Completo

El análisis final combina todas las métricas en un sistema de puntuación ponderada:

Paso 1: Consolidar datos en DataFrames

  • DataFrame de rendimiento: tiempos de carga, embedding y velocidad
  • DataFrame de calidad: similitud promedio y tiempo de búsqueda
  • Merge de ambos para análisis completo

Paso 2: Normalización de scores (0-1)

def normalize_score(series, higher_is_better=True):
    if higher_is_better:
        return (series - series.min()) / (series.max() - series.min())
    else:
        return (series.max() - series) / (series.max() - series.min())
Enter fullscreen mode

Exit fullscreen mode

Paso 3: Sistema de pesos configurables

  • 🎯 Calidad de búsqueda: 50% (lo más importante para RAG)
  • ⚡ Velocidad de búsqueda: 35% (experiencia de usuario)
  • 🔄 Velocidad de embedding: 10% (procesamiento batch)
  • 📥 Velocidad de carga: 5% (se hace una vez)

Paso 4: Cálculo de score final

score_final = (
    score_calidad * 0.5 +
    score_velocidad_busqueda * 0.35 +
    score_velocidad_embedding * 0.1 +
    score_velocidad_carga * 0.05
)
Enter fullscreen mode

Exit fullscreen mode

Resultado: Ranking ordenado de modelos por score final

💡 Código completo: Ver sección “Comprehensive Comparative Analysis” en el notebook



📊 Resultados de la Evaluación



Métricas de Rendimiento

Modelo Carga (s) Embedding (s) Total (s) Velocidad (textos/s)
sentence_similarity_spanish_es 2.71 4.96 7.67 5.85
paraphrase-multilingual-MiniLM-L12-v2 3.71 0.90 4.61 32.22
jina-embeddings-v2-base-es 19.18 8.28 27.46 3.50
distiluse-base-multilingual-cased-v2 4.85 1.67 6.52 17.37
multilingual-e5-base 6.12 4.67 10.79 6.21
paraphrase-multilingual-mpnet-base-v2 8.45 3.89 12.34 7.46
multilingual-e5-small 3.89 1.82 5.71 15.93
bge-m3-korean 15.67 16.08 31.75 1.80
LaBSE 7.23 4.56 11.79 6.36
snowflake-arctic-embed-l-v2.0 12.34 9.87 22.21 2.94
gte-multilingual-base 5.67 4.95 10.62 5.86



Métricas de Calidad

Modelo Similitud Promedio Tiempo Búsqueda (s) Consultas/segundo
multilingual-e5-small 0.901 0.1596 6.27
multilingual-e5-base 0.876 0.5625 1.78
gte-multilingual-base 0.821 0.0580 17.24
paraphrase-multilingual-mpnet-base-v2 0.784 0.7120 1.40
paraphrase-multilingual-MiniLM-L12-v2 0.783 0.2105 4.75
jina-embeddings-v2-base-es 0.723 0.0607 16.47
bge-m3-korean 0.697 1.8040 0.55
snowflake-arctic-embed-l-v2.0 0.696 1.3093 0.76
sentence_similarity_spanish_es 0.663 0.5597 1.79
LaBSE 0.582 0.5851 1.71
distiluse-base-multilingual-cased-v2 0.495 0.2950 3.39



Análisis por Dimensiones

Dimensiones Similitud Promedio Tiempo Búsqueda (s) Score Final
384 0.842 0.185 0.896
512 0.495 0.295 0.438
768 0.741 0.423 0.695
1024 0.697 1.557 0.346



🏆 Ranking Final de Modelos



Sistema de Puntuación Ponderada

Criterio Peso Descripción
Calidad de Búsqueda 50% Similitud promedio en consultas legales
Velocidad de Búsqueda 35% Tiempo de respuesta para usuarios
Velocidad de Embedding 10% Procesamiento de documentos batch
Velocidad de Carga 5% Tiempo de inicialización del modelo



Top 5 Modelos Recomendados

Pos Score Final Calidad Modelo Dimensiones
🥇 0.969 0.901 multilingual-e5-small 384
🥈 0.836 0.821 gte-multilingual-base 768
🥉 0.831 0.876 multilingual-e5-base 768
4️⃣ 0.823 0.783 paraphrase-multilingual-MiniLM-L12-v2 384
5️⃣ 0.750 0.723 jina-embeddings-v2-base-es 768



🎯 Recomendaciones Específicas por Caso de Uso



🏆 MEJOR MODELO GENERAL: multilingual-e5-small

Características:

  • Score Final: 0.969 (mejor balance general)
  • Similitud Promedio: 0.901 (excelente calidad)
  • Dimensiones: 384 (eficiente)
  • Velocidad: 6.27 consultas/segundo

Recomendado para:

  • ✅ Sistemas RAG de producción
  • ✅ Aplicaciones que requieren alta precisión
  • ✅ Entornos con recursos limitados
  • ✅ Consultas legales complejas



⚡ MÁS RÁPIDO PARA BÚSQUEDAS: gte-multilingual-base

Características:

  • Tiempo de Búsqueda: 0.0580s (más rápido)
  • Consultas/segundo: 17.24
  • Similitud Promedio: 0.821 (buena calidad)
  • Dimensiones: 768

Recomendado para:

  • ✅ Aplicaciones en tiempo real
  • ✅ Sistemas con alta carga de consultas
  • ✅ APIs que requieren respuesta rápida
  • ✅ Búsquedas interactivas



🚀 MÁS RÁPIDO PARA EMBEDDINGS: paraphrase-multilingual-MiniLM-L12-v2

Características:

  • Tiempo de Embedding: 0.90s (más rápido)
  • Velocidad: 32.22 textos/segundo
  • Similitud Promedio: 0.783 (buena calidad)
  • Dimensiones: 384

Recomendado para:

  • ✅ Procesamiento batch masivo
  • ✅ Carga inicial de grandes volúmenes
  • ✅ Sistemas de indexación
  • ✅ Migración de datos



🔧 Integración con Qdrant



Configuración de Colección

def create_qdrant_collection(client, collection_name, vector_size):
    if client.collection_exists(collection_name):
        client.delete_collection(collection_name)

    client.create_collection(
        collection_name=collection_name,
        vectors_config=VectorParams(
            size=vector_size,
            distance=Distance.COSINE
        ),
        timeout=60
    )

    print(f"Colección '{collection_name}' creada")
Enter fullscreen mode

Exit fullscreen mode



Inserción de Documentos con Metadatos

La función insert_documents_qdrant_collection() inserta los embeddings en Qdrant con metadatos enriquecidos:

Proceso:

  1. Crear payload para cada documento con:

    • Texto del artículo
    • Longitud del texto
    • Fuente (código_trabajo_paraguay)
    • Metadatos legales: libro, título, capítulo, número de artículo
  2. Crear PointStruct con:

    • ID único
    • Vector (embedding)
    • Payload con metadatos
  3. Inserción en lote usando client.upsert()

Estructura del payload:

point = PointStruct(
    id=i,
    vector=embedding.tolist(),
    payload=payload_with_metadata
)
Enter fullscreen mode

Exit fullscreen mode

💡 Código completo: Ver función insert_documents_qdrant_collection() en el notebook



Búsqueda Semántica

def search_qdrant_collection(client: QdrantClient, collection_name: str, 
                      query_embedding: np.ndarray, limit: int = 3):
    """Probar búsqueda en Qdrant"""
    try:
        results = client.query_points(
            collection_name=collection_name,
            query=query_embedding,
            limit=limit
        ).points

        return results
    except Exception as e:
        print(f"Error en búsqueda de '{collection_name}': {e}")
        return None
Enter fullscreen mode

Exit fullscreen mode



Ejemplo de Resultados de Búsqueda

Consulta: '¿Cuál es el objetivo principal del código en relación con las relaciones laborales?'

Resultados de búsqueda en Qdrant:
================================================================================

1. ✅ Similitud: 0.915
    📝 este código tiene por objeto establecer normas para regular las relaciones entre los trabajadores y empleadores, concern...
    📖 Libro: libro primero
    📚 Título: titulo primero
    📂 Capítulo: capitulo i - del objeto y aplicación del código
    📜 Artículo Nº: 1

2. ✅ Similitud: 0.866
    📝 los reglamentos de fábricas o talleres, contratos individuales y colectivos de trabajo que establezcan derechos o benefi...
    📖 Libro: libro primero
    📚 Título: titulo primero
    📂 Capítulo: capitulo i - del objeto y aplicación del código
    📜 Artículo Nº: 4

3. ✅ Similitud: 0.865
    📝 se entiende por trabajo, a los fines de este código, toda actividad humana, consciente y voluntaria, prestada en forma d...
    📖 Libro: libro primero
    📚 Título: titulo primero
    📂 Capítulo: capitulo ii - del trabajo y sus garantías
    📜 Artículo Nº: 8
Enter fullscreen mode

Exit fullscreen mode



🚀 Implementación en Casos de Uso Reales



Para Desarrolladores:

“Necesito implementar búsqueda semántica en mi aplicación legal”

Solución: Pipeline completo con multilingual-e5-small

# Configuración recomendada
model = SentenceTransformer('intfloat/multilingual-e5-small')
embeddings = model.encode(legal_texts)
# Integración directa con Qdrant
Enter fullscreen mode

Exit fullscreen mode



Para Científicos de Datos:

“Necesito evaluar diferentes modelos de embedding para mi dataset”

Solución: Framework de evaluación sistemática

# Evaluación automatizada
evaluator = EmbeddingModelEvaluator(qdrant_url, api_key)
results = evaluator.evaluate_all_models(models_to_test)
# Análisis comparativo con métricas normalizadas
Enter fullscreen mode

Exit fullscreen mode



Para DevOps:

“Necesito optimizar el rendimiento del sistema RAG en producción”

Solución: Modelo optimizado para velocidad y recursos

# Configuración para producción
model = SentenceTransformer('Alibaba-NLP/gte-multilingual-base')
# 17.24 consultas/segundo con 0.821 de similitud
Enter fullscreen mode

Exit fullscreen mode



Para Organizaciones:

“Necesito un sistema RAG escalable para múltiples países”

Solución: Modelo multilingüe robusto

# Configuración multilingüe
model = SentenceTransformer('intfloat/multilingual-e5-base')
# Balance óptimo calidad/velocidad para escala
Enter fullscreen mode

Exit fullscreen mode



💡 Lecciones Aprendidas



1. Dimensiones vs Rendimiento

  • 384 dimensiones: Mejor balance velocidad/calidad para aplicaciones RAG
  • 768 dimensiones: Mayor calidad pero menor velocidad
  • 1024 dimensiones: Calidad similar pero significativamente más lento



2. Velocidad de Búsqueda es Crítica

  • La velocidad de búsqueda (35% del score) es más importante que la velocidad de embedding (10%)
  • Los usuarios esperan respuestas en tiempo real
  • La diferencia entre 0.06s y 1.8s es perceptible para el usuario



3. Calidad de Similitud es Fundamental

  • La similitud promedio (50% del score) es el factor más importante
  • Un modelo con 0.90 de similitud vs 0.50 marca la diferencia en precisión
  • La calidad de resultados impacta directamente en la confianza del usuario



4. Modelos Especializados vs Generales

  • Los modelos especializados en español no siempre superan a los multilingües
  • Los modelos multilingües modernos (E5, GTE) ofrecen excelente rendimiento
  • La especialización debe balancearse con la versatilidad



🎯 Impacto y Beneficios del Sistema



Métricas de Éxito

  • 0.901 similitud promedio con multilingual-e5-small
  • 6.27 consultas/segundo en tiempo real
  • 29 artículos procesados y vectorizados
  • 16 consultas de prueba con resultados precisos
  • 11 modelos evaluados sistemáticamente



Beneficios Técnicos

  • Búsqueda semántica precisa en contenido legal
  • Integración robusta con Qdrant vector database
  • Metadatos enriquecidos para filtrado avanzado
  • Escalabilidad para grandes volúmenes de datos
  • Flexibilidad para diferentes casos de uso



Beneficios de Negocio

  • Respuestas más relevantes a consultas legales
  • Tiempo de respuesta optimizado para usuarios
  • Escalabilidad para múltiples países y leyes
  • Reducción de costos computacionales
  • Mejora en experiencia del usuario final



🔧 Tecnologías Utilizadas

  • Python 3.13 con sentence-transformers
  • Qdrant para base de datos vectorial
  • OpenAI GPT-4o-mini para generación de consultas
  • NumPy/Pandas para análisis de datos
  • Matplotlib/Seaborn para visualizaciones
  • Docker para containerización
  • Phoenix/OpenTelemetry para observabilidad



📈 Próximos Pasos e Implementación



Implementación en Producción

  1. Configurar multilingual-e5-small como modelo principal
  2. Implementar pipeline de vectorización con metadatos enriquecidos
  3. Configurar Qdrant con dimensiones 384 y distancia coseno
  4. Implementar sistema de monitoreo de calidad de embeddings
  5. Optimizar para escala con procesamiento batch



Optimizaciones Adicionales

  • Caching de embeddings para consultas frecuentes
  • Compresión de vectores para reducir almacenamiento
  • Fine-tuning del modelo con datos legales específicos
  • A/B testing de diferentes modelos en producción



Monitoreo Continuo

  • Métricas de calidad de búsquedas en tiempo real
  • Latencia de respuesta por consulta
  • Uso de recursos computacionales
  • Feedback de usuarios sobre relevancia de resultados



📋 Resumen Ejecutivo



Modelo Recomendado

intfloat/multilingual-e5-small

  • Score Final: 0.969 (mejor balance general)
  • Similitud Promedio: 0.901 (excelente calidad)
  • Dimensiones: 384 (eficiente)
  • Velocidad: 6.27 consultas/segundo



Criterios de Selección

  • Calidad de Búsqueda (50%): Similitud promedio en consultas legales
  • Velocidad de Búsqueda (35%): Tiempo de respuesta para usuarios
  • Velocidad de Embedding (10%): Procesamiento de documentos batch
  • Velocidad de Carga (5%): Tiempo de inicialización del modelo



Resultados Clave

  • ✅ 11 modelos evaluados sistemáticamente
  • ✅ 29 artículos procesados y vectorizados
  • ✅ 16 consultas de prueba con resultados precisos
  • ✅ Sistema de puntuación ponderada implementado



🔗 Recursos y Enlaces



Repositorio del Proyecto

  • GitHub: lus-laboris-py – Sistema completo de procesamiento de datos legales con observabilidad



Documentación Técnica



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *