Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -14,159 +14,151 @@ class AssistenteBiblico:
|
|
14 |
self.device = "cuda" if torch.cuda.is_available() else "cpu"
|
15 |
logger.info(f"Usando dispositivo: {self.device}")
|
16 |
|
17 |
-
# Carregando modelo e tokenizer em português
|
18 |
model_name = "neuralmind/bert-base-portuguese-cased"
|
19 |
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
|
20 |
self.model = AutoModel.from_pretrained(model_name).to(self.device)
|
21 |
-
|
22 |
-
# Usando modelo de sentimentos em português
|
23 |
self.analisador_sentimento = pipeline("sentiment-analysis",
|
24 |
model="pierreguillou/bert-base-multilingual-cased-sentiment-brazilian-news")
|
25 |
|
26 |
self.dados_biblia = self.carregar_dados_biblia()
|
27 |
self.embeddings_versiculos = self.computar_embeddings()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
def carregar_dados_biblia(self):
|
30 |
-
# Base de dados simulada em português
|
31 |
return [
|
32 |
{
|
33 |
"referencia": "João 3:16",
|
34 |
"texto": "Porque Deus amou o mundo de tal maneira que deu o seu Filho unigênito, para que todo aquele que nele crê não pereça, mas tenha a vida eterna.",
|
35 |
"topico": "Salvação"
|
36 |
},
|
|
|
37 |
{
|
38 |
-
"referencia": "
|
39 |
-
"texto": "
|
40 |
-
"topico": "
|
41 |
},
|
42 |
{
|
43 |
-
"referencia": "
|
44 |
-
"texto": "
|
45 |
-
"topico": "
|
46 |
},
|
47 |
{
|
48 |
-
"referencia": "
|
49 |
-
"texto": "
|
50 |
-
"topico": "
|
51 |
-
},
|
52 |
-
{
|
53 |
-
"referencia": "Mateus 11:28",
|
54 |
-
"texto": "Vinde a mim, todos os que estais cansados e oprimidos, e eu vos aliviarei.",
|
55 |
-
"topico": "Conforto"
|
56 |
-
},
|
57 |
-
{
|
58 |
-
"referencia": "Provérbios 3:5-6",
|
59 |
-
"texto": "Confie no Senhor de todo o seu coração e não se apoie em seu próprio entendimento; reconheça o Senhor em todos os seus caminhos, e ele endireitará as suas veredas.",
|
60 |
-
"topico": "Sabedoria"
|
61 |
}
|
62 |
]
|
63 |
|
64 |
-
|
65 |
-
token_embeddings = model_output[0]
|
66 |
-
input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
|
67 |
-
return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)
|
68 |
-
|
69 |
-
def get_embedding(self, texto: str) -> np.ndarray:
|
70 |
-
inputs = self.tokenizer(texto, padding=True, truncation=True, return_tensors='pt').to(self.device)
|
71 |
-
with torch.no_grad():
|
72 |
-
model_output = self.model(**inputs)
|
73 |
-
sentence_embeddings = self.mean_pooling(model_output, inputs['attention_mask'])
|
74 |
-
return sentence_embeddings.cpu().numpy()
|
75 |
|
76 |
-
def
|
77 |
-
|
|
|
78 |
|
79 |
-
def
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
return [self.dados_biblia[idx] for idx in top_k_idx]
|
87 |
|
88 |
-
|
89 |
-
def gerar_resposta(self, pergunta: str) -> str:
|
90 |
try:
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
for versiculo in versiculos_relevantes:
|
96 |
-
resposta += f"📖 {versiculo['referencia']}\n"
|
97 |
-
resposta += f"{versiculo['texto']}\n\n"
|
98 |
-
|
99 |
-
# Análise de sentimento da pergunta
|
100 |
-
sentimento = self.analisar_sentimento(pergunta)
|
101 |
-
resposta += f"\nSua pergunta parece ter um tom {sentimento}."
|
102 |
-
|
103 |
-
# Adiciona tópicos relacionados
|
104 |
-
topicos = [v['topico'] for v in versiculos_relevantes]
|
105 |
-
resposta += f"\n\nTópicos relacionados: {', '.join(topicos)}"
|
106 |
-
|
107 |
-
return resposta
|
108 |
-
|
109 |
except Exception as e:
|
110 |
-
logger.error(f"Erro
|
111 |
-
return
|
112 |
|
113 |
-
def
|
114 |
-
|
115 |
-
|
116 |
-
mapa_sentimentos = {
|
117 |
-
'positive': 'positivo',
|
118 |
-
'negative': 'negativo',
|
119 |
-
'neutral': 'neutro'
|
120 |
-
}
|
121 |
-
return mapa_sentimentos.get(resultado['label'], 'neutro')
|
122 |
-
|
123 |
-
def processar_mensagem(mensagem: str, historico: List) -> str:
|
124 |
-
try:
|
125 |
-
assistente = AssistenteBiblico()
|
126 |
-
resposta = assistente.gerar_resposta(mensagem)
|
127 |
-
return resposta
|
128 |
-
except Exception as e:
|
129 |
-
logger.error(f"Erro: {str(e)}")
|
130 |
-
return "Desculpe, ocorreu um erro."
|
131 |
-
|
132 |
-
# Interface Gradio
|
133 |
-
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
134 |
-
gr.HTML("""
|
135 |
-
<div style="text-align: center; padding: 20px;">
|
136 |
-
<h1>📚 Assistente Bíblico</h1>
|
137 |
-
<p>Faça perguntas sobre a Bíblia e receba respostas baseadas em versículos</p>
|
138 |
-
</div>
|
139 |
-
""")
|
140 |
|
141 |
-
with gr.
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
146 |
show_label=False,
|
147 |
-
|
148 |
-
scale=4
|
149 |
)
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
4. Os tópicos relacionados serão mostrados
|
159 |
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
167 |
|
168 |
-
|
169 |
-
limpar.click(lambda: None, None, chatbot, queue=False)
|
170 |
|
171 |
if __name__ == "__main__":
|
|
|
172 |
demo.launch()
|
|
|
14 |
self.device = "cuda" if torch.cuda.is_available() else "cpu"
|
15 |
logger.info(f"Usando dispositivo: {self.device}")
|
16 |
|
|
|
17 |
model_name = "neuralmind/bert-base-portuguese-cased"
|
18 |
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
|
19 |
self.model = AutoModel.from_pretrained(model_name).to(self.device)
|
|
|
|
|
20 |
self.analisador_sentimento = pipeline("sentiment-analysis",
|
21 |
model="pierreguillou/bert-base-multilingual-cased-sentiment-brazilian-news")
|
22 |
|
23 |
self.dados_biblia = self.carregar_dados_biblia()
|
24 |
self.embeddings_versiculos = self.computar_embeddings()
|
25 |
+
|
26 |
+
# Dicionário de prompts temáticos
|
27 |
+
self.prompts_tematicos = {
|
28 |
+
"Família": [
|
29 |
+
"Como criar filhos segundo a Bíblia?",
|
30 |
+
"Como ter um casamento abençoado?",
|
31 |
+
"Como honrar pai e mãe?",
|
32 |
+
"Como lidar com conflitos familiares?",
|
33 |
+
],
|
34 |
+
"Trabalho": [
|
35 |
+
"Como ser um bom profissional cristão?",
|
36 |
+
"Como lidar com problemas no trabalho?",
|
37 |
+
"Como encontrar propósito no trabalho?",
|
38 |
+
"Como administrar as finanças biblicamente?",
|
39 |
+
],
|
40 |
+
"Saúde": [
|
41 |
+
"Como encontrar força na doença?",
|
42 |
+
"Como confiar em Deus nos momentos difíceis?",
|
43 |
+
"Como lidar com ansiedade e depressão?",
|
44 |
+
"Como encontrar paz interior?",
|
45 |
+
],
|
46 |
+
"Relacionamentos": [
|
47 |
+
"Como perdoar quem nos magoou?",
|
48 |
+
"Como escolher boas amizades?",
|
49 |
+
"Como lidar com a solidão?",
|
50 |
+
"Como amar o próximo?",
|
51 |
+
],
|
52 |
+
"Vida Espiritual": [
|
53 |
+
"Como crescer na fé?",
|
54 |
+
"Como orar melhor?",
|
55 |
+
"Como ler a Bíblia diariamente?",
|
56 |
+
"Como desenvolver intimidade com Deus?",
|
57 |
+
]
|
58 |
+
}
|
59 |
|
60 |
def carregar_dados_biblia(self):
|
|
|
61 |
return [
|
62 |
{
|
63 |
"referencia": "João 3:16",
|
64 |
"texto": "Porque Deus amou o mundo de tal maneira que deu o seu Filho unigênito, para que todo aquele que nele crê não pereça, mas tenha a vida eterna.",
|
65 |
"topico": "Salvação"
|
66 |
},
|
67 |
+
# ... [mantém todos os versículos anteriores] ...
|
68 |
{
|
69 |
+
"referencia": "Efésios 6:4",
|
70 |
+
"texto": "E vós, pais, não provoqueis vossos filhos à ira, mas criai-os na disciplina e na admoestação do Senhor.",
|
71 |
+
"topico": "Família"
|
72 |
},
|
73 |
{
|
74 |
+
"referencia": "Colossenses 3:23",
|
75 |
+
"texto": "E tudo quanto fizerdes, fazei-o de coração, como ao Senhor e não aos homens.",
|
76 |
+
"topico": "Trabalho"
|
77 |
},
|
78 |
{
|
79 |
+
"referencia": "Filipenses 4:6-7",
|
80 |
+
"texto": "Não andeis ansiosos por coisa alguma; antes, em tudo, sejam os vossos pedidos conhecidos diante de Deus pela oração e súplica, com ação de graças. E a paz de Deus, que excede todo o entendimento, guardará os vossos corações e os vossos pensamentos em Cristo Jesus.",
|
81 |
+
"topico": "Saúde Mental"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
}
|
83 |
]
|
84 |
|
85 |
+
# [mantém os métodos anteriores de embeddings e busca...]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
|
87 |
+
def get_prompt_tematico(self, categoria: str, indice: int) -> str:
|
88 |
+
"""Retorna um prompt específico de uma categoria"""
|
89 |
+
return self.prompts_tematicos.get(categoria, [])[indice]
|
90 |
|
91 |
+
def get_categorias(self) -> List[str]:
|
92 |
+
"""Retorna todas as categorias disponíveis"""
|
93 |
+
return list(self.prompts_tematicos.keys())
|
94 |
+
|
95 |
+
# Interface Gradio atualizada
|
96 |
+
def criar_interface():
|
97 |
+
assistente = AssistenteBiblico()
|
|
|
98 |
|
99 |
+
def processar_prompt(prompt: str, historico: List) -> List:
|
|
|
100 |
try:
|
101 |
+
resposta = assistente.gerar_resposta(prompt)
|
102 |
+
historico.append((prompt, resposta))
|
103 |
+
return historico
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
except Exception as e:
|
105 |
+
logger.error(f"Erro: {str(e)}")
|
106 |
+
return historico + [(prompt, "Desculpe, ocorreu um erro.")]
|
107 |
|
108 |
+
def usar_prompt_tematico(categoria: str, indice: int, historico: List) -> List:
|
109 |
+
prompt = assistente.get_prompt_tematico(categoria, indice)
|
110 |
+
return processar_prompt(prompt, historico)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
|
112 |
+
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
113 |
+
gr.HTML("""
|
114 |
+
<div style="text-align: center; padding: 20px;">
|
115 |
+
<h1>🙏 Assistente Bíblico - Sua Luz na Palavra</h1>
|
116 |
+
<p>Encontre orientação bíblica para sua vida</p>
|
117 |
+
</div>
|
118 |
+
""")
|
119 |
+
|
120 |
+
with gr.Row():
|
121 |
+
with gr.Column(scale=2):
|
122 |
+
chatbot = gr.Chatbot(
|
123 |
+
height=400,
|
124 |
show_label=False,
|
125 |
+
layout="bubble",
|
|
|
126 |
)
|
127 |
+
|
128 |
+
with gr.Row():
|
129 |
+
msg = gr.Textbox(
|
130 |
+
show_label=False,
|
131 |
+
placeholder="Digite sua pergunta ou use os botões temáticos...",
|
132 |
+
scale=4
|
133 |
+
)
|
134 |
+
limpar = gr.Button("🔄 Limpar", scale=1)
|
|
|
135 |
|
136 |
+
with gr.Column(scale=1):
|
137 |
+
gr.Markdown("### 📚 Temas")
|
138 |
+
|
139 |
+
for categoria in assistente.get_categorias():
|
140 |
+
with gr.Accordion(f"🎯 {categoria}", open=False):
|
141 |
+
for i, prompt in enumerate(assistente.prompts_tematicos[categoria]):
|
142 |
+
btn = gr.Button(prompt)
|
143 |
+
btn.click(
|
144 |
+
fn=lambda cat=categoria, idx=i, hist=chatbot: usar_prompt_tematico(cat, idx, hist),
|
145 |
+
inputs=[chatbot],
|
146 |
+
outputs=[chatbot]
|
147 |
+
)
|
148 |
+
|
149 |
+
gr.Markdown("""
|
150 |
+
### 💡 Dicas
|
151 |
+
- Use os botões temáticos para perguntas comuns
|
152 |
+
- Digite suas próprias perguntas
|
153 |
+
- Explore diferentes temas da vida cristã
|
154 |
+
- Receba versículos específicos para cada situação
|
155 |
+
""")
|
156 |
+
|
157 |
+
msg.submit(processar_prompt, [msg, chatbot], [chatbot])
|
158 |
+
limpar.click(lambda: None, None, chatbot, queue=False)
|
159 |
|
160 |
+
return demo
|
|
|
161 |
|
162 |
if __name__ == "__main__":
|
163 |
+
demo = criar_interface()
|
164 |
demo.launch()
|