Cómo construimos Medri: chatbot RAG con Cloudflare AI Search y Workers AI
Diario técnico de la construcción del chatbot Medri: decisiones arquitectónicas, trampas encontradas y aprendizajes reales usando el ecosistema Cloudflare.
Daniel Gómez
Co-CEO y Cofundador · Arquitecto de software
Medri es el asistente virtual de MedraNet: vive en la esquina inferior del sitio y responde a preguntas sobre servicios, precios orientativos, tecnologías y forma de trabajo. Este post no es una guía genérica de “cómo montar un RAG”: es el diario técnico de un chatbot concreto en producción, montado por completo sobre el ecosistema Cloudflare. Si estás valorando un stack parecido, te ahorra un par de horas de callejones sin salida.
Una nota sobre nomenclatura y honestidad
Dos aclaraciones antes de entrar en materia:
Sobre nomenclatura: Cloudflare AI Search era conocido hasta hace poco como AutoRAG. Cloudflare renombró el producto y también introdujo bindings nuevos (ai_search y ai_search_namespaces) para acceder al servicio desde Workers. El binding heredado env.AI.autorag() sigue funcionando (que es lo que usamos ahora en Medri), pero para proyectos nuevos conviene revisar la migración al binding actual. Deberías verificarlo en la documentación oficial de Cloudflare porque el ecosistema evoluciona rápido.
Sobre métricas: este post no incluye métricas de rendimiento propias. El sistema lleva pocos días en producción y no tenemos un dataset suficientemente grande para dar números que aporten valor real al lector. Publicaremos una actualización cuando los tengamos.
Sí hablamos de arquitectura, decisiones, referencias al pricing público y limitaciones conocidas. Todo lo que aquí aparece es verificable o está marcado como estimación cuando no lo es.
Por qué este post te interesa aunque no vayas a construir el chatbot tú mismo
Si tomas decisiones tecnológicas en tu empresa pero no vas a escribir el código, sigue leyendo. La arquitectura que describimos aquí determina cosas muy concretas de tu día a día como responsable:
- Cuánto cuesta mantener el chatbot al mes una vez está montado.
- Cuánto tarda tu equipo en actualizar la información que responde a los usuarios.
- Qué pasa si tu proveedor sube precios o cambia condiciones.
- Qué tan atado quedas a la tecnología elegida si dentro de dos años quieres migrar.
- Qué tipo de errores vas a ver en producción y cómo se resuelven.
Todo esto se decide en la fase de arquitectura, no cuando el chatbot ya está en marcha. Un stack mal elegido para tu contexto genera costes crecientes que no aparecen en el primer presupuesto pero sí en la factura de cada mes.
Las secciones más técnicas te dan el detalle. Las secciones “Qué significa esta arquitectura si tienes que decidir esto en tu empresa” y “Cuándo tiene sentido este stack en un negocio” más abajo traducen el detalle a criterios de decisión de negocio.
Qué queríamos que hiciera Medri
Antes del stack, el problema. Queríamos un chatbot que:
- Respondiera con información específica de MedraNet, no genérica sobre “consultoría IT”.
- No inventara clientes, casos de éxito ni precios que no existen.
- Se pudiera actualizar cambiando un archivo Markdown, sin re-entrenar nada.
- Tuviera un coste operativo bajo mientras el volumen sea pequeño.
- Fuera fácil de mantener con un equipo pequeño.
Con esos requisitos, el debate RAG vs fine-tuning se resuelve solo: RAG. Ya explicamos por qué en nuestro post sobre RAG vs fine-tuning. El resumen: cuando la información cambia, es específica del negocio y quieres controlar las fuentes, RAG suele ser la opción correcta. Fine-tuning gana en otros escenarios.
Decisión 1: RAG gestionado, no montaje manual
Un RAG “hecho a mano” se compone de al menos cuatro piezas:
- Un modelo de embeddings para vectorizar el knowledge.
- Un vector store para guardar y buscar por similitud.
- Un orquestador (LangChain, LlamaIndex u otro) que gestione la recuperación.
- Un LLM que reciba el contexto recuperado y genere la respuesta.
Cada pieza tiene decisiones de proveedor, coste, latencia y mantenimiento. Para un chatbot corporativo con un knowledge acotado y un equipo de dos personas, cuatro piezas son demasiadas.
Cloudflare AI Search las une en un único servicio gestionado: le apuntas a un bucket R2 con documentos, eliges modelos de embeddings y generación de un catálogo predefinido, pegas un system prompt, y consumes desde el código con una sola llamada.
Ganancias:
- Menos superficie que mantener. Una instancia gestionada en vez de cuatro servicios que actualizar.
- Menos coste operativo para volúmenes bajos: no pagas un vector store ocioso.
- Integración nativa con Cloudflare Pages, que es donde vive el sitio.
Pérdidas honestas:
- Menos control fino. No eliges libremente cualquier modelo de embeddings ni cualquier LLM: te limitas al catálogo que expone AI Search. Si el día de mañana necesitamos un modelo específico no disponible, tocaría migrar el orquestador.
- Dependencia de un proveedor. Si Cloudflare cambia el pricing o las condiciones, tenemos que reevaluar.
Para donde estamos hoy, la ganancia compensa. Si estuviéramos manejando decenas de miles de consultas al día o necesitáramos un modelo muy específico, probablemente iríamos por el camino manual con más piezas.
Decisión 2: Astro estático + Pages Function serverless
El sitio de MedraNet es Astro con output: 'static'. Es HTML pre-renderizado, servido desde CDN, con cero JavaScript por defecto en las páginas. Elegido por SEO y Core Web Vitals.
Pero un chatbot necesita un endpoint dinámico. La opción de mover todo el sitio a output: 'server' para tener endpoints dentro de Astro nos rompía el modelo de SEO estático que ya funcionaba.
La alternativa fue Cloudflare Pages Functions: son funciones serverless que viven en la misma app Pages que sirve el sitio estático. Se despliegan juntas, comparten dominio y comparten los bindings de Cloudflare (Workers AI, R2, KV…).
El chatbot acaba siendo, por tanto, un endpoint POST en /api/chat que llama internamente al RAG de Cloudflare y devuelve JSON. El frontend es un widget Astro simple que hace fetch a ese endpoint.
La arquitectura resultante
Componentes y responsabilidades:
| Componente | Ubicación / identificador | Función |
|---|---|---|
| Frontend del chatbot | src/components/Chatbot.astro | Widget flotante con saludo hardcodeado, historial en memoria y fetch al backend |
| Endpoint backend | functions/api/chat.ts | Rate limit, validación, llamada al RAG, retorno JSON |
| Instancia RAG | Cloudflare AI Search medranet-chatbot | Recupera contexto y llama al LLM en una sola operación |
| Modelo de generación | @cf/meta/llama-3.3-70b-instruct-fp8-fast | LLM que produce la respuesta final |
| Modelo de embeddings | @cf/baai/bge-m3 | Vectoriza knowledge y consultas (buen soporte multilenguaje) |
| Knowledge base | R2 bucket medranet-knowledge con medranet-knowledge.md | Fuente de verdad factual sobre MedraNet |
| System prompt | Configurado dentro de la instancia AI Search | Reglas de comportamiento, tono y anti-invención |
| Binding en la Function | AI con env.AI.autorag() — implementación actual de Medri, no patrón recomendado para proyectos nuevos | Acceso desde la Function al servicio AI Search. Ver nota sobre binding actual más abajo |
El flujo de una consulta, paso a paso:
- El usuario escribe en el widget del chat y se envía un
POST /api/chat. - La Function comprueba el rate limit por IP y valida que la query no exceda 500 caracteres.
- Se invoca AI Search a través del binding.
- AI Search embebe la pregunta con
bge-m3, busca chunks similares en el knowledge indexado del R2, junta system prompt más contexto recuperado más pregunta, y se lo pasa a Llama 3.3 70B. - El modelo genera la respuesta y la Function la devuelve al frontend como JSON.
Todo el mantenimiento del knowledge es editar un archivo Markdown, subirlo al R2 y disparar re-indexación desde el dashboard. Sin migraciones, sin embeddings a mano, sin scripts de sync.
Nota sobre el binding: en esta versión de Medri usamos el binding heredado env.AI.autorag(...). Cloudflare ha introducido bindings nuevos (ai_search y ai_search_namespaces) que son los recomendados para proyectos nuevos. El nuestro seguirá funcionando, pero está en nuestra hoja de ruta migrar a la API actual para alinearnos con el estándar recomendado.
Trampa 1: el endpoint mal ubicado devolvía 405
Primera versión del endpoint la pusimos donde parecía natural: src/pages/api/chat.ts. En desarrollo local funcionaba, en preview de Cloudflare devolvía 405 Method Not Allowed.
La causa raíz: con output: 'static', Astro no procesa endpoints dinámicos dentro de src/pages/. Y aunque Cloudflare Pages tiene soporte para Pages Functions, solo las escanea si están en la carpeta functions/ en la raíz del repo, no dentro de src/.
La solución fue mover el archivo a functions/api/chat.ts. La misma convención aplica al endpoint del formulario de contacto, que también vive en functions/api/contact.ts.
Es una convención específica de la mezcla Astro estático + Cloudflare Pages Functions que no está en el “getting started” de ninguno de los dos por separado. Documentado ahora para no repetir el error.
Trampa 2: el chatbot repetía el saludo dos veces
Uno de los incidentes más útiles del desarrollo. Durante una sesión de pruebas, un usuario escribía “hola” y Medri respondía con exactamente la frase del “mensaje de bienvenida sugerido” que estaba en el knowledge base como plantilla interna. Es decir, texto que en teoría era una guía para el diseñador del chatbot, no contenido para servir al usuario.
Investigando: el RAG estaba recuperando ese chunk por similitud semántica (“mensaje de bienvenida” es un match muy fuerte para “hola”) y pasándoselo al modelo como contexto. El modelo, al ver texto que parecía una respuesta lista, lo devolvía verbatim.
La causa raíz no era del modelo ni del RAG. Era arquitectónica: habíamos mezclado en el mismo archivo dos tipos de contenido con propósitos incompatibles.
El principio: separación estricta entre knowledge y system prompt
Del incidente sacamos una regla que ahora es innegociable en cualquier RAG que hacemos:
El knowledge contiene solo información factual sobre el negocio. Las instrucciones de comportamiento del chatbot viven exclusivamente en el system prompt.
Regla de traducción concreta:
| Va en el knowledge (indexable) | Va en el system prompt (comportamiento) |
|---|---|
| Qué hace la empresa, servicios, precios | Cómo se presenta el chatbot |
| Equipo, contacto, dirección | Tono, estilo, formato de respuesta |
| FAQs con respuesta factual | Plantillas literales de respuesta |
| Filosofía y diferenciales | Reglas anti-manipulación |
| Tecnologías que domináis | Excepciones de comportamiento |
| Sectores en los que trabajáis | Frases de bienvenida o despedida |
Test rápido para revisar un knowledge antes de subirlo al R2:
- Si contiene frases en 2ª persona dirigidas al bot (“responde así”, “si te preguntan X, contesta Y”), esas frases no van en el knowledge, van en el system prompt.
- Si contiene plantillas literales de respuesta entre comillas, mismo destino.
- Si contiene secciones tipo “Instrucciones para el chatbot”, fuera del knowledge.
Este principio nos parece obvio ahora que lo hemos vivido. Antes del incidente no lo era, y probablemente cualquiera que monta su primer RAG a partir de un único documento de referencia empresarial se topa con la misma trampa.
Qué tenemos pendiente de reforzar
Ser honestos sobre las capas que aún estamos endureciendo es tan importante como enseñar lo que ya funciona. Sin entrar en detalles operativos específicos, estas son las áreas en evolución:
- Endurecimiento de abuso y cuotas. La primera versión del endpoint cubre validaciones básicas y una capa de control de uso; la evolución natural es apoyar esa capa en mecanismos gestionados del ecosistema Cloudflare (KV, WAF Rules, AI Gateway) para hacerla persistente y observable.
- Protección anti-bot en el widget. Añadir Cloudflare Turnstile para filtrar tráfico automatizado antes de que llegue al backend.
- Caché de respuestas frecuentes. Configurar AI Gateway con caché habilitado para servir preguntas repetidas sin invocar al LLM cada vez, con impacto positivo tanto en coste como en latencia.
- Observabilidad estructurada. Introducir logging sin datos personales, con timestamp y latencia por consulta, para poder identificar patrones y mejorar iterativamente el knowledge base.
Estas capas no impiden operar una primera versión controlada, pero forman parte del endurecimiento natural antes de escalar tráfico o exposición pública.
Qué significa esta arquitectura si tienes que decidir esto en tu empresa
Traducimos las decisiones técnicas a criterios de negocio útiles para responsables no técnicos:
Mantenimiento del contenido. Actualizar lo que sabe el chatbot es editar un archivo de texto y re-subirlo al panel de contenidos. Cualquier persona con acceso al panel puede hacerlo: no requiere pedir cambios a desarrollo, ni disparar un despliegue, ni contratar horas técnicas para cada actualización. Un cambio típico (“hemos añadido un nuevo servicio, hemos cambiado un precio”) se aplica en minutos, aunque sí requiere disparar la re-indexación desde el dashboard del proveedor.
Coste operativo. En modelo gestionado como el nuestro, el coste crece con el uso real: pagas por consumo, no por infraestructura ociosa. A 8 de julio de 2026, AI Search está en beta abierta y Cloudflare la ofrece sin coste dentro de sus límites publicados; Workers AI y AI Gateway se facturan aparte. Para presupuestar un caso real deberías verificar el pricing oficial actualizado, porque cambia. En volúmenes bajos o medios este stack tiende a resultar más barato que alquilar un servidor con un chatbot alojado.
Riesgo de proveedor. Estamos atados a Cloudflare para el RAG y el hosting. Si Cloudflare cambia condiciones, tenemos que evaluarlo. La contrapartida positiva: nuestro contenido (el knowledge base) es un archivo Markdown estándar. Migrar a otro proveedor de RAG mañana sería trabajo técnico, pero el contenido en sí está en formato abierto y portable. Esto es muy diferente a soluciones cerradas donde tu contenido queda atrapado en la plataforma.
Tipo de errores esperables. Un chatbot RAG puede: (a) responder que no sabe algo cuando la información sí está en el knowledge pero mal redactada; (b) recuperar contexto irrelevante y dar respuestas confusas; (c) inventar información si el system prompt no está bien blindado. Todos son solucionables editando el knowledge y el system prompt. Ninguno es un bug del que dependas del proveedor para arreglar.
Tiempo de arranque. Este stack está pensado para arrancar en días, no en meses. Un chatbot equivalente montado con LangChain, Pinecone y OpenAI implica más piezas, más contratos, más credenciales y más superficie de mantenimiento.
Cuándo tiene sentido este stack en un negocio
Cuatro escenarios reales donde este planteamiento encaja bien:
Empresa con documentación viva. Consultoría, despacho profesional, empresa de servicios con catálogo cambiante. El equipo actualiza servicios, precios o procesos con cierta frecuencia y quiere que el chatbot refleje siempre la última versión sin tocar código.
Ecommerce con FAQ extenso. Tienda online con muchas preguntas repetitivas (envíos, devoluciones, tallas, compatibilidades). El chatbot descarga al equipo de atención al cliente respondiendo lo que ya está documentado, y deriva a humano solo lo que requiere criterio.
Consultora o clínica con requisitos regulatorios. Cuando la información que el chatbot maneja es sensible pero no personal identificable (procedimientos, tarifas, documentación de servicios). Este stack permite concentrar buena parte de la arquitectura en un único proveedor y evaluar opciones de localización, jurisdicción y tratamiento de datos dentro del ecosistema Cloudflare. La configuración concreta de RGPD, residencia de datos, logs y subprocesadores debe revisarse caso por caso.
Producto SaaS con documentación técnica. Empresa que ofrece un producto software con documentación extensa. El chatbot ayuda a nuevos usuarios a resolver dudas sobre uso sin abrir tickets, y a los clientes existentes a encontrar respuestas concretas en documentación densa.
Escenarios donde este stack no es la elección obvia: chatbots que requieren integración pesada con sistemas propios en tiempo real (CRM, ERP, base de datos de pedidos), volúmenes masivos de consultas donde el coste por consulta empieza a pesar, o casos donde la respuesta requiere ejecutar acciones concretas (crear pedidos, agendar citas). En esos casos hay que valorar arquitecturas más complejas.
Qué haríamos diferente si empezáramos hoy
Con lo aprendido, si arrancáramos Medri desde cero mañana:
- Separaríamos knowledge y system prompt desde el primer minuto, no como refactor. Aprendizaje adquirido por la mala en el incidente del doble saludo.
- Elegiríamos desde el inicio el binding actual de AI Search (
ai_searchoai_search_namespaces) en lugar del binding heredado. Migrarlo después es trabajo evitable si el estándar ya está definido antes de arrancar. - Incorporaríamos KV, AI Gateway y Turnstile en la lista base de bindings, no como “capa futura”. Los mecanismos gestionados del ecosistema para cuotas, caché y protección anti-bot son mucho más eficaces implementados desde el día uno.
- Añadiríamos observabilidad desde el día uno. Ni siquiera métricas sofisticadas: un log estructurado en KV con timestamp, query hasheada y latencia habría dado un dataset útil para este mismo post.
- Documentaríamos el pricing de AI Search, Workers AI y AI Gateway en el propio proyecto, con snapshot fechado, para poder detectar cuándo cambia y ajustar arquitectura si es necesario.
Nada de esto invalida el diseño actual. Son ajustes de higiene técnica que se ven claros con la retrospectiva.
Conclusión
Cloudflare AI Search convierte un RAG “de libro” en un servicio gestionado ejecutable con una sola llamada desde código. Combinado con Pages Functions, permite añadir un chatbot corporativo a un sitio estático sin cambiar la arquitectura del sitio, sin infraestructura extra y con un coste operativo bajo mientras el volumen sea pequeño.
Las trampas que nos encontramos no eran de los servicios, eran de cómo los mezclamos: un endpoint en la carpeta equivocada, un knowledge con instrucciones de comportamiento contaminadas. Ambos aprendizajes son transferibles a cualquier stack similar.
Publicaremos una segunda parte cuando el sistema lleve el tiempo suficiente en producción para dar cifras honestas de coste, latencia y calidad percibida. Hasta entonces, este post documenta lo que sí podemos afirmar: la arquitectura, las decisiones y lo que hemos aprendido por el camino.
Cómo trabajamos con esto en MedraNet
Este chatbot forma parte de nuestro servicio de chatbots empresariales con IA dentro del pilar de automatizaciones e IA. Lo que has leído aquí es la arquitectura real de un caso propio: la misma que aplicamos cuando montamos chatbots para otras empresas.
Si eres CTO o responsable técnico y estás valorando un stack parecido, podemos contrastar tu planteamiento contra el nuestro en una llamada de 30 minutos, sin coste ni compromiso. Agenda aquí.
Si eres responsable de negocio y estás evaluando un chatbot con IA para reducir carga de atención al cliente, gestionar FAQs o exponer documentación interna, hacemos primero un diagnóstico previo de tu caso —volumen, integraciones, riesgos, coste realista—, sin compromiso. Cuéntanos tu caso.
Preguntas frecuentes
Preguntas frecuentes
¿Por qué usar Cloudflare AI Search en lugar de montar el RAG manualmente con LangChain o LlamaIndex?
¿Cuánto cuesta ejecutar un RAG en Cloudflare Workers AI?
¿Por qué el endpoint del chatbot no está en src/pages/api/ como sería habitual en Astro?
¿El knowledge base puede contener instrucciones de comportamiento para el chatbot?
¿Este tipo de chatbot tiene sentido para una empresa que no sea del sector tecnológico?
Etiquetas
Otros artículos relacionados
RAG vs. fine-tuning: cuándo elegir cada uno para tu chatbot empresarial
Diferencias prácticas entre Retrieval-Augmented Generation y fine-tuning de modelos, con criterios concretos para decidir cuál encaja en tu proyecto.
Daniel Gómez n8n vs chatbot custom: cuándo el low-code se queda corto (guía para CTOs)
Cuándo n8n es suficiente para tu chatbot empresarial y cuándo conviene construirlo a medida con Django. Comparativa con criterios técnicos reales.
Daniel Gómez ¿Te ha interesado este artículo?
En MedraNet trabajamos a fondo los temas que escribimos. Si quieres hablar de cómo aplicarlo a tu proyecto, hablamos sin compromiso.
Hablar con nosotros