Como funciona

O modelo propõe.
SQAI decide.

Um agente nunca escreve SQL e nunca emite código para executar. Ele escreve uma requisição tipada — e toda requisição percorre o mesmo caminho: validada contra um contrato fixado, verificada contra sua política, executada em um motor determinístico, retornada com os hashes que permitem reproduzi-la.

Toda requisição — ask(), compute() ou uma chamada de ferramenta do AI SDK — percorre o mesmo caminho. Nada toca o motor até que todas as verificações tenham passado.

01Intenção tipada

Uma requisição que o motor consegue analisar. Não uma string que ele precisa confiar.

O modelo emite um objeto tipado — nunca SQL, nunca código. Uma intenção de consulta é um QuerySpec: uma métrica a agregar sobre uma fonte nomeada. Uma intenção de computação é um ComputationSpec: uma função nomeada do contrato, com argumentos e vínculos. Uma união discriminada, duas formas — e em nenhuma delas há espaço para uma string executável se esconder.

Essa é toda a superfície de autoria. O que a forma não consegue expressar, o modelo não consegue solicitar.

QuerySpecanatomia
{
"kind": "query",a tag da união — query ou computation
"version": "1",a versão do spec, fixada
"source_name": "sales",uma fonte conectada, pelo nome exato
"metric": "revenue",a coluna a agregar
"aggregation": "sum",uma de sum · avg · count · min · max
"group_by": "region"opcional — divide o resultado por um campo
}

também opcionalfilter · limit · order

a forma de computaçãomodule · function · args · kwargs · bindings · seed?

02Verificação de contrato

Um contrato, fixado por hash. O desconhecido é recusado com orientações.

O spec é validado contra o contrato de capacidades — um arquivo gerado e fixado por hash que lista cada operação, sua assinatura exata e seus flags de determinismo. Uma capacidade é acessível apenas se for somente leitura e determinística, ou determinística quando semeada. Operações com escrita e não determinísticas não são bloqueadas em tempo de execução; elas simplesmente nunca foram geradas na superfície.

Uma função desconhecida falha como unsupported_operation e responde com nearest_matches do mesmo índice — o modelo se corrige em vez de entrar em loop.

Contrato de capacidades

contract_hashsha256:79f1c5a6c7164e7e9e1750e70a5c03292fa87eb52d8148a740c06695924be9a1

4,778
operações listadas no contrato
4,574
expostas aos SDKs, somente leitura
4,564
totalmente determinísticas
10
simulações que exigem semente
204
excluídas da superfície

elegibilidaderead_only && (deterministic || deterministic_when_seeded)

em nome desconhecidounsupported_operation + nearest_matches

03Verificação de regras

Sua lista de permissões decide se — e como — executa.

A política é fixada quando createSQAI() constrói a instância e aplicada em processo antes de qualquer execução — sobre a fonte, cada métrica, agrupamento, filtro e coluna vinculada, e sobre o nome da função. Ela só pode restringir o contrato: nomear uma capacidade fora da superfície elegível ainda lança unsupported_operation.

A entrada de ferramenta do modelo não carrega nenhum campo allowed*. Nada na requisição pode ampliar o acesso — portanto não há nada para uma injeção de prompt ampliar.

allowedSourcesfontes que o modelo pode nomear

  • "sales"

allowedFieldscolunas que pode ler, por fonte

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

allowedFunctionso padrão — toda capacidade somente leitura, nada mais

  • "all-readonly"

uma negação é precisa, atribuída, definitiva

  • policy_denied_source
  • policy_denied_field
  • policy_denied_function

source: "sqai" · sem nova tentativa

04Motor determinístico

Fixado antes de executar: float64, uma thread, um runtime.

Primeiro, os vínculos são resolvidos. O modelo nomeou uma fonte e um campo; SQAI extrai os valores reais pelo primitivo extractColumns do motor, alinhado por linha, com nulos tratados em pares. SQAI nunca compõe arrays por conta própria — portanto a entrada que é hasheada é exatamente a entrada que foi executada.

Só então a requisição toca o motor. O runtime é assinado, versionado e fixado: precisão float64, uma única thread. O primeiro compute() o provisiona uma vez, em cerca de 110 segundos; depois disso ele permanece residente — finance.npv mede 0,83–0,93 ms a quente.

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

Registrado com cada resultado — o envelope declara o escopo da garantia em vez de exagerá-la.

05Resposta + proveniência

Dois hashes. Um antes, um depois.

invocation_hash é carimbado antes da execução — sobre o módulo, função, argumentos, vínculos resolvidos, semente, contrato e escopo. computation_hash é carimbado depois: o hash de invocação combinado com o resultado canônico. Reproduzir significa executar novamente e comparar bytes.

Ambos os SDKs compartilham um serializador canônico único, de modo que a mesma computação produz hashes byte a byte idênticos em TypeScript e Python. Respostas de consulta seguem a mesma disciplina: um plan_hash sobre o plano resolvido canônico, mais o caminho de decisão e o escopo exato em que foi executado.

3188.1687606249325finance.npv · vinculado a uma coluna ativa · 0,83 ms a quente

carimbado antes da execução

invocation_hash

8223a694250fc751fcf8a7777b8e1f524c44ff1f0e7e83451467f554a6123950

módulo · função · args · bindings resolvidos · seed · contrato · escopo

registrado após a execução

computation_hash

ff5280ea128113f528dd1e9a28b9bc4a81469075ed7c981c7176fb172d98085d

o hash da invocação, combinado com o resultado canônico

Byte a byte idêntico em TypeScript e Python — um resultado calculado em uma linguagem é reproduzido e verificado na outra.

ambos calculados contracontract_hash sha256:79f1c5a6…

no plano de consultaplan_hash f87610d8afeb…decision_path "exact_spec"deterministic_scope "local_registered_source"

06O ciclo de descoberta

Sem suposições. Descubra, simule, depois execute.

Nomes de campos e assinaturas de funções são descobertos, não inventados. O AI SDK expõe exatamente três ferramentas — e apenas uma delas executa.

  1. 01listSources()

    O que posso acessar?

    Fontes conectadas, com nomes de campos exatos, tipos e as operações permitidas por campo. Nunca executa.

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

    O que posso calcular?

    A mesma ferramenta, consultando o catálogo determinístico — módulos correspondentes, assinaturas exatas e se um seed é necessário.

  3. 03explainQuery({ … })

    Vai funcionar?

    Uma simulação. Retorna o plano resolvido, a confiança e um invocation_hash de prévia — uma prévia, nunca um hash executado.

  4. 04queryData({ … })

    Executar.

    A única ferramenta que executa. Retorna o resultado com sua proveniência completa; resultados muito grandes permanecem acessíveis por result_id.

As ferramentas nunca lançam exceções — cada resultado é tipadook · needs_clarification · rejected · error

A mecânica, campo a campo.

Ler a documentação