Aviso Legal
Os dados de ações usados neste artigo são totalmente fictícios. São apenas para fins de demonstração. Por favor, não utilize esses dados para tomar decisões financeiras.
No artigo anterior, vimos os benefícios de usar o Ollama localmente para uma aplicação RAG. Neste artigo, vamos ampliar nossa avaliação do Ollama testando consultas em linguagem natural (NL) contra um sistema de banco de dados, utilizando o SQLDatabaseToolkit
do LangChain. O SQL servirá como o sistema de referência para comparação enquanto exploramos a qualidade dos resultados fornecidos pela OpenAI e pelo Ollama.
Os arquivos de notebook usados neste artigo estão disponíveis no GitHub.
Introdução
O SQLDatabaseToolkit
do LangChain é uma ferramenta poderosa projetada para integrar capacidades de processamento de NL com sistemas de banco de dados relacionais. Ele permite que os usuários consultem bancos de dados usando entradas em NL, aproveitando as capacidades de grandes modelos de linguagem (LLMs) para gerar consultas SQL dinamicamente. Isso o torna especialmente útil para aplicações onde usuários não técnicos ou sistemas automatizados precisam interagir com dados estruturados.
Vários LLMs são bem suportados pelo LangChain. O LangChain também oferece suporte ao Ollama. Neste artigo, vamos avaliar quão bem o LangChain se integra ao Ollama e a viabilidade de usar o SQLDatabaseToolkit
em uma configuração local.
Crie uma Conta na Nuvem SingleStore
Um artigo anterior mostrou os passos para criar uma conta gratuita na SingleStore Cloud. Usaremos o Nível Compartilhado Gratuito.
Selecionando o Espaço de Trabalho Inicial > Conectar > Cliente CLI, teremos os detalhes que precisamos mais tarde, como nome de usuário
, senha
, host
, porta
e banco de dados
.
Criar Tabelas de Banco de Dados
Para nosso ambiente de teste, usaremos o SingleStore rodando na nuvem como nosso sistema de banco de dados alvo, e nos conectaremos de forma segura a esse ambiente usando notebooks Jupyter rodando em um sistema local.
Do painel de navegação à esquerda no portal da nuvem SingleStore, selecionaremos DESENVOLVER > Data Studio > Abrir Editor SQL. Criaremos três tabelas, conforme segue:
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)
);
Carregaremos a tabela portfolio
com os seguintes dados fictícios:
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 a tabela stock_sentiment
, baixaremos o arquivo stock_sentiment.sql.zip e o descompactaremos. Carregaremos os dados na tabela usando um cliente MySQL, conforme segue:
mysql -u "<username>" -p"<password>" -h "<host>" -P <port> -D <database> < stock_sentiment.sql
Usaremos os valores de <nome de usuário>
, <senha>
, <host>
, <porta>
e <banco de dados>
que salvamos anteriormente.
Finalmente, para a tabela tick
, criaremos um 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);
Vamos ajustar para obter os dados mais recentes:
ALTER PIPELINE tick SET OFFSETS EARLIEST;
E testar o pipeline:
TEST PIPELINE tick LIMIT 1;
Exemplo de saída:
+--------+---------------------+--------+--------+--------+--------+--------+
| symbol | ts | open | high | low | price | volume |
+--------+---------------------+--------+--------+--------+--------+--------+
| MMM | 2025-01-23 21:40:32 | 178.34 | 178.43 | 178.17 | 178.24 | 38299 |
+--------+---------------------+--------+--------+--------+--------+--------+
E então iniciaremos o pipeline:
START PIPELINE tick;
Após alguns minutos, verificaremos a quantidade de dados carregados até agora:
SELECT COUNT(*)
FROM tick;
Ambiente de Teste Local
A partir de um artigo anterior, seguiremos os mesmos passos para configurar nosso ambiente de teste local conforme descrito nestas seções:
- Introdução. Use uma Máquina Virtual ou
venv
. - Criar uma conta na SingleStore Cloud. Esta etapa foi concluída acima.
- Criar um banco de dados. A Camada Compartilhada Gratuita já fornece um banco de dados e só precisamos anotar o nome do banco de dados.
- Instalar o Jupyter.
Texto Simples
pip install notebook
- Instalar Ollama.
Texto Simples
curl -fsSL https://ollama.com/install.sh | sh
- Variáveis de ambiente.
Texto simples:
@ : / “” data-lang=”text/plain”> export SINGLESTOREDB_URL="<usuário>:<senha>@<host>:<porta>/<banco de dados>"
Substitua
<usuário>
,<senha>
,<host>
,<porta>
e<banco de dados>
pelos valores do seu ambiente.Texto simples“” data-lang=”text/plain”>export OPENAI_API_KEY="<Chave da API OpenAI>"
Substitua
<Chave da API OpenAI>
pela sua chave. - Lançar Jupyter.
Texto Simples
jupyter notebook
Usaremos os notebooks Jupyter do GitHub. Esses notebooks estão configurados para usar OpenAI e Ollama. Para Ollama, usaremos um dos LLMs listados com suporte a ferramentas. Vamos testar as seguintes quatro consultas.
Primeira Consulta
SQL
SELECT symbol, (MAX(high) - MIN(low)) AS volatility
FROM tick
GROUP BY symbol
ORDER BY volatility ASC
LIMIT 1;
Idioma 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;
Idioma 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.
Terceira Consulta
SQL
-- Passo 1: Obter o preço mais recente para 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
)
)
-- Passo 2: Calcular o valor total do portfólio
SELECT SUM(p.shares_held * lp.price) AS total_portfolio_value
FROM portfolio p, latest_prices lp
WHERE p.symbol = lp.symbol;
Idioma 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.
Quarta 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;
Idioma 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
Resumo
Ao analisar os resultados, vemos que SQL e OpenAI produzem saídas consistentes em todas as quatro consultas. No entanto, Ollama apresenta problemas claros. Um tópico de discussão no GitHub destaca que, embora um modelo LLM deva suportar chamadas de ferramentas, essa funcionalidade não está disponível nativamente no Ollama.
Se você conseguir fazer essa funcionalidade do LangChain funcionar com Ollama em um dos LLMs suportados, por favor, me envie uma mensagem, e eu atualizarei o artigo e reconhecerei sua ajuda.
Source:
https://dzone.com/articles/openai-vs-ollama-langchain-sqldatabasetoolkit