Complete "Fundamentos: Cómo un agente de IA percibe, planifica y actúa" primero para desbloquear esta lección.Ir a la lección anterior

Introducción

Los agentes de IA se vuelven mucho más útiles cuando pueden interactuar directamente con bases de datos relacionales en nombre de los usuarios: respondiendo preguntas como "¿Cuáles fueron los productos más vendidos el trimestre pasado?" o "Actualiza la dirección de envío de este cliente" sin que una persona tenga que escribir SQL a mano. El reto es darle a un agente poder real sobre la base de datos sin permitirle ejecutar consultas destructivas o inseguras. Esta lección recorre los bloques prácticos: permitir que un agente lea tu esquema, generar SQL, validar ese SQL y solo entonces ejecutarlo contra una base de datos real.

Conceder conciencia del esquema al agente

Un agente no puede escribir SQL correcto si no sabe qué tablas y columnas existen. La técnica estándar es alimentar al modelo con una descripción condensada del esquema de la base de datos como parte del prompt del sistema o como un bloque de contexto recuperado. Para una base de datos PostgreSQL, puedes volcar tablas y columnas usando information_schema y luego recortar la salida antes de pasársela al modelo.

sql
SELECT table_name, column_name, data_type
FROM information_schema.columns
WHERE table_schema = 'public'
ORDER BY table_name, ordinal_position;

Las filas devueltas se convierten en un resumen de texto que el agente puede consultar cada vez que construya una consulta. Sin esto, el modelo inventará nombres de columnas y fallará repetidamente.

diagrama de flujo que muestra cómo el agente recibe la pregunta del usuario, recupera el contexto del esquema a partir de los metadatos de la base de datos, genera un candidato SQL, valida el SQL y luego ejecuta o rechaza

Generar y validar SQL

Una vez que el agente tiene el contexto del esquema, le pides que produzca una única sentencia SQL en respuesta a la solicitud del usuario. Envuelve esa salida en un parser para poder inspeccionarla antes de ejecutarla. Un pipeline robusto hace tres cosas en orden: (1) rechazar cualquier cosa que no sea una única sentencia, (2) rechazar cualquier sentencia cuyo verbo principal esté en una lista de prohibidos (DROP, TRUNCATE, DELETE sin WHERE, UPDATE sin WHERE, GRANT, etc.), y (3) ejecutar la sentencia con una conexión de solo lectura o con parámetros limitados según la intención.

python
import sqlparse
FORBIDDEN = {"drop", "truncate", "grant", "revoke"}
def safe_sql(raw: str) -> str:
parsed = sqlparse.parse(raw)
if len(parsed) != 1:
raise ValueError("Must be exactly one statement")
stmt = parsed[0]
first_token = stmt.get_type().lower()
head = stmt.token_first(skip_cm=True).value.lower()
if head in FORBIDDEN:
raise ValueError(f"Forbidden verb: {head}")
return str(stmt)

Esta capa de validación se ejecuta *antes* de que el SQL toque tu base de datos. Es la salvaguarda más importante de todo el pipeline.

Ejecutar a través de una conexión restringida

Incluso con validación, la defensa en profundidad importa. Conéctate a la base de datos como un usuario cuyos permisos ya estén restringidos: un rol de solo lectura para preguntas analíticas y un rol aparte con solo los derechos específicos de INSERT/UPDATE que tu aplicación necesita. Establece un tiempo de espera corto para sentencias a nivel de sesión para que las consultas descontroladas no puedan bloquear una tabla durante minutos.

sql
SET statement_timeout = '3s';
SET idle_in_transaction_session_timeout = '5s';

Combina estos tiempos de espera con un límite de filas añadido a los SELECT generados (por ejemplo, añadir siempre LIMIT 100 a menos que el usuario renuncie explícitamente) para que el agente no pueda arrastrar una tabla de un millón de filas a memoria y colapsar.

diagrama de bloques que compara dos roles de conexión a la base de datos: un rol analítico de solo lectura y un rol de escritura con alcance limitado, mostrando qué sentencias SQL puede ejecutar cada uno

Errores comunes

El fallo más frecuente es dejar que el agente devuelva SQL en crudo al chat sin ejecutarlo nunca; los usuarios entonces lo copian y lo ejecutan ellos mismos, y pierdes las pistas de auditoría. Otro es confiar en que el modelo "decida si la consulta es segura" dentro del mismo prompt; la autovigilancia no es fiable, así que aplica siempre la validación en código. Por último, evita pasar de golpe el esquema completo de una base de datos enorme: el modelo gasta contexto en tablas que nunca necesita, así que filtra a las tablas relevantes por solicitud o usa embeddings para recuperar solo las que coincidan.

Resumen

Conectar un agente a SQL es un problema por capas. Empieza exponiendo los metadatos del esquema para que el modelo pueda escribir SQL real, luego genera, parsea y valida cada sentencia en código antes de la ejecución. Apoya al validador con permisos basados en roles y tiempos de espera a nivel de conexión para que un error o un prompt malicioso no pueda borrar una tabla. Con esas cuatro capas (contexto de esquema, validación a nivel de código, roles restringidos y tiempos de espera), un agente puede responder preguntas de datos y realizar escrituras seguras sin poner en riesgo tu base de datos.

Práctica de la lección

Punto de control de la lección

Repasa lo aprendido y recibe comentarios sobre tu trabajo.

0/8
01¿Por qué alimentar al agente con metadatos del esquema es un prerrequisito para una generación precisa de SQL?
02¿Qué verbo SQL debe ser rechazado explícitamente por la capa de validación independientemente del contexto?
03En la función safe_sql de Python, ¿cuál es el propósito de comprobar len(parsed) != 1?
04¿Por qué aplicar statement_timeout a nivel de sesión en lugar de validar SQL solo en código?
05¿Qué problema surge cuando pasas el esquema completo de una base de datos grande al prompt del agente?
06¿Por qué se considera poco fiable que el agente "se autopolicíe" su propio SQL dentro del prompt?
07¿Cuál es el rol de un usuario de base de datos de solo lectura en esta configuración?
08¿Qué orden describe mejor la defensa en capas para SQL dirigido por agentes?
Respondidas · 0/8
Conectar agentes de IA a bases de datos SQL