Saltar al contenido principal

Vector embeddings

El vector embedding es uno de los seis artefactos que Clione produce por producto. Es un array de longitud fija de números en coma flotante que codifica el significado del texto del producto en un espacio de alta dimensión, de manera que dos productos semánticamente similares aterrizan cerca geométricamente aunque usen palabras distintas.

Para qué se usa

  • Búsqueda semántica — "sábanas de lino para gente que pasa calor durmiendo" matchea con un producto titulado "Ropa de cama 100% lino belga, termorreguladora" sin que coincida ni una palabra
  • Recomendaciones de productos similares
  • Detección de duplicados entre catálogos
  • Clustering — agrupar productos que se comportan parecido

Qué alimenta el embedding

Una sola cadena ensamblada por producto (fuente: packages/storage/src/embeddings/embedding-text.ts):

<core_identity> | <reasoning.recommended_for> | <reasoning.decision_logic>
| <technical_details.original_title> | <technical_details.vendor>
| <search_keywords joined>

Atención: el texto enriquecido alimenta el embedding, no solo el título crudo. Por eso importa la calidad del enriquecimiento — un mal enriquecimiento produce un embedding débil.

Qué modelo

EntornoProveedorModeloDimensiones
ProducciónOpenAItext-embedding-3-small1536
Dev (Ollama)Localnomic-embed-text768

Los vectores se L2-normalizan, así similitud coseno = producto escalar (rápido en pgvector).

Dónde viven

Columna embedding en la tabla product_embeddings — tipada vector(1536) vía la extensión pgvector.

Aviso sobre cambio de dimensión

El tipo de columna vector(1536) está fijado a nivel de schema. Si cambias el modelo de embedding por uno con otra dimensión (p. ej. el default de Ollama, 768 dims), necesitas:

  1. Una migración de schema para cambiar las dims de la columna embedding
  2. Re-indexar todo — cada embedding existente debe regenerarse desde el texto
  3. Tiempo muerto o periodo de dual-write según la estrategia

No es un toggle en runtime. Planifica con cabeza.

Consultar

Internamente:

-- Top 10 más similares a un vector de referencia
SELECT id, core_identity,
embedding <=> '[0.123, 0.456, ...]'::vector AS distance
FROM product_embeddings
WHERE tenant_id = $1
ORDER BY embedding <=> $2::vector
LIMIT 10;

El operador <=> es distancia coseno (más bajo = más similar).

Lo que cuestan los embeddings

OpenAI text-embedding-3-small: 0,02 $ por 1M tokens en el momento de escribir esto. El texto ensamblado por producto promedia ~200 tokens → ~0,00004 $ por producto → 4 $ por cada 100.000 productos. Barato comparado con la propia llamada de enriquecimiento al LLM.