Conceptos

Búsqueda semántica

Técnica de recuperación de información que utiliza embeddings vectoriales para encontrar resultados por significado, no solo por coincidencia exacta de palabras clave.

growing#search#embeddings#vector-search#nlp#transformers#information-retrieval

¿Qué es?

La búsqueda semántica es una técnica de recuperación de información que va más allá de la coincidencia literal de palabras. En lugar de buscar si un documento contiene exactamente los términos de la consulta, convierte tanto la consulta como los documentos en vectores numéricos — llamados embeddings — y mide la similitud entre ellos en un espacio vectorial de alta dimensión.

Si un usuario busca «cómo desplegar en la nube», una búsqueda por palabras clave solo encontraría documentos que contengan esas palabras exactas. La búsqueda semántica también encontraría documentos sobre «deployment en AWS», «infraestructura serverless» o «CI/CD con contenedores» — porque entiende que el significado es similar.

¿Cómo funciona?

El proceso tiene tres fases:

1. Generación de embeddings

Un modelo de lenguaje transforma texto en vectores de dimensión fija. Cada vector captura el significado semántico del texto en un espacio donde textos similares quedan cerca entre sí.

Los modelos más comunes para esto son:

  • all-MiniLM-L6-v2 — 384 dimensiones, ligero, buena calidad general
  • text-embedding-3-small (OpenAI) — 1536 dimensiones, API comercial
  • Cohere Embed v3 — multilingüe, optimizado para recuperación

2. Indexación

Los embeddings de todos los documentos se almacenan en una estructura que permite búsqueda eficiente por similitud. Las opciones van desde un simple arreglo en memoria hasta bases de datos vectoriales especializadas.

3. Consulta

La consulta del usuario se convierte en un embedding con el mismo modelo, y se calcula la similitud coseno contra todos los documentos indexados. Los resultados se ordenan por similitud.

consulta → embedding → similitud coseno → resultados ordenados

Implementación en este sitio

El primer intento (cliente)

La primera implementación de búsqueda semántica en este sitio usó Transformers.js con el modelo Xenova/all-MiniLM-L6-v2 ejecutándose directamente en el navegador vía WebAssembly. Los embeddings se pre-computaban en build time y se pasaban como props a la página de búsqueda.

¿Por qué se removió? Cuatro problemas lo hicieron inviable en producción:

  1. Descarga de ~30 MB en la primera búsqueda — el modelo ONNX se descargaba silenciosamente mientras el usuario veía «Buscando...» sin resultados. Para un sitio personal, esto es inaceptable.
  2. Inconsistencias en la API de tensores — Transformers.js v3 devuelve tensores con formatos diferentes entre Node.js y el runtime WASM del navegador. tolist(), .data y output[0] se comportaban distinto según el contexto, causando fallos silenciosos.
  3. Problemas de despliegue en Vercel — el runtime WASM tenía incompatibilidades en producción que no se reproducían localmente.
  4. Complejidad vs. valor — con pocos artículos, la búsqueda semántica no ofrece ventaja significativa sobre la búsqueda por palabras clave.

La decisión y los detalles técnicos están documentados en el issue #9 del repositorio.

El estado actual

La búsqueda actual es por palabras clave: coincidencia instantánea contra títulos, resúmenes y tags. Cero dependencias, funciona sincrónicamente, sin estado de carga.

Los embeddings pre-computados siguen generándose en build time (scripts/generate-embeddings.ts) y se almacenan en public/embeddings.json — listos para uso futuro.

Enfoques de producción

Para implementar búsqueda semántica de forma robusta, hay varias opciones según la escala:

Servidor con modelo local

Ejecutar el modelo de embeddings en una API route de Node.js (no en el navegador). El modelo se carga una vez al iniciar el servidor y procesa consultas en milisegundos. Viable para sitios con tráfico moderado.

Base de datos vectorial

Para colecciones grandes, una base de datos vectorial especializada maneja la indexación y búsqueda eficiente:

  • Pinecone — servicio gestionado, escala automática
  • Weaviate — open source, soporta búsqueda híbrida
  • pgvector — extensión de PostgreSQL, ideal si ya se usa Postgres
  • Qdrant — open source, alto rendimiento

API de embeddings + búsqueda en memoria

Para sitios estáticos con pocas decenas de documentos, pre-computar embeddings en build time y hacer la búsqueda coseno en el cliente es viable — siempre que el modelo no se descargue en el navegador. Los embeddings pre-computados pesan kilobytes, no megabytes.

Búsqueda híbrida

La combinación de búsqueda por palabras clave y búsqueda semántica suele dar mejores resultados que cualquiera de las dos por separado. El enfoque típico es:

  1. Ejecutar ambas búsquedas en paralelo
  2. Normalizar los scores de cada una
  3. Combinar con un peso configurable (por ejemplo, 0.7 semántico + 0.3 keyword)

Beneficios

  • Comprensión de sinónimos y paráfrasis — encuentra resultados relevantes aunque no compartan palabras exactas con la consulta
  • Búsqueda multilingüe — con modelos multilingües, una consulta en español puede encontrar documentos en inglés y viceversa
  • Tolerancia a errores tipográficos — los embeddings capturan significado, no ortografía exacta
  • Descubrimiento de contenido relacionado — la similitud vectorial permite sugerir artículos relacionados sin configuración manual
  • Escalabilidad — funciona igual de bien con 10 documentos que con 10 millones (con la infraestructura adecuada)

¿Cuándo vale la pena?

La búsqueda semántica agrega valor real cuando:

  • El corpus tiene más de ~20 documentos
  • Los usuarios buscan con lenguaje natural, no con términos exactos
  • El contenido es multilingüe
  • Se necesita descubrimiento de contenido relacionado

Para colecciones pequeñas con vocabulario predecible, la búsqueda por palabras clave es más simple, más rápida y suficientemente efectiva.

Referencias

Conceptos