PRODPlataforma BaaS europeia soberanaAbra o painel →

IA nativa · 8 minutos de leitura

Tutorial: construir um endpoint NL2SQL no Postgres

Affane Daylami · Fondateur · 28 de agosto de 2026

Voltar ao blog

Este tutorial mostra como receber uma pergunta em francês, transformá-la em uma consulta SQL validada e limitada e, em seguida, retornar o resultado — sem nunca executar SQL não verificado. O SQL realmente gerado é exibido em cada etapa, não apenas no resultado final.

Este texto em inglês foi gerado automaticamente a partir do original em francês e ainda não foi revisado.
Esta página foi traduzida automaticamente. A versão em inglês é oficial.

O mecanismo NL2SQL do Aurabase faz parte da IA nativaintegrada ao backend: não é um serviço de terceiros para montar. Pré-requisitos para seguir este guia: um projeto Aurabase existente, um esquema de banco de dados simples para o exemplo e uma chave API do projeto.

#
Objetivo

O que você vai construir

Um endpoint que recebe uma pergunta em linguagem natural, transforma-a em uma consulta SQL validada e limitada e retorna o resultado. O mecanismo nunca executa SQL gerado sem controle: cada consulta passa por validação sintática antes de chegar ao banco de dados.

Informações

Este tutorial usa o SDK JavaScript @aurabase/aurabase-js e a chamada HTTP bruta equivalente, para que você possa acompanhar em qualquer linguagem.

#
Sob o capô

Como funciona o mecanismo NL2SQL

A questão passa por um LLM configurado — OpenAI, Anthropic (Claude) ou Gemini, os três provedores nativos — que gera um SQL candidato. Este SQL nunca é executado como está: ele passa por um validador que analisa sua árvore de sintaxe (sqlparser), permite apenas consultas SELECT simples e adiciona um LIMIT limitado se algum estiver faltando.

O validador rejeita explicitamente CTE/WITH, subconsultas, UNIONs, cláusulas de bloqueio (FOR UPDATE) e qualquer função fora de uma lista de permissões (count, sum, avg, min, max, lower, upper, coalesce, date_trunc, now). Junções de múltiplas tabelas são suportadas.

Pergunta→LLM (OpenAI/Claude/Gemini)→Validação AST (sqlparser)→Limit limitado→Execução SELECT

O diagrama consultado nunca é fornecido por sua solicitação: ele é introspectado a partir da base real do projeto. Um campo schema, allowed_schema ou schema_context enviado no corpo da solicitação é explicitamente recusado (erro 400) em vez de ignorado silenciosamente - somente o servidor decide o que realmente existe.

#
Passo 1

Configurar o terminal NL2SQL

Com o JavaScript SDK, o cliente Aurabase expõe aura.ai.nl2sql(). A assinatura é nl2sql(question, options): o esquema não faz parte dela, é introspectado no lado do servidor.

app/api/ask/route.tstypescript
import { aura } from '@/lib/aurabase'

export async function POST(req: Request) {
  const { question } = await req.json()

  const { data, error } = await aura.ai.nl2sql(
    question,
    { limit: 50 }
  )

  if (error) return Response.json({ error }, { status: 400 })
  return Response.json(data)
}

No HTTP bruto, o endpoint é POST /v1/ai/{project_id}/nl2sql, autenticado pela chave de API do projeto.

terminalbash
curl -X POST https://<votre-gateway>/v1/ai/<project_id>/nl2sql \
  -H "apikey: <votre-cle-api>" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "Combien de commandes ont été passées ce mois-ci par des clients premium ?",
    "limit": 50
  }'
Campos recusados pelo servidor

Não envie schema, nem allowed_schema, nem schema_context no corpo da solicitação: o esquema consultado é determinado pelo servidor, esses campos são rejeitados explicitamente (400) em vez de sobrescritos silenciosamente.

#
Etapa 2

Teste com uma pergunta real em francês

Pergunta enviada: “Quantos pedidos foram feitos este mês por clientes premium?”. Aqui está a forma do SQL realmente renderizado (nomes de tabelas e colunas dependem do seu esquema):

resposta (trecho)json
{
  "data": {
    "sql": "SELECT count(*) FROM orders WHERE customer_plan = 'premium' AND created_at >= date_trunc('month', now()) LIMIT 50",
    "explanation": "Compte les commandes de ce mois pour les clients premium.",
    "confidence": 0.85,
    "tables": ["orders"],
    "columns": ["customer_plan", "created_at"],
    "limit": 50,
    "limit_injected": false
  },
  "meta": null
}

limit_injected indica se LIMIT vem do modelo ou foi adicionado pelo servidor. confidence é uma heurística na forma da resposta (bloco SQL bem formado ou não) - não uma medida de correção semântica do SQL gerado. Uma pergunta mal formulada retorna um erro explícito em vez de um SQL alucinado: por exemplo, se o SQL gerado consultar uma tabela que não está no seu esquema, a mensagem nomeia as tabelas realmente disponíveis.

#
Etapa 3

Produção segura

Três verificações antes da implantação: o limite de linha (LIMIT) está adaptado ao seu volume, a função Postgres usada pelo mecanismo permanece restrita ao esquema do projeto e as tabelas confidenciais têm uma política RLS ativa - NL2SQL consulta o mesmo banco de dados que o resto do seu aplicativo, ele não possui direitos de acesso estendidos por padrão.

  • O limite de linha padrão é configurável no lado do servidor; um valor solicitado acima do limite do servidor é negado explicitamente, em vez de ser reduzido silenciosamente.
  • O acesso ao catálogo do sistema (pg_catalog, information_schema) e aos esquemas que não são do projeto é bloqueado pelo validador, independentemente de suas políticas de RLS.
  • O RLS continua sendo sua última linha de defesa em tabelas confidenciais: o validador limita a forma do SQL, não os direitos comerciais sobre os dados.
#
Honestidade

Limites atuais a serem observados

O mecanismo é estritamente legível: apenas solicitações SELECT são aceitas. Qualquer tentativa deINSERT, UPDATE, DELETE, DROP, CREATE ou ALTER gerada pelo modelo é rejeitada antes da execução - esta não é uma convenção de prompt, é uma regra imposta no nível da árvore de sintaxe.

Outros limites estruturais: sem subconsultas, sem CTE/WITH, sem UNION e uma lista de permissões fechada de dez funções SQL. Uma pergunta que naturalmente exige uma subconsulta (“clientes que nunca fizeram pedidos”) deve ser reformulada para caber em uma simples SELECT, ou tratada de forma diferente no lado da aplicação.

#
Vá mais longe

RAG e agentes

NL2SQL cobre questões estruturadas sobre seus dados relacionais. Para dúvidas sobre conteúdo não estruturado (documentos, notas, tickets), o RAG nativo do Aurabase depende do pgvector e de uma pesquisa HNSW. Ambos os recursos - e como combiná-los em um agente - são detalhados na página IA nativa no Postgres.

#
Perguntas frequentes

Perguntas frequentes

O NL2SQL funciona com um esquema complexo (múltiplas junções)?+
Junções de múltiplas tabelas são suportadas pelo validador. Por outro lado, subconsultas e CTE/WITH são explicitamente rejeitadas: uma questão que naturalmente exige uma subconsulta deve ser reformulada para caber em um simples SELECT com junções, ou de outra forma tratada no lado da aplicação.
Qual provedor LLM escolher para NL2SQL?+
Os três provedores nativos (OpenAI, Anthropic/Claude, Gemini) são tratados igualmente pelo validador: nenhum possui vantagem estrutural na validação do SQL gerado. O custo e a latência dependem do modelo específico configurado para o seu projeto — compare-os no seu próprio volume em vez de seguir uma recomendação genérica.

PRONTO PARA IMPLEMENTAR?

Seu back-end em cinco minutos.

Não é necessário cartão de crédito · 500 MB grátis · 50.000 MAU