Búsqueda Semántica y RAG: Cómo tu IA Entiende Antes de Responder
Qué son los embeddings, por qué los vectores están reemplazando a las keywords, y cómo RAG convierte un LLM genérico en un experto de tu negocio — con datos reales, sin alucinaciones.
Pregúntale a ChatGPT algo sobre tu empresa. Sobre tus propios artículos. Sobre tus productos, tarifas o políticas internas. La respuesta será educada, elaborada… y probablemente inventada. Los modelos de lenguaje no saben nada de tu negocio — saben de todo lo demás.
RAG (Retrieval-Augmented Generation) resuelve exactamente esto. En lugar de esperar que el LLM "recuerde" tu contenido, primero buscas la información relevante en tu propia base de conocimiento y luego se la pasas al modelo como contexto. El resultado: respuestas precisas, con fuentes, sin alucinaciones.
En este artículo explicamos todo el pipeline — desde qué son los embeddings hasta cómo implementamos el chatbot de Codex que estás usando ahora mismo (sí, el botón de abajo a la derecha). Puedes probarlo mientras lees.
El problema que resuelve RAG
Un LLM tiene un corte de conocimiento (normalmente meses atrás) y no conoce tu contenido privado. Fine-tuning es caro y lento. RAG inyecta contexto real en cada pregunta — actualizable al instante, sin reentrenar nada, con coste por consulta de ~$0,0008.
¿Qué Son los Embeddings?
Un embedding es la representación numérica del significado de un texto. En lugar de tratar las palabras como cadenas de caracteres, un modelo de embeddings las convierte en vectores — listas de números con cientos o miles de dimensiones — donde textos con significados similares quedan cerca en el espacio vectorial.
"gato" → [0.23, -0.41, 0.87, 0.12, ..., -0.33] // 1024 dimensiones
"felino" → [0.25, -0.39, 0.85, 0.14, ..., -0.31] // ¡Muy cerca de "gato"!
"automóvil" → [-0.67, 0.52, -0.11, 0.83, ..., 0.44] // Lejos de ambos
// Distancia coseno:
// gato ↔ felino: 0.97 (casi idénticos semánticamente)
// gato ↔ automóvil: 0.12 (sin relación semántica) La magia está en que esto funciona más allá de sinónimos. "¿Cómo protegen los datos de mis clientes?" y "Seguridad y compliance del CRM" quedan cerca en el espacio vectorial aunque no compartan casi ninguna palabra. El modelo entiende la intención, no las letras.
Dimensiones
Cada embedding tiene cientos o miles de dimensiones. Más dimensiones = más matices semánticos capturados. bge-m3 que usamos genera vectores de 1.024 dimensiones.
Multilingüe por defecto
Los modelos modernos como bge-m3 son multilingües — una pregunta en español puede encontrar contenido en inglés porque el significado vive en el mismo espacio vectorial, independiente del idioma.
Generación instantánea
Generar el embedding de una pregunta toma ~50ms en Workers AI. No es como entrenar un modelo — es como convertir un texto a su "coordenada" semántica. Es una operación de inferencia, no de entrenamiento.
Búsqueda por Keywords vs Búsqueda Semántica
La búsqueda tradicional (SQL LIKE '%keyword%' o full-text search) busca coincidencias exactas de palabras. Funciona bien cuando sabes exactamente qué palabras usar. Pero los humanos no pensamos en keywords — pensamos en preguntas.
| Aspecto | Keyword Search | Búsqueda Semántica |
|---|---|---|
| Qué busca | Coincidencia de palabras | Similitud de significado |
| Sinónimos | No los entiende | Los captura automáticamente |
| Preguntas naturales | Pobre — depende de que las palabras coincidan | Excelente — entiende la intención |
| Multilingüe | Requiere índices separados por idioma | Un solo espacio vectorial sirve para todos |
| Escalabilidad | Excelente con índices SQL | Requiere base de datos vectorial (ANN) |
| Coste | Prácticamente cero | Bajo (embedding + query vectorial) |
Ejemplo real en Codex
Un usuario pregunta "¿cómo manejan la seguridad de los datos?". Con keyword search, necesitarías que el texto contenga exactamente "seguridad" y "datos". Con búsqueda semántica, también encuentra resultados sobre "GDPR", "compliance", "aislamiento multi-tenant", "encriptación" y "Turnstile" — aunque esas palabras no aparezcan en la pregunta.
¿Qué Es RAG y Por Qué Funciona?
RAG (Retrieval-Augmented Generation) es un patrón de arquitectura que combina dos fases: primero recuperas (Retrieval) la información relevante de tu base de conocimiento, y luego se la pasas al modelo generativo (Generation) como contexto. El modelo no necesita "saber" tus datos — solo necesita leerlos en el momento correcto.
Pregunta del usuario
"¿Cómo conecta Cadences con sistemas externos?" — El usuario escribe en lenguaje natural, sin pensar en keywords.
Embedding de la pregunta
Workers AI convierte la pregunta en un vector de 1.024 dimensiones usando bge-m3 (~50ms, gratis en Cloudflare).
Búsqueda vectorial (Retrieval)
El vector se compara contra todos los chunks indexados en Vectorize usando distancia coseno. Se obtienen los 5 fragmentos más similares — aunque no compartan ninguna palabra con la pregunta.
Contexto enriquecido
El texto completo de cada chunk se recupera de D1 y se inyecta en el prompt del LLM como contexto. El modelo lee tu contenido real, no lo inventa.
Respuesta generada (Generation)
DeepSeek V3.2 genera una respuesta basada exclusivamente en el contexto recuperado. Si la información no está en los chunks, dice "no tengo información" — elimina alucinaciones.
RAG vs Fine-Tuning vs Contexto Completo
Hay tres formas de "enseñarle" a un LLM sobre tu negocio. Cada una tiene su lugar, pero para la mayoría de casos de uso empresarial, RAG es la elección correcta.
| Método | Coste | Actualización | Precisión | Escalabilidad |
|---|---|---|---|---|
| Contexto completo | Alto (tokens caros) | Instantánea | Excelente (si cabe) | Limitado al context window |
| Fine-tuning | Muy alto ($100s–$1000s) | Días/semanas | Variable | Requiere reentrenamiento |
| RAG | ~$0,0008/consulta | Minutos | Alta (fuentes verificables) | 100K+ documentos |
¿Cuándo NO usar RAG?
- ⚠ Cuando tu base de conocimiento completa cabe en el context window (~200K tokens = ~150K palabras). En ese caso, pasa todo directamente.
- ⚠ Cuando necesitas que el modelo cambie su estilo o personalidad, no sus datos. Eso es fine-tuning.
- ⚠ Cuando las preguntas son puramente conversacionales ("hola, ¿qué tal?") sin necesidad de datos específicos.
Vectorize: La Base de Datos Vectorial en el Edge
Una base de datos vectorial almacena embeddings y permite buscar los más similares a un vector de consulta. El algoritmo estándar es ANN (Approximate Nearest Neighbors) — no compara contra todos los vectores uno por uno (sería lentísimo con millones), sino que usa estructuras de índice para encontrar los más cercanos en milisegundos.
Cloudflare Vectorize es la solución nativa de Cloudflare. Vive en el edge (junto a Workers y D1), tiene un tier gratuito generoso, y se integra directamente con Workers AI para generar embeddings — sin salir del ecosistema, sin latencia de red entre servicios.
Almacenamiento dual: Vectorize + D1
Los vectores (embeddings) viven en Vectorize para búsqueda rápida. Los textos originales viven en D1 (SQL relacional). Cuando Vectorize devuelve IDs de chunks similares, D1 proporciona el texto completo. Cada servicio hace lo que mejor sabe hacer.
Distancia coseno
La métrica que mide la similitud entre dos vectores. Un score de 1.0 = idénticos, 0.0 = sin relación. En la práctica, un resultado con score > 0.55 es relevante, > 0.70 es muy relevante, > 0.85 es prácticamente una coincidencia exacta.
Namespaces para filtrado
Vectorize soporta namespaces — particiones lógicas dentro del mismo índice. Nosotros usamos el idioma (es, en) como namespace para que las búsquedas en español solo comparen contra contenido en español.
[[vectorize]]
binding = "VECTORIZE"
index_name = "codex-knowledge" # 1024 dimensiones, coseno
# Tier gratuito: 200K vectores, 5M dims almacenadas/mes
# Suficiente para ~195 artículos × ~30 chunks = ~5.850 vectores Chunking: El Arte de Partir el Texto
No puedes generar un embedding de un artículo completo de 4.000 palabras — el significado se diluye. Necesitas partirlo en fragmentos (chunks) lo suficientemente pequeños para ser semánticamente precisos, pero lo suficientemente grandes para mantener contexto.
📏 Tamaño del chunk: ~400 palabras
Es el sweet spot para modelos como bge-m3. Demasiado corto (50 palabras) pierde contexto. Demasiado largo (1000+ palabras) diluye el significado. 400 palabras captura ~2-3 párrafos coherentes.
🔄 Overlap: 50 palabras
Cada chunk se solapa 50 palabras con el anterior. Esto evita que una idea que cruza el límite entre dos chunks se pierda. Si el punto clave está en la frontera, ambos chunks lo capturan.
🧹 Limpieza previa
Antes de chunk-ear, se elimina todo el HTML, CSS, SVG, clases de Tailwind, scripts, y metadatos. Solo queda el texto puro que un humano leería. Esto mejora dramáticamente la calidad de los embeddings.
Números reales de Codex
- ✦ 24 artículos (12 en español + 12 en inglés)
- ✦ 98 chunks generados (~4 chunks por artículo)
- ✦ 98 vectores de 1.024 dimensiones en Vectorize
- ✦ ~100K dimensiones almacenadas (0,5% del tier gratuito)
- ✦ Indexación completa en < 2 minutos
El Stack Completo del Chatbot de Codex
El chatbot que ves en esta web es un sistema RAG completo corriendo 100% en Cloudflare. Aquí está cada componente y por qué lo elegimos:
| Componente | Tecnología | Coste | Función |
|---|---|---|---|
| Embeddings | Workers AI bge-m3 | Gratis | Convierte texto → vector (1.024 dims) |
| Vector store | Cloudflare Vectorize | Gratis (tier actual) | Almacena y busca vectores por similitud |
| Texto + metadatos | Cloudflare D1 | Gratis (tier actual) | Almacena chunks de texto, títulos, URLs |
| LLM principal | DeepSeek V3.2 | $0,28 / 1M tokens in | Genera respuestas con contexto RAG |
| LLM fallback | Workers AI Llama 3.1 | Gratis | Respaldo si DeepSeek no disponible |
| Frontend | Astro + vanilla JS | Estático | Widget de chat flotante, voz, markdown |
// 1. Embedding de la pregunta (~50ms)
const embedding = await env.AI.run('@cf/baai/bge-m3', {
text: [question]
});
// 2. Búsqueda vectorial en Vectorize (~30ms)
const results = await env.VECTORIZE.query(embedding.data[0], {
topK: 5,
namespace: lang, // 'es' o 'en'
returnMetadata: 'all',
filter: { minScore: 0.55 }
});
// 3. Recuperar texto completo de D1
const chunks = await db.prepare(
'SELECT chunk_text, title, url FROM codex_chunks WHERE id IN (...)'
).all();
// 4. Generar respuesta con DeepSeek
const response = await fetch('https://api.deepseek.com/chat/completions', {
body: JSON.stringify({
model: 'deepseek-chat',
messages: [
{ role: 'system', content: systemPrompt + context },
...history,
{ role: 'user', content: question }
]
})
}); Análisis de Costes: ~$0,0008 por Consulta
Una de las grandes ventajas de RAG sobre otras arquitecturas es el coste. Al usar servicios con tiers gratuitos para embeddings y almacenamiento vectorial, el único coste variable es el LLM generativo. Aquí está el desglose real:
Embedding de la pregunta
$0,0000Workers AI bge-m3: gratis en el tier de Workers AI. Sin límite práctico para uso normal.
Búsqueda vectorial
$0,0000Vectorize: 30M queries/mes incluidos en el tier gratuito. Más que suficiente.
Lectura de D1
$0,0000D1: 5M lecturas/día en tier gratuito. Cada consulta lee ~5 filas.
DeepSeek V3.2 (respuesta)
~$0,0008~2K tokens input (contexto + pregunta) × $0,28/1M + ~500 tokens output × $0,42/1M ≈ $0,0008.
Coste mensual estimado
Con 1.000 consultas/mes (un volumen razonable para un blog técnico): ~$0,80/mes. El equivalente en GPT-4o sería ~$60/mes. DeepSeek V3.2 ofrece calidad comparable a GPT-4 al 1,3% del precio.
Voz, Markdown y Fuentes: La Experiencia del Chat
Un sistema RAG solo es útil si la interfaz es buena. El chatbot de Codex incluye funcionalidades que van más allá de un simple campo de texto:
Entrada por voz
Web Speech API nativa del navegador. Habla tu pregunta y se transcribe automáticamente. Sin coste adicional, funciona offline.
Markdown rendering
Las respuestas se renderizan con formato: negritas, cursivas, listas, código inline, code blocks y enlaces clicables.
Fuentes verificables
Cada respuesta incluye enlaces a los artículos originales que se usaron como contexto, con su score de similitud. Puedes verificar la información.
Dark mode + i18n
Se adapta al tema del sistema, soporta español e inglés, y es responsive — funciona a pantalla completa en móvil.
De 24 Artículos a 100K Documentos
El pipeline de Codex hoy indexa 24 artículos. Pero la arquitectura está diseñada para escalar varios órdenes de magnitud sin cambiar de tecnología:
| Escala | Vectores | Latencia búsqueda | Tier necesario |
|---|---|---|---|
| Blog (actual) | ~100 | ~30ms | Gratuito |
| Wiki mediana | ~5.000 | ~30ms | Gratuito |
| Knowledge base empresarial | ~50.000 | ~35ms | Workers Paid ($5/mes) |
| Documentación masiva | ~200.000 | ~40ms | Workers Paid ($5/mes) |
Vectorize usa HNSW (Hierarchical Navigable Small World) como algoritmo de indexación — la misma familia de algoritmos que usa Pinecone o pgvector. La latencia de búsqueda crece logarítmicamente, no linealmente: pasar de 100 a 100K vectores apenas añade 10ms.
Errores Comunes y Cómo Evitarlos
❌ Chunks demasiado largos
Si un chunk tiene 2.000 palabras sobre 5 temas diferentes, su embedding será un promedio borroso de todos ellos. La búsqueda será imprecisa. Solución: 300–500 palabras por chunk.
❌ No limpiar el HTML
Generar embeddings de <div class="flex items-center gap-3 mb-6"> desperdicia dimensiones en información irrelevante. Solución: Strip todo el markup antes de embeddings.
❌ Threshold de similitud muy bajo
Aceptar resultados con score < 0.4 inyecta contexto irrelevante que confunde al LLM. Solución: Usa minScore ≥ 0.55 y verifica empíricamente.
❌ Ignorar el system prompt
Sin instrucciones claras, el LLM puede inventar información fuera del contexto recuperado. Solución: System prompt que diga explícitamente "solo responde con la información del contexto proporcionado".
❌ No incluir metadatos útiles
Si el LLM solo ve texto suelto sin saber de qué artículo viene, no puede citar fuentes. Solución: Incluir título, URL y categoría de cada chunk en el contexto.
La IA que Sabe de lo Tuyo
RAG no es una moda — es el patrón que resuelve el problema fundamental de los LLMs: que saben mucho de todo, pero nada de tu negocio. Con embeddings, búsqueda semántica y generación basada en contexto real, puedes tener un asistente que responda con precisión sobre tu contenido, cite fuentes y cueste menos de $1/mes.
El chatbot de Codex es la prueba viva. Pregúntale lo que quieras sobre Cadences — busca en 98 chunks de 24 artículos, encuentra los más relevantes por similitud semántica, y genera una respuesta fundamentada con DeepSeek. Todo en el edge, todo serverless, todo por ~$0,0008 por pregunta.
Resumen técnico
- ✦ Embeddings: Workers AI bge-m3, 1.024 dimensiones, multilingüe, gratuito
- ✦ Vector DB: Cloudflare Vectorize con distancia coseno, namespaces por idioma
- ✦ Text store: D1 con chunks, metadatos (título, URL, categoría), indexado por slug
- ✦ LLM: DeepSeek V3.2 ($0,28/$0,42 por 1M tokens) + fallback Workers AI Llama
- ✦ Chunking: ~400 palabras con overlap de 50, HTML stripping completo
- ✦ Pipeline: pregunta → embedding → Vectorize query → D1 fetch → DeepSeek → respuesta con fuentes
- ✦ Coste real: ~$0,0008/consulta, ~$0,80/mes para 1.000 preguntas
- ✦ Rate limit: 20 consultas/día por IP (configurable), Turnstile-ready
Cadences Engineering
Documentación técnica del equipo de ingeniería
IA Generativa en el Trabajo
De la teoría a la práctica real
Artículo relacionado →Agentes de IA en Cadences
Del prompt al sistema autónomo