Spaces:
Running
Running
Update ai_logic.py
Browse files- ai_logic.py +53 -45
ai_logic.py
CHANGED
@@ -20,13 +20,13 @@ if not HF_TOKEN:
|
|
20 |
|
21 |
# Lista inicial de modelos
|
22 |
MODELS = {
|
23 |
-
"Mistral 7B (Mais acertivo)": "mistralai/Mistral-7B-Instruct-v0.3",
|
24 |
-
"Phi-3 Mini (Mais rápido)": "microsoft/Phi-3-mini-4k-instruct",
|
25 |
-
"Zephyr 7B (Meio Termo)": "HuggingFaceH4/zephyr-7b-beta"
|
26 |
}
|
27 |
|
28 |
# Novos modelos para testar
|
29 |
NEW_MODELS_TO_TEST = [
|
|
|
|
|
|
|
30 |
("LLaMA 2-7B Chat", "meta-llama/Llama-2-7b-chat-hf"),
|
31 |
("LLaMA 3.2-3B Instruct", "meta-llama/Llama-3.2-3B-Instruct"),
|
32 |
("Gemma 2B Instruct", "google/gemma-2b-it"),
|
@@ -64,7 +64,7 @@ def load_conversation_memory(session_id: str):
|
|
64 |
session_data = json.load(f)
|
65 |
except Exception as e:
|
66 |
print(f"Erro ao carregar memória para sessão '{session_id}': {e}")
|
67 |
-
|
68 |
user_sessions[session_id] = session_data
|
69 |
|
70 |
def save_conversation_memory(session_id: str):
|
@@ -107,7 +107,7 @@ def update_user_profile(session_id: str, user_message: str):
|
|
107 |
for topic, keywords in topics.items():
|
108 |
if any(keyword in message_lower for keyword in keywords):
|
109 |
profile[f'interesse_{topic}'] = profile.get(f'interesse_{topic}', 0) + 1
|
110 |
-
|
111 |
profile['total_perguntas'] = profile.get('total_perguntas', 0) + 1
|
112 |
user_sessions[session_id]['user_profile'] = profile
|
113 |
|
@@ -180,7 +180,7 @@ def build_and_save_vector_store():
|
|
180 |
texts = [scrape_text_from_url(link) for link in links if scrape_text_from_url(link)]
|
181 |
if not texts:
|
182 |
return "Nenhum conteúdo encontrado."
|
183 |
-
|
184 |
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=150)
|
185 |
chunks = text_splitter.create_documents(texts)
|
186 |
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
|
@@ -261,7 +261,7 @@ class HuggingFaceAPIClient:
|
|
261 |
return True, "Modelo disponível para inferência"
|
262 |
else:
|
263 |
return False, f"Resposta inesperada: {result}"
|
264 |
-
|
265 |
elif response.status_code == 503:
|
266 |
return False, "Modelo está carregando (503)"
|
267 |
elif response.status_code == 400:
|
@@ -289,7 +289,7 @@ class HuggingFaceAPIClient:
|
|
289 |
info_available, info_msg = self.check_model_info(model_name)
|
290 |
if not info_available:
|
291 |
return False, f"Info check failed: {info_msg}"
|
292 |
-
|
293 |
print(f" ✓ Info check: {info_msg}")
|
294 |
|
295 |
# Em seguida testa a inferência
|
@@ -348,7 +348,7 @@ class HuggingFaceAPIClient:
|
|
348 |
prompt_parts.append(f"Usuário: {content}")
|
349 |
elif role == 'assistant':
|
350 |
prompt_parts.append(f"Assistente: {content}")
|
351 |
-
|
352 |
prompt_parts.append("Assistente:")
|
353 |
return "\n\n".join(prompt_parts)
|
354 |
|
@@ -356,25 +356,30 @@ api_client = HuggingFaceAPIClient(HF_TOKEN)
|
|
356 |
|
357 |
# --- Função para Testar e Atualizar Modelos ---
|
358 |
def test_and_update_models() -> int:
|
359 |
-
"""
|
|
|
|
|
|
|
360 |
print("Testando disponibilidade dos novos modelos...")
|
361 |
print(f"Token HF disponível: {'Sim' if HF_TOKEN else 'Não'}")
|
362 |
print("-" * 60)
|
363 |
|
364 |
-
|
|
|
365 |
unavailable_models = []
|
366 |
|
367 |
for model_label, model_name in NEW_MODELS_TO_TEST:
|
368 |
is_available, message = api_client.test_model_availability(model_name)
|
369 |
|
370 |
if is_available:
|
371 |
-
|
372 |
-
|
|
|
373 |
print(f"✓ {model_label}")
|
374 |
else:
|
375 |
unavailable_models.append((model_label, model_name, message))
|
376 |
print(f"✗ {model_label} - {message}")
|
377 |
-
|
378 |
# Pequena pausa para evitar rate limiting
|
379 |
time.sleep(1)
|
380 |
|
@@ -383,14 +388,14 @@ def test_and_update_models() -> int:
|
|
383 |
print("RESULTADOS DA VALIDAÇÃO:")
|
384 |
print("=" * 60)
|
385 |
|
386 |
-
if
|
387 |
-
print(f"\n✓ MODELOS DISPONÍVEIS ({len(
|
388 |
-
for label, name, msg in
|
389 |
print(f" - {label}")
|
390 |
print(f" {name}")
|
391 |
print(f" Status: {msg}")
|
392 |
print()
|
393 |
-
|
394 |
if unavailable_models:
|
395 |
print(f"\n✗ MODELOS NÃO DISPONÍVEIS ({len(unavailable_models)}):")
|
396 |
for label, name, msg in unavailable_models:
|
@@ -398,14 +403,13 @@ def test_and_update_models() -> int:
|
|
398 |
print(f" {name}")
|
399 |
print(f" Motivo: {msg}")
|
400 |
print()
|
401 |
-
|
402 |
-
print(f"TOTAL DE MODELOS DISPONÍVEIS: {len(MODELS)}")
|
403 |
print("=" * 60)
|
404 |
|
405 |
# Salva a lista atualizada de modelos
|
406 |
save_updated_models()
|
407 |
-
|
408 |
-
return len(available_models) # Retorna o número de novos modelos aceitos
|
409 |
|
410 |
def save_updated_models():
|
411 |
"""Salva a lista atualizada de modelos em um arquivo."""
|
@@ -421,7 +425,7 @@ def responder_como_aldo(session_id: str, pergunta: str, modelo: str = DEFAULT_MO
|
|
421 |
"""Gera resposta como Dr. Aldo Henrique."""
|
422 |
if not pergunta.strip():
|
423 |
return "Por favor, faça uma pergunta válida."
|
424 |
-
|
425 |
load_conversation_memory(session_id)
|
426 |
update_user_profile(session_id, pergunta)
|
427 |
|
@@ -433,7 +437,7 @@ def responder_como_aldo(session_id: str, pergunta: str, modelo: str = DEFAULT_MO
|
|
433 |
contexto.append(f"**Conversa Anterior**\n{conversa}")
|
434 |
if blog := retrieve_context_from_blog(pergunta):
|
435 |
contexto.append(f"**Contexto do Blog**\n{blog}")
|
436 |
-
|
437 |
system_prompt = """Você é o Dr. Aldo Henrique,
|
438 |
Doutor em Ciências da Computação pela UnB (2024), mestre em Ciências da Computação pela UnB (2017) e bacharel em Sistemas de Informação pela UFV (2014).
|
439 |
Professor universitário, onde leciona disciplinas como Algoritmos, Inteligência Artificial, Ciência de Dados e Mineração de Dados.
|
@@ -463,29 +467,33 @@ def responder_como_aldo(session_id: str, pergunta: str, modelo: str = DEFAULT_MO
|
|
463 |
|
464 |
# --- Inicialização ---
|
465 |
def inicializar_sistema():
|
466 |
-
"""Inicializa o sistema
|
467 |
print("Inicializando Chatbot Dr. Aldo...")
|
468 |
|
469 |
-
|
470 |
-
num_models_accepted = test_and_update_models()
|
471 |
|
472 |
-
if
|
473 |
-
print(f"{num_models_accepted} modelos aceitos. Carregando a página...")
|
474 |
load_vector_store()
|
475 |
-
print("Sistema inicializado!")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
476 |
else:
|
477 |
-
print(
|
478 |
-
|
479 |
-
|
480 |
-
if __name__ == "__main__":
|
481 |
-
inicializar_sistema()
|
482 |
-
# Teste básico
|
483 |
-
session_id = "teste_123"
|
484 |
-
print("\n" + "="*50)
|
485 |
-
print("TESTE DO CHATBOT:")
|
486 |
-
print("="*50)
|
487 |
-
print(responder_como_aldo(session_id, "O que é Java?"))
|
488 |
-
print("\n" + "-"*50)
|
489 |
-
print(responder_como_aldo(session_id, "Mostre um exemplo de código Java."))
|
490 |
-
print("\n" + "-"*50)
|
491 |
-
print(clear_memory(session_id))
|
|
|
20 |
|
21 |
# Lista inicial de modelos
|
22 |
MODELS = {
|
|
|
|
|
|
|
23 |
}
|
24 |
|
25 |
# Novos modelos para testar
|
26 |
NEW_MODELS_TO_TEST = [
|
27 |
+
("Mistral 7B (Mais acertivo)", "mistralai/Mistral-7B-Instruct-v0.3"),
|
28 |
+
("Phi-3 Mini (Mais rápido)", "microsoft/Phi-3-mini-4k-instruct"),
|
29 |
+
("Zephyr 7B (Meio Termo)", "HuggingFaceH4/zephyr-7b-beta"),
|
30 |
("LLaMA 2-7B Chat", "meta-llama/Llama-2-7b-chat-hf"),
|
31 |
("LLaMA 3.2-3B Instruct", "meta-llama/Llama-3.2-3B-Instruct"),
|
32 |
("Gemma 2B Instruct", "google/gemma-2b-it"),
|
|
|
64 |
session_data = json.load(f)
|
65 |
except Exception as e:
|
66 |
print(f"Erro ao carregar memória para sessão '{session_id}': {e}")
|
67 |
+
|
68 |
user_sessions[session_id] = session_data
|
69 |
|
70 |
def save_conversation_memory(session_id: str):
|
|
|
107 |
for topic, keywords in topics.items():
|
108 |
if any(keyword in message_lower for keyword in keywords):
|
109 |
profile[f'interesse_{topic}'] = profile.get(f'interesse_{topic}', 0) + 1
|
110 |
+
|
111 |
profile['total_perguntas'] = profile.get('total_perguntas', 0) + 1
|
112 |
user_sessions[session_id]['user_profile'] = profile
|
113 |
|
|
|
180 |
texts = [scrape_text_from_url(link) for link in links if scrape_text_from_url(link)]
|
181 |
if not texts:
|
182 |
return "Nenhum conteúdo encontrado."
|
183 |
+
|
184 |
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=150)
|
185 |
chunks = text_splitter.create_documents(texts)
|
186 |
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
|
|
|
261 |
return True, "Modelo disponível para inferência"
|
262 |
else:
|
263 |
return False, f"Resposta inesperada: {result}"
|
264 |
+
|
265 |
elif response.status_code == 503:
|
266 |
return False, "Modelo está carregando (503)"
|
267 |
elif response.status_code == 400:
|
|
|
289 |
info_available, info_msg = self.check_model_info(model_name)
|
290 |
if not info_available:
|
291 |
return False, f"Info check failed: {info_msg}"
|
292 |
+
|
293 |
print(f" ✓ Info check: {info_msg}")
|
294 |
|
295 |
# Em seguida testa a inferência
|
|
|
348 |
prompt_parts.append(f"Usuário: {content}")
|
349 |
elif role == 'assistant':
|
350 |
prompt_parts.append(f"Assistente: {content}")
|
351 |
+
|
352 |
prompt_parts.append("Assistente:")
|
353 |
return "\n\n".join(prompt_parts)
|
354 |
|
|
|
356 |
|
357 |
# --- Função para Testar e Atualizar Modelos ---
|
358 |
def test_and_update_models() -> int:
|
359 |
+
"""
|
360 |
+
Testa a disponibilidade dos novos modelos e atualiza a lista MODELS.
|
361 |
+
Retorna o número de modelos disponíveis (incluindo os iniciais).
|
362 |
+
"""
|
363 |
print("Testando disponibilidade dos novos modelos...")
|
364 |
print(f"Token HF disponível: {'Sim' if HF_TOKEN else 'Não'}")
|
365 |
print("-" * 60)
|
366 |
|
367 |
+
initial_model_count = len(MODELS) # Contar os modelos já existentes
|
368 |
+
available_models_during_test = []
|
369 |
unavailable_models = []
|
370 |
|
371 |
for model_label, model_name in NEW_MODELS_TO_TEST:
|
372 |
is_available, message = api_client.test_model_availability(model_name)
|
373 |
|
374 |
if is_available:
|
375 |
+
if model_label not in MODELS: # Adiciona apenas se não estiver já na lista inicial
|
376 |
+
MODELS[model_label] = model_name
|
377 |
+
available_models_during_test.append((model_label, model_name, message))
|
378 |
print(f"✓ {model_label}")
|
379 |
else:
|
380 |
unavailable_models.append((model_label, model_name, message))
|
381 |
print(f"✗ {model_label} - {message}")
|
382 |
+
|
383 |
# Pequena pausa para evitar rate limiting
|
384 |
time.sleep(1)
|
385 |
|
|
|
388 |
print("RESULTADOS DA VALIDAÇÃO:")
|
389 |
print("=" * 60)
|
390 |
|
391 |
+
if available_models_during_test:
|
392 |
+
print(f"\n✓ MODELOS DISPONÍVEIS (novos e testados: {len(available_models_during_test)}):")
|
393 |
+
for label, name, msg in available_models_during_test:
|
394 |
print(f" - {label}")
|
395 |
print(f" {name}")
|
396 |
print(f" Status: {msg}")
|
397 |
print()
|
398 |
+
|
399 |
if unavailable_models:
|
400 |
print(f"\n✗ MODELOS NÃO DISPONÍVEIS ({len(unavailable_models)}):")
|
401 |
for label, name, msg in unavailable_models:
|
|
|
403 |
print(f" {name}")
|
404 |
print(f" Motivo: {msg}")
|
405 |
print()
|
406 |
+
|
407 |
+
print(f"TOTAL DE MODELOS ATUALMENTE DISPONÍVEIS: {len(MODELS)}")
|
408 |
print("=" * 60)
|
409 |
|
410 |
# Salva a lista atualizada de modelos
|
411 |
save_updated_models()
|
412 |
+
return len(MODELS) # Retorna a contagem total de modelos disponíveis
|
|
|
413 |
|
414 |
def save_updated_models():
|
415 |
"""Salva a lista atualizada de modelos em um arquivo."""
|
|
|
425 |
"""Gera resposta como Dr. Aldo Henrique."""
|
426 |
if not pergunta.strip():
|
427 |
return "Por favor, faça uma pergunta válida."
|
428 |
+
|
429 |
load_conversation_memory(session_id)
|
430 |
update_user_profile(session_id, pergunta)
|
431 |
|
|
|
437 |
contexto.append(f"**Conversa Anterior**\n{conversa}")
|
438 |
if blog := retrieve_context_from_blog(pergunta):
|
439 |
contexto.append(f"**Contexto do Blog**\n{blog}")
|
440 |
+
|
441 |
system_prompt = """Você é o Dr. Aldo Henrique,
|
442 |
Doutor em Ciências da Computação pela UnB (2024), mestre em Ciências da Computação pela UnB (2017) e bacharel em Sistemas de Informação pela UFV (2014).
|
443 |
Professor universitário, onde leciona disciplinas como Algoritmos, Inteligência Artificial, Ciência de Dados e Mineração de Dados.
|
|
|
467 |
|
468 |
# --- Inicialização ---
|
469 |
def inicializar_sistema():
|
470 |
+
"""Inicializa o sistema, garantindo no mínimo 3 modelos disponíveis."""
|
471 |
print("Inicializando Chatbot Dr. Aldo...")
|
472 |
|
473 |
+
num_available_models = test_and_update_models() # Retorna a contagem de modelos disponíveis
|
|
|
474 |
|
475 |
+
if num_available_models >= 3:
|
|
|
476 |
load_vector_store()
|
477 |
+
print("Sistema inicializado e pronto para uso com modelos suficientes!")
|
478 |
+
return True # Indica que a inicialização foi bem-sucedida
|
479 |
+
else:
|
480 |
+
print(f"Erro: Apenas {num_available_models} modelos disponíveis. São necessários pelo menos 3 modelos para iniciar o sistema.")
|
481 |
+
return False # Indica que a inicialização falhou
|
482 |
+
|
483 |
+
if __name__ == "__main__": # Apenas este bloco é executado quando o script é chamado diretamente
|
484 |
+
if inicializar_sistema():
|
485 |
+
# Este é o local onde você colocaria o código para "carregar a página"
|
486 |
+
# Por exemplo, iniciar um framework web como Flask ou Streamlit.
|
487 |
+
# Por enquanto, vou manter seu teste básico como um placeholder para "carregar a página".
|
488 |
+
print("\n" + "="*50)
|
489 |
+
print("SISTEMA INICIADO: Realizando teste básico do Chatbot...")
|
490 |
+
print("="*50)
|
491 |
+
session_id = "teste_123"
|
492 |
+
print(responder_como_aldo(session_id, "O que é Java?"))
|
493 |
+
print("\n" + "-"*50)
|
494 |
+
print(responder_como_aldo(session_id, "Mostre um exemplo de código Java."))
|
495 |
+
print("\n" + "-"*50)
|
496 |
+
print(clear_memory(session_id))
|
497 |
else:
|
498 |
+
print("\nSistema não pôde ser iniciado devido à falta de modelos suficientes.")
|
499 |
+
print("Por favor, verifique a conexão com o Hugging Face e o token de acesso.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|