Búsqueda vectorial: cómo los chatbots de IA encuentran respuestas
La búsqueda vectorial impulsa los chatbots de IA modernos. Aprende cómo funciona, por qué supera a la búsqueda por palabras clave y cómo los chatbots entienden lo que quieres decir.
La búsqueda vectorial impulsa los chatbots de IA modernos. Aprende cómo funciona, por qué supera a la búsqueda por palabras clave y cómo los chatbots entienden lo que quieres decir.
Cuando le preguntas a un chatbot de IA "¿Cómo cancelo?", ¿cómo sabe que te refieres a tu suscripción y no a una reunión? La respuesta es búsqueda vectorial: una tecnología que entiende significado, no solo palabras clave.
Resumen rápido:
- La búsqueda vectorial convierte texto en embeddings numéricos que capturan significado, de modo que "cancelar mi plan" coincide con "terminar suscripción" incluso sin palabras compartidas, resolviendo la mayor limitación de la búsqueda tradicional por palabras clave.
- Para producción, combina búsqueda vectorial con búsqueda por palabras clave (búsqueda híbrida) para obtener tanto comprensión semántica como precisión de coincidencia exacta, y luego reordena resultados para máxima relevancia.
- Configuración óptima: divide documentos en chunks de 500-1000 tokens con 100-200 tokens de solapamiento, usa un modelo de embeddings de calidad (por ejemplo, OpenAI text-embedding-3) y almacena vectores en una base de datos especializada como pgvector.
Esta guía sintetiza detalles operativos de tres categorías de fuentes:
Evitamos afirmaciones puramente de marketing y priorizamos ejemplos que se despliegan en bases de código reales. Cuando citamos cifras de latencia o precisión, la metodología, dataset o condiciones de prueba se indican junto a ellas. Revisado por última vez: abril de 2026.
La búsqueda tradicional coincide palabras. Pregunta "¿Cómo cancelo?" y busca documentos que contengan "cancelar".
Pero ¿qué pasa si tus docs de ayuda dicen "terminar suscripción" o "finalizar tu plan"? La búsqueda por palabras clave se pierde esos resultados por completo.
| Tú preguntas | El doc contiene | ¿Coincide por palabra clave? |
|---|---|---|
| "cancelar" | "cancelar" | Sí |
| "cancelar" | "terminar" | No |
| "cancelar" | "finalizar suscripción" | No |
| "cancelar mi plan" | "cómo cancelar" | Sí |
| "detener mi suscripción" | "cancelar plan" | No |
Por eso los chatbots antiguos se sentían tan frustrantes: pequeñas diferencias de redacción rompían todo.
La búsqueda vectorial convierte texto en embeddings: representaciones numéricas que capturan significado. En lugar de coincidir caracteres, coloca el texto en un espacio matemático de alta dimensión donde la proximidad corresponde a similitud semántica.
Un modelo de embedding es una red neuronal, normalmente una arquitectura transformer, entrenada con enormes corpus de texto. Durante el entrenamiento, el modelo aprende a mapear texto a un vector de longitud fija de modo que entradas semánticamente similares caigan cerca entre sí en el espacio vectorial.
Esto es lo que pasa paso a paso cuando generas el embedding de una frase:
["¿", "Cómo", "cancel", "##o", "mi", "sus", "##cripción", "?"].[CLS].La salida es una lista de números de punto flotante: el embedding:
"¿Cómo cancelo?" -> [0.23, -0.45, 0.67, 0.12, ...] (1536 dimensiones)
"Terminar mi suscripción" -> [0.21, -0.43, 0.69, 0.14, ...]
"¿Qué tiempo hace?" -> [-0.56, 0.34, -0.12, 0.78, ...]
¿Notas cómo significados similares tienen números similares? Esa es la idea central.
Cada número en un vector de embedding representa una característica aprendida del texto. Un embedding de 1536 dimensiones significa que el modelo codifica 1536 aspectos distintos de significado. Puedes pensar en las dimensiones, de forma aproximada, como ejes en un sistema de coordenadas:
Los embeddings de más dimensiones capturan más matices, pero requieren más almacenamiento y comparaciones más lentas. Un solo vector de 1536 dimensiones usando floats de 32 bits consume 6 KB de memoria. Con un millón de documentos, eso son aproximadamente 6 GB solo para los vectores.
| Dimensiones | Almacenamiento por vector | Almacenamiento para 1M de vectores | Tradeoff |
|---|---|---|---|
| 384 | 1.5 KB | ~1.5 GB | Rápido, menos matiz |
| 768 | 3 KB | ~3 GB | Equilibrado |
| 1536 | 6 KB | ~6 GB | Buen matiz, coste moderado |
| 3072 | 12 KB | ~12 GB | Máximo matiz, coste más alto |
Para encontrar contenido relevante, el sistema compara el vector de la consulta contra todos los vectores de documentos almacenados usando una métrica de distancia. La métrica más común es la similitud coseno.
La similitud coseno mide el ángulo entre dos vectores, ignorando su magnitud. Dos vectores apuntando en la misma dirección tienen una similitud coseno de 1.0 (significado idéntico); vectores ortogonales puntúan 0.0 (sin relación); vectores opuestos puntúan -1.0.
La fórmula para dos vectores A y B:
cosine_similarity(A, B) = (A . B) / (||A|| * ||B||)
Donde A . B es el producto punto (multiplicar elementos correspondientes y luego sumar) y ||A|| es la magnitud (raíz cuadrada de la suma de elementos al cuadrado).
Ejemplo trabajado con vectores pequeños de 4 dimensiones:
A = [0.5, 0.3, 0.8, 0.1] ("cancelar mi suscripción")
B = [0.4, 0.35, 0.75, 0.15] ("terminar mi plan")
C = [0.1, -0.6, 0.2, 0.9] ("pronóstico del tiempo hoy")
Producto punto A . B = (0.5*0.4) + (0.3*0.35) + (0.8*0.75) + (0.1*0.15)
= 0.20 + 0.105 + 0.60 + 0.015
= 0.92
||A|| = sqrt(0.25 + 0.09 + 0.64 + 0.01) = sqrt(0.99) = 0.995
||B|| = sqrt(0.16 + 0.1225 + 0.5625 + 0.0225) = sqrt(0.8675) = 0.931
cosine_similarity(A, B) = 0.92 / (0.995 * 0.931) = 0.993 (muy similar)
Producto punto A . C = (0.5*0.1) + (0.3*-0.6) + (0.8*0.2) + (0.1*0.9)
= 0.05 - 0.18 + 0.16 + 0.09
= 0.12
||C|| = sqrt(0.01 + 0.36 + 0.04 + 0.81) = sqrt(1.22) = 1.105
cosine_similarity(A, C) = 0.12 / (0.995 * 1.105) = 0.109 (no similar)
El proceso de recuperación luego ordena todos los documentos por su similitud coseno con la consulta y devuelve los top-K resultados:
Vector de pregunta: [0.23, -0.45, 0.67, ...]
|
Comparar con todos los vectores de documentos
|
Devolver: "Cómo cancelar tu suscripción" (similitud: 0.94)
"Finalizar tu plan antes de tiempo" (similitud: 0.89)
"Política de reembolso" (similitud: 0.72)
Otras métricas de distancia incluyen distancia euclidiana (L2) y producto punto. La similitud coseno se prefiere cuando los vectores no están normalizados, mientras que el producto punto es más rápido cuando sí lo están.
Para hacer tangible la diferencia, considera la misma consulta ejecutada contra ambos sistemas en una base de conocimiento con 500 artículos de ayuda.
Consulta: "Me cobraron dos veces en mi tarjeta de crédito"
BM25 busca documentos que contengan los términos "cobraron", "dos veces", "crédito" y "tarjeta". Ordena por frecuencia de término y frecuencia inversa de documento:
| Ranking | Título del documento | Por qué coincidió |
|---|---|---|
| 1 | "Métodos de pago con tarjeta de crédito" | Contiene "tarjeta de crédito" con frecuencia |
| 2 | "FAQ de impuesto de ventas cobrado" | Contiene "cobrado" |
| 3 | "Instrucciones para actualizar tarjeta de crédito" | Contiene "tarjeta de crédito" |
| 4 | "Ciclo de facturación semestral" | Contiene "dos veces" |
| 5 | "Información de límite de crédito" | Contiene "crédito" |
Ninguno es lo que el usuario necesita. El artículo realmente relevante, "Política de pago duplicado y reembolso", no contiene la frase "cobrado dos veces" ni "tarjeta de crédito", así que es invisible para la búsqueda por palabras clave.
La búsqueda vectorial crea el embedding de la consulta y encuentra documentos semánticamente similares sin importar vocabulario:
| Ranking | Título del documento | Similitud |
|---|---|---|
| 1 | "Política de pago duplicado y reembolso" | 0.94 |
| 2 | "Cómo solicitar un reembolso por doble facturación" | 0.91 |
| 3 | "Proceso de resolución de disputa de facturación" | 0.87 |
| 4 | "Troubleshooting de error de pago" | 0.83 |
| 5 | "Métodos de pago con tarjeta de crédito" | 0.71 |
Los primeros resultados abordan directamente el problema del usuario. "Pago duplicado", "doble facturación" y "disputa de facturación" son semánticamente cercanos a "cobrado dos veces" aunque compartan pocas palabras clave.
Este ejemplo ilustra por qué la búsqueda vectorial es esencial para cualquier sistema donde los usuarios formulan preguntas con sus propias palabras en lugar de usar la terminología exacta de tu documentación. Para casos donde necesitas tanto comprensión semántica como precisión de coincidencia exacta (como códigos de error o SKUs de producto), la búsqueda híbrida combina los dos enfoques. Lee nuestra guía profunda sobre búsqueda híbrida.
"Cancelar", "terminar", "finalizar" y "detener" se agrupan en el espacio vectorial.
"Quiero recuperar mi dinero" encuentra "política de reembolso" incluso sin palabras compartidas.
Los embeddings modernos funcionan entre idiomas: una pregunta en español puede coincidir con docs en inglés.
"Como cancelo mi suscripsion" sigue funcionando porque se captura el significado.
Modelos populares para embeddings de texto:
| Modelo | Dimensiones | Mejor para |
|---|---|---|
| OpenAI text-embedding-3-large | 3072 | Uso general |
| OpenAI text-embedding-3-small | 1536 | Uso general rentable |
| Cohere embed-v3 | 1024 | Multilingüe |
| Voyage-3 | 1024 | Documentos largos |
| BGE-large | 1024 | Opción open-source |
| nomic-embed-text-v1.5 | 768 | Open-source, soporte Matryoshka |
Más dimensiones = más matiz, pero búsqueda más lenta y mayor coste de almacenamiento. Muchos modelos nuevos soportan embeddings Matryoshka, permitiendo truncar vectores a menos dimensiones en tiempo de consulta para intercambiar precisión por velocidad.
Antes de generar embeddings, los documentos se dividen en chunks:
Documento completo (5000 palabras)
|
Chunk 1 (500 palabras): "Gestión de suscripción..."
Chunk 2 (500 palabras): "Política de cancelación..."
Chunk 3 (500 palabras): "Proceso de reembolso..."
¿Por qué usar chunks?
Tamaño óptimo de chunk: 500-1000 tokens con 100-200 tokens de solapamiento. El solapamiento asegura que no se pierda información que cruza un límite de chunk.
Almacenar y buscar vectores a escala requiere infraestructura especializada. Así se comparan las opciones líderes:
| Función | pgvector | Pinecone | Weaviate | Qdrant |
|---|---|---|---|---|
| Tipo | Extensión PostgreSQL | SaaS gestionado | Open-source / cloud | Open-source / cloud |
| Hosting | Postgres autogestionado o gestionado | Totalmente gestionado | Self-hosted o Weaviate Cloud | Self-hosted o Qdrant Cloud |
| Dimensiones máximas | Ilimitadas | 20,000 | Ilimitadas | Ilimitadas |
| Tipos de índice | IVFFlat, HNSW | Propietario | HNSW | HNSW, cuantización escalar/producto |
| Filtrado | Cláusulas SQL WHERE completas | Filtros de metadata | Filtros basados en GraphQL | Filtros de payload con campos indexados |
| Búsqueda híbrida | Combinar con búsqueda full-text de pg | Vectores sparse-dense | BM25 + vector integrado | Vectores sparse + vectores densos |
| Escalado | Vertical (o Citus para horizontal) | Horizontal automático | Horizontal automático | Sharding horizontal |
| Precios | Gratis (open-source) | Pago por vector + consulta | Gratis self-hosted; tiers cloud | Gratis self-hosted; tiers cloud |
| Mejor para | Equipos ya en Postgres; control de coste | Inicio rápido; cero ops | Apps de búsqueda con muchas funciones | Necesidades de alto rendimiento y baja latencia |
pgvector es la elección correcta si ya usas PostgreSQL. Obtienes búsqueda vectorial sin añadir otra base de datos a tu stack. Maneja millones de vectores bien en un solo nodo, y conservas todas las capacidades SQL para filtrado, joins y transacciones. En Chatsy, migramos de Pinecone a pgvector y redujimos nuestro coste de infraestructura mientras ganamos simplicidad operativa.
Pinecone es la opción gestionada más sencilla. Si quieres cero gestión de infraestructura y estás dispuesto a pagar por ello, Pinecone maneja sharding, replicación y escalado automáticamente. El tradeoff es lock-in de proveedor y coste a escala.
Weaviate destaca por búsqueda híbrida integrada y un ecosistema rico de módulos (auto-vectorización, búsqueda generativa). Es una opción fuerte para equipos que construyen aplicaciones intensivas en búsqueda que necesitan más que similitud vectorial cruda.
Qdrant sobresale en rendimiento bruto de consulta y ofrece opciones avanzadas de cuantización que reducen uso de memoria 4-32x con pérdida mínima de precisión. Encaja bien en aplicaciones sensibles a latencia con grandes colecciones vectoriales.
El rendimiento de búsqueda vectorial depende mucho de tu estrategia de indexado. Los dos enfoques dominantes en producción son IVFFlat y HNSW.
IVFFlat particiona vectores en clusters usando k-means. En tiempo de consulta, busca solo en los clusters más cercanos en lugar de escanear cada vector.
nprobe (número de clusters buscados).nprobe en tiempo de consulta. Demasiado bajo = resultados perdidos. Demasiado alto = consultas lentas.sql-- Crear un indice IVFFlat en pgvector CREATE INDEX ON chunks USING ivfflat (embedding vector_cosine_ops) WITH (lists = 1000); -- numero de clusters -- Ajustar precision de busqueda en tiempo de consulta SET ivfflat.probes = 10; -- buscar 10 de 1000 clusters
HNSW construye un grafo multicapa donde cada nodo se conecta con sus vecinos aproximados más cercanos. Las consultas atraviesan el grafo desde capas superiores (dispersas) hacia capas inferiores (densas), acercándose a los vectores más cercanos.
sql-- Crear un indice HNSW en pgvector CREATE INDEX ON chunks USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 200); -- Ajustar precision de busqueda en tiempo de consulta SET hnsw.ef_search = 100;
Las cifras de rendimiento varían por hardware, dataset y configuración. Las siguientes son benchmarks representativos de una instancia PostgreSQL de un solo nodo (8 vCPU, 32 GB RAM) con 1 millón de vectores de 1536 dimensiones:
| Métrica | IVFFlat (probes=10) | IVFFlat (probes=50) | HNSW (ef=100) | HNSW (ef=400) |
|---|---|---|---|---|
| Recall@10 | 85% | 95% | 98% | 99.5% |
| Latencia P95 | 8 ms | 35 ms | 5 ms | 18 ms |
| Tiempo de construcción de índice | 4 min | 4 min | 90 min | 90 min |
| Tamaño del índice en disco | 6.1 GB | 6.1 GB | 9.8 GB | 9.8 GB |
Para la mayoría de cargas de producción, HNSW con ef_search=100 ofrece el mejor equilibrio entre recall y latencia. Usa IVFFlat cuando necesites construcciones de índice más rápidas (por ejemplo, datasets actualizados con frecuencia) o tengas restricciones estrictas de memoria.
A escalas más altas (10M+ vectores), considera:
Este ejemplo muestra el flujo completo: generar un embedding, almacenarlo y consultarlo.
pythonfrom openai import OpenAI import psycopg2 import numpy as np client = OpenAI() def embed(text: str) -> list[float]: """Genera un embedding para una cadena de texto.""" response = client.embeddings.create( input=text, model="text-embedding-3-small" ) return response.data[0].embedding def cosine_similarity(a, b): """Calcula similitud coseno entre dos vectores.""" a, b = np.array(a), np.array(b) return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)) # --- Almacenar embeddings en pgvector --- conn = psycopg2.connect("postgresql://localhost/mydb") cur = conn.cursor() # Habilitar pgvector y crear tabla cur.execute("CREATE EXTENSION IF NOT EXISTS vector;") cur.execute(""" CREATE TABLE IF NOT EXISTS documents ( id SERIAL PRIMARY KEY, content TEXT NOT NULL, embedding vector(1536) ); """) # Insertar documentos con sus embeddings docs = [ "Cómo cancelar tu suscripción", "Política de reembolso para planes anuales", "Comparación de precios y planes", "Actualizar tu método de pago", ] for doc in docs: doc_embedding = embed(doc) cur.execute( "INSERT INTO documents (content, embedding) VALUES (%s, %s)", (doc, doc_embedding) ) conn.commit() # Crear un indice HNSW para busqueda rapida cur.execute(""" CREATE INDEX IF NOT EXISTS documents_embedding_idx ON documents USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 200); """) conn.commit() # --- Consultar --- query = "Quiero recuperar mi dinero" query_embedding = embed(query) cur.execute(""" SELECT content, 1 - (embedding <=> %s::vector) AS similarity FROM documents ORDER BY embedding <=> %s::vector LIMIT 3; """, (query_embedding, query_embedding)) results = cur.fetchall() for content, similarity in results: print(f"{similarity:.3f} {content}") # Salida: # 0.891 Política de reembolso para planes anuales # 0.834 Cómo cancelar tu suscripción # 0.712 Comparación de precios y planes
typescriptimport OpenAI from "openai"; import { Pool } from "pg"; const openai = new OpenAI(); const pool = new Pool({ connectionString: "postgresql://localhost/mydb" }); async function embed(text: string): Promise<number[]> { const response = await openai.embeddings.create({ input: text, model: "text-embedding-3-small", }); return response.data[0].embedding; } async function search(query: string, limit = 5) { const queryEmbedding = await embed(query); // pgvector usa <=> para distancia coseno (1 - similitud) const result = await pool.query( `SELECT content, 1 - (embedding <=> $1::vector) AS similarity FROM documents ORDER BY embedding <=> $1::vector LIMIT $2`, [JSON.stringify(queryEmbedding), limit] ); return result.rows; } // Uso const results = await search("Quiero recuperar mi dinero"); console.log(results); // [ // { content: "Política de reembolso para planes anuales", similarity: 0.891 }, // { content: "Cómo cancelar tu suscripción", similarity: 0.834 }, // ... // ]
Para aplicaciones reales:
La búsqueda vectorial no es perfecta:
"Código de error E-1234" puede no coincidir bien con "error E-1234" porque los embeddings se enfocan en significado semántico, no cadenas exactas.
Nombres de producto poco comunes o términos técnicos pueden no generar buenos embeddings si estuvieron poco representados en los datos de entrenamiento del modelo.
"No quiero cancelar" y "Quiero cancelar" tienen embeddings similares pese a significados opuestos. Los modelos de embedding codifican el tema con más fuerza que los operadores lógicos.
Los modelos de embedding tienen longitudes máximas de entrada (normalmente 512 a 8192 tokens). El texto más allá del límite se trunca, potencialmente perdiendo información crítica.
Combina búsqueda vectorial y búsqueda por palabras clave:
Pregunta del usuario
|
+------------------+------------------+
| Búsqueda vectorial | Búsqueda keyword |
| (significado) | (términos exactos) |
+------------------+------------------+
| |
+--------+-----------+
|
Combinar y reordenar
|
Resultados finales
Esto obtiene lo mejor de ambos mundos: comprensión semántica Y coincidencia exacta. Para un recorrido completo de implementación y benchmarks, lee Búsqueda híbrida explicada: lo mejor de ambos mundos.
Nuestro pipeline de generación aumentada por recuperación:
Este enfoque multietapa entrega tasas de respuesta relevante de 94%+. Si estás evaluando si usar RAG o hacer fine-tuning de un modelo para tu chatbot, mira nuestra comparación de RAG vs fine-tuning para chatbots.
Chatsy maneja toda esta complejidad por ti. Sube tus docs y automáticamente:
¿Quieres más? Lee sobre búsqueda híbrida y expansión de consultas.
La búsqueda vectorial es poderosa, pero es el default equivocado en varios casos:
Cuando la respuesta es "no estoy seguro", empieza con búsqueda híbrida. La búsqueda vectorial pura rara vez supera a la híbrida en producción.
La búsqueda vectorial es una técnica que encuentra contenido relevante por significado en lugar de palabras clave exactas. Convierte texto en embeddings numéricos (vectores) usando modelos de IA basados en transformers y los compara por similitud con métricas como similitud coseno, de modo que "cancelar mi plan" coincide con "terminar suscripción" incluso sin palabras compartidas. Impulsa chatbots de IA modernos, sistemas de generación aumentada por recuperación y búsqueda semántica.
La búsqueda por palabras clave coincide palabras exactas: "cancelar" solo encuentra documentos que contienen "cancelar". La búsqueda vectorial entiende significado: "quiero recuperar mi dinero" encuentra "política de reembolso" incluso sin términos compartidos. La búsqueda vectorial maneja sinónimos, paráfrasis y typos; la búsqueda por palabras clave no. Para producción, combina ambas en búsqueda híbrida para mejores resultados.
Los embeddings son representaciones numéricas de texto producidas por modelos de IA basados en transformers. Cada pieza de texto se convierte en una lista de números (por ejemplo, 1024 o 3072 dimensiones) que capturan su significado. Significados similares producen vectores similares: "cancelar" y "terminar" tienen embeddings cercanos. El modelo los genera procesando texto por capas de self-attention y agrupando la salida en un vector de longitud fija. Los embeddings habilitan búsqueda por similitud en grandes colecciones de documentos.
La búsqueda vectorial impulsa chatbots de IA, búsqueda semántica en centros de ayuda, recuperación de documentos para sistemas RAG y motores de recomendación. Sobresale cuando los usuarios formulan preguntas de forma distinta a tu documentación (sinónimos, paráfrasis) o cuando necesitas coincidencia basada en significado en contenido multilingüe o largo.
La búsqueda vectorial puede ser rápida con indexado adecuado (HNSW entrega latencia P95 sub-10ms con 1M de vectores), pero normalmente requiere más cómputo y memoria que una búsqueda simple por palabras clave. Para producción, usa una base de datos vectorial especializada (pgvector, Pinecone, Weaviate o Qdrant) y combínala con búsqueda por palabras clave en recuperación híbrida; luego reordena para mejor relevancia y rendimiento.
Si ya usas PostgreSQL, empieza con pgvector: evita añadir una base de datos nueva a tu stack y maneja millones de vectores en un solo nodo. Para infraestructura gestionada sin ops, considera Pinecone. Para funciones integradas de búsqueda híbrida, mira Weaviate. Para máximo rendimiento de consulta con cuantización avanzada, prueba Qdrant. Lee sobre nuestra migración de Pinecone a pgvector para una comparación real.
IVFFlat particiona vectores en clusters y busca solo clusters cercanos en tiempo de consulta. Se construye rápido, pero requiere ajustar el número de clusters a explorar. HNSW construye un grafo multicapa conectando vecinos aproximados más cercanos, entregando consultas más rápidas y mayor recall a costa de más tiempo de construcción y más memoria. Para la mayoría de cargas de producción, HNSW es el mejor default.
Los chatbots de IA pueden inventar información y dañar la confianza del cliente. Aprende las técnicas que usamos para mantener nuestra IA anclada en hechos y prevenir alucinaciones.