Как проверить SQL-запрос, написанный ИИ, прежде чем дать ему доступ к базе
ИИ может написать SQL за минуту, но скорость набора запроса не гарантирует правильный отчёт. Самые дорогие ошибки обычно выглядят правдоподобно: двойной подсчёт заказов после соединения с позициями, неверная граница даты, исключённые возвраты или тихо изменённая валюта. Этот гайд не требует доверять модели доступ к боевой базе. Мы разбираем безопасный порядок, в котором человек сначала формулирует ожидаемый результат, затем проверяет текст запроса на копии данных и только после этого решает, нужен ли реальный запуск.
1. Сначала опишите результат обычными словами
Пусть задача звучит так: «Сколько оплаченных заказов было за прошлую неделю по каждому магазину?». До обращения к ИИ уточните четыре определения. Что считается оплаченным: отметка статуса или факт проводки? По какому часовому поясу режется неделя? Что делать с возвратом? Считать количество заказов или сумму строк в заказах? Если эти правила не зафиксированы, два разных SQL могут быть синтаксически правильными и давать разные числа.
Запишите мини-контракт результата: одна строка на магазин; столбцы — идентификатор, число уникальных заказов и сумма в одной валюте; интервал — с полуночи понедельника включительно до полуночи следующего понедельника не включительно; отменённые заказы отдельно. Этот контракт важнее промпта. Его можно сравнить с проверкой формул в таблице: сначала ожидаемые строки и границы, потом автоматический расчёт.
2. Передавайте модели схему, а не секреты
Для черновика достаточно названий таблиц, типов столбцов, ключей и нескольких вымышленных строк. Не вставляйте реальные имена клиентов, адреса, токены доступа и полную выгрузку заказов. Укажите отношения: у заказа несколько позиций, платёж может иметь несколько попыток, возврат может быть отдельной записью. Если схема неизвестна, попросите администратора выдать описание или работайте локально с обезличенной копией. Модель не должна угадывать название столбца и затем незаметно подставлять несуществующее поле.
В запросе к ИИ попросите две вещи: SQL и краткое объяснение, почему каждый JOIN не увеличивает число заказов. Отдельно попросите перечислить предположения о статусах и временных границах. Так становится видно, где модель сделала выбор за владельца данных. Если объяснение расплывчато, не запускайте запрос ради «быстрой проверки».
3. Прочитайте запрос глазами владельца данных
Проверьте, нет ли в нём команд изменения: UPDATE, DELETE, INSERT, DROP, ALTER, TRUNCATE, вызова внешней функции либо записи во временную таблицу с неожиданными правами. Для отчёта нужен только доступ на чтение. Убедитесь, что фильтр по дате относится к нужной сущности: дате создания заказа, подтверждения платежа или возврата. Проверьте, не переведён ли левый JOIN в фактически внутренний фильтром по столбцу присоединённой таблицы в WHERE.
Отдельно посмотрите на кратность. Если к десяти заказам присоединить по три позиции, COUNT(*) вернёт 30 строк. Иногда нужен COUNT(DISTINCT order_id), но это не универсальное лекарство: сумма платежей при таком соединении тоже может утроиться. Более надёжный путь — агрегировать позиции или платежи до нужной гранулярности до JOIN. Попросите модель показать промежуточные числа строк на каждом шаге, а затем подтвердите их тестом. В обзоре локального аудита DuckDB разобрано, почему сохранённая выборка удобнее оценки «на глаз».
4. Создайте маленький контрольный набор
В обезличенной копии сделайте шесть-семь заказов с намеренно неудобными случаями: две позиции в одном заказе, две неудачные попытки платежа и одна успешная, возврат на следующий день, заказ точно на границе интервала, отмена после оплаты, магазин без продаж. Запишите ожидаемый ответ вручную. Только после этого запускайте SQL. Если запрос не проходит эти случаи, большой реальный набор не делает его верным — он лишь прячет ошибку среди множества строк.
Сравните три числа: количество исходных заказов, количество уникальных заказов после соединений и итоговое количество в отчёте. Если второе число неожиданно выросло, найдите источник размножения строк. Для сумм сравните несколько конкретных order_id с учётной системой. Не ограничивайтесь совпадением общего итога: ошибки разных знаков иногда взаимно компенсируются.
5. Оцените цену выполнения до большого запуска
На тестовой базе выполните EXPLAIN или штатный планировщик СУБД. Он показывает вероятный полный просмотр крупной таблицы, тяжёлую сортировку и неудачное соединение. При необходимости добавьте ограничения на время и ресурсы в тестовом окружении. Это не повод слепо применять подсказанные ИИ индексы: новый индекс влияет на запись и место на диске, его нужно согласовывать с администратором. Если план расходится с ожиданием, лучше переписать запрос, чем увеличивать лимит сервера.
После получения корректного результата сохраните текст SQL, версию схемы, контрольный набор, проверенные примеры и имя человека, который утвердил определения. Для регулярного отчёта эти материалы нужны при следующем изменении таблиц. В сравнении CSV и Parquet показано, почему формат выгрузки тоже влияет на воспроизводимость контрольного расчёта.
Итоговый критерий готовности
Запрос можно передать в рабочий контур, когда его смысл соответствует текстовому контракту, граничные случаи дают ожидаемые значения, права ограничены чтением, план выполнения приемлем и результаты нескольких реальных записей сверены с первичным учётом. «Модель уверена» не входит в этот список. Если данных недостаточно для проверки, честный ответ — отложить запуск, а не подкручивать промпт до приятного числа.
Частые вопросы
Достаточно ли SELECT в начале, чтобы запрос был безопасным?
Нет. Нужно проверить вложенные выражения, функции, права учётной записи, объём данных и конкретную СУБД. SELECT может оказаться дорогим или раскрыть лишние строки.
Можно ли проверять только общий итог?
Нельзя. Два противоположных искажения могут дать правильную общую сумму. Нужны строки-примеры, контроль кратности и граничные случаи.
Нужно ли показывать модели реальные клиентские данные?
Обычно нет. Для черновика хватает схемы и синтетических примеров. Реальную проверку проводят в контролируемой среде по правилам доступа организации.
Кто отвечает за итоговый отчёт?
Тот, кто утверждает бизнес-определения и допускает запрос к данным. ИИ помогает подготовить черновик, но не заменяет владельца метрики и администратора базы.