Cómo funciona

El modelo propone.
SQAI decide.

Un agente nunca escribe SQL ni emite código para ejecutar. Escribe una solicitud tipada — y cada solicitud recorre el mismo camino: validada contra un contrato fijado, verificada contra tu política, ejecutada en un motor determinista, devuelta con los hashes que permiten reproducirla.

Cada solicitud — ask(), compute() o una llamada a herramienta del AI SDK — recorre el mismo camino. Nada toca el motor hasta que todas las verificaciones han pasado.

01Intención tipada

Una solicitud que el motor puede analizar. No una cadena que deba confiar.

El modelo emite un objeto tipado — nunca SQL, nunca código. Una intención de consulta es un QuerySpec: una métrica a agregar sobre una fuente nombrada. Una intención de cómputo es un ComputationSpec: una función nombrada del contrato, con argumentos y enlaces. Una unión discriminada, dos formas — y en ninguna de ellas hay lugar donde una cadena ejecutable pueda ocultarse.

Esa es la superficie de autoría completa. Lo que la forma no puede expresar, el modelo no puede solicitar.

QuerySpecanatomía
{
"kind": "query",la etiqueta de unión — consulta o cómputo
"version": "1",la versión del spec, fijada
"source_name": "sales",una fuente conectada, por nombre exacto
"metric": "revenue",la columna a agregar
"aggregation": "sum",una de sum · avg · count · min · max
"group_by": "region"opcional — divide el resultado por un campo
}

también opcionalfilter · limit · order

la forma de cómputomodule · function · args · kwargs · bindings · seed?

02Verificación de contrato

Un contrato, fijado por hash. Lo desconocido se rechaza con indicaciones.

El spec se valida contra el contrato de capacidades — un archivo generado y fijado por hash que lista cada operación, su firma exacta y sus indicadores de determinismo. Una capacidad es accesible solo si es de solo lectura y determinista, o determinista con semilla. Las operaciones con escritura y no deterministas no se bloquean en tiempo de ejecución; nunca se generaron en la superficie.

Una función desconocida falla como unsupported_operation y responde con nearest_matches del mismo índice — el modelo se corrige en lugar de entrar en bucle.

Contrato de capacidades

contract_hashsha256:79f1c5a6c7164e7e9e1750e70a5c03292fa87eb52d8148a740c06695924be9a1

4,778
operaciones listadas en el contrato
4,574
expuestas a los SDK, solo lectura
4,564
completamente deterministas
10
simulaciones que requieren semilla
204
excluidas de la superficie

elegibilidadread_only && (deterministic || deterministic_when_seeded)

ante un nombre desconocidounsupported_operation + nearest_matches

03Control de política

Tu lista de permisos decide si — y cómo — se ejecuta.

La política se fija cuando createSQAI() construye la instancia y se aplica en proceso antes de que nada se ejecute — sobre la fuente, cada métrica, agrupación, filtro y columna enlazada, y sobre el nombre de la función. Solo puede restringir el contrato: nombrar una capacidad fuera de la superficie elegible sigue lanzando unsupported_operation.

La entrada de herramienta del modelo no lleva ningún campo allowed*. Nada en la solicitud puede ampliar el acceso — así que no hay nada que una inyección de prompt pueda ampliar.

allowedSourcesfuentes que el modelo puede nombrar

  • "sales"

allowedFieldscolumnas que puede leer, por fuente

  • sales.region
  • sales.revenue
  • sales.order_date

allowedFunctionsel valor por defecto — toda capacidad de solo lectura, nada más

  • "all-readonly"

una denegación es precisa, atribuida, definitiva

  • policy_denied_source
  • policy_denied_field
  • policy_denied_function

source: "sqai" · no reintentable

04Motor determinista

Fijado antes de ejecutar: float64, un hilo, un runtime.

Primero, los enlaces se resuelven. El modelo nombró una fuente y un campo; SQAI extrae los valores reales a través del primitivo extractColumns del motor, alineado por filas, con nulos tratados por pares. SQAI nunca combina arrays por su cuenta — así que la entrada que se hashea es exactamente la entrada que se ejecutó.

Solo entonces toca la solicitud al motor. El runtime está firmado, versionado y fijado: precisión float64, un único hilo. El primer compute() lo aprovisiona una vez, en unos 110 segundos; después permanece residente — finance.npv mide 0,83–0,93 ms en caliente.

envolvente de determinismo
runtime_bundle_version0.1.0
runtime_bundle_sha2564d64142e4c1ff63d299cfc8b172fdf97cb59169b545e1e02978e678a632ce6e1
platformdarwin
architecturearm64
precision_modefloat64
thread_count1
seed
input_hash2ea5ede72acd2912fe9e1230cef34afad4c9436bfa8a709bac2da02b478e3212

Registrada con cada resultado — la envolvente declara el alcance de la garantía en lugar de exagerarlo.

05Respuesta + procedencia

Dos hashes. Uno antes, uno después.

invocation_hash se sella antes de la ejecución — sobre el módulo, la función, los argumentos, los enlaces resueltos, la semilla, el contrato y el alcance. computation_hash se sella después: el hash de invocación combinado con el resultado canónico. Reproducir significa ejecutarlo de nuevo y comparar bytes.

Ambos SDK comparten un serializador canónico único, de modo que el mismo cómputo produce hashes byte a byte idénticos en TypeScript y Python. Las respuestas de consulta siguen la misma disciplina: un plan_hash sobre el plan resuelto canónico, más la ruta de decisión y el alcance exacto en que se ejecutó.

3188.1687606249325finance.npv · enlazado a una columna activa · 0,83 ms en caliente

sellado antes de la ejecución

invocation_hash

8223a694250fc751fcf8a7777b8e1f524c44ff1f0e7e83451467f554a6123950

módulo · función · args · bindings resueltos · seed · contrato · ámbito

sellado tras la ejecución

computation_hash

ff5280ea128113f528dd1e9a28b9bc4a81469075ed7c981c7176fb172d98085d

el hash de invocación, combinado con el resultado canónico

Idéntico byte a byte en TypeScript y Python — un resultado calculado en un lenguaje se reproduce y verifica en el otro.

ambos calculados contracontract_hash sha256:79f1c5a6…

en el plano de consultaplan_hash f87610d8afeb…decision_path "exact_spec"deterministic_scope "local_registered_source"

06El bucle de descubrimiento

Sin suposiciones. Descubre, simula, luego ejecuta.

Los nombres de campo y las firmas de función se descubren, no se alucinan. El AI SDK expone exactamente tres herramientas — y solo una de ellas ejecuta.

  1. 01listSources()

    ¿Qué puedo consultar?

    Fuentes conectadas, con nombres de campo exactos, tipos y las operaciones permitidas por campo. Nunca ejecuta.

  2. 02listSources({ capabilitySearch: "npv" })

    ¿Qué puedo calcular?

    La misma herramienta, buscando en el catálogo determinista — módulos coincidentes, firmas exactas y si se requiere un seed.

  3. 03explainQuery({ … })

    ¿Funcionará?

    Una simulación en seco. Devuelve el plan resuelto, la confianza y un invocation_hash de vista previa — una vista previa, nunca un hash ejecutado.

  4. 04queryData({ … })

    Ejecutar.

    La única herramienta que ejecuta. Devuelve el resultado junto con su procedencia completa; los resultados de gran tamaño permanecen recuperables por result_id.

Las herramientas nunca lanzan errores — cada resultado tiene tipook · needs_clarification · rejected · error

La mecánica, campo por campo.

Leer la documentación