Spaces:
Sleeping
Sleeping
File size: 5,662 Bytes
f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 f241c48 91c1358 |
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 |
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 |