danielspba's picture
Update app.py
91c1358 verified
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import ConversationChain # Keep using this for now, despite deprecation
from langchain.memory import ConversationBufferMemory # Keep using this for now
import gradio as gr
import traceback
# Carrega a chave da API
load_dotenv()
api_key = os.getenv("OPENROUTER_API_KEY")
if not api_key:
raise ValueError("❌ Variável OPENROUTER_API_KEY não encontrada.")
# Define variáveis do ambiente
os.environ["OPENAI_API_KEY"] = api_key
os.environ["OPENAI_API_BASE"] = "https://openrouter.ai/api/v1"
# Instancia o modelo
llm = ChatOpenAI(
model="mistralai/mistral-7b-instruct:free",
temperature=0.5
)
# Lista de Tutores/Matérias
subjects = [
"Python", "Java", "Ruby", "Golang", "C++", "C#", "Rust",
"SQL", "Tableau", "Power BI", "Excel", "Looker", "Solidity"
]
# --- Template Modificado ---
# Agora SÓ espera 'history' e 'input'. O contexto da matéria será parte do 'input'.
template_string = """Você é um assistente virtual e tutor especialista. A especialidade desejada pelo aluno está indicada claramente no início da pergunta dele (procure por 'Especialidade Foco:').
Ajude os alunos com dúvidas sobre a especialidade mencionada na pergunta atual, sempre de forma clara, objetiva e com exemplos didáticos.
Adapte a profundidade da sua resposta ao nível aparente da pergunta. Se a pergunta for muito vaga, peça mais detalhes.
Concentre-se estritamente na especialidade indicada na pergunta atual, a menos que o aluno peça explicitamente para comparar com outra tecnologia.
Histórico da conversa:
{history}
Aluno: {input}
Resposta:"""
# Prompt agora só precisa de 'history' e 'input'
template = PromptTemplate(
input_variables=["history", "input"], # APENAS history e input
template=template_string
)
# --- Memória da Conversa ---
# Aviso de Depreciação: ConversationBufferMemory está sendo substituída.
# Para agora, ela funciona, mas considere migrar para RunnableWithMessageHistory no futuro.
memoria = ConversationBufferMemory(return_messages=True) # memory_key='history' é o padrão
# --- Criação da Chain ---
# Aviso de Depreciação: ConversationChain está sendo substituída.
# Para agora, ela funciona com o prompt ajustado.
chat_chain = ConversationChain(
llm=llm,
memory=memoria,
prompt=template, # Passa o prompt que agora só espera 'history' e 'input'
input_key='input', # Confirma que a chave de entrada principal é 'input' (padrão)
verbose=False
)
# --- Função para Responder com Contexto Formatado ---
def responder(subject, user_message):
"""
Formata a entrada e gera a resposta do LLM.
"""
if not subject:
return "⚠️ Por favor, selecione uma matéria primeiro."
if not user_message or not user_message.strip(): # Verifica se a mensagem não está vazia ou só espaços
return "⚠️ Por favor, digite sua dúvida."
# **Importante:** Formata a entrada para incluir o contexto da matéria
# É ESSENCIAL que o LLM veja essa informação claramente no início do input.
formatted_input = f"**Especialidade Foco:** {subject}\n\n**Dúvida do Aluno:** {user_message}"
try:
# Passa a string formatada como a única entrada 'input' para a chain
response = chat_chain.run(formatted_input)
return response
except Exception as e:
print(f"❌ Erro ao processar a solicitação:\n{traceback.format_exc()}")
return f"❌ Desculpe, ocorreu um erro ao processar sua solicitação. Detalhes: {str(e)}"
# --- Interface Gradio (sem alterações na estrutura) ---
with gr.Blocks(theme=gr.themes.Soft()) as app: # Adicionando um tema suave
gr.Markdown("# Tutor Poliglota com IA 🤖🎓")
gr.Markdown("Selecione a matéria e tire suas dúvidas com um assistente que lembra da conversa.")
with gr.Row():
subject_selector = gr.Dropdown(
choices=subjects,
label="Selecione a Matéria",
info="Escolha sobre qual linguagem ou ferramenta você quer perguntar."
)
with gr.Row():
input_textbox = gr.Textbox(
placeholder="Ex: Como declarar uma variável em Java?",
label="Sua Dúvida",
lines=3,
show_copy_button=True
)
with gr.Row():
submit_button = gr.Button("Perguntar ao Tutor", variant="primary") # Botão com destaque
with gr.Row():
output_textbox = gr.Textbox(
label="Resposta do Tutor",
lines=10, # Mais espaço para resposta
show_copy_button=True
)
clear_button = gr.ClearButton(
components=[input_textbox, output_textbox, subject_selector], # Limpa também o dropdown
value="Limpar Campos e Memória"
)
submit_button.click(
fn=responder,
inputs=[subject_selector, input_textbox],
outputs=output_textbox
)
def clear_memory_and_interface():
try:
memoria.clear() # Limpa a memória da conversa
print("Memória da conversa limpa.")
except Exception as e:
print(f"Erro ao limpar a memória: {e}")
# Retorna valor padrão para dropdown (None) e vazio para textbox
return [None, "", ""]
# Atualiza a ação do clear_button para retornar valores para todos os componentes
clear_button.click(fn=clear_memory_and_interface, outputs=[subject_selector, input_textbox, output_textbox])
# Lança a aplicação
app.launch(share=True, debug=True) # Adiciona debug=True para mais informações no console