Text-to-SQLAI AgentsLLM API

Text-to-SQL агенты 2026: от запроса до безопасного SQL

1 мин чтения

В этом году каждый BI-вендор встроил NL-to-SQL. Новый продакшн-гайд публикуется каждые несколько недель. Окно для создания собственного решения закрывается — и разрыв между демо и продакшном ещё никогда не был так легко измерим, и именно это делает данное руководство.

Это руководство охватывает четыре вещи, которые разделяют демо и продакшн: что эти агенты реально умеют, как измерять точность на вашей схеме, архитектуру, которая генерирует и валидирует запросы, и guardrails, которые делают «безопасно» стандартом, а не надеждой.

Что умеют text-to-SQL агенты сегодня

Ключевой вывод: современный text-to-SQL оценивается по исполнению, учитывает схему и становится всё более агентным — и именно на разрыве между single-shot и агентным подходом теряется большинство команд.

В 2026 году существуют две формы:

  • Single-shot генерация — модель видит схему и вопрос и выдаёт один SQL-запрос. Быстро, дёшево и корректно на простых вопросах.
  • Агентные пайплайны — модель планирует, генерирует, исполняет, проверяет результаты и повторяет: многошаговый анализ, уточняющие вопросы, follow-up запросы. Медленнее и дороже, и единственная форма, которая выживает при неоднозначных вопросах и многотабличных join-ах.

Практическое разделение: single-shot для дашбордов и отчётов; агентный подход для аналитических сессий, где пользователь итерирует. Команды, которые прогоняют всё через одну форму, платят за неправильную.

Честная картина бенчмарков: на стандартном бенчмарке Spider текущие системы показывают execution accuracy в диапазоне верхних 80-х — нижних 90-х процентов на однозначном подмножестве — исследование IEEE по системам 2026 года оценивает диапазон примерно в 87-91%. И оговорка важна не меньше самой цифры: анализ 2026 года обнаружил повсеместные ошибки аннотаций в самих публичных бенчмарках, поэтому «Spider говорит X» — отправная точка для вашего собственного eval, а не вывод о вашей базе данных.

Почему SQL-агенты терпят неудачу — и почему окно закрывается

Ключевой вывод: исход в продакшне определяют три класса отказов — понимание схемы, галлюцинированные колонки и дрейф диалектов — и рынок прямо сейчас сходится на решениях.

  1. Понимание схемы. Модель не понимает вашу схему так, как её понимает ваша команда: имена колонок непонятны, связи подразумеваются, а каталог больше контекстного окна. Schema linking — инъекция нужных таблиц и связей — самый большой рычаг точности, и его пропускают чаще всего.
  2. Галлюцинированные колонки. Модель выдаёт несуществующую колонку или выполняет join таблиц, между которыми нет связи. Без валидации на этапе генерации запрос либо громко падает (unknown column), либо — что хуже — успешно выполняется с едва заметно неверным join-ом.
  3. Дрейф диалектов. Postgres, Snowflake и BigQuery реально различаются: кавычки, функции, семантика LIMIT, обработка дат. Запрос, который идеально работает на вашем dev-Postgres, ломается — или, что хуже, молча меняет смысл — на warehouse клиента.

Срочность реальна: в 2026 году произошёл взрыв продакшн-инструментов text-to-SQL — database-native агенты, guardrail-фреймворки и интеграции с платформами выходят ежемесячно. Каждый месяц окно сужается, потому что паттерны из этого руководства становятся обязательным минимумом.

Измеренная точность: одна схема, одни вопросы, пять моделей

Ключевой вывод: бенчмаркайте на своей схеме с оценкой по исполнению — никогда по совпадению текста и никогда на чужой схеме.

Тест, отвечающий на ваш вопрос, за полдня:

  1. Соберите набор из 100 вопросов из реальных пользовательских запросов, покрывающий простые выборки, многотабличные join-ы и неоднозначные формулировки.
  2. Прогоните тот же набор через модели-кандидаты — GPT, Claude, Gemini, DeepSeek и SQL-специализированные open-модели — с идентичной инъекцией схемы.
  3. Оценивайте по исполнению: выполняется ли запрос и возвращает ли ожидаемый результат? Оценка по совпадению текста вознаграждает «похожий SQL» и наказывает «корректный, но иной SQL» — ровно обратное тому, что вам нужно.
  4. Отслеживайте стоимость за запрос наряду с точностью. Модель на 3 пункта точнее при 10-кратной стоимости — это решение о маршрутизации, а не победитель.

Таблица результатов, к которой вы идёте: точность и стоимость за запрос по каждой модели, на вашей схеме, на ваших диалектах. Это набор данных, который потребляет слой маршрутизации, — та же методология оценки по исполнению, которую эта серия применяет к любому LLM-выводу, применённая конкретно к SQL.

Как построить архитектуру агента: схема → генерация → валидация → исполнение

Ключевой вывод: четыре этапа, и именно валидация отделяет продакшн от демо.

Основной цикл, на едином chat endpoint:

import sqlite3
from openai import OpenAI

client = OpenAI()  # unified endpoint

def build_prompt(schema_snippet: str, question: str) -> list[dict]:
    return [
        {"role": "system", "content":
            "You write SQL for this schema. Use ONLY tables and columns shown. "
            "Never invent columns. Dialect: PostgreSQL.\n\n" + schema_snippet},
        {"role": "user", "content": question},
    ]

def validate_sql(sql: str, valid_columns: set[str]) -> str | None:
    # Static validation: reject unknown columns and non-SELECT statements
    if not sql.strip().upper().startswith("SELECT"):
        return None
    # Column whitelist check (simplified — production uses a real parser)
    return sql if any(c in sql for c in valid_columns) else None

def run(question: str, schema_snippet: str, valid_columns: set[str], conn: sqlite3.Connection):
    sql = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=build_prompt(schema_snippet, question),
    ).choices[0].message.content
    sql = validate_sql(sql, valid_columns)
    if sql is None:
        return {"error": "query rejected by guard"}
    return conn.execute(sql).fetchall()  # read-only connection only

Правила, которые делают это продакшн-уровнем:

  1. Schema linking, а не выгрузка всей схемы. Инжектируйте релевантные таблицы и связи, а не весь каталог — бюджет контекста реален, и именно с нерелевантных таблиц начинаются галлюцинации. Паттерны function calling применимы к поверхности инструментов.
  2. Валидируйте статически до исполнения. Белые списки колонок, проверки типа оператора и настоящий SQL-парсер для продакшн-версии. Валидация — разница между демо и продакшном.
  3. Исполняйте только read-only. Подключение read-only по построению — см. раздел о guardrails ниже, потому что это пункт без права на компромисс.
  4. Агентный режим только по необходимости. Начинайте с single-shot; добавляйте многошаговое планирование (архитектура агентов из этой серии), только когда eval-набор показывает, что single-shot проваливается на реальных вопросах.

Как внедрять guardrails: read-only по умолчанию

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

СлойЧто блокируетГде живёт
Read-only аккаунт БДвсе записи, структурноконфигурация БД
Перехват запросовоператоры не-SELECT, независимо от моделиapplication middleware
Лимиты строк/времени/стоимостивышедшие из-под контроля запросы и join-ыapplication middleware + rate limits
Разграничение правcross-tenant запросы и эскалация привилегийschema views + access guards

Первый слой — тот, который команды пропускают, и тот, который важнее всего: read-only аккаунт БД превращает «модель сгенерировала DELETE» из инцидента в не-событие. Инструменты 2026 года подтянулись: продакшн-фреймворки теперь поставляют детерминированные access guards, которые применяют реальные правила доступа каждого пользователя к сгенерированным запросам, что закрывает cross-tenant дыру, которую не закрыть инструкциями в промпте. Паттерн в порядке доверия: аккаунт БД → middleware-парсер → per-user access guard → инструкции модели. Последний слой — любезность, а не контроль.

Частые ошибки, которые выпускают опасный SQL

Ключевой вывод: четыре класса отказов — три про безопасность, один про стоимость, все предотвратимы.

  1. Нет read-only контроля. Модель не может писать, если аккаунт не может писать. Всё остальное — эшелонированная защита (defense in depth); это и есть глубина.
  2. Нет валидации колонок. Галлюцинированные колонки падают громко — но галлюцинированные join-ы выполняются тихо. Статическая валидация настоящим парсером ловит и то, и другое.
  3. Продакшн на одном диалекте. Протестировано на Postgres, развёрнуто на Snowflake: дрейф диалектов превращает рабочие запросы в сломанные или едва заметно неверные. Eval-набор прогоняется на каждом поддерживаемом диалекте.
  4. Frontier-модель для каждого запроса. Колонка стоимости в eval-наборе существует не зря: простые выборки на бюджетной модели за долю стоимости, frontier-модель — только для неоднозначных 10%. Кастомная маршрутизация делает это механическим, а каталог моделей показывает, что доступно.

FAQ

Насколько точны text-to-SQL агенты в 2026 году?

На однозначном подмножестве публичных бенчмарков — примерно 87-91% execution accuracy, при этом в самих бенчмарках задокументированы ошибки аннотаций, так что единственное число, которое имеет значение, — это eval на вашей схеме. Реальная точность на сложных многотабличных схемах ниже, и именно для этого нужен eval-набор.

Как остановить галлюцинации колонок у агента?

Три слоя: инъекция схемы только с релевантными таблицами, статическая валидация по белому списку колонок настоящим парсером и обработка ошибок на этапе исполнения, которая возвращает отказ на повторную попытку. Одних инструкций в промпте недостаточно.

Достаточно ли read-only контроля?

Как основной контроль — да: read-only аккаунт БД делает любую сгенерированную запись невозможной, что бы ни делала модель. Добавьте перехват запросов, лимиты строк/стоимости и per-user access guards как слои, которые обрабатывают остальное.

Single-shot или агентный подход — что строить?

Начинайте с single-shot и пусть eval-набор решает. Если реальные вопросы проваливаются на join-ах или неоднозначности, добавляйте агентное планирование инкрементально. Команды, которые начинают с агентного подхода, платят за планирование на запросах, которым оно не нужно.

Как поддерживать несколько SQL-диалектов?

Инъекция схемы включает указания по диалекту, eval-набор прогоняется на каждом диалекте, а различия диалектов (кавычки, функции, семантика LIMIT) задокументированы в промпт-контракте. Тестируйте на всех диалектах до релиза любого из них.

Сколько стоит text-to-SQL запрос?

От долей цента на бюджетных моделях для простых выборок до значительных кратных на frontier-моделях для агентного анализа. Отслеживайте стоимость за запрос в eval-наборе, маршрутизируйте по сложности — и средняя останется низкой; quickstart показывает паттерн унифицированного endpoint, который превращает маршрутизацию в конфигурацию.

Итоги

Text-to-SQL агенты в 2026 году готовы к продакшну, с заложенными оговорками: бенчмаркайте на своей схеме с оценкой по исполнению, линкуйте схему вместо выгрузки, валидируйте статически до исполнения и обеспечьте read-only на уровне базы данных. Окно закрывается по мере взросления инструментов — но команды, которые построят eval-набор и guardrails сейчас, будут теми, чьи агенты попадут в продакшн, а демо-версии останутся демо.

Окно закрывается — ваш eval-набор — это путь сквозь него. Получите ключ TokSpan API, прогоните набор из 100 вопросов через несколько моделей — $5 бесплатных кредитов покроют первый eval — и пусть точность за доллар выберет стек.