Según W3Techs, alrededor del 43 % de todos los sitios web funciona sobre WordPress. La ironía es que muchos de los plugins de IA que se instalan encima envían cada comentario, cada borrador y cada dato de formulario a una API de terceros. Ollama y Qdrant permiten dar la vuelta a ese flujo: el modelo y los vectores viven en tu servidor y fuera solo cruza lo que tú decidas.
Qué significa IA local en un sitio WordPress
Ejecutar IA local en WordPress significa que la inferencia ocurre en hardware que controlas: sin proveedor intermedio, sin factura por token y sin enviar el contenido fuera. En la práctica necesitas tres piezas: un modelo de lenguaje que genera texto, un modelo de embeddings que convierte texto en vectores y una base de datos vectorial que los guarda y los busca. Ollama cubre los dos primeros papeles, Qdrant se encarga del tercero y WordPress sigue siendo PHP y MySQL, hablando con ambos por HTTP.
Sin factura por tokens: el coste de la inferencia
La factura por tokens desaparece porque el cómputo ocurre en tu servidor. El coste real se desplaza a la RAM del VPS y al disco que ocupan los modelos, que son fijos y previsibles: un modelo de 8B cargado consume los mismos 5 GB con diez visitas que con diez mil.
La privacidad es el argumento obvio, pero no el único. Al desaparecer el coste por petición desaparece el techo que limita experimentar: puedes indexar todo el archivo del blog o reevaluar cada comentario nuevo sin mirar un contador de tokens. El precio lo pagas en hardware y en mantenimiento, y conviene mirar eso de frente antes de instalar nada, porque el caso de uso determina el tamaño del modelo y del servidor. El siguiente movimiento es decidir qué motor corre ese modelo, y Ollama es la opción más directa.
Ollama: el motor de inferencia
Ollama empaqueta llama.cpp detrás de una interfaz sencilla: descarga modelos, los sirve cuantizados, gestiona la memoria y expone una API REST en el puerto 11434. Si quieres una capa de chat encima, Open WebUI monta un chat de IA privado sobre ese motor. Un modelo como Llama 3.1 8B con la cuantización por defecto de Ollama (4 bits) ocupa algo menos de 5 GB en disco y funciona con holgura en una máquina de 16 GB de RAM, sin GPU, para la carga típica de un blog.
Modelos cuantizados y API en el puerto 11434
Ollama descarga los modelos ya cuantizados y los expone por una API REST en el puerto 11434 con el formato de chat que ya usan decenas de herramientas. El mismo binario sirve generate y chat, y el keep_alive evita recargar el modelo en cada petición.
Los dos comandos que arrancan todo:
ollama pull llama3.1:8b
ollama pull nomic-embed-text
El segundo es un modelo de embeddings ligero, de unos pocos cientos de megabytes, y será el que alimente a Qdrant. Si vas a repetir siempre las mismas instrucciones, un Modelfile te deja fijar el system prompt y parámetros como la temperatura, de forma que el plugin solo envíe la consulta. Dos detalles que ahorran dolores de cabeza: la variable OLLAMA_KEEP_ALIVE evita que el modelo se descargue de memoria entre peticiones, y Ollama también expone un endpoint compatible con la API de OpenAI bajo /v1, lo que permite reutilizar plugins pensados para OpenAI si los apuntas a tu servidor. Elige el modelo por tarea: uno pequeño para embeddings y otro para generación, en lugar de un solo modelo gigante que lo haga todo a medias.
Qdrant: la memoria semántica
La búsqueda de WordPress compara palabras; si el visitante escribe «coche», no encontrará la entrada que dice «automóvil». Qdrant resuelve eso por diseño: guarda vectores y devuelve los puntos más cercanos a un vector de consulta, es decir, los textos con significado más parecido. Está escrito en Rust, ofrece API REST en el puerto 6333 y gRPC en el 6334, y arranca en un contenedor:
Embeddings: de texto a vectores comparables
El pipeline parte de embeddings: trocear cada entrada, calcular el vector con nomic-embed-text y guardarlo en Qdrant. La búsqueda semántica compara distancias entre vectores, no coincidencias literales.
Colecciones y filtros en Qdrant
Una colección por tipo de contenido mantiene los resultados limpios: posts en una, documentación en otra. Los payload filters permiten restringir por categoría o idioma sin levantar más servicios.
docker run -p 6333:6333 -v qdrant_storage:/qdrant/storage qdrant/qdrant
Cada punto admite un payload con metadatos (ID de entrada, categoría, fecha), y los filtros de Qdrant permiten acotar la búsqueda a una categoría o a un rango de fechas antes de comparar vectores.
Un matiz que evita frustraciones: Qdrant no calcula embeddings. El flujo es siempre el mismo: WordPress pide a Ollama el vector de un texto, Ollama lo devuelve y Qdrant lo indexa en una colección; la búsqueda repite el camino en sentido inverso. Para montar tu primera colección con esquema de puntos y filtros, escribí «RAG y búsqueda semántica con Qdrant: de la teoría a tu primera colección», donde detallé el proceso paso a paso.
Qué modelo para qué tarea
La familia concreta importa menos que el tamaño. Como referencia de partida: modelos de 2 a 4B para clasificar, etiquetar y tareas cortas; los de 7-8B, como Llama 3.1 8B o Mistral 7B, para el uso general de un blog; y por encima de ahí solo si el hardware acompaña. Para embeddings, nomic-embed-text cubre el caso habitual, y si tu contenido mezcla idiomas hay alternativas multilingües en la biblioteca de Ollama, como bge-m3.
Un consejo práctico: prueba siempre el modelo más pequeño que resuelva la tarea. La latencia baja, la RAM queda libre para Qdrant y el sistema aguanta mejor los picos de tráfico. Con los modelos elegidos, el siguiente paso es enchufar el stack desde WordPress.
Plugins y PHP: cómo se conecta WordPress con el stack
WordPress habla HTTP y tu stack también, así que la integración va por ahí. Hay tres caminos, de más rápido a más controlado:
Los tres caminos de integración
Del más rápido al más controlado: plugin conversacional que apunta a Ollama, wp_local que ejecuta la inferencia desde PHP, y un microservicio propio para el pipeline de embeddings.
- Plugins con endpoint configurable: cualquier plugin de IA que acepte una URL base personalizada compatible con la API de OpenAI puede apuntar a http://tu-servidor:11434/v1 y usar los modelos de tu Ollama. Revisa la documentación antes de pagar, porque hay plugins que solo admiten claves de OpenAI o de Azure y no dejan cambiar el destino.
- Snippets propios: con wp_remote_post() en el functions.php de un tema hijo puedes llamar a Ollama y a Qdrant directamente, que es el camino que prefiero para casos a medida.
- Plugins cerrados: si no hay forma de cambiar el endpoint, descártalos y busca alternativas más flexibles.
No existe un conector oficial de Qdrant para WordPress, y no hace falta: su API REST es directa y las llamadas caben en unas pocas líneas de PHP. Analicé este ecosistema con más detalle en «IA local en WordPress: Ollama, Qdrant y los plugins que lo unen todo», donde repasé qué encaja con cada nivel de ambición. Criterio de elección: plugin solo si su cauce coincide con lo que necesitas; si quieres controlar qué sale del servidor, snippet propio.
Un caso para empezar: entradas relacionadas semánticas
El primer caso que merece la pena montar no es un chatbot, sino entradas relacionadas que entienden el contenido. El pipeline cabe en tres pasos. Al guardar una entrada (gancho save_post), generas su embedding con nomic-embed-text y lo subes a Qdrant con el ID de la entrada como metadato. En el front, calculas el vector de la entrada actual y pides a Qdrant los cinco puntos más cercanos con un POST a /collections/wp_contenido/points/search.
El pipeline en tres pasos
Al guardar una entrada, se calcula su embedding, se inserta en Qdrant y un shortcode muestra los vecinos más cercanos. Nada de colas ni reintentos: un hook y una colección.
El cuerpo mínimo lleva el vector, un límite y with_payload en true. Con los IDs devueltos, pintas los resultados usando WP_Query. Todo el flujo corre en tu servidor, sin llamadas externas, sin coste variable y con latencia estable.
El mismo esquema sirve para un buscador que entiende sinónimos o para un chat que responde con contexto de tus propios textos, pero empieza por lo relacionado: es un caso de bajo riesgo, no está expuesto al visitante y te da números reales de latencia y calidad antes de comprometerte a más.
Hardware, alojamiento y límites reales
El límite duro es la memoria. El modelo de 8B ocupa algo menos de 5 GB y en RAM necesita un margen similar más el contexto, de modo que cada modelo cargado suma; OLLAMA_MAX_LOADED_MODELS controla cuántos conviven. En CPU el rendimiento alcanza para un blog con tráfico moderado; si esperas picos de peticiones simultáneas, OLLAMA_NUM_PARALLEL pasa a importar y una GPU cambia la ecuación. El alojamiento es la segunda frontera: en la mayoría de hostings compartidos no hay Docker ni SSH, así que hablamos de un VPS o de un servidor propio. En disco, un par de modelos más el volumen de Qdrant ya suman varias decenas de gigas.
RAM: el límite que decide todo
Cada modelo cargado suma su peso en RAM más margen de contexto. Con 16 GB caben un 8B y el sistema; por debajo, hay que rotar modelos o quedarse en los pequeños.
VPS o mini PC: dónde vive el stack
Un VPS sin GPU sirve para embeddings y búsqueda; la inferencia conversacional exige más. Un mini PC en la oficina cubre el segundo caso con coste único.
Y una limitación honesta: un modelo de 8B no escribe como un modelo puntero de pago; en tareas creativas largas la diferencia se nota. En tareas como resumir, clasificar, generar embeddings y responder con contexto propio, el margen se estrecha mucho. Mide tu tráfico real antes de dimensionar: un sitio con pocas visitas simultáneas va sobrado en CPU, y eso decide el tamaño de la factura del VPS.
Del prototipo a producción
Un prototipo funciona; el tráfico real rompe supuestos. Tres detalles conviene resolver antes de abrir nada al público: los tiempos de espera de PHP (una petición a un modelo que tarda medio minuto arruina la experiencia, así que acota el contexto y el número de tokens de salida), la red entre contenedores (si WordPress y Ollama comparten red de Docker, la URL es el nombre del servicio y no localhost) y la persistencia (el volumen de Qdrant debe entrar en tu plan de copias igual que la base de datos). Para reindexar el archivo completo, un comando de WP-CLI o un cron evita bloquear las peticiones web con trabajos largos. Ningún punto es difícil, y los tres duelen si aparecen por sorpresa en producción.
Tiempos de espera, caché y concurrencia
Los tiempos de espera de PHP, el keep_alive de los modelos y una cola para las peticiones concurrentes son los tres detalles que separan la demo del servicio.
Privacidad como criterio de arquitectura
Con un stack self-hosted, los datos de tus usuarios no cruzan la frontera del servidor: comentarios, consultas de búsqueda y borradores se quedan en tu infraestructura. Para un sitio que trata datos de personas en la Unión Europea, eso elimina de la ecuación al encargado de tratamiento externo en la fase de inferencia y simplifica el análisis; no exime del resto, porque registros, cachés y copias de seguridad también contienen datos personales y hay que tratarlos como tales.
Los datos nunca salen del servidor
Comentarios, consultas y borradores se quedan en tu infraestructura. Sin terceros que registren el tráfico, sin cláusulas de entrenamiento que revisar.
Un punto ciego habitual: si el plugin combina llamadas locales con telemetría o con servicios externos para otras funciones, el dato vuelve a salir. Antes de dar la arquitectura por buena, mira qué peticiones emite el plugin en la pestaña de red de las herramientas de desarrollo del navegador y cierra lo que no necesites.
Conclusión: por dónde empezar mañana
El recorrido corto cabe en una tarde: levanta Ollama y Qdrant con Docker en un VPS, descarga nomic-embed-text, crea una colección con tus últimas veinte entradas y monta las entradas relacionadas con un snippet. Deja esa prueba en marcha una semana y anota latencia y calidad de resultados; con esos números decidirás si el siguiente paso es el buscador semántico o el chat con contexto. La ventaja de fondo no es el ahorro, sino el control: qué datos salen de tu servidor vuelve a ser una decisión tuya y no un ajuste por defecto de un plugin. Cuando el stack funcione y quieras que un agente lo orqueste todo con un protocolo común, el Model Context Protocol sobre Ollama, Qdrant y WordPress da el paso siguiente.
