File size: 7,503 Bytes
23bfddb 6a4f5a1 23bfddb 6a4f5a1 23bfddb 7e379df 23bfddb 987d067 23bfddb 6a4f5a1 987d067 6a4f5a1 23bfddb 6a4f5a1 23bfddb b156340 23bfddb 1c392ee 23bfddb f5e8688 23bfddb 6a4f5a1 23bfddb 6a4f5a1 23bfddb 6a4f5a1 f5fb10b 6a4f5a1 f5fb10b 6a4f5a1 23bfddb 6a4f5a1 23bfddb 6a4f5a1 23bfddb 85465d4 23bfddb 6a4f5a1 23bfddb 6a4f5a1 85465d4 6a4f5a1 23bfddb 6a4f5a1 23bfddb 6a4f5a1 23bfddb 6a4f5a1 23bfddb 7e379df 6a4f5a1 23bfddb 6a4f5a1 23bfddb 6a4f5a1 23bfddb b55f3b5 6a4f5a1 23bfddb 6a4f5a1 23bfddb 6a4f5a1 e95a2ba 6a4f5a1 23bfddb 6a4f5a1 23bfddb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
import os
import time
import json
import pandas as pd
import numpy as np
from sqlalchemy import create_engine
from langchain_openai import ChatOpenAI
from langchain_community.agent_toolkits import create_sql_agent
from langchain_community.utilities import SQLDatabase
from huggingface_hub import InferenceClient
import gradio as gr
from dotenv import load_dotenv
load_dotenv()
CSV_FILE_PATH = "tabela_tiago_formated.csv"
SQL_DB_PATH = "data.db"
HUGGINGFACE_API_KEY = os.getenv("HUGGINGFACE_API_KEY")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
LLAMA_MODEL = "meta-llama/Llama-3.3-70B-Instruct"
LLAMA_MODEL_FINAL = "Qwen/QwQ-32B"
hf_client = InferenceClient(
provider="sambanova",
api_key=HUGGINGFACE_API_KEY,
)
os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY
query_cache = {}
# Criar banco de dados SQL a partir do JSON
def create_or_load_sql_database(csv_path, sql_db_path):
if os.path.exists(sql_db_path):
print("Banco de dados SQL já existe. Carregando...")
return create_engine(f"sqlite:///{sql_db_path}")
else:
print("Banco de dados SQL não encontrado. Criando..")
engine = create_engine(f"sqlite:///{sql_db_path}")
df = pd.read_csv(csv_path, sep=";", on_bad_lines="skip")
print(f"CSV carregado: {len(df)} linhas, {len(df.columns)} colunas")
df.to_sql("tabela_tiago_formated", engine, index=False, if_exists="replace")
print("Banco de dados SQL criado com sucesso!")
return engine
engine = create_or_load_sql_database(CSV_FILE_PATH, SQL_DB_PATH)
db = SQLDatabase(engine=engine)
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
sql_agent = create_sql_agent(llm, db=db, agent_type="openai-tools", verbose=True, max_iterations=20, return_intermediate_steps=True)
def generate_initial_context(db_sample):
return (
f"Você é um assistente que gera queries SQL objetivas e eficientes. Sempre inclua LIMIT 15 nas queries. Aqui está o banco de dados:\n\n"
###f"Colunas: {', '.join(db_sample.columns)}\n"
f"Exemplos do banco de dados:\n{db_sample.head().to_string(index=False)}\n\n"
"\n***IMPORTANTE***: Detecte automaticamente o idioma da pergunta do usuário e responda sempre no mesmo idioma.\n"
"\nRetorne apenas a pergunta e a query SQL mais eficiente para entregar ao agent SQL do LangChain para gerar uma resposta para a pergunta. O formato deve ser:\n"
"\nPergunta: <pergunta do usuário>\n"
"\nOpção de Query SQL:\n<query SQL>"
"\nIdioma: <idioma>"
)
def is_greeting(user_query):
greetings = ["olá", "oi", "bom dia", "boa tarde", "boa noite", "oi, tudo bem?"]
return user_query.lower().strip() in greetings
def query_with_llama(user_query, db_sample, chat_history):
initial_context = generate_initial_context(db_sample)
#formatted_history = "" # Não inclui histórico temporariamente
formatted_history = "\n".join(
[f"{msg['role'].capitalize()}: {msg['content']}" for msg in chat_history[-1:]]
)
full_prompt = f"{initial_context}\n\nHistórico recente:\n{formatted_history}\n\nPergunta do usuário:\n{user_query}"
print("------- Modelo Llama 3.3: Gerando query SQL -------")
print(f"[DEBUG] Contexto enviado ao Llama:\n{full_prompt}\n")
start_time = time.time()
try:
response = hf_client.chat.completions.create(
model=LLAMA_MODEL,
messages=[{"role": "system", "content": full_prompt}],
max_tokens=800,
stream=False
)
llama_response = response["choices"][0]["message"]["content"]
end_time = time.time()
print(f"[DEBUG] Resposta do Llama: {llama_response.strip()}\n[Tempo de execução: {end_time - start_time:.2f}s]\n")
chat_history.append({"role": "assistant", "content": llama_response})
return llama_response.strip(), chat_history
except Exception as e:
print(f"[ERRO] Falha ao interagir com o Llama: {e}")
return None, chat_history
def refine_response_with_llama(user_query, sql_response):
prompt = f"""
Você é um assistente especializado em consolidar e explicar as informações. Abaixo estão as entradas:\n
Pergunta:
{user_query}
Resposta do Agente:
{sql_response}\n
"""
print("------- Modelo Final: Refinando resposta -------")
print(f"[DEBUG] Contexto enviado ao Llama Final:\n{prompt}\n")
start_time = time.time()
try:
response = hf_client.chat.completions.create(
model=LLAMA_MODEL_FINAL,
messages=[{"role": "system", "content": prompt}],
max_tokens=8000
)
final_response = response["choices"][0]["message"]["content"]
end_time = time.time()
print(f"[DEBUG] Resposta do Llama Final: {final_response.strip()}\n[Tempo de execução: {end_time - start_time:.2f}s]\n")
return final_response.strip()
except Exception as e:
print(f"[ERRO] Falha ao interagir com o Llama Final: {e}")
return "Erro ao consolidar a resposta. Por favor, tente novamente."
def query_sql_agent(user_query, chat_history):
try:
if user_query in query_cache:
print("[CACHE] Retornando resposta do cache para a consulta: {user_query}")
return query_cache[user_query], chat_history
if is_greeting(user_query):
greeting_response = "Olá! Estou aqui para ajudar com suas consultas. Pergunte algo relacionado aos dados carregados no agente!"
return greeting_response, chat_history
column_data = pd.read_sql_query("SELECT * FROM tabela_tiago_formated LIMIT 10", engine)
llama_instruction, chat_history = query_with_llama(user_query, column_data, chat_history)
if not llama_instruction:
return "Erro: O modelo Llama não conseguiu gerar uma instrução válida.", chat_history
print("------- Agent SQL: Executando query -------")
print(f"[DEBUG] Instrução gerada pelo Llama:\n{llama_instruction}\n")
start_time = time.time()
response = sql_agent.invoke({"input": llama_instruction})
sql_response = response.get("output", "Erro ao obter a resposta do agente...")
end_time = time.time()
print(f"[DEBUG] Resposta do Agent SQL: {sql_response}\n[Tempo de execução: {end_time - start_time:.2f}s]\n")
final_response = refine_response_with_llama(user_query, sql_response)
query_cache[user_query] = final_response # Armazenar no cache
return final_response, chat_history
except Exception as e:
return f"Erro ao consultar o agente SQL: {e}", chat_history
def gradio_interface():
chat_history = []
def respond(user_input):
nonlocal chat_history
response, chat_history = query_sql_agent(user_input, chat_history)
chat_history.append({"role": "user", "content": user_input})
chat_history.append({"role": "assistant", "content": response})
return [{"role": "user", "content": user_input}, {"role": "assistant", "content": response}]
with gr.Blocks() as demo:
gr.Markdown("# Agent")
chatbot = gr.Chatbot(label="Result Agent", type="messages")
user_input = gr.Textbox(label="Digite sua pergunta")
submit_button = gr.Button("Enviar")
submit_button.click(respond, inputs=user_input, outputs=chatbot)
return demo
if __name__ == "__main__":
demo = gradio_interface()
demo.launch(share=False) |