SQL + IA: Consultando Bases de Datos con Lenguaje Natural (Text-to-SQL)
Introducción
Una de las aplicaciones más prácticas de la IA generativa en el mundo del desarrollo es el Text-to-SQL: convertir preguntas escritas en lenguaje natural ("¿cuántos clientes compraron en marzo?") en consultas SQL ejecutables contra una base de datos real.
En este post recopilamos tres enfoques distintos para resolver este problema, cada uno con su propio stack tecnológico, ejemplos de código funcionales y un repositorio público de referencia para que puedas clonarlo y probarlo tú mismo.
1️⃣ Extractor de datos SQL con LLM + Python puro
Idea central: usar un modelo de lenguaje (vía API) para traducir la pregunta del usuario a SQL, ejecutar esa consulta contra una base de datos (por ejemplo SQLite o PostgreSQL) y devolver el resultado ya formateado.
Flujo típico
- El usuario escribe una pregunta en español o inglés.
- Se le pasa al modelo el schema de la base de datos como contexto.
- El modelo devuelve una consulta SQL.
- La aplicación valida y ejecuta la consulta.
- El resultado se muestra o se re-explica en lenguaje natural. ### Ejemplo de código
import sqlite3
import openai # o el cliente de tu proveedor de LLM preferido
# 1. Definimos el esquema de la base de datos como contexto
DB_SCHEMA = """
Tabla: empleados (id INTEGER, nombre TEXT, departamento TEXT, salario REAL)
Tabla: departamentos (id INTEGER, nombre TEXT, presupuesto REAL)
"""
def generar_sql(pregunta_usuario: str) -> str:
prompt = f"""
Eres un asistente experto en SQL. Dado el siguiente esquema:
{DB_SCHEMA}
Convierte esta pregunta en una consulta SQL válida y responde
únicamente con la consulta, sin explicaciones adicionales.
Pregunta: {pregunta_usuario}
"""
respuesta = openai.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
temperature=0
)
return respuesta.choices[0].message.content.strip()
def ejecutar_consulta(sql: str, db_path: str = "empresa.db"):
conexion = sqlite3.connect(db_path)
cursor = conexion.cursor()
try:
cursor.execute(sql)
columnas = [desc[0] for desc in cursor.description]
filas = cursor.fetchall()
return columnas, filas
finally:
conexion.close()
if __name__ == "__main__":
pregunta = "¿Cuáles son los 5 empleados con mayor salario?"
sql_generado = generar_sql(pregunta)
print("SQL generado:", sql_generado)
columnas, resultados = ejecutar_consulta(sql_generado)
print(columnas)
for fila in resultados:
print(fila)
Este patrón —contexto de schema + generación + ejecución validada— es la base de casi todas las herramientas de este tipo. Es importante sanitizar y validar el SQL generado antes de ejecutarlo (por ejemplo, bloqueando DROP, DELETE o UPDATE si solo se espera lectura).
📖 Referencia detallada: freeCodeCamp – Talk to Databases Using AI
🔗 Repositorio de ejemplo público: github.com/freeCodeCamp/text-to-sql-examples (revisa el artículo enlazado, que incluye el repo completo paso a paso con Streamlit/FastAPI)
2️⃣ Agentes autónomos con smolagents de Hugging Face
Idea central: en lugar de un solo llamado "pregunta → SQL → ejecución", se usa un agente capaz de razonar en varios pasos: puede inspeccionar el schema, generar SQL, ejecutarlo, revisar el resultado y corregirse a sí mismo si la consulta falla.
smolagents es una librería ligera de Hugging Face para construir agentes basados en LLMs con herramientas (tools) personalizadas.
Ejemplo de código
from smolagents import CodeAgent, tool, InferenceClientModel
import sqlite3
@tool
def consultar_base_datos(sql_query: str) -> str:
"""
Ejecuta una consulta SQL de solo lectura contra la base de datos
de la empresa y devuelve el resultado como texto.
Args:
sql_query: la consulta SQL a ejecutar.
"""
conexion = sqlite3.connect("empresa.db")
cursor = conexion.cursor()
try:
cursor.execute(sql_query)
resultado = cursor.fetchall()
return str(resultado)
except Exception as e:
return f"Error ejecutando la consulta: {e}"
finally:
conexion.close()
modelo = InferenceClientModel() # usa un modelo alojado en Hugging Face
agente = CodeAgent(
tools=[consultar_base_datos],
model=modelo,
)
respuesta = agente.run(
"¿Qué departamento tiene el presupuesto más alto y "
"cuántos empleados tiene asignados?"
)
print(respuesta)
Lo interesante de este enfoque es que el agente puede encadenar múltiples llamadas: primero explora las tablas disponibles, luego construye la consulta, la ejecuta y, si el resultado no tiene sentido, reintenta con una consulta corregida sin intervención humana.
📖 Documentación oficial con el ejemplo completo: Hugging Face – smolagents: Text to SQL
🔗 Repositorio público: github.com/huggingface/smolagents
3️⃣ Interfaz visual con Streamlit + Hugging Face
Idea central: envolver el pipeline de text-to-SQL en una interfaz web interactiva usando Streamlit, para que usuarios sin conocimientos técnicos puedan hacer preguntas sobre una base de datos directamente desde el navegador.
Ejemplo de código
import streamlit as st
import pandas as pd
import sqlite3
from transformers import pipeline
st.title("🔎 Consulta tu base de datos en lenguaje natural")
@st.cache_resource
def cargar_modelo():
return pipeline("text2text-generation", model="tu-modelo-text-to-sql")
modelo_sql = cargar_modelo()
esquema = """
empleados(id, nombre, departamento, salario)
departamentos(id, nombre, presupuesto)
"""
pregunta = st.text_input("Escribe tu pregunta:", "¿Cuál es el salario promedio por departamento?")
if st.button("Consultar"):
prompt = f"Esquema: {esquema}\nPregunta: {pregunta}\nSQL:"
sql_generado = modelo_sql(prompt, max_length=128)[0]["generated_text"]
st.code(sql_generado, language="sql")
try:
conexion = sqlite3.connect("empresa.db")
df = pd.read_sql_query(sql_generado, conexion)
st.dataframe(df)
except Exception as e:
st.error(f"No se pudo ejecutar la consulta: {e}")
finally:
conexion.close()
Este enfoque es ideal para dashboards internos o prototipos rápidos donde el equipo de negocio quiere "hablarle" a la base de datos sin escribir SQL manualmente.
📖 Artículo original con el desarrollo completo: Medium – Building a Text-to-SQL Query Generator with Streamlit and Hugging Face
🔗 Repositorio público de ejemplo: github.com/kuhelidey/text-to-sql-streamlit (ver enlace del repositorio dentro del artículo de Medium)
Comparativa rápida
| Enfoque | Complejidad | Mejor para | Herramientas clave |
|---|---|---|---|
| LLM + Python puro | Baja | Prototipos rápidos, scripts internos | OpenAI API, sqlite3 |
Agentes (smolagents) |
Media-Alta | Consultas complejas, auto-corrección | Hugging Face, smolagents |
| Streamlit + HF | Media | Dashboards para usuarios no técnicos | Streamlit, transformers |
Conclusiones y buenas prácticas
-
Nunca ejecutes SQL generado por IA sin validarlo. Usa listas blancas de operaciones permitidas (
SELECTsolamente) y usuarios de base de datos con permisos de solo lectura. - El contexto del schema es clave. Cuanto más claro y completo sea el esquema que le das al modelo, mejor será el SQL generado.
- Los agentes brillan en tareas multi-paso, pero cuestan más tokens/latencia que una llamada simple.
- Streamlit es la vía más rápida para llevar un prototipo a manos de usuarios no técnicos. ¿Ya probaste alguno de estos enfoques en tu equipo? Cuéntame en los comentarios qué stack usaste y qué problemas encontraste al conectar LLMs con bases de datos reales. 🚀
Este post recopila y adapta ejemplos de tres fuentes públicas (enlazadas arriba) con fines educativos y de referencia para la comunidad.
Top comments (0)