Buscaste «cómo apagar un incendio» y tu sistema devolvió «mejores técnicas para encender fogatas». Si todavía usas LIKE '%texto%' o incluso búsquedas full-text con TF-IDF, estás jugando a la lotería semántica. Los embeddings no son magia: son geometría aplicada al lenguaje, y entenderlos te separa de quienes siguen programando como si fuera 2010.
El problema de la coincidencia literal
Durante años resolvemos búsqueda de texto con índices invertidos: tokenizas, normalizas, y buscas coincidencias exactas o stemmings. Funciona para SKUs y códigos postales, pero falla estrepitosamente con sinónimos, contexto o intención. «Rey» y «monarca» son la misma entidad, pero para SQL son cadenas diferentes.
Los embeddings solucionan esto traduciendo el lenguaje a coordenadas en un espacio vectorial denso. No importa si escribo «auto», «coche» o «vehículo»; si el modelo fue entrenado correctamente, estos tres vectores apuntarán en direcciones muy similares dentro de un hiperespacio de 768 o 1536 dimensiones.
Qué son exactamente (sin matemáticas espantosas)
Un embedding es una representación vectorial densa generada por un modelo de lenguaje (transformers, para ser específicos). Piensa en ello como una función hash que preserva significado: texto entrada → vector de floats salida.
La clave está en que la distancia entre vectores codifica relaciones semánticas. En el embedding space:
- Vectores cercanos = significado similar
- Direcciones específicas codifican atributos (género, tiempo verbal, tamaño)
- Operaciones aritméticas capturan analogías: Rey – Hombre + Mujer ≈ Reina
No necesitas entender la arquitectura del transformer para usarlos, pero sí debes saber que estás comprimiendo el significado contextual en un array de floats que consume memoria y requiere índices específicos para búsquedas eficientes.
La geometría escondida en 768 dimensiones
Una vez tienes vectores, ¿cómo comparas? No uses distancia euclidiana a menos que tus vectores estén normalizados. Lo estándar es similitud coseno: mide el ángulo entre vectores, ignorando magnitud (útil cuando comparas oraciones cortas vs largas con el mismo significado).
import numpy as np
from sentence_transformers import SentenceTransformer
# Modelo ligero, corre local sin GPU
model = SentenceTransformer('all-MiniLM-L6-v2')
sentences = [
"El médico curó al paciente",
"El doctor trató al enfermo",
"La pizza estaba deliciosa"
]
embeddings = model.encode(sentences)
# Producto punto = similitud coseno si están normalizados L2
similarity = np.dot(embeddings[0], embeddings[1])
print(f"Similitud médico/doctor: {similarity:.3f}") # ~0.85
print(f"Similitud médico/pizza: {np.dot(embeddings[0], embeddings[2]):.3f}") # ~0.20
El resultado es un score entre -1 y 1. En producción, usas un threshold (típicamente 0.7+) para decidir si dos textos son semánticamente equivalentes.
Geek de la tecnología, en busca de la mejora y aprendizaje continuo.
Ingeniero en ciencias de la computación, Postgrado en Análisis y predicción de datos