Volver al portfolio
LangChain Text-to-SQL FastAPI

Asistente IA para
Base de Datos en Lenguaje Natural

API REST que traduce preguntas en lenguaje natural a consultas SQL ejecutadas sobre una base de datos MySQL real, devolviendo respuestas interpretadas en streaming. Construido para el marketplace de beats musicales Lambda Beats.

PythonFastAPILangChainGoogle Gemini 2.5 FlashMySQLSQLDatabaseStreaming
Ver en GitHub

¿Qué problema resuelve?

Los administradores de un marketplace necesitan acceder a datos constantemente: ventas del mes, beats más escuchados, ingresos por tipo de licencia... Habitualmente esto requiere escribir SQL o depender de un analista de datos.

Este proyecto elimina esa fricción: el administrador hace una pregunta en lenguaje natural, el sistema genera la SQL correcta, la ejecuta de forma segura y devuelve una respuesta interpretada en streaming con cifras formateadas y en tono profesional.

La API incluye soporte para conversaciones multi-turno (el contexto de mensajes anteriores se mantiene) y restricción de dominio: preguntas fuera del contexto del marketplace devuelven OUT_OF_CONTEXT.

¿Cómo funciona?

1

Arranque: extracción del esquema

Al iniciar la API, SQLDatabase.get_table_info() extrae automáticamente el esquema completo de 8 tablas relevantes de MySQL. Este esquema se inyecta en el system prompt de Gemini con contexto de negocio detallado.

2

Generación de SQL con Gemini

El endpoint POST /ask recibe el historial de mensajes. Gemini 2.5 Flash recibe el esquema + historial completo y genera una consulta SQL pura sin markdown. Si la pregunta no es sobre el marketplace, responde OUT_OF_CONTEXT.

3

Capa de seguridad: solo SELECT

Antes de ejecutar, dos validaciones regex bloquean cualquier operación de escritura: la query debe comenzar por SELECT y no puede contener INSERT/UPDATE/DELETE/DROP/.... Las queries de escritura se registran en logs y se bloquean con un mensaje de error al usuario.

4

Ejecución en MySQL

La query validada se ejecuta sobre la BD real usando SQLDatabase.run() de LangChain. Los resultados crudos (tuplas) se pasan a la siguiente fase. Los errores de BD se capturan con logging estructurado sin exponer detalles de la query al usuario.

5

Interpretación en streaming

Gemini recibe la pregunta original + los datos en crudo y genera una respuesta en lenguaje natural con tono profesional usando model.stream(). FastAPI devuelve un StreamingResponse para que la respuesta aparezca progresivamente en el cliente.

Flujo de datos

💬 Query
──→
🤖 Gemini → SQL
──→
🛡️ Validation
🗄️ MySQL
📡 Streaming
←──
🤖 Gemini → Interprets
←──
📊 SQL Results

Decisiones de diseño

Conversación multi-turno

El endpoint acepta un array de mensajes, permitiendo que Gemini tenga contexto de preguntas anteriores y pueda responder "¿y del mes pasado?" sin perder el hilo.

Context window del esquema

El esquema SQL completo se inyecta en cada petición. Se limitó a 8 tablas relevantes para no saturar el contexto de Gemini con tablas obsoletas.

Seguridad read-only

Doble validación regex: la query debe empezar en SELECT y no puede contener ninguna operación de escritura. Las queries bloqueadas se loguean con WARNING.

Restricción de dominio

Si la pregunta no es sobre beats, ventas o métricas del marketplace, el modelo responde OUT_OF_CONTEXT y el backend lo convierte en un mensaje amigable.

Proyecto personal · Python · FastAPI · 2025

Ver código en GitHub