Благодаря OpenAI и его версии для Azure, которые набирают все большую популярность, возможны различные ситуации. Одним из примеров этого является использование ИИ для создания SQL-запросов для вашей текущей схемы базы данных. Несмотря на то, что это может показаться простым, есть некоторые трудности. Я пройдусь по ним после того, как покажу, как начать ваши эксперименты.

Настройка:

  1. Экземпляр Azure OpenAI (или вы можете использовать обычный OpenAI с небольшим изменением кода)
  2. База данных SQL (в своей лабораторной установке я использую локально установленный SQL Server 2022 и образец базы данных AdventureWorks2019)
  3. Python-движок

В моем случае я использую VS Code с его расширением Python и Python 3.10, установленным через Microsoft Store.

Общая логика получения ответов на ваши вопросы выглядит следующим образом:

  1. Подключитесь к вашей базе данных SQL.
  2. Используйте INFORMATION_SCHEMA для извлечения определений таблиц.
  3. Создайте текстовую оболочку для вашей схемы, чтобы передать приглашение OpenAI.
  4. Добавьте свой вопрос к подсказке.
  5. Вызовите API и проанализируйте свой ответ.

Полный список кодов приведен ниже:

import os
import pyodbc
import openai

# Connect to SQL Server and retrieve the schema
server = '<server name>'  # replace with your SQL Server name
database = 'database name'  # replace with your database name
username = 'login'  # replace with your username
password = 'password'  # replace with your password

# Connect to SQL Server
conn = pyodbc.connect(
    f'DRIVER={{ODBC Driver 17 for SQL Server}};'
    f'SERVER={server};'
    f'DATABASE={database};'
    f'UID={username};'
    f'PWD={password};'
)

# Fetch schema information
cursor = conn.cursor()
cursor.execute("SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'vSalesModel'and COLUMN_NAME not in ('rowguid','startdate','enddate','modifieddate')") #I am using highly customized single-table view of my "semantic" representation of the tables I am insterested in
schema = cursor.fetchall()

# Prepare schema data for Azure OpenAI
schema_text = ''
for table_name, column_name, data_type in schema:
    schema_text += f"Table: {table_name}, Column: {column_name}, Data Type: {data_type}\n"

# Set up Azure OpenAI credentials
openai.api_type = "azure"
openai.api_base = "<endpoint name>"#shoudl be something like this"https://<open ai service name>.openai.azure.com/"
openai.api_version = "2022-12-01" #at the time of writing this is the api version
openai.api_key = '<your api key from Azure Open AI endpoint>'



# Define a function to generate responses from Azure OpenAI
def generate_response(prompt):
    response = openai.Completion.create(
        engine="code-davinci-002",
        prompt=prompt,
        temperature=0.7,
        max_tokens=1024,
        top_p=1,
        frequency_penalty=0,
        presence_penalty=0
    )
    return response.choices[0].text.strip()

# Ask questions to Azure OpenAI
while True:
    question = input("Ask a question about SQL statement writing: ")
    if question.lower() == 'exit':
        break
    prompt = f"Question: {question}\nSchema: {schema_text}\nHow to write SQL statement for "
    response = generate_response(prompt)
    print(response)

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

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

Передача схемы базы данных в модель ИИ

Чтобы получить правильные ответы, модель должна понимать структуру вашей таблицы, имена столбцов, отношения между таблицами, и это довольно сложно реализовать, если вы хотите сохранить свою звезду/снежинку или нормализованную схему базы данных. Или, если подытожить, вам нужно решить, какая стратегия вам больше подходит — OBT (One Big Table) или Star-Schema. Пара отличных сравнительных постов с разными инструментами, которые вы можете найти здесь и здесь.

OBT.Для написания SQL-запросов использование OBT (одна большая таблица) может быть более подходящим, если ваш вариант использования ориентирован на бизнес-аналитиков, которые могут не обязательно понимать соединения или структуры таблиц. Кроме того, вам не всегда нужно материализовать большую таблицу (в зависимости от ваших потребностей), если вы удовлетворены производительностью. Вы можете создать большое представление, которое объединяет все ваши таблицы и обеспечивает семантическое представление вашей области бизнеса. Этот подход позволяет указать удобные для пользователя имена столбцов, добавить логику к представлению, применить дополнительную фильтрацию и т. д. Это не означает замену существующего семантического слоя (если он у вас есть), а скорее создает достаточно близкое представление которые могут помочь вашим пользователям быстрее получить представление.

Схема-звезда. В этом подходе вы предоставляете всю схему таблицы и столбца модели OpenAI. Однако определить отношения между таблицами непросто. Модель OpenAI пытается установить соединения на основе имен столбцов, но, по моему опыту, это не очень успешно. В результате есть риск не получить рабочий запрос. При этом этот подход больше подходит для опытных пользователей и разработчиков, которые хотят ускорить процесс разработки.

Важно — для обоих этих подходов вы ограничены максимальным количеством токенов, которые вы можете отправить. На момент написания статьи это около 8000 для модели Code Davinci (ранее GPT-4, что позволяло около 32000), что не позволило мне раскрыть всю базу данных AdventureWorks2019. И при каждом вызове API эта схема должна быть встроена в подсказку. Или, по крайней мере, я не мог найти способ отправить схему базы данных за пару вызовов, чтобы «обучить» модель, а затем просто задать вопросы.