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

  1. Texto inicial del prompt: "Eres un asistente de SQL que..."

    #El contenido de nuestro prompt ahora es: Eres un asistente de SQL que...

    1. Ejecuto el cliente de la base de datos para obtener el resultado de "DESCRIBE TABLE nombreTabla".

    2. 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  β”‚              β”‚                    β”‚         β”‚                  β”‚                β”‚
      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
      



  2. 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):

  1. 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.

  2. 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'."

Β 


 




Lea otros artículos de Inteligencia Artificial para SEOs

Últimos posts

Últimos comentarios


Lino
@Emil8ano, no son tokens, son caracteres... Pero estoy casi seguro que el limite de texto en cada llamada aumentarΓ‘ rΓ‘pidamente.
Post: aNΓ³tame: extensiΓ³n para guardar notas y generar resumenes usando Gemini de manera local

Emiliano
Gran idea! Pregunta. Los 8000 caracteres no son tokens no? Si es asΓ­ ojo que sin 8000 entre entrada y salida. O sea si te comes 6000 de ent
Post: aNΓ³tame: extensiΓ³n para guardar notas y generar resumenes usando Gemini de manera local

Lino
@spamloco a tΓ­ r hacerme ver que no soy al ΓΊnico que le importa :p A ver si nos vemos!
Post: ΒΏCΓ³mo decide Google que URL debe rastrear?

Alejandro
Gracias Lino, siempre investigando un poco mΓ‘s allΓ‘.
Post: ΒΏCΓ³mo decide Google que URL debe rastrear?

Lino
3,2,1... Gracias a ti Pedro!! y sΓ­, parece que los humanos somos expertos en haciendo ruido cuando intentamos que alguien nos escuche... :p
Post: ΒΏCΓ³mo decide Google que URL debe rastrear?

Pedro
1,2...1,2... probando. Gracias por el artΓ­culo, verdaderamente interesante ver cΓ³mo no paramos de generar ruido :)
Post: ΒΏCΓ³mo decide Google que URL debe rastrear?

Lino
Funcionan!! Ahora solo tengo que generar engagement :D A ver si quito lo de avisar por Twitter... no sΓ© cuΓ‘ntos aΓ±os llevarΓ‘ sin funcio
Post: ΒΏCΓ³mo decide Google que URL debe rastrear?

Juanan Carapapa
Yo tambiΓ©n vengo a probar los comentarios, probando probando xD
Post: ΒΏCΓ³mo decide Google que URL debe rastrear?

Lino2
Hola @errioxa que tal
Post: ΒΏCΓ³mo decide Google que URL debe rastrear?

Lino2
Hola
Post: ΒΏCΓ³mo decide Google que URL debe rastrear?