DHEIVER commited on
Commit
c2667bf
·
verified ·
1 Parent(s): 963b058

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +85 -74
app.py CHANGED
@@ -71,91 +71,102 @@ def process_files(files):
71
  return (structured_chunks, knowledge_base_embeddings), f"✅ Sucesso! {len(files)} ficheiro(s) processado(s), gerando {len(structured_chunks)} chunks estruturados."
72
 
73
 
74
- # --- 3. A FERRAMENTA PRINCIPAL DO AGENTE: find_info ---
75
- def find_info(question, knowledge_state):
76
- """Esta função atua como a 'ferramenta de busca' do agente. Ela não dá a resposta final,
77
- apenas extrai a informação bruta pedida."""
 
 
 
 
 
 
 
78
  knowledge_base, knowledge_base_embeddings = knowledge_state
79
 
80
- question_embedding = retriever_model.encode(question, convert_to_tensor=True)
 
 
 
 
 
 
81
  cosine_scores = util.cos_sim(question_embedding, knowledge_base_embeddings)
82
- top_k = min(5, len(knowledge_base))
83
  top_results = torch.topk(cosine_scores, k=top_k, dim=-1)
84
- retrieved_context = "\n---\n".join([knowledge_base[i] for i in top_results.indices[0]])
85
 
86
- prompt = f"### Instruction:\nExtraia a informação exata para responder à pergunta com base no contexto. Se a informação não for encontrada, responda 'Não encontrado'. Seja direto.\n\nContexto:\n{retrieved_context}\n\nPergunta:\n{question}\n\n### Response:"
87
-
88
- input_ids = generator_tokenizer(prompt, return_tensors="pt").input_ids
89
- outputs = generator_model.generate(input_ids, max_new_tokens=150, do_sample=False, pad_token_id=generator_tokenizer.eos_token_id)
90
- answer = generator_tokenizer.decode(outputs[0, input_ids.shape[1]:], skip_special_tokens=True)
91
- return answer.strip()
92
 
 
 
 
 
93
 
94
- # --- 4. O CÉREBRO DO AGENTE: evaluate_document ---
95
- def evaluate_document(task, knowledge_state, progress=gr.Progress(track_tqdm=True)):
96
- """Esta é a função principal do agente. Ela orquestra as chamadas à ferramenta 'find_info'
97
- para construir um relatório de avaliação completo, seguindo uma checklist."""
98
- if not task:
99
- return "Por favor, forneça uma tarefa de avaliação."
100
- if not knowledge_state or not knowledge_state[0] or knowledge_state[1] is None:
101
- return "⚠️ A base de conhecimento está vazia. Por favor, processe alguns ficheiros primeiro."
102
 
103
- # Checklist de avaliação baseada na sua solicitação
104
- checklist = {
105
- "1. Incerteza de Medição": [
106
- ("1.1 a 1.2 Casas Decimais / Compatibilidade", "Qual a incerteza de medição declarada e o número de casas decimais dos resultados?"),
107
- ("1.3 Nível de Confiança, Fator de Abrangência (k) e Graus de Liberdade", "Qual o nível de confiança, fator de abrangência (k) e graus de liberdade declarados para a incerteza?"),
108
- ("1.4 Declaração de Rastreabilidade dos Resultados", "Existe uma declaração de que os resultados se referem somente aos itens calibrados?")
109
- ],
110
- "2. Resultados da Calibração": [
111
- ("2.1 a 2.3 Unidades SI, Casas Decimais e Algarismos Significativos", "Os resultados da calibração são apresentados com unidades do Sistema Internacional (SI)? Qual o mensurando e a quantidade de algarismos significativos?"),
112
- ],
113
- "3. Conformidade da Faixa": [
114
- ("3.1 Faixa e Especificações Solicitadas", "A calibração foi realizada na faixa de utilização especificada ou solicitada?")
115
- ],
116
- "4. Condições Ambientais": [
117
- ("4.1 Registro das Condições e Incerteza Associada", "Quais foram as condições ambientais (temperatura, umidade) registadas durante a calibração? Há menção de incerteza associada a elas?")
118
- ],
119
- "5. Identificação do Item": [
120
- ("5.1 Descrição e Identificação do Item", "Qual a descrição completa e identificação do item calibrado (nome, fabricante, tipo, modelo, número de série)?")
121
- ],
122
- "6. Identificação do Método": [
123
- ("6.1 Método/Procedimento Utilizado", "Qual o método ou procedimento de calibração utilizado?")
124
- ],
125
- "7. Identificação do Cliente": [
126
- ("7.1 Nome e Endereço do Cliente", "Qual o nome e o endereço do cliente/contratante?")
127
- ],
128
- "8. Identificação do Laboratório": [
129
- ("8.1 Nome e Endereço do Laboratório", "Qual o nome e o endereço do laboratório que emitiu o certificado?")
130
- ],
131
- "9. Identificação do Certificado": [
132
- ("9.1 Número do Certificado", "Qual o número de identificação unívoca do certificado?")
133
- ],
134
- "10. Autorização": [
135
- ("10.1 Pessoas Autorizadas", "Quem são os responsáveis (nome e função) pela emissão ou assinatura do certificado?")
136
- ]
137
- }
138
-
139
- report = f"# Relatório de Análise de Conformidade\n\n**Tarefa:** {task}\n\n---\n\n"
 
 
 
 
 
 
 
 
 
140
 
141
- # Itera sobre a checklist, fazendo perguntas ao documento para cada item
142
- for section, questions in progress.tqdm(checklist.items(), desc="A avaliar documento..."):
143
- report += f"## {section}\n\n"
144
- for sub_item, question in questions:
145
- # O agente "pergunta" ao documento
146
- answer = find_info(question, knowledge_state)
147
- # Adiciona a resposta ao relatório
148
- report += f"**{sub_item}:**\n{answer}\n\n"
149
- report += "---\n\n"
150
-
151
- return report
152
-
153
- # --- 5. Interface Gráfica (Atualizada para o Agente) ---
154
  with gr.Blocks(theme=gr.themes.Soft()) as interface:
155
  knowledge_state = gr.State()
156
  gr.Markdown(
157
  """
158
- # 🤖 Agente de Análise de Conformidade Metrológica
159
  **1. Carregue um documento**: Envie um certificado de calibração (`.pdf` ou `.txt`).
160
  **2. Processe o documento**: Clique no botão para criar a base de conhecimento.
161
  **3. Inicie a Análise**: Dê uma tarefa ao agente (ex: "Analisar conformidade deste certificado") e clique em "Iniciar Análise".
@@ -176,8 +187,8 @@ with gr.Blocks(theme=gr.themes.Soft()) as interface:
176
  report_box = gr.Markdown(label="Relatório Final de Análise")
177
 
178
  process_button.click(fn=process_files, inputs=[file_uploader], outputs=[knowledge_state, status_box])
179
- submit_button.click(fn=evaluate_document, inputs=[task_box, knowledge_state], outputs=[report_box])
180
 
181
- # --- 6. Lançamento do App ---
182
  if __name__ == "__main__":
183
  interface.launch()
 
71
  return (structured_chunks, knowledge_base_embeddings), f"✅ Sucesso! {len(files)} ficheiro(s) processado(s), gerando {len(structured_chunks)} chunks estruturados."
72
 
73
 
74
+ # --- 3. O CÉREBRO DA ANÁLISE: generate_compliance_report ---
75
+ def generate_compliance_report(task, knowledge_state, progress=gr.Progress(track_tqdm=True)):
76
+ """
77
+ Esta função orquestra todo o processo de RAG: recupera um contexto amplo e usa um único
78
+ 'super-prompt' para gerar o relatório de conformidade completo de uma só vez.
79
+ """
80
+ if not task:
81
+ return "Por favor, forneça uma tarefa de análise."
82
+ if not knowledge_state or not knowledge_state[0] or knowledge_state[1] is None:
83
+ return "⚠️ A base de conhecimento está vazia. Por favor, processe alguns ficheiros primeiro."
84
+
85
  knowledge_base, knowledge_base_embeddings = knowledge_state
86
 
87
+ progress(0, desc="A recuperar contexto relevante...")
88
+
89
+ # Passo 1: Recuperação Ampla do Contexto
90
+ # Usamos uma pergunta genérica para recuperar os chunks mais relevantes do documento inteiro.
91
+ # Aumentamos o top_k para dar ao modelo uma visão mais completa.
92
+ search_query = "Informações completas do certificado de calibração"
93
+ question_embedding = retriever_model.encode(search_query, convert_to_tensor=True)
94
  cosine_scores = util.cos_sim(question_embedding, knowledge_base_embeddings)
95
+ top_k = min(15, len(knowledge_base)) # Aumentado para 15 para um contexto muito mais rico
96
  top_results = torch.topk(cosine_scores, k=top_k, dim=-1)
97
+ retrieved_context = "\n\n---\n\n".join([knowledge_base[i] for i in top_results.indices[0]])
98
 
99
+ progress(0.5, desc="A gerar o relatório de conformidade...")
 
 
 
 
 
100
 
101
+ # Passo 2: Geração com "Super-Prompt"
102
+ # Este prompt contém a checklist completa e instrui o modelo a preenchê-la.
103
+ final_prompt = f"""### Instruction:
104
+ Você é um auditor de metrologia a preencher um relatório de conformidade. Com base no 'Contexto do Documento' fornecido, preencha cada item da 'Checklist de Análise' abaixo. Se uma informação não for encontrada no contexto, escreva 'Não encontrado'.
105
 
106
+ **Contexto do Documento:**
107
+ {retrieved_context}
 
 
 
 
 
 
108
 
109
+ **Checklist de Análise:**
110
+ # Relatório de Análise de Conformidade
111
+
112
+ ## 1. Incerteza de Medição
113
+ - **1.1 a 1.2 Casas Decimais / Compatibilidade:**
114
+ - **1.3 Nível de Confiança, Fator de Abrangência (k) e Graus de Liberdade:**
115
+ - **1.4 Declaração de Rastreabilidade dos Resultados:**
116
+
117
+ ## 2. Resultados da Calibração
118
+ - **2.1 a 2.3 Unidades SI, Casas Decimais e Algarismos Significativos:**
119
+
120
+ ## 3. Conformidade da Faixa
121
+ - **3.1 Faixa e Especificações Solicitadas:**
122
+
123
+ ## 4. Condições Ambientais
124
+ - **4.1 Registro das Condições e Incerteza Associada:**
125
+
126
+ ## 5. Identificação do Item
127
+ - **5.1 Descrição e Identificação do Item:**
128
+
129
+ ## 6. Identificação do Método
130
+ - **6.1 Método/Procedimento Utilizado:**
131
+
132
+ ## 7. Identificação do Cliente
133
+ - **7.1 Nome e Endereço do Cliente:**
134
+
135
+ ## 8. Identificação do Laboratório
136
+ - **8.1 Nome e Endereço do Laboratório:**
137
+
138
+ ## 9. Identificação do Certificado
139
+ - **9.1 Número do Certificado:**
140
+
141
+ ## 10. Autorização
142
+ - **10.1 Pessoas Autorizadas:**
143
+
144
+ ### Response:
145
+ """
146
+
147
+ input_ids = generator_tokenizer(final_prompt, return_tensors="pt").input_ids
148
+ outputs = generator_model.generate(
149
+ input_ids,
150
+ max_new_tokens=1024, # Aumentado para relatórios detalhados
151
+ do_sample=False,
152
+ pad_token_id=generator_tokenizer.eos_token_id
153
+ )
154
+ final_report = generator_tokenizer.decode(outputs[0], skip_special_tokens=True)
155
 
156
+ # Limpa a resposta para remover o prompt inicial
157
+ if "### Response:" in final_report:
158
+ final_report = final_report.split("### Response:")[1].strip()
159
+
160
+ progress(1, desc="Análise concluída.")
161
+ return final_report
162
+
163
+
164
+ # --- 4. Interface Gráfica (Simplificada para o novo fluxo) ---
 
 
 
 
165
  with gr.Blocks(theme=gr.themes.Soft()) as interface:
166
  knowledge_state = gr.State()
167
  gr.Markdown(
168
  """
169
+ # 🤖 Agente de Análise de Conformidade Metrológica (v12 - Robusto)
170
  **1. Carregue um documento**: Envie um certificado de calibração (`.pdf` ou `.txt`).
171
  **2. Processe o documento**: Clique no botão para criar a base de conhecimento.
172
  **3. Inicie a Análise**: Dê uma tarefa ao agente (ex: "Analisar conformidade deste certificado") e clique em "Iniciar Análise".
 
187
  report_box = gr.Markdown(label="Relatório Final de Análise")
188
 
189
  process_button.click(fn=process_files, inputs=[file_uploader], outputs=[knowledge_state, status_box])
190
+ submit_button.click(fn=generate_compliance_report, inputs=[task_box, knowledge_state], outputs=[report_box])
191
 
192
+ # --- 5. Lançamento do App ---
193
  if __name__ == "__main__":
194
  interface.launch()