OpenAI vs Ollama en utilisant l’outil SQLDatabaseToolkit de LangChain

Avertissement

Les données boursières utilisées dans cet article sont entièrement fictives. Elles sont purement à des fins de démonstration. Veuillez ne pas utiliser ces données pour prendre des décisions financières.

Dans un article précédent, nous avons vu les avantages d’utiliser Ollama localement pour une application RAG. Dans cet article, nous allons étendre notre évaluation d’Ollama en testant des requêtes en langage naturel (NL) contre un système de base de données, en utilisant le SQLDatabaseToolkit de LangChain. SQL servira de système de référence pour la comparaison alors que nous explorons la qualité des résultats fournis par OpenAI et Ollama.

Les fichiers de notebook utilisés dans cet article sont disponibles sur GitHub.

Introduction

Le SQLDatabaseToolkit de LangChain est un outil puissant conçu pour intégrer les capacités de traitement NL avec les systèmes de bases de données relationnelles. Il permet aux utilisateurs d’interroger les bases de données en utilisant des entrées NL, en utilisant les capacités des grands modèles de langage (LLMs) pour générer dynamiquement des requêtes SQL. Cela le rend particulièrement utile pour les applications où des utilisateurs non techniques ou des systèmes automatisés ont besoin d’interagir avec des données structurées. 

Plusieurs LLMs sont bien pris en charge par LangChain. LangChain fournit également un support pour Ollama. Dans cet article, nous évaluerons comment LangChain s’intègre bien avec Ollama et la faisabilité d’utiliser le SQLDatabaseToolkit dans une configuration locale.

Créez un compte SingleStore Cloud

Un article précédent a montré les étapes pour créer un compte gratuit SingleStore Cloud. Nous utiliserons le niveau gratuit partagé.

En sélectionnant l’Espace de travail Starter > Se connecter > Client CLI, nous obtiendrons les détails dont nous aurons besoin plus tard, tels que le nom d'utilisateur, le mot de passe, l’hôte, le port et la base de données.

Créer des tables de base de données

Pour notre environnement de test, nous utiliserons SingleStore fonctionnant dans le Cloud comme notre système de base de données cible, et nous nous connecterons de manière sécurisée à cet environnement en utilisant des notebooks Jupyter fonctionnant sur un système local.

Dans le volet de navigation de gauche du portail cloud SingleStore, nous sélectionnerons DÉVELOPPER > Data Studio > Ouvrir l’Éditeur SQL. Nous créerons trois tables, comme suit:

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)
);

Nous chargerons la table portefeuille avec les données fictives suivantes:

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);

Pour la table sentiment_action, nous téléchargerons le fichier stock_sentiment.sql.zip et le décompresserons. Nous chargerons les données dans la table en utilisant un client MySQL, comme suit:

Shell

 

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

Nous utiliserons les valeurs pour <nom d'utilisateur>, <mot de passe>, <hôte>, <port> et <base de données> que nous avons enregistrées précédemment.

Enfin, pour la table tic, nous créerons un pipeline:

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);

Nous ajusterons pour obtenir les données les plus récentes:

SQL

 

ALTER PIPELINE tick SET OFFSETS EARLIEST;

Et tester le pipeline:

SQL

 

TEST PIPELINE tick LIMIT 1;

Exemple de sortie:

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 |
+--------+---------------------+--------+--------+--------+--------+--------+

Ensuite, nous démarrerons le pipeline:

SQL

 

START PIPELINE tick;

Après quelques minutes, nous vérifierons la quantité de données chargées jusqu’à présent:

SQL

 

SELECT COUNT(*)
FROM tick;

Environnement de test local

Dans un article précédent, nous suivrons les mêmes étapes pour configurer notre environnement de test local tel que décrit dans ces sections:

  • Introduction. Utilisez une machine virtuelle ou venv.
  • Créer un compte SingleStore Cloud. Cette étape a été réalisée ci-dessus.
  • Créer une base de données. Le niveau gratuit partagé fournit déjà une base de données et nous devons simplement noter le nom de la base de données.
  • Installer Jupyter.
    Texte brut

     

    pip install notebook
  • Installer Ollama.
    Texte brut

    curl -fsSL https://ollama.com/install.sh | sh
  • Variables d’environnement.
    Texte brut

    :@:/«  » data-lang= »text/plain »>

    export SINGLESTOREDB_URL="<nom d'utilisateur>:<mot de passe>@<hôte>:<port>/<base de données>"

    Remplacez <nom d'utilisateur>, <mot de passe>, <hôte>, <port> et <base de données> par les valeurs de votre environnement.

    Texte brut

    «  » data-lang= »text/plain »>

    export OPENAI_API_KEY="<Clé API OpenAI>"

    Remplacez <Clé API OpenAI> par votre clé.

  • Lancer Jupyter.
    Texte brut

    jupyter notebook

Nous utiliserons les notebooks Jupyter depuis GitHub. Ces notebooks sont configurés pour utiliser OpenAI et Ollama. Pour Ollama, nous utiliserons l’un des LLMs répertoriés avec Support des outils. Nous allons tester les quatre requêtes suivantes.

Première requête

SQL

SQL

 

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

Langage naturel

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?"

Résultats

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

Deuxième requête

SQL

SQL

 

SELECT COUNT(*)
FROM tick;

Langage naturel

Plain Text

 

"How many rows are in the tick table?"

Résultats

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.

Troisième requête

SQL

SQL

 

-- Étape 1 : Obtenir le dernier prix pour chaque symbole
WITH latest_prices AS (
    SELECT symbol, price
    FROM tick t1
    WHERE ts = (
        SELECT MAX(ts)
        FROM tick t2
        WHERE t2.symbol = t1.symbol
    )
)

-- Étape 2 : Calculer la valeur totale du portefeuille
SELECT SUM(p.shares_held * lp.price) AS total_portfolio_value
FROM portfolio p, latest_prices lp
WHERE p.symbol = lp.symbol;

Langage naturel

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."

Résultats

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.

Quatrième requête

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;

Langage naturel

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."

Résultats

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

Résumé

En analysant les résultats, nous constatons que SQL et OpenAI produisent des sorties cohérentes pour les quatre requêtes. Cependant, Ollama présente des problèmes évidents. Un fil de discussion sur GitHub souligne que bien qu’un modèle LLM devrait prendre en charge l’appel d’outils, cette fonctionnalité n’est pas nativement disponible dans Ollama.

Si vous parvenez à faire fonctionner cette fonctionnalité LangChain avec Ollama dans l’un des LLM pris en charge, veuillez m’envoyer un message, et je mettrai à jour l’article et reconnaîtrai votre aide.

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