Embeddings y Búsqueda Vectorial: Guía para Principiantes
Quieres añadir búsqueda semántica a tu aplicación: los usuarios escriben una consulta y obtienen resultados basados en el significado, no en palabras clave exactas. Pero no sabes por dónde empezar: ¿qué son los embeddings? ¿Necesitas una base de datos vectorial? ¿Cómo se mide la similitud? Esta guía responde a esas preguntas con pasos prácticos y código que puedes ejecutar hoy.
¿Qué son los embeddings?
Un embedding es un vector denso de números en coma flotante que representa el significado de una entrada: texto, imagen, audio, etc. Para texto, un modelo como text-embedding-3-small o una alternativa de código abierto (p. ej., all-MiniLM-L6-v2) convierte una frase en, digamos, un vector de 384 dimensiones. Las palabras o frases con significados similares terminan cerca unas de otras en este espacio vectorial.
Ejemplo: "gato" y "gatito" tendrán vectores más cercanos que "gato" y "avión". Esta propiedad permite la búsqueda semántica: incrustas tus documentos y la consulta, y luego encuentras los vectores de documentos más cercanos.
Cómo funciona la búsqueda vectorial
La búsqueda vectorial (también llamada búsqueda por similitud) encuentra los vectores de tu conjunto de datos que son más similares a un vector de consulta. La similitud se mide típicamente con similitud coseno o producto punto. Para vectores normalizados, la similitud coseno y el producto punto son equivalentes.
La búsqueda por fuerza bruta compara la consulta con cada vector: está bien para miles de vectores, pero es demasiado lenta para millones. Ahí es donde entran los algoritmos de Vecino Más Cercano Aproximado (ANN), como HNSW (Hierarchical Navigable Small World) o IVF (Inverted File Index). Sacrifican un poco de precisión a cambio de enormes ganancias de velocidad.
Paso a paso: Construye un prototipo de búsqueda semántica
- Elige un modelo de embedding. Para texto en inglés, empieza con un modelo pequeño y rápido como
all-MiniLM-L6-v2(384 dims) de Sentence Transformers. Para producción, consideratext-embedding-3-small(1536 dims) otext-embedding-3-large(3072 dims) de OpenAI. - Incrusta tus documentos. Divide textos largos en fragmentos (p. ej., 200–500 palabras) para que cada fragmento capture una idea coherente. Almacena el texto original junto al vector.
- Elige un almacén vectorial. Para empezar rápido, usa una librería en memoria como FAISS o un simple array de NumPy. Para producción, elige una base de datos vectorial dedicada (ver tabla abajo).
- Incrusta la consulta. Usa el mismo modelo para incrustar la consulta de búsqueda del usuario.
- Busca. Calcula la similitud entre el vector de consulta y todos los vectores de documentos (o usa un índice ANN) y devuelve los k mejores resultados.
- Itera. Evalúa los resultados, ajusta el tamaño de los fragmentos, el modelo o la métrica de similitud.
Ejemplo mínimo en Python con Sentence Transformers y FAISS
from sentence_transformers import SentenceTransformer
import faiss
import numpy as np
# 1. Cargar modelo
model = SentenceTransformer('all-MiniLM-L6-v2')
# 2. Documentos de ejemplo
docs = [
"The cat sat on the mat.",
"A kitten is playing with yarn.",
"The stock market crashed today.",
"Investors are worried about inflation."
]
# 3. Crear embeddings
embeddings = model.encode(docs, convert_to_numpy=True)
# 4. Construir índice FAISS
dim = embeddings.shape[1]
index = faiss.IndexFlatL2(dim) # distancia L2; para coseno, normaliza primero
index.add(embeddings)
# 5. Buscar
query = "feline resting"
query_vec = model.encode([query], convert_to_numpy=True)
D, I = index.search(query_vec, k=2)
print([docs[i] for i in I[0]])
# Salida probable: ['The cat sat on the mat.', 'A kitten is playing with yarn.']
Elegir una base de datos vectorial
Para proyectos pequeños, puedes almacenar vectores en un archivo simple o en un índice en memoria. A medida que escalas, una base de datos vectorial dedicada ofrece persistencia, filtrado e índices ANN. Aquí tienes una comparación rápida:
| Base de datos | Tipo | Ideal para |
|---|---|---|
| FAISS | Librería | Prototipado, experimentos locales |
| Chroma | Embebida / Cliente-Servidor | Aplicaciones pequeñas y medianas, configuración fácil |
| Pinecone | Nube gestionada | Producción, escalado serverless |
| Weaviate | Código abierto / Nube | Búsqueda híbrida, API GraphQL |
| Qdrant | Código abierto / Nube | Alto rendimiento, filtrado |
| pgvector | Extensión de PostgreSQL | Stack existente de Postgres |
Buenas prácticas y errores comunes
- Normaliza los vectores si usas similitud coseno: muchas librerías asumen vectores unitarios para el producto punto.
- Divide con criterio: fragmentos demasiado grandes pierden especificidad; demasiado pequeños pierden contexto. Experimenta con solapamiento.
- Usa el mismo modelo para documentos y consultas. Mezclar modelos rompe la similitud.
- Considera la reducción de dimensionalidad (p. ej., PCA) solo si el almacenamiento o la velocidad son críticos; puede perjudicar la precisión.
- La búsqueda híbrida (combinar palabras clave y vectores) suele mejorar los resultados para coincidencias exactas.
Preguntas frecuentes
¿Necesito una base de datos vectorial para un proyecto pequeño?
No. Para unos pocos miles de vectores, puedes usar una librería en memoria como FAISS o incluso un array de NumPy. Una base de datos vectorial resulta útil cuando necesitas persistencia, filtrado o escalar más allá de la memoria.
¿Cómo elijo un modelo de embedding?
Empieza con un modelo pequeño y rápido como all-MiniLM-L6-v2 para prototipar. Si necesitas mayor precisión y puedes asumir costes de API, prueba text-embedding-3-small o text-embedding-3-large de OpenAI. Evalúa siempre con tus propios datos.
¿Cuál es la diferencia entre similitud coseno y distancia euclidiana?
La similitud coseno mide el ángulo entre vectores, ignorando la magnitud. La distancia euclidiana mide la distancia en línea recta. Para vectores normalizados, dan el mismo ranking. El coseno es común para embeddings de texto porque se centra en la dirección (significado) en lugar de la longitud.
Siguientes pasos
Ahora que entiendes lo básico, intenta construir una pequeña búsqueda semántica sobre tus propias notas o documentación. Experimenta con tamaños de fragmentos y modelos. A medida que crezcas, migra a una base de datos vectorial gestionada y añade búsqueda híbrida. El campo avanza rápido, pero estos fundamentos seguirán siendo relevantes.
Cuando necesites formatear respuestas de API o depurar payloads JSON de servicios de embeddings, el JSON Formatter puede ayudarte a inspeccionar y validar los datos rápidamente.