João Victor Winderfeld Bussolotto
Add application file
678db8f
import os
import pandas as pd
import gradio as gr
from langchain_experimental.agents.agent_toolkits import create_pandas_dataframe_agent
from langchain.chat_models import init_chat_model
from langchain_core.rate_limiters import InMemoryRateLimiter
from dotenv import load_dotenv
load_dotenv()
rate_limiter = InMemoryRateLimiter(
requests_per_second=0.5,
check_every_n_seconds=0.1,
max_bucket_size=10,
)
llm = init_chat_model(
"llama-3.3-70b-versatile",
model_provider="groq",
rate_limiter=rate_limiter,
api_key=os.getenv("GROQ_API_KEY"),
)
# Carregar datasets
print("Carregando dados...")
df_funcionarios = pd.read_csv("CadastroFuncionarios.csv", sep=";", decimal=",")
df_clientes = pd.read_csv("CadastroClientes.csv", sep=";")
df_servicos = pd.read_excel("BaseServiçosPrestados.xlsx")
df_integrado = df_servicos.merge(df_clientes, on="ID Cliente", how="left")
df_integrado = df_integrado.merge(
df_funcionarios[["ID Funcionário", "Salario Base", "Cargo", "Area"]],
on="ID Funcionário",
how="left",
)
df_integrado["Receita Estimada"] = (
df_integrado["Valor Contrato Mensal"]
* df_integrado["Tempo Total de Contrato (Meses)"]
)
print(
f"✓ {len(df_funcionarios)} funcionários, {len(df_clientes)} clientes, {len(df_servicos)} serviços"
)
# Construir descrição dinâmica dos DataFrames
prefix_prompt = f"""Você é um agente de análise de dados com acesso a 4 DataFrames pandas já carregados:
df1: CadastroFuncionarios ({len(df_funcionarios)} registros)
Colunas: {', '.join(df_funcionarios.columns.tolist())}
df2: CadastroClientes ({len(df_clientes)} registros)
Colunas: {', '.join(df_clientes.columns.tolist())}
df3: BaseServiçosPrestados ({len(df_servicos)} registros)
Colunas: {', '.join(df_servicos.columns.tolist())}
df4: df_integrado ({len(df_integrado)} registros) - Merge completo dos 3 DataFrames
Colunas: {', '.join(df_integrado.columns.tolist())}
REGRAS OBRIGATÓRIAS:
1. SEMPRE use python_repl_ast para consultar os DataFrames
2. NUNCA responda sem executar código Python
3. NUNCA invente ou crie dados sintéticos
4. Use df1, df2, df3, df4 para acessar os dados
5. Execute código pandas para cada pergunta"""
# Criar agente com TODOS os dataframes
agent = create_pandas_dataframe_agent(
llm,
[df_funcionarios, df_clientes, df_servicos, df_integrado],
verbose=False,
agent_type="tool-calling",
allow_dangerous_code=True,
return_intermediate_steps=True,
prefix=prefix_prompt,
suffix="""Lembre-se: SEMPRE execute código Python usando a ferramenta python_repl_ast.
NUNCA responda sem consultar os dados reais nos DataFrames.""",
include_df_in_prompt=False,
number_of_head_rows=2,
)
def consultar(pergunta, historico):
"""Processa pergunta e retorna resposta com passos intermediários."""
try:
resultado = agent.invoke({"input": pergunta})
# Construir resposta com tool calls
resposta_completa = ""
# Mostrar passos intermediários (tool calls)
if "intermediate_steps" in resultado:
for i, (action, observation) in enumerate(
resultado["intermediate_steps"], 1
):
tool_name = action.tool if hasattr(action, "tool") else "Tool"
tool_input = action.tool_input if hasattr(action, "tool_input") else ""
resposta_completa += (
f"**🔧 Passo {i}: {tool_name}**\n```\n{tool_input}\n```\n\n"
)
# Adicionar resposta final
output = resultado.get("output", str(resultado))
resposta_completa += f"**✅ Resposta:**\n{output}"
return resposta_completa
except Exception as e:
return f"❌ Erro: {str(e)}"
demo = gr.ChatInterface(
fn=consultar,
title="🤖 Agente de Consultas Analíticas",
description="""Faça perguntas sobre funcionários, clientes e serviços. O agente mostrará os passos de raciocínio.
**Desenvolvido para:** Estatística Aplicada - Pós-graduação em Inteligência Artificial Aplicada
**Autor:** João Victor Winderfeld Bussolotto""",
examples=[
"Quantos funcionários temos por cargo?",
"Qual o salário médio por área?",
"Top 5 clientes com maior contrato mensal",
"Receita total estimada de todos os serviços",
"Qual cargo tem o maior salário médio?",
"Quantos clientes tem contrato acima de R$ 5000?",
"Liste os 3 funcionários com maior salário",
"Qual área tem mais funcionários?",
],
)
demo.launch(share=False)