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:
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:
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:
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:
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:
ALTER PIPELINE tick SET OFFSETS EARLIEST;
Et tester le pipeline:
TEST PIPELINE tick LIMIT 1;
Exemple de sortie:
+--------+---------------------+--------+--------+--------+--------+--------+
| 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:
START PIPELINE tick;
Après quelques minutes, nous vérifierons la quantité de données chargées jusqu’à présent:
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
SELECT symbol, (MAX(high) - MIN(low)) AS volatility
FROM tick
GROUP BY symbol
ORDER BY volatility ASC
LIMIT 1;
Langage naturel
"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
+--------+------------+
| symbol | volatility |
+--------+------------+
| FTR | 0.55 |
+--------+------------+
OpenAI
The stock symbol with the least volatility is FTR, with a volatility of 0.55.
Ollama
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
SELECT COUNT(*)
FROM tick;
Langage naturel
"How many rows are in the tick table?"
Résultats
SQL
+----------+
| COUNT(*) |
+----------+
| 22367162 |
+----------+
OpenAI
There are 22,367,162 rows in the tick table.
Ollama
The "tick" table has 3 rows.
Troisième requête
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
"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
+-----------------------+
| total_portfolio_value |
+-----------------------+
| 44540.60 |
+-----------------------+
OpenAI
$44,540.60
Ollama
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
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
"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
+---------------------+-------------------------+--------------------+
| sentiment_date | most_positive_sentiment | current_best_price |
+---------------------+-------------------------+--------------------+
| 2020-05-28 00:00:00 | 0.331509 | 116.27 |
+---------------------+-------------------------+--------------------+
OpenAI
On 2020-05-28, the most positive sentiment for AAPL was 0.331509, and the current best price for AAPL is 116.27.
Ollama
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