🚀 Попробуйте Zilliz Cloud, полностью управляемый Milvus, бесплатно — ощутите 10-кратное увеличение производительности! Попробовать сейчас>

milvus-logo
LFAI
Главная
  • Интеграции
    • Инженерия знаний
  • Home
  • Docs
  • Интеграции

  • Инженерия знаний

  • Ванна

Пишите SQL с помощью Vanna и Milvus

Open In Colab GitHub Repository

Vanna - это фреймворк Python RAG (Retrieval-Augmented Generation) с открытым исходным кодом для генерации SQL и связанных с ним функций. Milvus - самая продвинутая в мире векторная база данных с открытым исходным кодом, созданная для работы с приложениями для поиска сходства при встраивании и искусственного интеллекта.

Vanna работает в два простых шага - обучает "модель" RAG на ваших данных, а затем задает вопросы, которые возвращают SQL-запросы, которые могут быть настроены для выполнения в вашей базе данных. В этом руководстве показано, как использовать Vanna для генерации и выполнения SQL-запросов на основе данных, хранящихся в базе данных.

Предварительные условия

Перед запуском этого блокнота убедитесь, что у вас установлены следующие зависимости:

$ pip install "vanna[milvus,openai]"

Если вы используете Google Colab, для включения только что установленных зависимостей может потребоваться перезапуск среды выполнения (щелкните на меню "Runtime" в верхней части экрана и выберите "Restart session" из выпадающего меню).

Также вам нужно установить OPENAI_API_KEY в переменных окружения. Ключ API можно получить в OpenAI.

import os

os.environ["OPENAI_API_KEY"] = "sk-***********"

Подготовка данных

Сначала нам нужно наследоваться от классов Milvus_VectorStore и OpenAI_Chat из Vanna и определить новый класс VannaMilvus, который объединяет возможности обоих классов.

from pymilvus import MilvusClient, model
from vanna.milvus import Milvus_VectorStore
from vanna.openai import OpenAI_Chat


class VannaMilvus(Milvus_VectorStore, OpenAI_Chat):
    def __init__(self, config=None):
        Milvus_VectorStore.__init__(self, config=config)
        OpenAI_Chat.__init__(self, config=config)

Мы инициализируем класс VannaMilvus с необходимыми параметрами конфигурации. Мы используем экземпляр milvus_client для хранения вкраплений и model.DefaultEmbeddingFunction(), инициализированный из milvus_model, для генерации вкраплений.C

Что касается аргумента MilvusClient:

  • Установка uri в качестве локального файла, например,./milvus.db, является наиболее удобным методом, так как он автоматически использует Milvus Lite для хранения всех данных в этом файле.
  • Если у вас большой объем данных, вы можете настроить более производительный сервер Milvus на docker или kubernetes. В этом случае используйте ури сервера, напримерhttp://localhost:19530, в качестве uri.
  • Если вы хотите использовать Zilliz Cloud, полностью управляемый облачный сервис для Milvus, измените uri и token, которые соответствуют публичной конечной точке и ключу Api в Zilliz Cloud.
milvus_uri = "./milvus_vanna.db"

milvus_client = MilvusClient(uri=milvus_uri)

vn_milvus = VannaMilvus(
    config={
        "api_key": os.getenv("OPENAI_API_KEY"),
        "model": "gpt-3.5-turbo",
        "milvus_client": milvus_client,
        "embedding_function": model.DefaultEmbeddingFunction(),
        "n_results": 2,  # The number of results to return from Milvus semantic search.
    }
)

Это простой пример с несколькими выборками данных, поэтому мы установили значение n_results равным 2, чтобы обеспечить поиск двух наиболее похожих результатов. На практике при работе с большим набором обучающих данных следует установить значение n_results на более высокое значение.

Мы будем использовать пример базы данных SQLite с несколькими таблицами, содержащими некоторые примеры данных.

import sqlite3

sqlite_path = "./my-database.sqlite"
sql_connect = sqlite3.connect(sqlite_path)
c = sql_connect.cursor()

init_sqls = """
CREATE TABLE IF NOT EXISTS Customer (
    ID INTEGER PRIMARY KEY AUTOINCREMENT,
    Name TEXT NOT NULL,
    Company TEXT NOT NULL,
    City TEXT NOT NULL,
    Phone TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS Company (
    ID INTEGER PRIMARY KEY AUTOINCREMENT,
    Name TEXT NOT NULL,
    Industry TEXT NOT NULL,
    Location TEXT NOT NULL,
    EmployeeCount INTEGER NOT NULL
);

CREATE TABLE IF NOT EXISTS User (
    ID INTEGER PRIMARY KEY AUTOINCREMENT,
    Username TEXT NOT NULL UNIQUE,
    Email TEXT NOT NULL UNIQUE
);

INSERT INTO Customer (Name, Company, City, Phone) 
VALUES ('John Doe', 'ABC Corp', 'New York', '123-456-7890');

INSERT INTO Customer (Name, Company, City, Phone) 
VALUES ('Jane Smith', 'XYZ Inc', 'Los Angeles', '098-765-4321');

INSERT INTO Company (Name, Industry, Location, EmployeeCount)
VALUES ('ABC Corp', 'cutting-edge technology', 'New York', 100);

INSERT INTO User (Username, Email)
VALUES ('johndoe123', 'johndoe123@example.com');
"""

for sql in init_sqls.split(";"):
    c.execute(sql)

sql_connect.commit()

# Connect to the SQLite database
vn_milvus.connect_to_sqlite(sqlite_path)

Обучение на данных

Мы можем обучить модель на DDL-данных базы данных SQLite. Мы получаем данные DDL и передаем их в функцию train.

# If there exists training data, we should remove it before training.
existing_training_data = vn_milvus.get_training_data()
if len(existing_training_data) > 0:
    for _, training_data in existing_training_data.iterrows():
        vn_milvus.remove_training_data(training_data["id"])

# Get the DDL of the SQLite database
df_ddl = vn_milvus.run_sql("SELECT type, sql FROM sqlite_master WHERE sql is not null")

# Train the model on the DDL data
for ddl in df_ddl["sql"].to_list():
    vn_milvus.train(ddl=ddl)
Adding ddl: CREATE TABLE Customer (
    ID INTEGER PRIMARY KEY AUTOINCREMENT,
    Name TEXT NOT NULL,
    Company TEXT NOT NULL,
    City TEXT NOT NULL,
    Phone TEXT NOT NULL
)
Adding ddl: CREATE TABLE sqlite_sequence(name,seq)
Adding ddl: CREATE TABLE Company (
    ID INTEGER PRIMARY KEY AUTOINCREMENT,
    Name TEXT NOT NULL,
    Industry TEXT NOT NULL,
    Location TEXT NOT NULL,
    EmployeeCount INTEGER NOT NULL
)
Adding ddl: CREATE TABLE User (
    ID INTEGER PRIMARY KEY AUTOINCREMENT,
    Username TEXT NOT NULL UNIQUE,
    Email TEXT NOT NULL UNIQUE
)

Кроме обучения на DDL-данных, мы также можем обучаться на документации и SQL-запросах базы данных.

# Add documentation about your business terminology or definitions.
vn_milvus.train(
    documentation="ABC Corp specializes in cutting-edge technology solutions and innovation."
)
vn_milvus.train(
    documentation="XYZ Inc is a global leader in manufacturing and supply chain management."
)

# You can also add SQL queries to your training data.
vn_milvus.train(sql="SELECT * FROM Customer WHERE Name = 'John Doe'")
Adding documentation....
Adding documentation....
Using model gpt-3.5-turbo for 65.0 tokens (approx)
Question generated with sql: What are the details of the customer named John Doe? 
Adding SQL...





'595b185c-e6ad-47b0-98fd-0e93ef9b6a0a-sql'

Давайте посмотрим на обучающие данные.

training_data = vn_milvus.get_training_data()
training_data
# id вопрос содержание
0 595b185c-e6ad-47b0-98fd-0e93ef9b6a0a-sql Каковы данные о клиенте по имени Джо... SELECT * FROM Customer WHERE Name = 'John Doe'
0 25f4956c-e370-4097-994f-996f22d145fa-ddl Нет CREATE TABLE Company (\n ID INTEGER PRIMARY...
1 b95ecc66-f65b-49dc-a9f1-c1842ad230ff-ddl Нет CREATE TABLE Customer (\n ID INTEGER PRIMAR...
2 fcc73d15-30a5-4421-9d73-b8c3b0ed5305-ddl Нет CREATE TABLE sqlite_sequence(name,seq)
3 feae618c-5910-4f6f-8b4b-6cc3e03aec06-ddl Нет CREATE TABLE User (\n ID INTEGER PRIMARY KE...
0 79a48db1-ba1f-4fd5-be99-74f2ca2eaeeb-doc Нет Компания XYZ Inc является мировым лидером в производстве...
1 9f9df1b8-ae62-4823-ad28-d7e0f2d1f4c0-doc Нет ABC Corp специализируется на передовых технологиях...

Генерация SQL и их выполнение

Поскольку мы тренировались с данными DDL, структура таблицы теперь доступна для генерации SQL-запросов.

Давайте попробуем выполнить простой вопрос.

sql = vn_milvus.generate_sql("what is the phone number of John Doe?")
vn_milvus.run_sql(sql)
SQL Prompt: [{'role': 'system', 'content': "You are a SQLite expert. Please help to generate a SQL query to answer the question. Your response should ONLY be based on the given context and follow the response guidelines and format instructions. \n===Tables \nCREATE TABLE Customer (\n    ID INTEGER PRIMARY KEY AUTOINCREMENT,\n    Name TEXT NOT NULL,\n    Company TEXT NOT NULL,\n    City TEXT NOT NULL,\n    Phone TEXT NOT NULL\n)\n\nCREATE TABLE User (\n    ID INTEGER PRIMARY KEY AUTOINCREMENT,\n    Username TEXT NOT NULL UNIQUE,\n    Email TEXT NOT NULL UNIQUE\n)\n\n\n===Additional Context \n\nABC Corp specializes in cutting-edge technology solutions and innovation.\n\nXYZ Inc is a global leader in manufacturing and supply chain management.\n\n===Response Guidelines \n1. If the provided context is sufficient, please generate a valid SQL query without any explanations for the question. \n2. If the provided context is almost sufficient but requires knowledge of a specific string in a particular column, please generate an intermediate SQL query to find the distinct strings in that column. Prepend the query with a comment saying intermediate_sql \n3. If the provided context is insufficient, please explain why it can't be generated. \n4. Please use the most relevant table(s). \n5. If the question has been asked and answered before, please repeat the answer exactly as it was given before. \n"}, {'role': 'user', 'content': 'What are the details of the customer named John Doe?'}, {'role': 'assistant', 'content': "SELECT * FROM Customer WHERE Name = 'John Doe'"}, {'role': 'user', 'content': 'what is the phone number of John Doe?'}]
Using model gpt-3.5-turbo for 367.25 tokens (approx)
LLM Response: SELECT Phone FROM Customer WHERE Name = 'John Doe'
# Телефон
0 123-456-7890

А вот более сложный вопрос. Информация о названии производственной корпорации находится в данных документа, который является справочной информацией. Сформированный SQL-запрос извлекает информацию о клиенте на основе конкретного названия производственной корпорации.

sql = vn_milvus.generate_sql("which customer works for a manufacturing corporation?")
vn_milvus.run_sql(sql)
SQL Prompt: [{'role': 'system', 'content': "You are a SQLite expert. Please help to generate a SQL query to answer the question. Your response should ONLY be based on the given context and follow the response guidelines and format instructions. \n===Tables \nCREATE TABLE Company (\n    ID INTEGER PRIMARY KEY AUTOINCREMENT,\n    Name TEXT NOT NULL,\n    Industry TEXT NOT NULL,\n    Location TEXT NOT NULL,\n    EmployeeCount INTEGER NOT NULL\n)\n\nCREATE TABLE Customer (\n    ID INTEGER PRIMARY KEY AUTOINCREMENT,\n    Name TEXT NOT NULL,\n    Company TEXT NOT NULL,\n    City TEXT NOT NULL,\n    Phone TEXT NOT NULL\n)\n\n\n===Additional Context \n\nXYZ Inc is a global leader in manufacturing and supply chain management.\n\nABC Corp specializes in cutting-edge technology solutions and innovation.\n\n===Response Guidelines \n1. If the provided context is sufficient, please generate a valid SQL query without any explanations for the question. \n2. If the provided context is almost sufficient but requires knowledge of a specific string in a particular column, please generate an intermediate SQL query to find the distinct strings in that column. Prepend the query with a comment saying intermediate_sql \n3. If the provided context is insufficient, please explain why it can't be generated. \n4. Please use the most relevant table(s). \n5. If the question has been asked and answered before, please repeat the answer exactly as it was given before. \n"}, {'role': 'user', 'content': 'What are the details of the customer named John Doe?'}, {'role': 'assistant', 'content': "SELECT * FROM Customer WHERE Name = 'John Doe'"}, {'role': 'user', 'content': 'which customer works for a manufacturing corporation?'}]
Using model gpt-3.5-turbo for 384.25 tokens (approx)
LLM Response: SELECT * 
FROM Customer 
WHERE Company = 'XYZ Inc'
# ID Имя Компания Город Телефон
0 2 Джейн Смит XYZ Inc Лос-Анджелес 098-765-4321

Отключитесь от SQLite и Milvus и удалите их, чтобы освободить ресурсы.

sql_connect.close()
milvus_client.close()

os.remove(sqlite_path)
if os.path.exists(milvus_uri):
    os.remove(milvus_uri)

Попробуйте Managed Milvus бесплатно

Zilliz Cloud работает без проблем, поддерживается Milvus и в 10 раз быстрее.

Начать
Обратная связь

Была ли эта страница полезной?