Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -3,7 +3,7 @@ import os
|
|
3 |
import json
|
4 |
import re
|
5 |
import gradio as gr
|
6 |
-
from typing import Dict, Any, List, Optional
|
7 |
import pickle
|
8 |
|
9 |
# --- Novas importações para o RAG ---
|
@@ -85,10 +85,11 @@ def scrape_text_from_url(url: str) -> str:
|
|
85 |
print(f"Erro ao raspar {url}: {e}")
|
86 |
return ""
|
87 |
|
88 |
-
def build_and_save_vector_store() -> str:
|
89 |
"""
|
90 |
Função principal do RAG: raspa o blog, cria chunks, gera embeddings e salva o vector store.
|
91 |
Esta é a nossa função de "treino".
|
|
|
92 |
"""
|
93 |
global vector_store
|
94 |
start_time = time.time()
|
@@ -106,7 +107,7 @@ def build_and_save_vector_store() -> str:
|
|
106 |
print(f"Textos extraídos de {len(all_texts)} novas páginas.")
|
107 |
|
108 |
if not all_texts:
|
109 |
-
return "Nenhum novo conteúdo encontrado para treinar."
|
110 |
|
111 |
# 3. Dividir os textos em chunks
|
112 |
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=150)
|
@@ -128,7 +129,8 @@ def build_and_save_vector_store() -> str:
|
|
128 |
pickle.dump(all_links, f)
|
129 |
|
130 |
end_time = time.time()
|
131 |
-
|
|
|
132 |
|
133 |
def load_vector_store():
|
134 |
"""Carrega o vector store do arquivo, se existir."""
|
@@ -141,7 +143,9 @@ def load_vector_store():
|
|
141 |
else:
|
142 |
print("Nenhum vector store encontrado. É necessário treinar o modelo.")
|
143 |
# Inicia o treino automaticamente se não houver um índice
|
144 |
-
|
|
|
|
|
145 |
|
146 |
def retrieve_context_from_blog(query: str, k: int = 3) -> str:
|
147 |
"""Busca no vector store por chunks de texto similares à pergunta."""
|
@@ -274,6 +278,7 @@ def responder_como_aldo(pergunta: str, modelo_escolhido: str = DEFAULT_MODEL) ->
|
|
274 |
"Responda com clareza, profundidade e tom acadêmico. Foque em explicar e não em só mostrar o resultado. "
|
275 |
"Responda sempre em português brasileiro. Use blocos de código formatados com ```. "
|
276 |
"Não responda nada se a pergunta não for sobre o universo de programação e tecnologia."
|
|
|
277 |
)
|
278 |
|
279 |
# Montar prompt do usuário, injetando o contexto do blog
|
@@ -366,6 +371,9 @@ with gr.Blocks(title="Dr. Aldo Henrique - API Externa", theme=gr.themes.Soft(),
|
|
366 |
with gr.Accordion("⚙️ Controle do Conhecimento (RAG)", open=False):
|
367 |
status_rag = gr.Textbox(label="Status do Retreino", interactive=False)
|
368 |
botao_retreinar = gr.Button("🔄 Atualizar Conhecimento do Blog", variant="stop")
|
|
|
|
|
|
|
369 |
|
370 |
with gr.Accordion("📚 Exemplos de Perguntas", open=False):
|
371 |
gr.Examples(
|
@@ -393,7 +401,13 @@ with gr.Blocks(title="Dr. Aldo Henrique - API Externa", theme=gr.themes.Soft(),
|
|
393 |
# Eventos
|
394 |
botao_perguntar.click(fn=responder_como_aldo, inputs=[entrada, modelo_select], outputs=saida, show_progress=True)
|
395 |
botao_testar.click(fn=testar_todos_modelos, outputs=status_api, show_progress=True)
|
396 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
397 |
|
398 |
# Lançar aplicação
|
399 |
if __name__ == "__main__":
|
|
|
3 |
import json
|
4 |
import re
|
5 |
import gradio as gr
|
6 |
+
from typing import Dict, Any, List, Optional, Tuple # Importando Tuple
|
7 |
import pickle
|
8 |
|
9 |
# --- Novas importações para o RAG ---
|
|
|
85 |
print(f"Erro ao raspar {url}: {e}")
|
86 |
return ""
|
87 |
|
88 |
+
def build_and_save_vector_store() -> Tuple[str, Optional[str], Optional[str]]: # Alterado o tipo de retorno para incluir os dois caminhos
|
89 |
"""
|
90 |
Função principal do RAG: raspa o blog, cria chunks, gera embeddings e salva o vector store.
|
91 |
Esta é a nossa função de "treino".
|
92 |
+
Retorna uma tupla (mensagem_status, caminho_do_arquivo_faiss_para_download, caminho_do_arquivo_urls_para_download).
|
93 |
"""
|
94 |
global vector_store
|
95 |
start_time = time.time()
|
|
|
107 |
print(f"Textos extraídos de {len(all_texts)} novas páginas.")
|
108 |
|
109 |
if not all_texts:
|
110 |
+
return "Nenhum novo conteúdo encontrado para treinar.", None, None # Retorna None para os arquivos se não houver conteúdo
|
111 |
|
112 |
# 3. Dividir os textos em chunks
|
113 |
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=150)
|
|
|
129 |
pickle.dump(all_links, f)
|
130 |
|
131 |
end_time = time.time()
|
132 |
+
message = f"✅ Retreino do RAG concluído em {end_time - start_time:.2f} segundos. {len(chunks)} chunks de texto processados."
|
133 |
+
return message, VECTOR_STORE_PATH, PROCESSED_URLS_PATH # Retorna a mensagem e os caminhos dos dois arquivos para download
|
134 |
|
135 |
def load_vector_store():
|
136 |
"""Carrega o vector store do arquivo, se existir."""
|
|
|
143 |
else:
|
144 |
print("Nenhum vector store encontrado. É necessário treinar o modelo.")
|
145 |
# Inicia o treino automaticamente se não houver um índice
|
146 |
+
# Modificado para ignorar o retorno dos caminhos dos arquivos ao carregar
|
147 |
+
message, _, _ = build_and_save_vector_store()
|
148 |
+
print(message) # Imprime a mensagem de status do treino inicial
|
149 |
|
150 |
def retrieve_context_from_blog(query: str, k: int = 3) -> str:
|
151 |
"""Busca no vector store por chunks de texto similares à pergunta."""
|
|
|
278 |
"Responda com clareza, profundidade e tom acadêmico. Foque em explicar e não em só mostrar o resultado. "
|
279 |
"Responda sempre em português brasileiro. Use blocos de código formatados com ```. "
|
280 |
"Não responda nada se a pergunta não for sobre o universo de programação e tecnologia."
|
281 |
+
"No código, sempre explique bem utilizando comentários, o aluno precisa aprender olhando os comentários."
|
282 |
)
|
283 |
|
284 |
# Montar prompt do usuário, injetando o contexto do blog
|
|
|
371 |
with gr.Accordion("⚙️ Controle do Conhecimento (RAG)", open=False):
|
372 |
status_rag = gr.Textbox(label="Status do Retreino", interactive=False)
|
373 |
botao_retreinar = gr.Button("🔄 Atualizar Conhecimento do Blog", variant="stop")
|
374 |
+
# Novos componentes para download
|
375 |
+
download_faiss_file = gr.File(label="Download do Índice FAISS", interactive=False, file_count="single", file_types=[".pkl"])
|
376 |
+
download_urls_file = gr.File(label="Download das URLs Processadas", interactive=False, file_count="single", file_types=[".pkl"])
|
377 |
|
378 |
with gr.Accordion("📚 Exemplos de Perguntas", open=False):
|
379 |
gr.Examples(
|
|
|
401 |
# Eventos
|
402 |
botao_perguntar.click(fn=responder_como_aldo, inputs=[entrada, modelo_select], outputs=saida, show_progress=True)
|
403 |
botao_testar.click(fn=testar_todos_modelos, outputs=status_api, show_progress=True)
|
404 |
+
# Atualiza o evento para a função build_and_save_vector_store
|
405 |
+
# Agora, ela retorna três valores: a mensagem de status e os caminhos dos dois arquivos
|
406 |
+
botao_retreinar.click(
|
407 |
+
fn=build_and_save_vector_store,
|
408 |
+
outputs=[status_rag, download_faiss_file, download_urls_file], # Saídas atualizadas
|
409 |
+
show_progress=True
|
410 |
+
)
|
411 |
|
412 |
# Lançar aplicação
|
413 |
if __name__ == "__main__":
|