DHEIVER commited on
Commit
37f3bb4
·
verified ·
1 Parent(s): 5558e3e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -11
app.py CHANGED
@@ -5,6 +5,7 @@ from sentence_transformers import SentenceTransformer, util
5
  from transformers import AutoTokenizer, AutoModelForCausalLM
6
  from pypdf import PdfReader
7
  import os
 
8
 
9
  # --- 1. Carregamento dos Modelos ---
10
  # Modelo de recuperação não muda, ele é excelente para essa tarefa.
@@ -24,7 +25,7 @@ generator_model = AutoModelForCausalLM.from_pretrained(
24
  )
25
  print("Modelos carregados com sucesso!")
26
 
27
- # --- 2. Função para Processar Arquivos Enviados (sem alterações) ---
28
  def process_files(files):
29
  if not files:
30
  return None, "Por favor, envie um ou mais arquivos."
@@ -37,30 +38,53 @@ def process_files(files):
37
  for page in reader.pages:
38
  page_text = page.extract_text()
39
  if page_text:
40
- knowledge_text += page_text + "\n"
 
41
  except Exception as e:
42
  return None, f"Erro ao ler o arquivo PDF {os.path.basename(file_path)}: {e}"
43
  elif file_path.endswith(".txt"):
44
  try:
45
  with open(file_path, 'r', encoding='utf-8') as f:
46
- knowledge_text += f.read() + "\n"
47
  except Exception as e:
48
  return None, f"Erro ao ler o arquivo TXT {os.path.basename(file_path)}: {e}"
49
 
50
  if not knowledge_text.strip():
51
  return None, "Não foi possível extrair texto dos arquivos fornecidos."
52
 
53
- text_chunks = [chunk.strip() for chunk in knowledge_text.split('\n') if chunk.strip() and len(chunk) > 10]
54
- if not text_chunks:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  return None, "O texto extraído não continha blocos de texto válidos para processamento."
56
 
57
- print(f"Processando {len(text_chunks)} blocos de texto dos arquivos...")
58
- knowledge_base_embeddings = retriever_model.encode(text_chunks, convert_to_tensor=True, show_progress_bar=True)
59
  print("Base de conhecimento criada a partir dos arquivos.")
60
 
61
- return (text_chunks, knowledge_base_embeddings), f"✅ Sucesso! {len(files)} arquivo(s) processado(s), gerando {len(text_chunks)} blocos de texto."
 
62
 
63
- # --- 3. A Função Principal do RAG (com prompt e decodificação ajustados) ---
64
  def answer_question(question, knowledge_state):
65
  if not question:
66
  return "Por favor, insira uma pergunta."
@@ -84,7 +108,7 @@ def answer_question(question, knowledge_state):
84
  print(f"Pergunta: {question}")
85
  print(f"Contexto Recuperado (Top {top_k}):\n{retrieved_context}")
86
 
87
- # MUDANÇA PRINCIPAL: Prompt com regras explícitas de extração de entidades
88
  prompt = f"""### Instruction:
89
  Você é um assistente de IA especialista em extrair informações de documentos técnicos. Analise o 'Contexto' para responder à 'Pergunta' seguindo estas regras rigorosamente:
90
 
@@ -127,7 +151,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as interface:
127
  knowledge_state = gr.State()
128
  gr.Markdown(
129
  """
130
- # 🤖 RAG - Auditor de Documentos (v8 - Extração de Entidades)
131
  **1. Carregue seus arquivos**: Envie um ou mais certificados ou documentos nos formatos `.pdf` ou `.txt`.
132
  **2. Processe os arquivos**: Clique no botão para criar a base de conhecimento.
133
  **3. Faça perguntas**: Após o processamento, faça perguntas sobre o conteúdo dos documentos.
 
5
  from transformers import AutoTokenizer, AutoModelForCausalLM
6
  from pypdf import PdfReader
7
  import os
8
+ import re # MÓDULO ADICIONADO para Expressões Regulares
9
 
10
  # --- 1. Carregamento dos Modelos ---
11
  # Modelo de recuperação não muda, ele é excelente para essa tarefa.
 
25
  )
26
  print("Modelos carregados com sucesso!")
27
 
28
+ # --- 2. Função para Processar Arquivos Enviados (COM CHUNKING ESTRUTURADO) ---
29
  def process_files(files):
30
  if not files:
31
  return None, "Por favor, envie um ou mais arquivos."
 
38
  for page in reader.pages:
39
  page_text = page.extract_text()
40
  if page_text:
41
+ # Adiciona um espaço extra entre as páginas para garantir a separação
42
+ knowledge_text += page_text + "\n\n"
43
  except Exception as e:
44
  return None, f"Erro ao ler o arquivo PDF {os.path.basename(file_path)}: {e}"
45
  elif file_path.endswith(".txt"):
46
  try:
47
  with open(file_path, 'r', encoding='utf-8') as f:
48
+ knowledge_text += f.read() + "\n\n"
49
  except Exception as e:
50
  return None, f"Erro ao ler o arquivo TXT {os.path.basename(file_path)}: {e}"
51
 
52
  if not knowledge_text.strip():
53
  return None, "Não foi possível extrair texto dos arquivos fornecidos."
54
 
55
+ # MUDANÇA PRINCIPAL: Extrator Estruturado usando Regex
56
+ # Este padrão de regex divide o texto ANTES de uma linha que parece um cabeçalho de seção
57
+ # (Ex: "1. CLIENTE", "8. PADRÕES"). Isso mantém a seção inteira em um único chunk.
58
+ # O `(?m)` ativa o modo multiline, fazendo `^` corresponder ao início de cada linha.
59
+ chunk_pattern = r"(?m)(^\d+\..*)"
60
+
61
+ # Divide o texto em chunks usando o padrão e remove os vazios
62
+ text_chunks = [chunk.strip() for chunk in re.split(chunk_pattern, knowledge_text) if chunk.strip()]
63
+
64
+ # Reagrupa o cabeçalho com seu conteúdo
65
+ structured_chunks = []
66
+ i = 0
67
+ while i < len(text_chunks):
68
+ if re.match(chunk_pattern, text_chunks[i]) and i + 1 < len(text_chunks):
69
+ # Junta o cabeçalho (ex: "1. CLIENTE") com o conteúdo seguinte
70
+ structured_chunks.append(text_chunks[i] + "\n" + text_chunks[i+1])
71
+ i += 2
72
+ else:
73
+ # Adiciona conteúdo que não corresponde a um cabeçalho
74
+ structured_chunks.append(text_chunks[i])
75
+ i += 1
76
+
77
+ if not structured_chunks:
78
  return None, "O texto extraído não continha blocos de texto válidos para processamento."
79
 
80
+ print(f"Processando {len(structured_chunks)} chunks estruturados dos arquivos...")
81
+ knowledge_base_embeddings = retriever_model.encode(structured_chunks, convert_to_tensor=True, show_progress_bar=True)
82
  print("Base de conhecimento criada a partir dos arquivos.")
83
 
84
+ return (structured_chunks, knowledge_base_embeddings), f"✅ Sucesso! {len(files)} arquivo(s) processado(s), gerando {len(structured_chunks)} chunks estruturados."
85
+
86
 
87
+ # --- 3. A Função Principal do RAG (sem alterações) ---
88
  def answer_question(question, knowledge_state):
89
  if not question:
90
  return "Por favor, insira uma pergunta."
 
108
  print(f"Pergunta: {question}")
109
  print(f"Contexto Recuperado (Top {top_k}):\n{retrieved_context}")
110
 
111
+ # Prompt com regras explícitas de extração de entidades
112
  prompt = f"""### Instruction:
113
  Você é um assistente de IA especialista em extrair informações de documentos técnicos. Analise o 'Contexto' para responder à 'Pergunta' seguindo estas regras rigorosamente:
114
 
 
151
  knowledge_state = gr.State()
152
  gr.Markdown(
153
  """
154
+ # 🤖 RAG - Auditor de Documentos (v9 - Chunking Estruturado)
155
  **1. Carregue seus arquivos**: Envie um ou mais certificados ou documentos nos formatos `.pdf` ou `.txt`.
156
  **2. Processe os arquivos**: Clique no botão para criar a base de conhecimento.
157
  **3. Faça perguntas**: Após o processamento, faça perguntas sobre o conteúdo dos documentos.