IEl caso contra el SQL generado

El modelo no debería
escribir el SQL.

Text-to-SQL es la forma obvia de apuntar un agente a una base de datos, y la demo es genuinamente impresionante. La producción es donde todo cambia: la misma pregunta compila a SQL distinto, un error silencioso en un join desplaza los ingresos un 15%, y la salida del modelo se convierte en una superficie de ataque. Hay otro camino.

IIPrimero, el crédito

Text-to-SQL se ganó el hype. En su carril.

Dónde es la herramienta correcta

  • Prototipos sobre datos desechables
  • Explorar un esquema desconocido, con supervisión humana
  • Preguntas puntuales que alguien verificará
  • La demo — funciona realmente bien en demos

Dónde falla

  • Cifras sobre las que alguien actuará
  • Texto no confiable en cualquier parte del contexto
  • Credenciales de producción en la conexión
  • Respuestas que deben ser reproducibles o auditables
  • Agentes que operan sin supervisión

El patrón no es el problema. El radio de explosión sí lo es. Cada riesgo de esta página se origina en una sola decisión de diseño: la salida del modelo se ejecuta como código.

IIILos dos caminos

La misma pregunta. Dos arquitecturas.

Sigue una pregunta por ambos caminos: una cadena SQL libre a la izquierda, un plan tipado a la derecha. Los números remiten al registro de riesgos a continuación.

la pregunta

¿Qué región tiene el mayor ingreso total?

Camino A

El modelo escribe SQL

  1. el modelo improvisa una cadena 010304

    Todo lo que el modelo leyó — un mensaje de usuario, una fila recuperada — puede moldear esta cadena.

    ejecución 1SELECT region, SUM(total) FROM orders GROUP BY region;ejecución 2 · misma preguntaSELECT o.region, SUM(i.amount) FROM orders o LEFT JOIN order_items i ON i.order_id = o.id GROUP BY 1;
  2. tu conexión lo ejecuta 05

    Con toda la autoridad de la conexión. Lectura, joins — y salvo que alguien recordara el flag, escritura.

la respuesta

run 1 → east · 2130.50

run 2 → east · 2450.08+15% — fan-out de join 02

Dos ejecuciones, dos cifras. Ambas plausibles. Sin señal de cuál — si alguna — es correcta.

Camino B

El modelo presenta un plan tipado

  1. intención tipada

    No una cadena — un valor con esquema. Solo puede nombrar operaciones que el contrato define.

    { "kind": "query", "version": "1", "source": "revenue", "op": "sum", "group_by": "region" }
  2. verificación de contrato

    Anclado por hash. Una operación desconocida devuelve unsupported_operation con las coincidencias más cercanas — nunca una suposición.

  3. verificación de política

    Tu lista de permisos a nivel de código. Una solicitud puede reducir la superficie, nunca ampliarla.

  4. ejecución determinista

    float64, hilo único, runtime anclado. Mismo plan, mismos bytes, misma respuesta.

la respuesta

east · 2130.50

plan_hash f87610d8afeb…

decision_path "exact_spec"

Una sola respuesta, con los hashes para reproducirla — la semana que viene, el trimestre que viene, en cualquiera de los dos lenguajes.

IVEl registro de riesgos

Cinco formas en que el SQL generado falla

  1. 01

    P2SQLarXiv 2308.01990

    La inyección se desplaza al canal de salida

    El saneamiento de entrada inspecciona lo que entra al modelo. Los ataques P2SQL llegan en lo que sale: SQL malicioso y bien formado, ensamblado a partir de instrucciones ocultas en un mensaje de usuario o una fila recuperada. Ningún filtro de entrada lo ve jamás — el ataque es la salida.

  2. 02

    −15%el dashboard que mentía

    Los joins incorrectos fallan en silencio

    Un join con fan-out cuenta filas dobles y los ingresos aparecen con un 15% de desviación. Sin excepción, sin advertencia — el SQL incorrecto no falla, reporta. El resultado siempre es un número, y un número plausible no da ninguna señal de que está mal.

  3. 03

    1 → nuna pregunta, n consultas

    La misma pregunta, SQL diferente

    Pregunta dos veces y el modelo puede compilar la pregunta de dos formas distintas — a veces con dos respuestas diferentes. No existe una consulta canónica que revisar, cachear o reproducir. El número de ayer no puede reproducirse, ni siquiera para verificarlo.

  4. 04

    91.2 → 21.3% correcto · benchmark → esquema empresarial

    El precipicio de precisión

    En esquemas de benchmark limpios, un modelo de frontera escribió SQL correcto el 91,2% de las veces. En esquemas empresariales reales: el 21,3%. En la misma oleada de investigación, aproximadamente el 40% de las ejecuciones de agentes text-to-SQL fallaron por completo o devolvieron resultados incorrectos. Los benchmarks son ordenados. Tu esquema no lo es.

  5. 05

    1 BD en prodeliminada por un agente — el incidente de Replit

    La ruta de escritura siempre estuvo ahí

    El agente de programación de Replit eliminó una base de datos de producción pese a instrucciones explícitas de no tocarla. Esa es la lección: una instrucción de solo lectura es una petición. Si la conexión puede escribir, la ruta de escritura existe, y tarde o temprano una mala respuesta la encuentra. Solo lectura tiene que ser una propiedad de la herramienta, no una línea del prompt.

No filtres la salida.
No la generes.

Sin cadena SQL, sin inyección · sin suposición, sin deriva

VEl certificado

Cinco dimensiones, cara a cara

No es un generador LLM a SQLREADME del motor

Certificado de diferencia

superficie de autoríaSQL generadouna cadena SQL de forma libreplan tipadouna intención tipada y versionada
superficie de ejecuciónSQL generadotodo lo que la conexión permiteplan tipado4 574 capacidades de solo lectura
ruta de escrituraSQL generadopresente salvo bloqueo explícitoplan tipadoninguna, por construcción
gobernanzaSQL generadoa nivel de prompt, con mejor esfuerzoplan tipadolistas de permisos en código que el modelo no puede ampliar
reproducibilidadSQL generadoningunaplan tipadoun hash de repetición en cada resultado

columna derecha anclada al contratosha256:79f1c5a6…924be9a1

La letra pequeña se sostiene: la única vía de escape del motor — getUnsafeRuntime — está ausente de toda superficie expuesta al modelo, de modo que el modelo no puede alcanzarla. Y el README enuncia la doctrina sin ambigüedad: esto no es un generador LLM a SQL.

VIPreguntas

Planteadas en producción

¿Cómo bloqueo DELETE y DROP en SQL generado por un LLM?

No filtres el SQL — deja de generarlo. Las listas de denegación inspeccionan cadenas, y los modelos son infinitamente creativos produciendo nuevas. SQAI elimina la clase entera: el modelo presenta un plan tipado contra 4 574 capacidades de solo lectura, y no existe ninguna capacidad de escritura que ningún plan pueda invocar.

¿Qué es la inyección P2SQL?

Inyección prompt a SQL: SQL malicioso que aparece en la salida del modelo, ensamblado a partir de instrucciones ocultas en lo que el modelo leyó — un mensaje de usuario, un documento, una fila recuperada. El saneamiento de entrada nunca lo detecta, porque el ataque vive en el canal de salida. Está documentado en arXiv 2308.01990.

¿Hay casos en que text-to-SQL sea la elección correcta?

Sí — para prototipos y exploración supervisada sobre datos no productivos es rápido y genuinamente útil. Es la elección equivocada en cuanto el número vaya a usarse para tomar decisiones, el contexto contenga texto no confiable, o la respuesta deba ser reproducible.

¿Cómo doy a un agente de IA acceso de solo lectura a una base de datos?

Haz que solo lectura sea estructural, no configurado. Un flag de solo lectura en una conexión es un ajuste que alguien puede cambiar. La superficie de ejecución de SQAI contiene únicamente capacidades de lectura — la ruta de escritura está ausente por construcción, e incluso la vía de escape del motor es inalcanzable desde cualquier herramienta expuesta al modelo.

¿En qué se diferencia un plan tipado del SQL generado?

Una cadena SQL puede expresar cualquier cosa que la gramática permita. Un plan tipado solo puede expresar lo que el contrato define. Cada plan se valida contra un contrato anclado por hash, se comprueba frente a tu política de listas de permisos y se ejecuta en un motor determinista — con un hash de repetición en cada resultado.

Toma el otro camino.

Sin cuenta. Sin clave. Los datos locales permanecen locales.