Руководителю проекта нужно знать, сколько бетона ушло на корпус за квартал и как это соотносится со сметой. Ответ лежит в базе, но получить его можно только заявкой в ИТ-отдел: выгрузку готовят в порядке очереди, и приходит она через 2–3 дня. В нашем проекте для средней строительной компании мы сделали сервис, которому такой вопрос задают обычным языком. Теперь отчет готов за 5 минут, а нагрузка на ИТ-отдел снизилась на 70%. Подход называется text-to-SQL. Разберем, как он устроен, где ошибается и что подготовить, чтобы цифрам в таком отчете можно было верить.
Модель пишет запрос, а считает база
Text-to-SQL — это перевод вопроса на обычном языке в запрос к базе данных на языке SQL. Языковая модель получает вопрос, описание таблиц и полей и несколько примеров. По ним она составляет запрос, система его проверяет, база выполняет, а пользователь видит таблицу или график в привычной BI-панели.
Главное в этой схеме — распределение ролей. Модель не складывает числа сама и не держит в памяти таблицы. Она пишет запрос, а суммы, количества и средние считает база — так же точно, как в отчете, который пишет аналитик. Поэтому числу в ответе можно доверять ровно настолько, насколько можно доверять запросу.
В этом отличие от попытки загрузить выгрузку в чат-бот и спросить, сколько в ней затрат по объекту. Языковая модель генерирует правдоподобный текст, а не считает: на таблице из тысяч строк она выдаст похожее на правду число и уверенно его объяснит. В text-to-SQL модель занята тем, что у нее получается, — переводом с языка вопроса на язык запроса.
Опасна не синтаксическая ошибка, а смысловая
Запрос с синтаксической ошибкой не страшен: база вернет ошибку, и система попросит модель исправить запрос. Опасен запрос, который выполняется и возвращает правдоподобное, но неверное число. В нашем проекте это и было главной сложностью: генерировать не просто синтаксически верный, а семантически правильный SQL под реальную схему базы.
Вот типичные смысловые ошибки.
- Не та таблица: объем работ взят из заявок, а не из подписанных актов.
- Не тот фильтр: в сумму попали отмененные документы и записи, помеченные на удаление.
- Не та дата: период посчитан по дате ввода документа, а не по дате выполнения работ.
- Двойной счет: соединение двух таблиц размножило строки, и сумма по подрядчику выросла вдвое.
- Не тот термин: стоимость работ посчитана с НДС, а финансовая служба считает без него.
У всех этих ошибок общая черта: человек, который знает данные, заметит их сразу, а база выполнит такой запрос без единого предупреждения. Поэтому защиту строят в трех местах: в описании данных для модели, в проверке запроса до выполнения и в том, как ответ показан пользователю.
Одной самопроверки модели здесь мало: если она неверно поняла данные, при повторной проверке она поймет их так же. Нужна внешняя проверка — правилами, которые написаны заранее, и набором вопросов с известными ответами.
Модели нужна не вся база, а витрина под вопросы
База учетной системы — это сотни таблиц с техническими названиями, служебными полями и связями, которые знает только разработчик. Отдавать ее модели целиком — верный способ получить ошибки из списка выше.
Рабочий подход другой. Под частые вопросы собирают витрину данных — набор представлений с понятными названиями: «акты», «оплаты», «объекты», «подрядчики», «материалы». В них уже отброшены отмененные документы, выбрана правильная дата, суммы приведены к одной единице. Модель пишет запрос к витрине, а не к сырым таблицам.
У каждого поля витрины есть описание на языке бизнеса: что в нем лежит, в каких единицах, какие значения бывают. Это описание и есть главная часть настройки. Чем точнее описаны поля, тем меньше модели приходится угадывать.
Практический прием: витрина не спрячет дефекты базы, а повторит их в ответе. Если в справочниках копятся дубли, а документы вводят задним числом, сервис будет уверенно складывать дубли и путать периоды. Прежде чем строить text-to-SQL, проверьте данные на типовые дефекты. Полная проверка занимает около недели и экономит месяцы споров о том, почему цифры не сходятся.
Словарь терминов важнее выбора модели
Самые трудные вопросы — не сложные, а неоднозначные. «Сколько мы заработали на объекте» можно понять как выручку, как маржу и как оплаченную часть. Модель выберет одно из толкований, и выбор будет выглядеть разумно.
Поэтому до разработки с финансовой службой и руководителями согласуют словарь: что такое выручка, маржа, просроченный платеж, завершенный объект, активный подрядчик. Каждое определение записывают формулой над полями витрины. Модель получает словарь вместе с описанием данных и пользуется им, а не своими представлениями о том, как принято считать.
Словарь полезен и сам по себе. Нередко при его составлении выясняется, что два отдела годами считали выручку по-разному, и именно поэтому их отчеты не сходились.
Что проверяется до выполнения запроса
Сгенерированный запрос не отправляют в базу сразу. Сначала он проходит проверку — в нашем проекте она стоит перед каждым выполнением и защищает от ошибочных выборок. Проверка смотрит на пять вещей.
- Только чтение: разрешены запросы на выборку, а изменение и удаление данных отсекаются до базы.
- Только разрешенные представления: запрос к служебной таблице или к таблице с зарплатами не пройдет.
- Соответствие схеме: все таблицы и поля из запроса существуют, а соединения идут по описанным связям.
- Ограничения объема: лимит строк и времени выполнения, чтобы один неудачный запрос не нагрузил базу.
- Смысловые правила там, где их можно формализовать: есть фильтр по статусу документа, период задан явно.
Отдельная мера — права учетной записи, от имени которой работает сервис. У нее доступ только на чтение и только к витрине. Тогда даже пропущенная проверкой ошибка не превратится в изменение данных: база сама откажет. Сервис лучше подключать к копии базы, а не к рабочей, — так тяжелый запрос не замедлит учетную систему в разгар рабочего дня.
Права доступа задает база, а не инструкция для модели
Если руководитель проекта должен видеть только свои объекты, это ограничение нельзя поручать инструкции для модели. Инструкцию можно обойти формулировкой вопроса, а модель может просто ошибиться.
Ограничение ставят на уровне данных. Каждый пользователь работает со своей ролью, и база возвращает ему только строки, к которым у него есть доступ. Модель при этом может написать какой угодно запрос — чужих объектов в ответе все равно не будет. Проверить это просто: задать сервису вопрос о чужом объекте от имени пользователя без прав и убедиться, что ответ пустой.
Ответ должен показывать, что именно посчитано
Голое число — худший формат ответа. Человек не может понять, что именно посчитано, и либо верит на слово, либо идет перепроверять в ИТ-отдел. Хороший ответ показывает, как сервис понял вопрос. В нем четыре части.
- Толкование словами: «акты КС-2 по объекту за июль — сентябрь, по дате выполнения работ, без отмененных документов».
- Таблица с итогом и возможностью раскрыть строки, из которых он сложился.
- Сам запрос — для аналитика, который хочет проверить логику.
- Предупреждение, если результат необычный: пустая выборка, слишком много строк, итог в разы больше прошлого периода.
Если вопрос допускает два толкования, сервис должен переспросить, а не выбрать сам: «стоимость с НДС или без?». Одно уточнение раздражает меньше, чем неверная цифра на совещании.
Качество меряют на вопросах с эталонными ответами
Качество text-to-SQL проверяют так же, как качество любого ассистента: на наборе реальных вопросов с эталонными ответами. Источник вопросов очевиден — заявки на отчеты, которые приходили в ИТ-отдел за последние месяцы.
Эталон здесь — не текст запроса, а число или таблица, которые посчитал аналитик. Один и тот же результат можно получить разными запросами, поэтому сравнивают результат, а не код. В наборе нужны вопросы нескольких типов.
- Простые выборки и суммы за период.
- Сравнения: план и факт, этот квартал и прошлый.
- Рейтинги: пять подрядчиков с наибольшим отставанием от графика.
- Неоднозначные вопросы, на которые правильная реакция — уточнение.
- Вопросы о данных, которых в базе нет. Правильный ответ — «таких данных нет», а не запрос к похожему полю.
Главная метрика — доля неверных чисел, выданных без предупреждения. Отказ и уточнение обходятся дешево, правдоподобная ошибка — дорого. Часть набора стоит держать закрытой от подрядчика до приемки, иначе система окажется подогнана под знакомые вопросы.
Какие вопросы сервис закрывает, а какие нет
Text-to-SQL хорошо отвечает на вопросы «сколько», «какие» и «как изменилось»: суммы и количества за период, сравнения, рейтинги, списки по условиям. Это и есть основная масса заявок на нестандартные отчеты.
Хуже он отвечает на вопросы «почему». Вопрос «почему выросли затраты по объекту» требует не запроса, а анализа: сравнить несколько срезов, отбросить случайные причины, проверить гипотезы. Сервис поможет быстро получить нужные срезы, но вывод остается за человеком.
Не ответит он и там, где данных нет в базе или они разбросаны по системам, которые не сведены вместе. Если график работ лежит в таблице у руководителя проекта, а факт — в учетной системе, сравнение плана и факта начнется не с модели, а с загрузки графика в витрину.
Частый вопрос лучше превратить в обычный отчет
Если один и тот же вопрос задают каждый день, его выгоднее один раз оформить как обычный отчет в BI-панели. Такой отчет проверяют один раз, он работает без обращений к модели и не зависит от формулировки.
Поэтому журнал вопросов к сервису полезен не только для поиска ошибок. Он показывает, какие отчеты действительно нужны руководителям. Text-to-SQL берет на себя длинный хвост разовых вопросов, а частые со временем переезжают в регулярную отчетность.
Облачная модель или своя
В text-to-SQL модель видит вопрос и описание витрины, но не обязательно сами данные: результат запроса идет из базы прямо пользователю. Это снижает риск, но не убирает его. Названия объектов, контрагентов и суммы в вопросах — тоже коммерческая информация, а если модель пишет пояснение к результату, данные уходят к ней.
Если вопросы и схема чувствительны, языковую модель разворачивают в контуре компании. В нашем проекте работала открытая модель Llama 2. Качество в такой задаче сильнее зависит от описания витрины и словаря, чем от размера модели, поэтому сравнивать модели стоит на своем проверочном наборе, а не по общим рейтингам.
Сколько стоит одно обращение
Каждый вопрос — одно-два обращения к модели. В запрос уходят вопрос, описание нужной части витрины, словарь и примеры, а это несколько тысяч токенов.
Условный пример: 50 руководителей задают по 10 вопросов в день, на каждый вопрос уходит около 4 тыс. токенов. Это 2 млн токенов в день. По тарифам Сбера для юрлиц на осень 2026 года тысяча токенов GigaChat Pro стоит 0,5 ₽ — около 1 тыс. ₽ в день и порядка 22 тыс. ₽ в месяц при 22 рабочих днях. На таком потоке оплата модели — малая часть стоимости решения: основные затраты приходятся на витрину, словарь и проверочный набор.
Что остается за ИТ-отделом
Нагрузка на ИТ-отдел падает, но не исчезает. В нашем проекте она снизилась на 70%: типовые вопросы ушли в сервис, а у разработчиков осталась работа, которую сервис сделать не может.
- Поддерживать витрину: добавлять поля и представления под новые вопросы.
- Обновлять словарь, когда меняются правила учета.
- Разбирать вопросы, на которые сервис не ответил, — это готовый план развития.
- Прогонять проверочный набор после изменений в базе и смены версии модели.
Последний пункт часто упускают. Учетную систему обновляют, поле переименовывают, и запросы, которые месяц назад работали, начинают молча возвращать неполные данные. Прогон набора после каждого изменения ловит это раньше, чем ошибка попадет в отчет руководителю.
С чего начать
- Выгрузите заявки на отчеты в ИТ-отдел за квартал и разложите их по темам.
- Выберите одну область, на которую приходится больше всего заявок: например, акты и оплаты по объектам.
- Опишите для нее витрину и согласуйте словарь терминов с финансовой службой.
- Соберите 50–100 вопросов с эталонными ответами, посчитанными аналитиком.
- Замерьте долю верных ответов на прототипе и только потом подключайте пользователей.
Начинать с одной области полезно не только из осторожности. Витрина, словарь и проверки для второй области строятся заметно быстрее: каркас уже есть, а пользователи научились задавать вопросы.
Как понять, что сервис работает
Через месяц после запуска о сервисе судят не по впечатлениям, а по цифрам. Их немного.
- Доля вопросов, на которые сервис ответил без обращения в ИТ-отдел.
- Доля ответов, которые пользователи перепроверяли или оспаривали.
- Число заявок на нестандартные отчеты в ИТ-отдел по сравнению с периодом до запуска.
- Сколько руководителей задают вопросы каждую неделю, а не только в первые дни.
Третья цифра ближе всего к деньгам: каждая заявка, которая не дошла до ИТ-отдела, — это сэкономленные часы разработчиков и дни ожидания для руководителя. Четвертая показывает, прижился ли сервис. Если руководители спрашивают раз в месяц, причину ищут в качестве ответов или в том, что частые вопросы уже закрыты обычными отчетами.
Сроки, бюджет и команда
Прототип — от 600 тыс. ₽ и до двух недель: одна область данных, витрина, словарь и замер доли верных ответов на ваших вопросах. Пилот — 1,5–3,5 млн ₽ и 3–6 недель: несколько областей, интеграция с BI-панелью, роли и права доступа, работа с реальными пользователями.
С нашей стороны работают ML-инженер, бэкенд-разработчик и аналитик данных, который знает SQL. С вашей нужны владелец процесса — например, руководитель финансовой службы или проектного офиса, — администратор базы и аналитик, который считает эталонные ответы.
Коротко
- Text-to-SQL переводит вопрос на русском в запрос к базе: модель пишет запрос, а числа считает база.
- Главный риск — запрос, который выполняется и возвращает правдоподобное, но неверное число.
- Модели нужна витрина с понятными полями и словарь терминов, а не вся база.
- Запрос проверяется до выполнения, доступ открыт только на чтение, права задает база, а не инструкция.
- Ответ показывает толкование вопроса, а неоднозначный вопрос сервис уточняет.
- В строительной компании отчет готовится за 5 минут вместо 2–3 дней, нагрузка на ИТ-отдел снизилась на 70%.