File size: 4,009 Bytes
e679b32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# chatbot_controller.py
# Duarte Grilo - 2201320 - Projeto Informático

import time
import re
from models.velvet_runner import generate_response, salvar_completo_em_arquivo  # Geração e gravação
from models.rag_engine import retrieve_context                         # Busca com RAG
from models.tradutor_local import traduzir                             # Tradução PT/EN


# Conta tokens de um texto (simples split por espaço)
def contar_tokens(texto: str) -> int:
    return len(texto.split())


# Valida se a resposta contém palavras-chave do contexto
def validar_resposta_por_keywords(resposta: str, contexto: str, min_match: int = 3) -> tuple[bool, int]:
    palavras_contexto = re.findall(r'\b\w{4,}\b', contexto.lower())
    palavras_resposta = re.findall(r'\b\w{4,}\b', resposta.lower())
    comuns = set(palavras_contexto).intersection(set(palavras_resposta))
    return len(comuns) >= min_match, len(comuns)


# Função principal que processa cada pergunta
def process_user_input(question: str) -> str:
    print("\n🔍 [DEBUG] Entrou em process_user_input()")
    print(f"🔍 [DEBUG] Pergunta recebida: {question}")

    # Obtém contexto, scores e dados brutos com debug incluído
    context_pt, scores, context_en, context_norm, debug_ctx = retrieve_context(
        question, return_scores=True, return_raw=True
    )

    print(f"\n📚 [DEBUG] Contexto traduzido (PT, início): {context_pt[:120]}...")

    # Traduz a pergunta para inglês
    question_en = traduzir(question, origem='pt', destino='en')

    # Cria prompt final a ser enviado ao Velvet
    prompt_en = f"Context:\n{debug_ctx['context_en']}\n\nQuestion: {question_en}\nAnswer:"
    print(f"\n🧠 [DEBUG] Prompt final (EN) enviado à Velvet:\n{prompt_en}\n")

    # Mede tempo de geração
    inicio = time.time()
    resposta_en = generate_response(prompt_en)
    duracao = time.time() - inicio

    print(f"\n💬 [DEBUG] Resposta bruta (EN) gerada pelo Velvet:\n{resposta_en.strip()}")

    # Tenta traduzir de volta para português
    try:
        resposta_final = traduzir(resposta_en.strip(), origem="en", destino="pt")
    except Exception as e:
        print("⚠️ Erro na tradução da resposta:", e)
        resposta_final = resposta_en.strip()

    # Validação da resposta com palavras-chave
    valido, num_keywords = validar_resposta_por_keywords(resposta_final, context_pt)
    if not valido or len(resposta_final) < 10:
        resposta_final = "⚠️ Não foi possível gerar uma resposta adequada com base no contexto."

    # Exibe métricas no terminal
    print("\n📊 [MÉTRICAS DE RESPOSTA]")
    print(f"🔸 Prompt Tokens:        {contar_tokens(prompt_en)}")
    print(f"🔸 Resposta Tokens:      {contar_tokens(resposta_en)}")
    print(f"🔸 Tempo de geração:     {duracao:.2f}s")
    print(f"🔸 Palavras-chave comuns: {num_keywords}")
    print(f"🔸 Validação por keywords: {'✅' if valido else '❌'}")

    # Mostra documentos usados com suas pontuações
    print("\n🔸 Similaridade RAG:")
    for i, (trecho, score) in enumerate(scores, start=1):
        preview = trecho.page_content[:80].replace("\n", " ")
        print(f"    Doc#{i}: score={score:.2f}{preview}...")

    # Guarda tudo no histórico local com estrutura completa
    salvar_completo_em_arquivo({
        "pergunta_original": question,
        "query_en": question_en,
        "context_en": context_en,
        "context_normalizado": context_norm,
        "context_pt": context_pt,
        "prompt_enviado": prompt_en,
        "resposta_en": resposta_en.strip(),
        "resposta_pt": resposta_final,
        "scores": [{"doc": trecho.page_content, "score": float(score)} for trecho, score in scores],
        "tempo_execucao": round(duracao, 2),
        "validacao_keywords": valido
    })

    print(f"\n✅ [DEBUG] Resposta final traduzida (PT):\n{resposta_final}\n")
    return resposta_final