Para agentes — la herramienta de datos gobernada

Herramientas para agentes de IA
que responden con prueba.

SQAI da a un modelo con llamada a herramientas acceso de solo lectura a datos estructurados a través de tres herramientas gobernadas. El modelo redacta intención tipada. Un contrato y tu política la verifican. Un motor determinista la ejecuta. Cada respuesta incluye un hash que la reproduce.

IUn turno del bucle

la solicitud entra¿Qué región tuvo los mayores ingresos totales?
cualquier modelo con llamada a herramientasEl modelo

Planifica los pasos. Redacta la intención. Nunca toca los datos.

llamada a herramienta — intención tipada, nunca SQL{ version:"1", kind:"query", spec:{ metric:"revenue", aggregation:"sum", group_by:"region", source:"sales" } }
la herramienta gobernadaSQAI
  1. contractcontrato de capacidad fijado por hash
  2. policytus listas de permisos, verificadas antes de la ejecución
  3. engineejecución determinista y de solo lectura
estado tipado — nunca una excepciónstatus: ok · needs_clarification · rejected · error
la respuesta sale — con su hasheast — 2,130.50 · plan_hash f87610d8afeb…
ok

Sale del bucle. Las filas o el valor — y el hash que los reproduce.

needs_clarification ↺

Vuelve al bucle. Una pregunta y los candidatos encontrados — el modelo refina la especificación y llama de nuevo. Nunca adivina una columna.

los rechazos y los errores usan el mismo canal de retorno — resultados tipados que el modelo puede leer, no excepciones que abortan la ejecución.

IILas herramientas

Tres herramientas. Una ejecuta.

sqai.tools() devuelve exactamente tres herramientas — una superficie deliberadamente pequeña. El descubrimiento y los ensayos nunca ejecutan; la ejecución ocurre en un único lugar.

listSources

nunca ejecuta

Descubrimiento. Fuentes conectadas con campos tipados, módulos de capacidad, firmas de función — tres modos desde una sola entrada, para que las specs usen nombres exactos.

sources · capabilitySearch · module
ops: sum avg count min max eq in gt gte lt lte is_null is_not_null

queryData

el que ejecuta

Una entrada versionada — una unión discriminada sobre kind: una consulta o un cómputo. Cuatro resultados, siempre tipados, sin excepciones.

version "1" · kind: query | computation
ok · needs_clarification · rejected · error

explainQuery

simulacro — nunca ejecuta

Resuelve y valida una intención sin ejecutarla. El modelo la usa para depurar aclaraciones; tú la usas para previsualizar un plan.

preview invocation_hash ≠ executed hash

El conjunto se integra directamente en generateText o streamText — tipado, asignable sin cast. Configuración de Vercel AI SDK

IIIEl contrato de errores

Las herramientas no fallan.

Una excepción aborta una ejecución del agente. Por eso nada aquí lanza: la ambigüedad, el rechazo y el fallo regresan como estados tipados que el modelo puede leer — y corregir — dentro de su presupuesto de pasos.

retryable marca los transitorios — network_error · timeout · rate_limited · service_unavailable

queryData — los cuatro resultados

okEl resultado: filas o valor, hashes de procedencia, truncación declarada.plan_hash · invocation_hash · computation_hash · truncated
needs_clarificationLa intención era ambigua. Una pregunta más los candidatos — nunca una suposición.question · candidates · explanation
rejectedEl resolver rechazó la intención. Nada se ejecutó.rejection_reason · candidates · explanation
errorUn fallo estructurado con un código estable — el modelo lo lee y se ajusta.code · message · retryable · nearest_matches?

Cada rama es dato. El bucle conserva su turno.

El principio

Trata al modelo como
un cliente no confiable.

política en código · ningún campo de política en ninguna entrada de tool · solo restricción

IVEl principio, aplicado

La industria aprendió esto en producción — un agente de codificación autónomo eliminó célebremente una base de datos en vivo. La respuesta de SQAI es estructural, no conductual: la superficie expuesta es de solo lectura por construcción. Las categorías de escritura y no deterministas nunca se generan en ella, y ningún flag, política ni entrada del modelo las reactiva.

Lo que el modelo envía
Solo intención tipada — una spec versionada. Sin cadena SQL, sin código, sin handle de conexión.
Lo que nunca puede enviar
Política. allowedSources, allowedFields y allowedFunctions se fijan en la configuración de createSQAI() — ningún esquema de entrada de tool contiene un campo de política, por lo que una solicitud puede reducir la superficie pero nunca ampliarla.
Cuando lo solicita de todos modos
Una denegación estructurada — policy_denied_source, policy_denied_field, policy_denied_function. No reintentable, legible por el modelo, y la ejecución continúa.
Modelo de política completo

VLa conexión

Tres líneas. Acotado por defecto.

Un paquete envuelve el cliente en tools. Las fuentes se conectan de forma diferida en la primera llamada; el primer cómputo aprovisiona el runtime una vez y luego permanece activo — 0,83 ms medidos.

import { generateText } from "ai";
import { createSQAI } from "@thyn-ai/sqai-ai-sdk";

const sqai = createSQAI({
  sources: [{ data: "./data/sales.csv", name: "sales" }],
});

const { text, steps } = await generateText({
  model,                  // any AI SDK model
  tools: sqai.tools(),    // listSources · queryData · explainQuery
  prompt: "Which region had the highest total revenue?",
});
ai ^7.0.0zod ^4.0.0node ≥ 20runtime = "nodejs"

Solo en servidor — en Next.js, usa el runtime de Node, no Edge.

Lo que llega al modelo

maxRowsToModel
25filas que ve el modelo, del total ejecutado por el motor
maxCellsToModel
250presupuesto de celdas — se eliminan filas completas para ajustarse; nunca se muestra una fila parcial
maxBytesToModel
32,000presupuesto en bytes para el valor visible por el modelo
maxExecutionRows
1,000límite máximo que ejecuta el motor — defaultLimit 100 cuando una spec omite el límite

El truncamiento siempre se declara — truncated: true, returned_rows < total_rows. Nunca silencioso. Los resultados completos siguen siendo recuperables en el código de aplicación mediante result_id.

VIAnalítica agéntica

Análisis que un agente puede defender.

La analítica agéntica falla de formas conocidas: llamadas a tools malformadas, modelos haciendo su propia aritmética, números plausibles que nadie puede verificar. Cada problema se resuelve de forma estructural, no con un mejor prompt.

01Llamadas a tools inválidas

Una entrada versionada, validada antes de que nada se ejecute. Una intención malformada o ambigua devuelve un estado tipado — el bucle continúa en lugar de fallar.

02El modelo hace los cálculos

Aquí no. El motor computa. En un conjunto cuantitativo de 16 preguntas, el mismo modelo pasó de 0/16 a 16/16 en cuanto el motor asumió el cómputo.

03Números no verificables

Cada respuesta lleva su hash. Reproduce la misma intención sobre los mismos datos y el hash coincide — idéntico byte a byte en TypeScript y Python.

04Acumulación de latencia

Un bucle multiplica la latencia. El plano de consulta se ejecuta en proceso a submilisegundo; el cómputo en caliente se midió en 0,83 ms.

VIIPreguntas

Para agentes — las preguntas

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

No filtres SQL — no lo generes. Conecta fuentes a createSQAI() y entrega al modelo sqai.tools(): la superficie a la que accede son 4.574 capacidades de solo lectura más tus fuentes, sin ruta de escritura por construcción. No existe ninguna categoría de escritura que bloquear, ni ninguna entrada del modelo que la reactive.

¿Qué ocurre cuando la solicitud del agente es ambigua?

queryData devuelve needs_clarification con una pregunta y los campos candidatos encontrados. Nunca infiere una columna. El modelo responde la pregunta y vuelve a llamar: una vuelta más del bucle.

¿Las herramientas lanzan excepciones alguna vez?

No. Cada fallo es un resultado estructurado con un código estable, un mensaje y un indicador de reintento. Ambigüedad, rechazo, denegación de política y fallos transitorios vuelven todos como datos que el modelo puede leer.

¿Puede el modelo ampliar sus propios permisos?

No. allowedSources, allowedFields y allowedFunctions viven en el código, fijados en el momento de createSQAI() y verificados antes de la ejecución. Ningún esquema de entrada de herramienta contiene un campo de política; nombrar una capacidad denegada devuelve un error estructurado policy_denied.

¿Funciona con el Vercel AI SDK?

Sí — @thyn-ai/sqai-ai-sdk incluye las tres herramientas como conjunto tipado para generateText y streamText, con ai ^7.0.0 y zod ^4.0.0 como peers, Node 20 o superior, en servidor. El cliente subyacente es el mismo SDK que puede integrarse en cualquier bucle de agente.