Descargo de responsabilidad
Los datos bursátiles utilizados en este artículo son completamente ficticios. Son únicamente para fines de demostración. Por favor, no utilice estos datos para tomar decisiones financieras.
En un artículo anterior, vimos los beneficios de usar Ollama localmente para una aplicación RAG. En este artículo, ampliaremos nuestra evaluación de Ollama probando consultas en lenguaje natural (NL) contra un sistema de base de datos, utilizando el SQLDatabaseToolkit
de LangChain. SQL servirá como el sistema de referencia para la comparación mientras exploramos la calidad de los resultados proporcionados por OpenAI y Ollama.
Los archivos de notebook utilizados en este artículo están disponibles en GitHub.
Introducción
El SQLDatabaseToolkit
de LangChain es una herramienta poderosa diseñada para integrar capacidades de procesamiento de NL con sistemas de bases de datos relacionales. Permite a los usuarios consultar bases de datos utilizando entradas de NL, empleando las capacidades de grandes modelos de lenguaje (LLMs) para generar consultas SQL de manera dinámica. Esto lo hace especialmente útil para aplicaciones donde usuarios no técnicos o sistemas automatizados necesitan interactuar con datos estructurados.
Varios LLMs son bien soportados por LangChain. LangChain también proporciona soporte para Ollama. En este artículo, evaluaremos qué tan bien se integra LangChain con Ollama y la viabilidad de usar el SQLDatabaseToolkit
en una configuración local.
Crear una cuenta en SingleStore Cloud
Un artículo anterior mostró los pasos para crear una cuenta gratuita en SingleStore Cloud. Usaremos el Nivel Compartido Gratuito.
Seleccionar el Espacio de Trabajo de Inicio > Conectar > Cliente CLI nos dará los detalles que necesitaremos más tarde, como nombre de usuario
, contraseña
, host
, puerto
y base de datos
.
Crear Tablas de Base de Datos
Para nuestro entorno de prueba, usaremos SingleStore ejecutándose en la nube como nuestro sistema de base de datos objetivo, y nos conectaremos de forma segura a este entorno utilizando cuadernos Jupyter ejecutándose en un sistema local.
Desde el panel de navegación izquierdo en el portal de la nube de SingleStore, seleccionaremos DESARROLLAR > Estudio de Datos > Abrir Editor SQL. Crearemos tres tablas, de la siguiente manera:
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)
);
Cargaremos la tabla portafolio
con los siguientes datos ficticios:
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);
Para la tabla sentimiento_de_acciones
, descargaremos el archivo stock_sentiment.sql.zip y lo descomprimiremos. Cargaremos los datos en la tabla utilizando un cliente MySQL, de la siguiente manera:
mysql -u "<username>" -p"<password>" -h "<host>" -P <port> -D <database> < stock_sentiment.sql
Utilizaremos los valores para <nombre de usuario>
, <contraseña>
, <host>
, <puerto>
y <base de datos>
que guardamos anteriormente.
Finalmente, para la tabla tick
, crearemos 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);
Ajustaremos para obtener los datos más tempranos:
ALTER PIPELINE tick SET OFFSETS EARLIEST;
Y probaremos el pipeline:
TEST PIPELINE tick LIMIT 1;
Ejemplo de salida:
+--------+---------------------+--------+--------+--------+--------+--------+
| symbol | ts | open | high | low | price | volume |
+--------+---------------------+--------+--------+--------+--------+--------+
| MMM | 2025-01-23 21:40:32 | 178.34 | 178.43 | 178.17 | 178.24 | 38299 |
+--------+---------------------+--------+--------+--------+--------+--------+
Y luego comenzaremos el pipeline:
START PIPELINE tick;
Después de unos minutos, verificaremos la cantidad de datos cargados hasta ahora:
SELECT COUNT(*)
FROM tick;
Entorno de prueba local
De un artículo anterior, seguiremos los mismos pasos para configurar nuestro entorno de prueba local como se describe en estas secciones:
- Introducción. Utilice una máquina virtual o
venv
. - Crear una cuenta de SingleStore Cloud. Este paso se completó arriba.
- Crear una base de datos. El nivel gratuito compartido ya proporciona una base de datos y solo necesitamos anotar el nombre de la base de datos.
- Instalar Jupyter.
Texto plano
pip install notebook
- Instalar Ollama.
Texto sin formato
curl -fsSL https://ollama.com/install.sh | sh
- Variables de entorno.
Texto sin formato:
@ : / “” data-lang=”text/plain”> export SINGLESTOREDB_URL="<username>:<password>@<host>:<port>/<database>"
Reemplace
<username>
,<password>
,<host>
,<port>
y<database>
con los valores para su entorno.Texto sin formato“” data-lang=”text/plain”>export OPENAI_API_KEY="<OpenAI API Key>"
Reemplace
<OpenAI API Key>
con su clave. - Iniciar Jupyter.
Texto sin formato
jupyter notebook
Vamos a utilizar los cuadernos de Jupyter desde GitHub. Estos cuadernos están configurados para usar OpenAI y Ollama. Para Ollama, utilizaremos uno de los LLMs listados con Soporte de herramientas. Probaremos las siguientes cuatro consultas.
Primera Consulta
SQL
SELECT symbol, (MAX(high) - MIN(low)) AS volatility
FROM tick
GROUP BY symbol
ORDER BY volatility ASC
LIMIT 1;
Lenguaje Natural
"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?"
Resultados
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
Segunda Consulta
SQL
SELECT COUNT(*)
FROM tick;
Lenguaje Natural
"How many rows are in the tick table?"
Resultados
SQL
+----------+
| COUNT(*) |
+----------+
| 22367162 |
+----------+
OpenAI
There are 22,367,162 rows in the tick table.
Ollama
The "tick" table has 3 rows.
Tercera Consulta
SQL
-- Paso 1: Obtener el último precio de cada símbolo
WITH latest_prices AS (
SELECT symbol, price
FROM tick t1
WHERE ts = (
SELECT MAX(ts)
FROM tick t2
WHERE t2.symbol = t1.symbol
)
)
-- Paso 2: Calcular el valor total de la cartera
SELECT SUM(p.shares_held * lp.price) AS total_portfolio_value
FROM portfolio p, latest_prices lp
WHERE p.symbol = lp.symbol;
Lenguaje Natural
"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."
Resultados
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.
Cuarta Consulta
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;
Lenguaje Natural
"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."
Resultados
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
Resumen
Al analizar los resultados, vemos que SQL y OpenAI producen salidas consistentes en las cuatro consultas. Sin embargo, Ollama presenta problemas evidentes. Un hilo de discusión en GitHub destaca que mientras un modelo LLM debería admitir la llamada de herramientas, esta funcionalidad no está disponible nativamente en Ollama.
Si logras que esta funcionalidad de LangChain funcione con Ollama en uno de los LLM admitidos, por favor envíame un mensaje, y actualizaré el artículo y reconoceré tu ayuda.
Source:
https://dzone.com/articles/openai-vs-ollama-langchain-sqldatabasetoolkit