В этом году каждый 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-агенты терпят неудачу — и почему окно закрывается
Ключевой вывод: исход в продакшне определяют три класса отказов — понимание схемы, галлюцинированные колонки и дрейф диалектов — и рынок прямо сейчас сходится на решениях.
- Понимание схемы. Модель не понимает вашу схему так, как её понимает ваша команда: имена колонок непонятны, связи подразумеваются, а каталог больше контекстного окна. Schema linking — инъекция нужных таблиц и связей — самый большой рычаг точности, и его пропускают чаще всего.
- Галлюцинированные колонки. Модель выдаёт несуществующую колонку или выполняет join таблиц, между которыми нет связи. Без валидации на этапе генерации запрос либо громко падает (unknown column), либо — что хуже — успешно выполняется с едва заметно неверным join-ом.
- Дрейф диалектов. Postgres, Snowflake и BigQuery реально различаются: кавычки, функции, семантика LIMIT, обработка дат. Запрос, который идеально работает на вашем dev-Postgres, ломается — или, что хуже, молча меняет смысл — на warehouse клиента.
Срочность реальна: в 2026 году произошёл взрыв продакшн-инструментов text-to-SQL — database-native агенты, guardrail-фреймворки и интеграции с платформами выходят ежемесячно. Каждый месяц окно сужается, потому что паттерны из этого руководства становятся обязательным минимумом.
Измеренная точность: одна схема, одни вопросы, пять моделей
Ключевой вывод: бенчмаркайте на своей схеме с оценкой по исполнению — никогда по совпадению текста и никогда на чужой схеме.
Тест, отвечающий на ваш вопрос, за полдня:
- Соберите набор из 100 вопросов из реальных пользовательских запросов, покрывающий простые выборки, многотабличные join-ы и неоднозначные формулировки.
- Прогоните тот же набор через модели-кандидаты — GPT, Claude, Gemini, DeepSeek и SQL-специализированные open-модели — с идентичной инъекцией схемы.
- Оценивайте по исполнению: выполняется ли запрос и возвращает ли ожидаемый результат? Оценка по совпадению текста вознаграждает «похожий SQL» и наказывает «корректный, но иной SQL» — ровно обратное тому, что вам нужно.
- Отслеживайте стоимость за запрос наряду с точностью. Модель на 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
Правила, которые делают это продакшн-уровнем:
- Schema linking, а не выгрузка всей схемы. Инжектируйте релевантные таблицы и связи, а не весь каталог — бюджет контекста реален, и именно с нерелевантных таблиц начинаются галлюцинации. Паттерны function calling применимы к поверхности инструментов.
- Валидируйте статически до исполнения. Белые списки колонок, проверки типа оператора и настоящий SQL-парсер для продакшн-версии. Валидация — разница между демо и продакшном.
- Исполняйте только read-only. Подключение read-only по построению — см. раздел о guardrails ниже, потому что это пункт без права на компромисс.
- Агентный режим только по необходимости. Начинайте с 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
Ключевой вывод: четыре класса отказов — три про безопасность, один про стоимость, все предотвратимы.
- Нет read-only контроля. Модель не может писать, если аккаунт не может писать. Всё остальное — эшелонированная защита (defense in depth); это и есть глубина.
- Нет валидации колонок. Галлюцинированные колонки падают громко — но галлюцинированные join-ы выполняются тихо. Статическая валидация настоящим парсером ловит и то, и другое.
- Продакшн на одном диалекте. Протестировано на Postgres, развёрнуто на Snowflake: дрейф диалектов превращает рабочие запросы в сломанные или едва заметно неверные. Eval-набор прогоняется на каждом поддерживаемом диалекте.
- 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 — и пусть точность за доллар выберет стек.