TL;DR
Implicit-промпт — это обычная инструкция к запросу, где модели говорят: «во входном вопросе могут быть ошибки, сначала оцени, можно ли на него отвечать». К ответу добавляется поле с вердиктом (is_valid) и объяснением. Без такой инструкции модель молча чинит вопрос сама и выдаёт уверенный ответ.
Главная находка: по умолчанию модели доверяют вопросу и почти никогда не говорят «это некорректно». Спросишь про колонку, которой нет в таблице, и модель подставит похожую и выдаст рабочий SQL, который считает не то. Мягкое предупреждение примерно вдвое увеличивает долю пойманных ошибок. Жёсткая формулировка «в вопросе точно есть ошибка» ломает другое: модель начинает отказываться и от нормальных вопросов, потому что слушается промпта, а не данных. Размер и свежесть модели этого не лечат.
Метод в одном шаге: предупреди модель, что ошибки возможны, дай схему и вопрос, потребуй JSON с sql, is_valid, reason. Нейтральная формулировка («может быть») работает, утверждающая («есть») вредит.
Схема метода
ОДИН ПРОМПТ:
1. Предупреждение: «вопрос МОЖЕТ содержать ошибки, оцени валидность до ответа»
2. Контекст: схема таблиц + вопрос
3. Формат вывода: JSON {sql, is_valid, reason}
- вопрос корректен → sql заполнен, is_valid = true
- вопрос некорректен → sql = null, is_valid = false, reason = в чём ошибка
НЕ ДЕЛАТЬ: «В вопросе есть ошибка» (Explicit) → ложные отказы
Четыре типа ошибок в вопросах, которые исследователи проверяли: - E1 Выражение: неоднозначность, неясная цель. - E2 Противоречие: условия исключают друг друга или не сходятся со схемой. - E3 Пропуск: нет фильтра, нужной таблицы или колонки, понятие не сопоставляется со схемой. - E4 За пределами: SQL не может это выразить, или нужны внешние знания.
Пример применения
Задача: Вы руководитель аналитики в интернет-магазине электроники из Новосибирска. Продакт пишет в корпоративный бот: «Покажи среднюю маржу по заказам за март». В базе есть orders(id, customer_id, city, total, created_at) и order_items(order_id, product_id, qty, price). Колонки с себестоимостью нет, маржу посчитать нельзя. Обычный промпт выдаст SQL, где «маржа» тихо превратится в total или price. Цифра будет красивой и неверной.
Промпт:
Ты помогаешь аналитикам писать SQL (PostgreSQL).
Входной вопрос МОЖЕТ содержать ошибки: неоднозначность, противоречия,
отсутствующие в схеме данные или требования, которые SQL не может выполнить.
Сначала оцени, корректен ли вопрос и можно ли на него ответить по этой схеме.
Не додумывай недостающее.
Схема:
orders(id, customer_id, city, total, created_at)
order_items(order_id, product_id, qty, price)
Вопрос: Покажи среднюю маржу по заказам за март.
Верни JSON:
{
"sql": "<запрос или null, если отвечать нельзя>",
"is_valid": true/false,
"reason": "<почему вопрос корректен или в чём именно ошибка>"
}
Результат: Модель с большой вероятностью, но не гарантированно, вернёт sql: null, is_valid: false и объяснение, что в схеме нет себестоимости. Без предупреждения такая же модель чаще всего выдала бы SQL с подменой маржи на выручку. Если вопрос корректен («средний чек по заказам за март»), должен прийти нормальный SQL с is_valid: true. Но часть моделей на таком мягком предупреждении начинает перестраховываться, поэтому проверьте на своих корректных запросах.
Почему это работает
Слабость. Модель обучена быть полезной и отвечать. Вопрос для неё условие задачи, а не объект проверки. Поэтому она молча достраивает недостающее: сопоставляет «человека» с «актёром», «маржу» с «выручкой». SQL при этом синтаксически корректен, и ошибку не видно.
Сильная сторона. Если попросить оценить вопрос явно, модель это умеет. Знание о том, что колонки нет, у неё есть, просто оно не включается само. Её собственный вердикт к тому же управляет поведением: когда is_valid = false, SQL почти всегда не пишется, и наоборот.
Как метод это использует. Предупреждение «может быть ошибка» включает проверку, а поле is_valid с reason заставляет написать вывод до или вместе с ответом. Слово «может» важно. Оно оставляет модели возможность сказать «всё в порядке». Утверждение «ошибка есть» убирает эту возможность. Модель принимает его как факт и ищет ошибку там, где её нет.
Рычаги управления:
- Сила формулировки. «Может содержать ошибки» даёт баланс. «Содержит ошибки» повышает отлов, но ломает нормальные запросы. Отсутствие предупреждения даёт почти нулевой отлов.
- Поле reason. Оставь его: по нему видно, увидела модель реальную проблему или придралась.
- Значение при отказе. Вместо null можно просить «уточняющий вопрос пользователю». Это часть сценария из Figure 1 статьи.
- Список типов ошибок. Чем конкретнее перечень в предупреждении, тем больше подсказок, но тем выше риск перестраховки. Проверяй на своих корректных вопросах.
Шаблон промпта
Ты — {роль_и_задача}.
Входной запрос МОЖЕТ содержать ошибки. Сначала оцени, корректен ли он
и можно ли на него ответить с учётом контекста ниже.
Не додумывай недостающее.
Контекст:
{контекст_или_схема}
Запрос: {запрос}
Верни JSON:
{
"sql": "<результат или null, если отвечать нельзя>",
"is_valid": true/false,
"reason": "<почему запрос корректен или в чём именно ошибка>"
}
Что подставлять: {роль_и_задача} — например, «аналитик, пишущий SQL». {контекст_или_схема} — описание таблиц или правил. {запрос} — вопрос пользователя. Ключ sql можно переименовать в answer, если задача не про SQL, но идея проверена только на SQL.
🚀 Быстрый старт — вставь в чат:
Вот шаблон промпта, который заставляет модель проверять корректность вопроса
перед ответом. Адаптируй под мою задачу: [твоя задача].
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит, какие у тебя данные или контекст и что считать «ответить нельзя». Это нужно, чтобы предупреждение было привязано к твоему контексту, а модель знала, с чем сверять запрос.
Ограничения
⚠️ Цена за мягкое предупреждение: даже нейтральная формулировка заставляет часть моделей отказываться от нормальных вопросов. У одной из моделей почти половина корректных запросов осталась без ответа. Проверяй на своих правильных вопросах, а не только на сломанных.
⚠️ Жёсткая формулировка вредит: фраза «в вопросе есть ошибка» поднимает отлов почти до максимума, но модель начинает отклонять и корректные запросы. Одна из моделей отказывалась практически от всех нормальных вопросов. Высокие цифры отлова тут обманчивы: это послушание, а не проверка.
⚠️ Масштаб не спасает: новые и крупные модели лучше только частично, а лучшая модель без предупреждения ловит меньше половины ошибок. В одном сравнении меньшая модель отловила больше большой. Нужно тестировать на своей модели.
⚠️ Ошибка вердикта тянет ошибку ответа: модель почти всегда действует по собственному
is_valid. Если вердикт неверный, неверным будет и действие. Полеreasonне гарантирует, что вердикт правильный.
⚠️ Один домен: всё проверено на Text-to-SQL, ошибки искусственно созданы другой LLM. Перенос на другие задачи логичен, но авторами не проверялся. Определить тип ошибки модели тоже труднее, чем просто заметить, что она есть.
⚠️ Нет готового промпта: в доступном тексте приведено описание трёх режимов, а не полный текст промптов. Шаблон выше собран по этому описанию. Текст статьи также обрывается на разделе про типы ошибок.
Как исследовали
Исследователи взяли два популярных набора вопросов для SQL, Spider и BIRD, и испортили 1 800 вопросов по таксономии из четырёх типов ошибок. Порча шла одной LLM, проверка другой LLM и затем людьми. К каждому испорченному вопросу оставили оригинал как контрольный. Это ключевая идея дизайна: иначе нельзя отличить настоящую проверку от привычки отказывать.
Дальше 16 современных моделей прогнали через три режима: обычный (Base), с мягким предупреждением (Implicit) и с утверждением «ошибка есть» (Explicit). Всего получилось около 173 тысяч ответов. Ответы оценивали две LLM-судьи, которые сошлись между собой и с людьми.
Результаты. В Base модели отлавливали около трети ошибок и почти всегда выдавали SQL. В Implicit отлов вырос примерно вдвое, а доля нормальных вопросов с ответом упала лишь с 99% до 90%. В Explicit отлов почти достиг максимума, но доля нормальных вопросов с ответом упала примерно до половины. Для каждой модели при переходе к Explicit отлов вырос, а ответы на корректные вопросы сократились.
Удивило то, что нет чёткого «чем новее и больше, тем лучше». И то, что вердикт is_valid почти полностью предсказывал, будет ли SQL, даже когда вердикт ошибочный. Практический вывод: формулировка предупреждения и проверка на «хороших» запросах важнее выбора модели.
Адаптации и экстраполяции
Это мои идеи, авторы их не проверяли.
🔧 Техника: добавить типы ошибок → подсказать, что искать
Проверь запрос на: (1) неоднозначность, (2) противоречия условий или со схемой, (3) отсутствующие данные или фильтры, (4) то, что нельзя вычислить по этим данным.
В статье у типов ошибок есть свои метрики, но перечень внутри промпта они не тестировали. Может повысить точность reason, но может усилить перестраховку. Обязательно проверь на корректных запросах.
Экстраполяция: правило в файле инструкций агента. Для агента, который отвечает на вопросы по данным (CLAUDE.md, системный промпт кастомного GPT):
Перед тем как писать запрос или отчёт, проверь: все ли поля, периоды и
метрики из вопроса есть в доступных данных. Если чего-то нет или вопрос
допускает несколько толкований, не подменяй понятия. Напиши, что именно
отсутствует или неясно, и задай один уточняющий вопрос. Если вопрос
корректен, отвечай сразу, без лишних сомнений.
Последняя фраза нужна, чтобы не получить эффект Explicit-режима, где модель отказывается от нормальных запросов.
Ресурсы
- PremiseSQL: Evaluating Premise Critique and Abstention in Text-to-SQL Systems — Shuo Lin, Jinzhe Li, Chenlu Guo, Yanhan Li, Yuan Wu, Yi Chang.
- Организации: Jilin University (School of AI; Engineering Research Center of Knowledge-Driven Human-Machine Intelligence; International Center of Future Science), Bilibili Inc., China Telecom AI Technology (Beijing).
- Код и бенчмарк: https://github.com/vegeet/PremiseSQL
- Исходные наборы: Spider 1.0, BIRD. Смежные работы: TriageSQL, TrustSQL, NL2SQL-BUGs, AbstentionBench.
