Использование LLM для автоматического построения запросов на основе описания структуры базы данных

Использование LLM для автоматического построения запросов на основе описания структуры базы данных

В рамках разработки автоматизированной системы BI-отчетности для заказчика мы столкнулись с проблемой обеспечения бесперебойного обмена информацией между различными системами (Google Docs, Bitrix24, 1С) и интеграции данных в единую систему. Для решения этой проблемы был разработан BI-коннектор, поскольку стандартный коннектор не поддерживал загрузку всех нужных сущностей. Наше же решение было гибким и обеспечивало сбор информации с нужной глубиной и точностью. Это позволило получить доступ ко всем необходимым полям и связям в Bitrix24, что существенно повысило качество интеграции, а также точность аналитики.

В процессе работы над коннектором мы решили провести эксперимент — на основе бизнес-требований автоматически построить SQL-запросы с помощью LLM. Хотя для эксперимента мы решили взять простые примеры, по сравнению с реальными отчетами, это должно дать понимание — как AI справятся с агрегированием данных и объединением таблиц.

Для этого мы добавили возможность выгрузки метаданных таблиц (DDL). Условно, это текстовый файл с содержимым следующего вида.

Использование LLM для автоматического построения запросов на основе описания структуры базы данных

Описание даёт представление о таблицах, доступных для аналитики, и их полях, что особенно важно для пользовательских полей Битрикс24, которые обычно, имеют код вида ufCrm_1664767880922.

Для эксперимента мы решили использовать следующие нейросети:

  • OpenAI — GPT4o,
  • Athropic — Claude 3.5 Sonnet-20240620,
  • DeepSeek,
  • QweenAI.

В турнирную таблицу не был включен Яндекс GPT, поскольку он имеет ограничение на вводимый текст и не мог включить в себя даже урезанную версию DDL.

Задачи эксперимента

В рамках нашего эксперимента перед нейросетями ставились 3 задачи, сложность которых постепенно увеличивалась.

Задача 1: вывод сводки по лидам, группируя их по статусу

Цель: сформировать запрос, который будет группировать лиды по их статусам и подсчитывать количество лидов в каждом статусе.

Результат должен быть представлен в следующем формате:

  • NEW: 1
  • WON: 7

Задача 2: вывод сводки по лидам с человекочитаемыми названиями стадий

Цель: сформировать запрос, который не просто группирует лиды по статусам, а выводит их с реальными названиями стадий, а не внутренними идентификаторами. Необходимо использовать таблицу status для получения человекочитаемых названий.

Результат должен быть представлен в следующем формате:

  • Не обработан: 1
  • Не удалось связаться: 2

Задача 3: вывод сводки по лидам с количеством лидов по стадиям для каждого ответственного

Цель: создать запрос, который выводит ФИО ответственного и количество лидов по каждому статусу (например, количество лидов в стадии «Не обработан», «Не удалось связаться» и т.д.). Необходимо учитывать, что лиды могут быть на разных стадиях, и для каждого ответственного нужно подсчитать количество лидов в каждой стадии.

Результат должен содержать:

  • ФИО ответственного,
  • Количество лидов в стадии “Не обработан”,
  • Количество лидов в стадии “Не удалось связаться”,
  • Количество лидов в стадии “В работе” и т.д.

Генерация промпта

На этом этапе перед нейросетями ставится задача создать промпты, которые будут использованы для формирования SQL-запросов для решения аналитических задач на основе данных из базы данных ClickHouse.

Первоначальный промпт для нейросетей:

Привет. Тебе необходимо сформировать промт для LLM для следующей задачи. Есть база данных в ClickHouse. Мы предоставим DDL описание этой базы данных следующего вида:

*пример DDL выше*.


Исходя из данной структуры, сформируй запрос для решения следующей задачи: *текст задачи*

OpenAI GPT4o - Задача 1

У меня есть следующее описание таблиц в ClickHouse:

*содержимое DDL файла*


На основе этой структуры, сгенерируй SQL-запрос для получения сводки по лидам, группируя их по статусу, используя поле `stageId`. Мне нужно, чтобы результат включал количество лидов на каждой стадии, в формате, подобном такому: NEW: 1, WON: 7.

OpenAI GPT4o - Задача 2

У меня есть следующее описание таблиц в ClickHouse:

*содержимое DDL файла*


На основе этой структуры, сгенерируй SQL-запрос для получения сводки по лидам с человекочитаемыми названиями стадий из таблицы `status`.

Результат должен содержать количество лидов для каждой стадии в формате: Не обработан: 1 Не удалось связаться: 2

OpenAI GPT4o - Задача 3

У меня есть следующее описание таблицы в ClickHouse:

*содержимое DDL файла*


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

1. ФИО ответственного

2. Количество лидов в стадии "Не обработан"

3. Количество лидов в стадии "Не удалось связаться"

И так далее для всех статусов лидов.


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

Athropic - claude-3-5-sonnet-20240620 - Задача 1

Ты - опытный SQL-разработчик, специализирующийся на Clickhouse. У нас есть структура таблиц базы данных:

*содержимое DDL*


Задача: написать SQL-запрос для вывода сводки по лидам, группируя их по статусу. Результат должен быть в формате 'СТАТУС:КОЛИЧЕСТВО', например: NEW:1 WON:7


Пожалуйста, напиши SQL-запрос для Clickhouse, который решит эту задачу. Используй поле 'stageId' для группировки по статусу. Обрати внимание на следующие моменты:

1. Используй функцию COUNT для подсчета количества лидов.

2. Используй GROUP BY для группировки по статусу.

3. Отформатируй вывод в соответствии с требуемым форматом 'СТАТУС:КОЛИЧЕСТВО'.

Предоставь запрос с пояснениями каждой его части.

Athropic - claude-3-5-sonnet-20240620 - Задача 2

Ты - опытный SQL-разработчик, специализирующийся на Clickhouse. У нас есть структура таблиц базы данных: *содержимое DDL*


Задача: написать SQL-запрос для вывода сводки по лидам, группируя их по статусу, используя человекочитаемые названия из таблицы status. Результат должен быть в формате 'НАЗВАНИЕ_СТАТУСА: КОЛИЧЕСТВО', например: Не обработан: 1 Не удалось связаться: 2


Пожалуйста, напиши SQL-запрос для Clickhouse, который решит эту задачу. Обрати внимание на следующие моменты:

1. Используй JOIN для соединения таблиц DYNAMIC_1 и status по соответствующему полю (предположительно, stageId в DYNAMIC_1 соответствует id в STATUS_ID).

2. Используй функцию COUNT для подсчета количества лидов.

3. Используй GROUP BY для группировки по названию статуса.

4. Отформатируй вывод в соответствии с требуемым форматом 'НАЗВАНИЕ_СТАТУСА: КОЛИЧЕСТВО'.

5. Отсортируй результат по количеству лидов в убывающем порядке.


Предоставь запрос с пояснениями каждой его части. Если для выполнения запроса требуется дополнительная информация о структуре таблицы status, укажи это в комментарии к запросу

Athropic - claude-3-5-sonnet-20240620 - Задача 3

Ты - опытный SQL-разработчик, специализирующийся на Clickhouse. У нас есть структура таблиц базы данных: *содержимое DDL*


Задача: написать SQL-запрос для вывода сводки по лидам, учитывая ответственных и все возможные статусы лидов.


Результат должен содержать:

1. ФИО ответственного

2. Количество лидов в каждой стадии (например, "Не обработан", "Не удалось связаться" и т.д.)


Пожалуйста, напиши SQL-запрос для Clickhouse, который решит эту задачу. Обрати внимание на следующие моменты:

1. Используй JOIN для соединения всех необходимых таблиц.

2. Используй условные агрегации (например, SUM(CASE WHEN ...)) для подсчета количества лидов в каждой стадии.

3. Результат должен быть в формате таблицы, где каждая строка представляет одного ответственного, а столбцы - количество лидов в различных стадиях.

4. Используй динамическое построение столбцов для всех возможных статусов, так как их количество может меняться.

5. Отсортируй результат по ФИО ответственного.


Предоставь запрос с пояснениями каждой его части. Если для выполнения запроса требуется дополнительная информация о структуре таблиц с ответственными или статусами, укажи это в комментарии к запросу.


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

DeepSeek - Задача 1

Ты — опытный аналитик данных, который хорошо разбирается в SQL и базах данных, особенно в ClickHouse. Тебе нужно сформировать SQL-запрос для выполнения задачи на основе предоставленного DDL описания таблицы.


Описание таблиц:

**содержимое DDL**


Задача:

Необходимо вывести сводку по лидам, группируя их по статусу. Результат должен быть в формате:

NEW:1

WON:7


Требования к запросу:

1. Запрос должен группировать лиды по значению поля stageId.

2. Для каждого статуса нужно вывести количество лидов.

3. Результат должен быть отсортирован по количеству лидов в убывающем порядке.


Сформируй SQL-запрос для ClickHouse, который решит эту задачу.

DeepSeek - Задача 2

Ты — опытный аналитик данных, который хорошо разбирается в SQL и базах данных, особенно в ClickHouse. Тебе нужно сформировать SQL-запрос для выполнения задачи на основе предоставленного DDL описания таблиц.


Описание таблиц:

**содержимое DDL**


Задача:

Необходимо вывести сводку по лидам, группируя их по статусу, но вместо идентификаторов статусов (stageId) использовать человекочитаемые названия из таблицы status. Результат должен быть в формате:

Не обработан: 1

Не удалось связаться: 2


Требования к запросу:

1. Запрос должен группировать лиды по значению поля stageId.

2. Для каждого статуса нужно вывести количество лидов.

3. Использовать человекочитаемые названия статусов из таблицы status.

4. Результат должен быть отсортирован по количеству лидов в убывающем порядке.


Сформируй SQL-запрос для ClickHouse, который решит эту задачу.

DeepSeek - Задача 3

Ты — опытный аналитик данных, который хорошо разбирается в SQL и базах данных, особенно в ClickHouse. Тебе нужно сформировать SQL-запрос для выполнения задачи на основе предоставленного DDL описания таблиц.


Описание таблиц:

**содержимое DDL**


Задача:

Необходимо вывести сводку по лидам, учитывая ответственных. Результирующая таблица должна содержать:

1. ФИО ответственного.

2. Количество лидов в стадии "Не обработан".

3. Количество лидов в стадии "Не удалось связаться".

4. И так далее для всех статусов лидов.


Требования к запросу:

1. Используй таблицы DYNAMIC_1, responsibles и status. ФИО ответственного должно быть объединено в одну строку (фамилия, имя, отчество).

2. Для каждого статуса (stageName) создай отдельный столбец с количеством лидов.

3. Группируй данные по ответственным.

4. Отсортируй результат по ФИО ответственного.


Сформируй SQL-запрос для ClickHouse, который решит эту задачу.

qweenlm - Задача 1

Ты работаешь с базой данных ClickHouse. Тебе необходимо составить SQL-запрос на основе предоставленной структуры таблицы и описанной задачи.


Структура бд:

**содержимое DDL**


Задача:

Составь SQL-запрос для вывода сводки по лидам, группируя их по значению stageSemanticId (Группа стадии).


Результат должен отображать количество лидов для каждой группы стадии в формате:

<stageSemanticId>:<количество_лидов>

NEW:1

WON:7


Убедись, что запрос учитывает только те строки, где stageSemanticId не является NULL.

qweenlm - Задача 2

Ты работаешь с базой данных ClickHouse. Тебе необходимо составить SQL-запрос на основе предоставленной структуры двух таблиц и описанной задачи.


Структура бд:

**содержимое DDL**


Задача:

Составь SQL-запрос для вывода сводки по лидам, где вместо технического идентификатора статуса (stageSemanticId) используется человекочитаемое название статуса из таблицы status. Результат должен отображать количество лидов для каждого статуса в формате:

<человекочитаемое_название>:<количество_лидов>


Например:

Не обработан: 1

Не удалось связаться: 2


Убедись, что запрос учитывает только те строки, где stageSemanticId не является NULL.

qweenlm - Задача 3

Ты работаешь с базой данных ClickHouse. Тебе необходимо составить SQL-запрос на основе предоставленной структуры трех таблиц и описанной задачи.


Структура бд:

**содержимое DDL**


Задача:

Составь SQL-запрос для вывода сводки по лидам, учитывая ответственных пользователей. Таблица должна содержать следующие столбцы:


1. ФИО ответственного пользователя (в формате «Фамилия Имя Отчество»).

2. Количество лидов в каждой стадии (stageSemanticId), представленной человекочитаемым названием из таблицы status.


Например, если стадии имеют следующие названия: «Не обработан», «Не удалось связаться», то результат должен выглядеть так: ``` ФИО | Не обработан | Не удалось связаться | ... Иванов Иван Иванович | 5 | 2 | ... Петров Петр Петрович | 3 | 0 | ...

Генерация запроса по полученным промптам

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

Результаты того, как нейросети справились с поставленными задачами, отражены в таблице.

Использование LLM для автоматического построения запросов на основе описания структуры базы данных

OpenAI - GPT4o - Задача 1

Использование LLM для автоматического построения запросов на основе описания структуры базы данных

OpenAI - GPT4o - Задача 2

Использование LLM для автоматического построения запросов на основе описания структуры базы данных

OpenAI - GPT4o - Задача 3

Использование LLM для автоматического построения запросов на основе описания структуры базы данных

Athropic - claude-3-5-sonnet-20240620 - Задача 1

Использование LLM для автоматического построения запросов на основе описания структуры базы данных

Athropic - claude-3-5-sonnet-20240620 - Задача 2

Использование LLM для автоматического построения запросов на основе описания структуры базы данных
Использование LLM для автоматического построения запросов на основе описания структуры базы данных

Athropic - claude-3-5-sonnet-20240620 - Задача 3

Использование LLM для автоматического построения запросов на основе описания структуры базы данных

DeepSeek - Задача 1

Использование LLM для автоматического построения запросов на основе описания структуры базы данных

DeepSeek - Задача 2

Использование LLM для автоматического построения запросов на основе описания структуры базы данных

DeepSeek - Задача 3

Использование LLM для автоматического построения запросов на основе описания структуры базы данных

QweenLm - Задача 1

Использование LLM для автоматического построения запросов на основе описания структуры базы данных

QweenLm - Задача 2

Использование LLM для автоматического построения запросов на основе описания структуры базы данных

QweenLm - Задача 2 (с промптом с угрозами)

Использование LLM для автоматического построения запросов на основе описания структуры базы данных

Вывод

Из полученных данных следует, что на текущем этапе LLM могут эффективно помогать в решении небольших аналитических задач, а также справляться с синтаксисом и частично автоматизировать рутинные операции. Однако при создании более сложных запросов возникает необходимость в корректировке промптов, уточнении контекста и постоянной доработке полученных результатов, что требует значительных временных затрат.

Начать дискуссию