PRODСуверенная европейская платформа BaaSОткрыть панель управления →

Родной ИИ · 8 минута чтения

Учебное пособие: создание конечной точки NL2SQL на Postgres

Affane Daylami · Fondateur · 28 августа 2026 г.

Вернуться в блог

В этом руководстве показано, как получить вопрос на французском языке, преобразовать его в проверенный и ограниченный SQL-запрос, а затем вернуть результат — даже не выполняя непроверенный SQL. Фактически сгенерированный SQL отображается на каждом этапе, а не только конечный результат.

Этот текст на английском языке был создан автоматически на основе французского оригинала и еще не проверялся.
Эта страница была переведена автоматически. Английская версия является авторитетной.

Движок NL2SQL Aurabase является частью собственного искусственного интеллекта, интегрированного в бэкэнд, а не сторонней службы, которую можно собрать вместе. Предварительные условия для следования этому руководству: существующий проект Aurabase, простая схема базы данных для примера и ключ API проекта.

#
Цель

Что вы построите

Конечная точка, которая получает вопрос на естественном языке, преобразует его в проверенный и ограниченный запрос SQL, а затем возвращает результат. Движок никогда не выполняет сгенерированный SQL без контроля: каждый запрос проходит синтаксическую проверку, прежде чем попасть в базу данных.

Информация

В этом руководстве используется JavaScript SDK @aurabase/aurabase-js и эквивалентный необработанный HTTP-вызов, поэтому вы можете следовать инструкциям на любом языке.

#
Под капотом

Как работает механизм NL2SQL

Вопрос проходит через настроенный LLM — OpenAI, Anthropic (Claude) или Gemini, три собственных поставщика, — который генерирует кандидатный SQL. Этот SQL никогда не выполняется как есть: он проходит через валидатор, который анализирует его синтаксическое дерево (sqlparser), разрешает только простые запросы SELECT и добавляет ограниченный LIMIT, если он отсутствует.

Валидатор явно отклоняет CTE/WITH, подзапросы, UNION, предложения блокировки (FOR UPDATE) и любую функцию за пределами белого списка (count, sum, avg, min, max, lower, upper, coalesce, date_trunc, now). Поддерживаются объединения нескольких таблиц.

Вопрос→LLM (OpenAI/Claude/Gemini)→Проверка AST (sqlparser)→Bounded LIMIT→Выполнение SELECT

Запрошенная диаграмма никогда не предоставляется по вашему запросу: она анализируется на основе реальной базы проекта. Поле schema, allowed_schema или schema_context, отправленное в теле запроса, явно отклоняется (ошибка 400), а не игнорируется молча — только сервер решает, что на самом деле существует.

#
Шаг 1

Настройте конечную точку NL2SQL

С помощью JavaScript SDK клиент Aurabase предоставляет aura.ai.nl2sql(). Подпись — nl2sql(question, options): схема не является ее частью, она проверяется на стороне сервера.

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)
}

В необработанном HTTP конечной точкой является POST /v1/ai/{project_id}/nl2sql, аутентифицированная ключом API проекта.

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
  }'
Поля отклонены сервером

Не отправляйте schema, allowed_schemaили schema_context в теле запроса: запрашиваемая схема определяется сервером, эти поля явно отклоняются (400), а не перезаписываются автоматически.

#
Шаг 2

Тест с реальным вопросом на французском языке

Отправлен вопрос: «Сколько заказов в этом месяце разместили премиальные клиенты?». Вот форма фактически отображаемого SQL (имена таблиц и столбцов зависят от вашей схемы):

ответ (отрывок)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 указывает, получен ли LIMIT из шаблона или добавлен сервером. confidence — это эвристика формы ответа (правильно сформированный блок SQL или нет), а не мера семантической корректности сгенерированного SQL. Плохо сформулированный вопрос возвращает явную ошибку, а не галлюцинированный SQL: например, если сгенерированный SQL запрашивает таблицу, отсутствующую в вашей схеме, в сообщении будут указаны фактически доступные таблицы.

#
Шаг 3

Безопасное производство

Три проверки перед развертыванием: адаптирован ли потолок строк (LIMIT) к вашему тому, остается ли роль Postgres, используемая движком, ограниченной схемой проекта, и имеют ли конфиденциальные таблицы активную политику RLS — NL2SQL запрашивает ту же базу данных, что и остальная часть вашего приложения, по умолчанию он не имеет расширенных прав доступа.

  • Ограничение строки по умолчанию настраивается на стороне сервера; запрошенное значение, превышающее ограничение сервера, явно отклоняется, а не уменьшается автоматически.
  • Доступ к системному каталогу (pg_catalog, information_schema) и непроектным схемам блокируется валидатором независимо от ваших политик RLS.
  • RLS остается вашей последней линией защиты для конфиденциальных таблиц: валидатор ограничивает форму SQL, а не бизнес-права на данные.
#
Честность

Текущие ограничения, о которых следует знать

Движок строго читаем: принимаются только запросы SELECT. Любая попыткаINSERT, UPDATE, DELETE, DROP, CREATE или ALTER, сгенерированная шаблоном, отклоняется до выполнения — это не соглашение о подсказках, это правило, установленное на уровне синтаксического дерева.

Другие структурные ограничения: отсутствие подзапросов, отсутствие CTE/WITH, отсутствие UNION и закрытый белый список из десяти функций SQL. Вопрос, который, естественно, требует подзапроса («клиенты, которые никогда не заказывали»), необходимо переформулировать, чтобы он соответствовал простому SELECT, или обрабатываться по-другому на стороне приложения.

#
Иди дальше

РАГ и агенты

NL2SQL отвечает на структурированные вопросы о ваших реляционных данных. При возникновении вопросов о неструктурированном контенте (документах, заметках, билетах) собственный RAG Aurabase использует pgvector и поиск HNSW. Обе возможности — и способы их объединения в агенте — подробно описаны на странице Native AI на Postgres.

#
Часто задаваемые вопросы

Часто задаваемые вопросы

Работает ли NL2SQL со сложной схемой (множественными соединениями)?+
Валидатор поддерживает многотабличные соединения. С другой стороны, подзапросы и CTE/WITH явно отвергаются: вопрос, который естественным образом требует подзапроса, должен быть переформулирован, чтобы соответствовать простому SELECT с объединениями, или иным образом обрабатываться на стороне приложения.
Какого LLM-провайдера выбрать для NL2SQL?+
Три собственных провайдера (OpenAI, Anthropic/Claude, Gemini) рассматриваются валидатором одинаково: ни один из них не имеет структурного преимущества при проверке сгенерированного SQL. Стоимость и задержка зависят от конкретной модели, настроенной для вашего проекта. Сравните их с собственным объемом, а не следуйте общим рекомендациям.

ГОТОВЫ К РАЗВЕРТЫВАНИЮ?

Ваш бэкэнд за пять минут.

Кредитная карта не требуется · 500 МБ бесплатно · 50 000 MAU