OpenAI против Ollama с использованием SQLDatabaseToolkit от LangChain

Отказ от ответственности

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

В предыдущей статье мы рассмотрели преимущества использования Ollama локально для приложения RAG. В этой статье мы продолжим нашу оценку Ollama, тестируя запросы на естественном языке (NL) к системе баз данных, используя SQLDatabaseToolkit от LangChain. SQL будет служить базовой системой для сравнения, пока мы исследуем качество результатов, предоставляемых OpenAI и Ollama.

Файлы блокнотов, использованные в этой статье, доступны на GitHub.

Введение

SQLDatabaseToolkit от LangChain — это мощный инструмент, предназначенный для интеграции возможностей обработки NL с реляционными системами баз данных. Он позволяет пользователям запрашивать базы данных, используя NL ввод, используя возможности крупных языковых моделей (LLM) для динамической генерации SQL-запросов. Это особенно полезно для приложений, где нетехнические пользователи или автоматизированные системы должны взаимодействовать со структурированными данными.

Ряд LLM хорошо поддерживается LangChain. LangChain также предоставляет поддержку для Ollama. В этой статье мы оценим, насколько хорошо LangChain интегрируется с Ollama и целесообразность использования SQLDatabaseToolkit в локальной настройке.

Создайте аккаунт в SingleStore Cloud

В предыдущей статье показаны шаги по созданию бесплатного аккаунта SingleStore Cloud. Мы будем использовать Бесплатный Общий Уровень.

Выбрав Рабочее пространство “Старт” > Подключиться > Клиент командной строки, мы получим необходимые позже детали, такие как имя пользователя, пароль, хост, порт и база данных.

Создание таблиц базы данных

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

В левой панели навигации в портале облака SingleStore мы выберем РАЗРАБОТКА > Студия данных > Открыть редактор SQL. Мы создадим три таблицы следующим образом:

SQL

 

CREATE TABLE IF NOT EXISTS tick (
    symbol VARCHAR(10),
    ts     DATETIME SERIES TIMESTAMP,
    open   NUMERIC(18, 2),
    high   NUMERIC(18, 2),
    low    NUMERIC(18, 2),
    price  NUMERIC(18, 2),
    volume INT,
    KEY(ts)
);

CREATE TABLE IF NOT EXISTS portfolio (
    symbol         VARCHAR(10),
    shares_held    INT,
    purchase_date  DATE,
    purchase_price NUMERIC(18, 2)
);

CREATE TABLE IF NOT EXISTS stock_sentiment (
    headline  VARCHAR(250),
    positive  FLOAT,
    negative  FLOAT,
    neutral   FLOAT,
    url       TEXT,
    publisher VARCHAR(30),
    ts        DATETIME,
    symbol    VARCHAR(10)
);

Мы загрузим таблицу портфолио следующими вымышленными данными:

SQL

 

INSERT INTO portfolio (symbol, shares_held, purchase_date, purchase_price) VALUES
('AAPL', 100, '2022-01-15',  150.25),
('MSFT',  50, '2021-12-10',  305.50),
('GOOGL', 25, '2021-11-05', 2800.75),
('AMZN',  10, '2020-07-20', 3200.00),
('TSLA',  40, '2022-02-18',  900.60),
('NFLX',  15, '2021-09-01',  550.00);

Для таблицы настроение по акциям мы загрузим файл stock_sentiment.sql.zip и распакуем его. Мы загрузим данные в таблицу, используя клиент MySQL, следующим образом:

Shell

 

mysql -u "<username>" -p"<password>" -h "<host>" -P <port> -D <database> < stock_sentiment.sql

Мы будем использовать значения для <имя пользователя>, <пароль>, <хост>, <порт> и <база данных>, которые мы сохранили ранее.

Наконец, для таблицы тик мы создадим конвейер:

SQL

 

CREATE PIPELINE tick
AS LOAD DATA KAFKA 'public-kafka.memcompute.com:9092/stockticker'
BATCH_INTERVAL 45000
INTO TABLE tick
FIELDS TERMINATED BY ','
(symbol,ts,open,high,low,price,volume);

Мы настроимся для получения самых ранних данных:

SQL

 

ALTER PIPELINE tick SET OFFSETS EARLIEST;

И протестируем конвейер:

SQL

 

TEST PIPELINE tick LIMIT 1;

Пример вывода:

Plain Text

 

+--------+---------------------+--------+--------+--------+--------+--------+
| symbol | ts                  | open   | high   | low    | price  | volume |
+--------+---------------------+--------+--------+--------+--------+--------+
| MMM    | 2025-01-23 21:40:32 | 178.34 | 178.43 | 178.17 | 178.24 |  38299 |
+--------+---------------------+--------+--------+--------+--------+--------+

Затем мы запустим конвейер:

SQL

 

START PIPELINE tick;

Через несколько минут мы проверим количество загруженных данных:

SQL

 

SELECT COUNT(*)
FROM tick;

Локальная тестовая среда

Из предыдущей статьи мы выполним такие же шаги для настройки нашей локальной тестовой среды, как описано в этих разделах:

  • Введение. Используйте виртуальную машину или venv.
  • Создайте учетную запись в SingleStore Cloud. Этот шаг был завершен выше.
  • Создайте базу данных. Бесплатный общий уровень уже предоставляет базу данных, и нам просто нужно записать название базы данных.
  • Установите Jupyter.
    Обычный текст

     

    pip install notebook
  • Установите Ollama.
    Обычный текст

     

    curl -fsSL https://ollama.com/install.sh | sh
  • Переменные среды.
    Обычный текст

     

    :@:/“” data-lang=”text/plain”>

    export SINGLESTOREDB_URL="<username>:<password>@<host>:<port>/<database>"

    Замените <username>, <password>, <host>, <port> и <database> на значения для вашей среды.

    Обычный текст

     

    “” data-lang=”text/plain”>

    export OPENAI_API_KEY="<OpenAI API Key>"

    Замените <OpenAI API Key> на ваш ключ.

  • Запустите Jupyter.
    Обычный текст

     

    jupyter notebook

Мы будем использовать блокноты Jupyter с GitHub. Эти блокноты настроены на использование OpenAI и Ollama. Для Ollama мы будем использовать один из LLM, указанных в Поддержка инструментов. Мы протестируем следующие четыре запроса.

Первый запрос

SQL

SQL

 

SELECT symbol, (MAX(high) - MIN(low)) AS volatility
FROM tick
GROUP BY symbol
ORDER BY volatility ASC
LIMIT 1;

Естественный язык

Plain Text

 

"For each stock symbol, calculate the volatility as the difference\n"
"between the highest recorded price and the lowest recorded price over time.\n"
"Which stock symbol has the least volatility?"

Результаты

SQL

Plain Text

 

+--------+------------+
| symbol | volatility |
+--------+------------+
| FTR    |       0.55 |
+--------+------------+

OpenAI

Plain Text

 

The stock symbol with the least volatility is FTR, with a volatility of 0.55.

Ollama

Plain Text

 

To find the stock with the highest price, we need to compare the prices of all the given stocks and find the maximum value. However, I don't have real-time access to financial data or the ability to execute code that interacts with external APIs. Therefore, I can't directly calculate the highest price from this list.

However, if you provide me with a specific date or time range, I can help you find the stock with the highest price during that period. For example, if you want to know the stock with the highest price on a particular day in the past, I can assist you with that.

If you're looking for the current highest-priced stock, I recommend checking a financial news website or an API that provides real-time stock data, such as Yahoo Finance, Google Finance, or a service like Alpha Vantage or Finnhub.io. These platforms can give you the most up-to-date information on stock prices.`
For troubleshooting, visit: https://python.langchain.com/docs/troubleshooting/errors/OUTPUT_PARSING_FAILURE

Второй запрос

SQL

SQL

 

SELECT COUNT(*)
FROM tick;

Естественный язык

Plain Text

 

"How many rows are in the tick table?"

Результаты

SQL

Plain Text

 

+----------+
| COUNT(*) |
+----------+
| 22367162 |
+----------+

OpenAI

Plain Text

 

There are 22,367,162 rows in the tick table.

Ollama

Plain Text

 

The "tick" table has 3 rows.

Третий запрос

SQL

SQL

 

-- Шаг 1: Получить последнюю цену для каждого символа
WITH latest_prices AS (
    SELECT symbol, price
    FROM tick t1
    WHERE ts = (
        SELECT MAX(ts)
        FROM tick t2
        WHERE t2.symbol = t1.symbol
    )
)

-- Шаг 2: Рассчитать общую стоимость портфеля
SELECT SUM(p.shares_held * lp.price) AS total_portfolio_value
FROM portfolio p, latest_prices lp
WHERE p.symbol = lp.symbol;

Естественный язык

Plain Text

 

"Taking all the stock symbols from the portfolio table,\n"
"and using the latest value for each stock symbol from the tick table,\n"
"calculate the grand total value of all the shares listed in the portfolio table."

Результаты

SQL

Plain Text

 

+-----------------------+
| total_portfolio_value |
+-----------------------+
|              44540.60 |
+-----------------------+

OpenAI

Plain Text

 

$44,540.60

Ollama

Plain Text

 

I don't know. The provided SQL query does not contain any of the common mistakes listed. It uses the correct join conditions, functions, and data types. The query also properly quotes identifiers and uses the correct number of arguments for functions. Therefore, no changes are needed. However, without access to the actual database schema and table data, I cannot provide a specific answer to the question.

Четвертый запрос

SQL

SQL

 

SELECT
    (
        SELECT ts
        FROM stock_sentiment
        WHERE symbol = 'AAPL'
        ORDER BY positive DESC
        LIMIT 1
    ) AS sentiment_date,
    (
        SELECT positive
        FROM stock_sentiment
        WHERE symbol = 'AAPL'
        ORDER BY positive DESC
        LIMIT 1
    ) AS most_positive_sentiment,
    (
        SELECT price
        FROM tick
        WHERE symbol = 'AAPL'
        ORDER BY ts DESC
        LIMIT 1
    ) AS current_best_price;

Естественный язык

Plain Text

 

"Using the symbol AAPL, show me the date and the most\n"
"positive sentiment in the stock sentiment table and the\n"
"current best price for this symbol from the tick table."

Результаты

SQL

Plain Text

 

+---------------------+-------------------------+--------------------+
| sentiment_date      | most_positive_sentiment | current_best_price |
+---------------------+-------------------------+--------------------+
| 2020-05-28 00:00:00 |                0.331509 |             116.27 |
+---------------------+-------------------------+--------------------+

OpenAI

Plain Text

 

On 2020-05-28, the most positive sentiment for AAPL was 0.331509, and the current best price for AAPL is 116.27.

Ollama

Plain Text

 

The provided list contains decimal numbers, which appear to be the results of some kind of experiment or analysis. Without additional context, it's difficult to determine the exact nature of these results. However, we can observe that the majority of the numbers are between 116.85 and 117.27, with a few outliers at 115.99 and 117.30. The smallest number in the list is 115.99, and the largest is 117.30.`
For troubleshooting, visit: https://python.langchain.com/docs/troubleshooting/errors/OUTPUT_PARSING_FAILURE

Обзор

Анализируя результаты, мы видим, что SQL и OpenAI производят последовательные выводы по всем четырем запросам. Однако у Ollama есть явные проблемы. Обсуждение ветви на GitHub подчеркивает, что хотя модель LLM должна поддерживать вызов инструмента, эта функциональность не доступна нативно в Ollama.

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

Source:
https://dzone.com/articles/openai-vs-ollama-langchain-sqldatabasetoolkit