Consultar datos de Search Console usando un LLM local
Publicado por Lino UruΓ±uela el 19 de marzo de 2025
Β
Los grandes modelos de lenguaje (LLMs) como los disponibles por OpenAI o Google se pueden ejecutar en tu propio ordenador sin apenas consumir recursos, ya que realmente se procesan en las mΓ‘quinas de estos proveedores. Esto, en principio, no serΓa un impedimento para ejecutar LLMs en tu ordenador, pero son de pago y, para el volumen de datos con el que suelo trabajar, no me resulta rentable.
Aunque el precio por token de entrada/salida es aparentemente bajo, deja de serlo si tienes que solicitar decenas o cientos de millones... Por ejemplo, algunas propiedades de Search Console pueden tener millones de keywords ΓΊnicas. Y no solo eso, si combinas ciertos datos como keyword, title y algo mΓ‘s en una pΓ‘gina que tenga unas 100.000 URLs, el nΓΊmero de tokens que querrΓ‘s procesar comienza a crecer rΓ‘pidamente.
Β
Cuando se trata de un funcionamiento en producciΓ³n, puede tener mucho sentido usar los modelos de pago de los grandes proveedores, dependerΓ‘ del problema que estΓ©s resolviendo y, sobre todo, del valor que aporte la soluciΓ³n. Si eres una empresa de seguros y un LLM bien ejecutado puede resolver un porcentaje de las consultas que hacen los usuarios, posiblemente puedas (y debas) considerar estos modelos.
Pero si eres alguien como yo, que estΓ‘ todo el dΓa investigando con grandes volΓΊmenes de datos para explorar nuevas utilidades o funcionalidades que solo voy a usar yo, o por ejemplo, para crear un buscador en tu sitio web o un buscador semΓ‘ntico en los contenidos de vΓdeos, posiblemente no te salga a cuenta.
Β

Β
Nuevo modelo de Mistral (mistral-small-2503)
Dicho esto, el otro dΓa probΓ© el nuevo modelo de Mistral y, sinceramente, me ha encantado. Funciona relativamente bien, al menos en el primer caso de uso que estoy creando, que es mostrar datos, por ejemplo de Search Console, haciΓ©ndole preguntas en lenguaje natural.
De momento, he creado un script bΓ‘sico que se ejecuta desde la lΓnea de comandos. Odio los stacks y frameworks, etc., cuando voy a ser yo el ΓΊnico que lo ejecute y use. Soy un poco "hater" de los frameworks, sean de lo que sean, normalmente para mis casos de uso solo aΓ±aden complejidad.
Β
Usando llm para ejecutar LLM en local
Para ejecutar los LLMs que mi ordenador es capaz de procesar uso llm (desarrollado por Simon Willison, si no le sigues, Β‘deberΓas!), ya que es fΓ‘cil, tiene actualizados todos los modelos y me ocupa mucho menos espacio que cuando instalo LLMs con Ollama, puede que por mi propio desconocimiento...
Β
Por si quieres probarlo,aquΓ tienes las instrucciones, solo con 1 lΓnea ya lo tendrΓ‘s instalado y luego, por ejemplo, este serΓa el comando para descargar la lista de modelos de Mistral:
$ llm install llm-mistral
Ahora vamos al lΓo :), vamos a ejecutar el modelo 'mistral/mistral-small-2503', por ejemplo, le solicitamos la lista de modelos de Nike en la ΓΊltima dΓ©cada.
$ llm -m mistral/mistral-small-2503 "lista los modelos de zapatillas Nike en los ΓΊltimos 10 aΓ±os"
Β
Lo que nos devuelve la lista de zapatillas Nike en formato Markdown
1. **Nike Air Max 270** (2018) - Conocida por su gran unidad Air Max para mΓ‘xima amortiguaciΓ³n.
2. **Nike Air VaporMax** (2017) - Introduce una unidad Air completa sin soporte adicional, ofreciendo una sensaciΓ³n de flotaciΓ³n.
3. **Nike Air Zoom Pegasus 36** (2019) - Parte de la popular serie Pegasus, conocida por su comodidad y rendimiento.
4. **Nike Air Force 1** (Versiones actualizadas) - Un clΓ‘sico que ha sido reimaginado con nuevas tecnologΓas y diseΓ±os.
5. **Nike Air Max 720** (2016) - Ofrece una unidad Air Max de 360 grados para una amortiguaciΓ³n completa.
[...recortado por extensiΓ³n...]
Β
Haciendo preguntas sobre Google Search Console a un script
Ya hemos visto cΓ³mo podemos ejecutar fΓ‘cilmente este modelo de Mistral en nuestro ordenador. Ahora intentaremos ir un poco mΓ‘s allΓ‘ y nos marcaremos como objetivo poder realizar consultas a Search Console usando lenguaje natural.
Yo proceso los datos de logs, Search Console, Analytics y otras fuentes diariamente. Cada dΓa me descargo a mi BBDD los nuevos datos generados en GSC para todos los proyectos de mis clientes y los uso a menudo para diferentes tareas como anΓ‘lisis profundos, alertas, forecast, etc... Y sΓ, tambiΓ©n porque me gusta, o tengo el sΓndrome de DiΓ³genes con los datos :).
Vamos a usar la lΓnea de comandos para ejecutar una consulta SQL a la base de datos, que estΓ‘ en mi ordenador. Se podrΓa usar cualquier cliente de bases de datos tΓpico como MySQL, PostgreSQL, DuckDB, ClickHouse, etc. Para este ejemplo, estoy usando ClickHouse.
En este caso, vamos a usar el cliente de ClickHouse para hacer una consulta de prueba:
clickhouse-client -u default --ask-password -q "select now()"
βββββββββββββββββββββββ
β now() β
β‘ββββββββββββββββββββββ©
β 2025-03-19 11:27:46 β
βββββββββββββββββββββββ
Β
Pero tambiΓ©n podrΓa hacer una consulta a la base de datos de GSC para contar cuΓ‘ntas filas hay en la tabla.
#A partir de aquΓ usarΓ© 'sqlCH' en vez de 'clickhouse-client -u default --ask-password'para hacerlo mΓ‘s corto
sqlCH "select count() cnt from default.GSC_ https_MiDominio_dev FORMAT Pretty"
ββββββββββββ
β cnt β
β‘βββββββββββ©
β 10648667 β
ββββββββββββ
Algo crucial es comunicarle al modelo cΓ³mo se llaman las tablas, cuΓ‘les son las columnas y quΓ© tipo de variables son. Esto lo hago con la SQL "DESCRIBE TABLE", cuyo resultado serΓ‘ intercalado en el prompt que pasaremos al LLM.
sqlCH "DESCRIBE Table default.GSC_ https_MiDominio_dev FORMAT Pretty"
βββββββββββββββ³ββββββββββ³βββββββββββββββ³βββββββββββββββββββββ³ββββββββββ³βββββββββββββββββββ³βββββββββββββββββ
β name β type β default_type β default_expression β comment β codec_expression β ttl_expression β
β‘ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ©
1. β fecha β Date β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
2. β consulta β String β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
3. β landing β String β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
4. β clicks β UInt32 β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
5. β impresiones β UInt32 β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
6. β posicion β Float32 β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
7. β ctr β Float32 β Float32 β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
8. β dispositivo β String β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
9. β pais β String β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
10. β id_cliente β UInt32 β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
11. β propiedad β String β β β β β β
βββββββββββββββ΄ββββββββββ΄βββββββββββββββ΄βββββββββββββββββββββ΄ββββββββββ΄βββββββββββββββββββ΄βββββββββββββββββ
Β
Ahora podemos ir juntando/concatenando las diferentes piezas que tenemos para crear el prompt que enviaremos al modelo, indicΓ‘ndole el nombre de la tabla y luego el resultado de la SQL DESCRIBE. Al final, si os fijΓ‘is, aΓ±ado la consulta que quiero hacer, en este caso: "Genera una SQL que sume el total de clicks en la tabla".
:~$ llm -m mistral/mistral-small-2503 "Este es el esquema de la tabla: \
βββββββββββββββ³ββββββββββ³βββββββββββββββ³βββββββββββββββββββββ³ββββββββββ³βββββββββββββββββββ³βββββββββββββββββ
β name β type β default_type β default_expression β comment β codec_expression β ttl_expression β
β‘ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ©
β fecha β Date β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
β consulta β String β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
β landing β String β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
β clicks β UInt32 β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
β impresiones β UInt32 β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
β posicion β Float32 β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
β ctr β Float32 β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
β dispositivo β String β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
β pais β String β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
β id_cliente β UInt32 β β β β β β
βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€
β propiedad β String β β β β β β
βββββββββββββββ΄ββββββββββ΄βββββββββββββββ΄βββββββββββββββββββββ΄ββββββββββ΄βββββββββββββββββββ΄βββββββββββββββββ
Genera una SQL que sume el total de clicks en la tabla"
Esto nos devuelve una SQL que podemos ejecutar en nuestra base de datos para obtener el dato que hemos solicitado.
sql
SELECT SUM(clicks) AS total_clicks
FROM .GSC_https_ MiDominio_dev;
Esta consulta selecciona la suma de la columna clicks y la etiqueta como total_clicks. La tabla .GSC_https_ MiDominio_dev es especificada en la clΓ‘usula FROM.
Si necesitas agregar alguna condiciΓ³n, como filtrar por un rango de fechas o algΓΊn otro criterio, puedes hacerlo utilizando la clΓ‘usula WHERE. Por ejemplo, si quieres sumar los clicks solo para un rango de fechas especΓfico, podrΓas hacer algo como esto:
sql
SELECT SUM(clicks) AS total_clicks
FROM .GSC_https_ MiDominio_dev
WHERE fecha BETWEEN '2023-01-01' AND '2023-12-31';
AsegΓΊrate de ajustar las fechas y cualquier otra condiciΓ³n segΓΊn tus necesidades especΓficas.
Β
Este tipo de consultas SQL las resuelve bastante bien, tampoco tiene mucha ciencia, pero podemos ir bastante mΓ‘s allΓ‘.
Β
Para poder aprovechar la SQL que nos facilita Mistral, debemos hacer que el modelo se calle, y que ΓΊnicamente devuelva la SQL, sin explicaciones ni consejos ni nada, solo la SQL para poder ejecutar la salida del modelo directamente contra la base de datos...
Β
AquΓ un consejo importante: utiliza un usuario de la base de datos que solo tenga permisos de lectura, porque nadie te puede asegurar que el LLM no genere accidentalmente un DROP DATABASE..... En serio, si ejecutas muchas SQL obtenidas de LLMs, serΓ‘ cuestiΓ³n de estadΓstica que algo asΓ ocurra, o al menos esa es mi hipΓ³tesis.
Β
DescripciΓ³n del proceso
Como un esquema simple, podrΓamos decir que:
#De momento nuestro prompt estΓ‘ vacΓo
-
Texto inicial del prompt: "Eres un asistente de SQL que..."
#El contenido de nuestro prompt ahora es: Eres un asistente de SQL que...
-
Ejecuto el cliente de la base de datos para obtener el resultado de "DESCRIBE TABLE nombreTabla".
-
Concateno lo que me devuelve el comando para aΓ±adirlo al prompt.
#El contenido de nuestro prompt ahora es:
Eres un asistente de SQL que... . Este es el esquema de la tabla nombreTabla: βββββββββββββββ³ββββββββββ³βββββββββββββββ³βββββββββββββββββββββ³ββββββββββ³βββββββββββββββββββ³βββββββββββββββββ β name β type β default_type β default_expression β comment β codec_expression β ttl_expression β β‘ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ© β fecha β Date β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β consulta β String β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β landing β String β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β clicks β UInt32 β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β impresiones β UInt32 β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β posicion β Float32 β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β ctr β Float32 β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β dispositivo β String β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β pais β String β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β id_cliente β UInt32 β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β propiedad β String β β β β β β βββββββββββββββ΄ββββββββββ΄βββββββββββββββ΄βββββββββββββββββββββ΄ββββββββββ΄βββββββββββββββββββ΄βββββββββββββββββ
-
- AΓ±adimos indicamos quΓ© queremos obtener, por ejemplo: " Genera una SQL que sume el total de clicks".
#Ahora nuestro prompt contiene:
Eres un asistente de SQL que... . Este es el esquema de la tabla nombreTabla: βββββββββββββββ³ββββββββββ³βββββββββββββββ³βββββββββββββββββββββ³ββββββββββ³βββββββββββββββββββ³βββββββββββββββββ β name β type β default_type β default_expression β comment β codec_expression β ttl_expression β β‘ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ© β fecha β Date β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β consulta β String β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β landing β String β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β clicks β UInt32 β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β impresiones β UInt32 β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β posicion β Float32 β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β ctr β Float32 β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β dispositivo β String β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β pais β String β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β id_cliente β UInt32 β β β β β β βββββββββββββββΌββββββββββΌβββββββββββββββΌβββββββββββββββββββββΌββββββββββΌβββββββββββββββββββΌβββββββββββββββββ€ β propiedad β String β β β β β β βββββββββββββββ΄ββββββββββ΄βββββββββββββββ΄βββββββββββββββββββββ΄ββββββββββ΄βββββββββββββββββββ΄βββββββββββββββββ Genera una SQL que sume el total de clicks. Devuelve ΓΊnicamente la SQL completa, sin comentarios adicionales, en texto plano.
Como he dicho antes, para que el modelo se centre en devolver solo lo que ejecutaremos posteriormente, he aΓ±adido el prompt: "*Devuelve ΓΊnicamente la SQL completa, sin comentarios adicionales, en texto plano.*". Otros mΓ©todos, como definir el tipo de datos que sale en formato Json, serΓan mΓ‘s robustos, pero de momento funciona bastante bien.
Ya tenemos un prompt "completo", que se lo damos al LLM pasΓ‘ndole la informaciΓ³n necesaria para comprender los datos y que genera la respuesta, en este caso una SQL que ejecutaremos en nuestra base de datos, en este caso concreto para obtener el nΓΊmero total de clicks.
Β
Organizarlo todo en un script
Va siendo hora de organizar todo esto dentro de un script, porque ademΓ‘s veremos cΓ³mo podemos ir mejorando/complicando esta pila de ejecuciΓ³n.
Al script que he creado le paso dos argumentos (bueno, tres, pero los ΓΊltimos son para activar/desactivar determinadas funcionalidades):
-
Como primer argumento, le paso el nombre de la base de datos y la tabla. En el script, se ejecuta la SQL "DESCRIBE TABLE..." y el resultado se aΓ±ade a la variable del prompt.
-
El segundo argumento es la pregunta en sΓ, en este caso serΓa: "Genera una SQL que sume el total de clicks. Devuelve ΓΊnicamente la SQL completa, sin comentarios adicionales, en texto plano."
Con este simple prompt ya creado y guardado en una variable, ejecuto el LLM de Mistral, que me devuelve la SQL a ejecutar y que guardo en otra variable. El siguiente paso simplemente es ejecutar la SQL devuelta por el LLM, Β‘y listo!
Β
Pero las cosas no son tan sencillas, ni tan complicadas... Muchas veces falla, usa funciones SQL que no son compatibles con la base de datos que le indicas, o genera la SQL con errores de formato. Sin embargo, es posible corregirlo.
Β
CuΓ‘ndo la ejecuciΓ³n de la SQL falla podemos volver a pedir al LLM que genere una SQL, pero le aΓ±adiremos al prompt la SQL que acabamos de ejecutar y el mensaje de error que ha generado para indicar al LLM que pruebe con otra SQL diferente y teniendo en cuenta el error que habΓa generado.
Β
De esta forma, cuando falla, vuelve a intentarlo teniendo el contexto de los intentos anteriores. En consultas complejas se ve cΓ³mo va corrigiendo los errores, por ejemplo, si ha usado una funciΓ³n que ClickHouse no admite, se da cuenta y en el siguiente reintento lo corrige. Si el nΓΊmero de intentos al ejecutar la SQL supera un mΓ‘ximo que defino yo, se para y termina.
Β
Este proceso podrΓamos repetirlo las veces que quisiΓ©ramos con la idea de que alguna acertarΓ‘, pero la probabilidad de que la SQL genere un resultado correcto intuyo qye serΓ‘ inversamente proporcional al nΓΊmero de intentos...
Β
Por ΓΊltimo, si aΓ±ado como parΓ‘metro al script '--explicaSQL=si' cuΓ‘ndo ejecute la SQL correctamente se crearΓ‘ un nuevo prompt con las instrucciones para que el LLM explique la SQL que ha generado resultados.
AquΓ dejo una imagen en la que intento representar el flujo de instrucciones que sigue el script
Β
Este script, aunque parezca complejo, es bastante simple, y funciona para muchΓsimas de las consultas que realizo. Para SQLs con cierto nivel de dificultad, por ejemplo regresiones logΓsticas o uso de datos de entrenamiento y validaciΓ³n en las propias SQL, si bien no lo hace mal del todo, no te puedes fiar completamente, ya que a veces no realiza bien la "teorizaciΓ³n" del problema.
Β
Y aquΓ dejo el cΓ³digo del script que implementa este proceso.
#!/bin/bash
if [ "$#" -lt 2 ]; then
echo "Uso: $0 '' [--explicaSQL=si]"
exit 1
fi
DB_TABLA="$1"
PROMPT="$2"
MUESTRA_EXPLICACION=0
if [ "$3" = "--explicaSQL=si" ]; then
MUESTRA_EXPLICACION=1
fi
CLICKHOUSE_CLIENT="clickhouse-client -u default --password=MI_PASSWORD!"
intentos=0
max_intentos=15
errores_acumulados=""
mkdir -p logs
LOG_FILE="logs/sqlResultados_log.csv"
if [ ! -f "$LOG_FILE" ]; then
echo "prompt;sql;estado_salida;respuesta;tabla" > "$LOG_FILE"
fi
tabla=$($CLICKHOUSE_CLIENT --query="DESCRIBE TABLE $DB_TABLA" | tr '\n' ' ')
while [ "$intentos" -lt "$max_intentos" ]; do
sqlIA=$(llm -m mistral/mistral-small-2503 "Este es el esquema SQL de ClickHouse para la tabla $DB_TABLA: $tabla. $PROMPT ${errores_acumulados:+Ten en cuenta los siguientes errores generados anteriormente al ejecutar SQLs anteriores: $errores_acumulados} Devuelve ΓΊnicamente la SQL completa, sin comentarios adicionales, en texto plano." | grep -v '
')
salida=$($CLICKHOUSE_CLIENT -q "$sqlIA" 2>&1)
resultado=$?
if [ "$resultado" -eq 0 ]; then
estado_salida="correcta"
respuesta="$salida"
else
estado_salida="error"
respuesta="$salida"
errores_acumulados+=" | SQL: ${sqlIA//[$'\n'$'\t']/ } Error: ${salida//[$'\n'$'\t']/ }"
fi
echo "\"${PROMPT//\"/\"\"}\";\"${sqlIA//\"/\"\"}\";$estado_salida;\"${respuesta//\"/\"\"}\";$DB_TABLA" >> "$LOG_FILE"
if [ "$resultado" -eq 0 ]; then
echo " SQL ejecutada con Γ©xito:\n$sqlIA\n Resultado:\n$salida"
if [ "$MUESTRA_EXPLICACION" -eq 1 ]; then
explicacion=$(llm -m mistral/mistral-small-2503 "Explica quΓ© hace esta SQL: $sqlIA")
echo -e " ExplicaciΓ³n:\n$explicacion"
fi
exit 0
else
intentos=$((intentos+1))
echo -e " Intento $intentos fallido:\n$respuesta"
sleep 1
fi
done
echo " Se han agotado los intentos, no se generΓ³ una SQL vΓ‘lida."
exit 1
Ejemplos de consultas realizadas a Search Console usando lLLM
Obtener las 10 KWs que mΓ‘s clicks tienen
sqlCHIA3.sh "default.GSC_ https_MiDominio_dev" "Genera una consulta SQL vΓ‘lida para ClickHouse que liste las 10 consultas con mΓ‘s clicks totales desde tres meses antes de la ΓΊltima fecha disponible hasta dicha ΓΊltima fecha, (NO DESDE HOY, TEN EN CUENTA QUE LA ΓLTIMA FECHA EN LA TABLA NO ES LA DE HOY). Las columnas serΓ‘n exactamente: consulta,totalClicks. Limita los resultados ΓΊnicamente a las 10 consultas con mΓ‘s clicks totales, aΓ±adir al final de la consulta SQL 'FORMAT Markdown'. Usa funciones analΓticas o agregadas propias de ClickHouse."

Β
Obtener TOP paΓses con mΓ‘s clicks
sqlCHIA3.sh "default.GSC_ https_MiDominio_dev" "Genera una consulta SQL vΓ‘lida para ClickHouse que liste las 10 consultas con mΓ‘s clicks totales desde tres meses antes de la ΓΊltima fecha disponible hasta dicha ΓΊltima fecha, (NO DESDE HOY, TEN EN CUENTA QUE LA ΓLTIMA FECHA EN LA TABLA NO ES LA DE HOY). Las columnas serΓ‘n exactamente: consulta,totalClicks. Limita los resultados ΓΊnicamente a las 10 consultas con mΓ‘s clicks totales, aΓ±adir al final de la consulta SQL 'FORMAT Markdown'. Usa funciones analΓticas o agregadas propias de ClickHouse."

Β
URLs que mΓ‘s clcks pierden entre dos fechas con % acumulado
sqlCHIA3.sh \
"WA.GSC_ MiDominio_dv" \
"Genera una consulta SQL vΓ‘lida para que devuelva las URLs que mΓ‘s diferencia de clicks hay entre los periodos:
- Periodo 1: desde 2025-02-03 al 2025-02-16
- Periodo 2: desde 2025-01-13 al 2025-01-26
Devolver las columnas:
- landing
- clicks_Periodo_1
- clicks_Periodo_2
- diferencia_clicks_Periodo1_Periodo2
- % de clicks perdidos (cuanto representa frente al total de clicks perdidos de todas las landings), con dos decimales
- % de clicks perdidos acumulado (va sumando cada % de clicks perdidos), con dos decimales
Ordena las URLs en base al total de clicks perdidos (es decir, aquellas cuya diferencia: clicks en Periodo_1 menos clicks en Periodo_2, sea menor).
Limita el nΓΊmero de resultados a 100. AΓ±adir al final de la consulta SQL: 'FORMAT Markdown'."
Β
