Spaces:
Sleeping
Sleeping
Update app.py
Browse files
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.
|
75 |
-
def
|
76 |
-
"""
|
77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
knowledge_base, knowledge_base_embeddings = knowledge_state
|
79 |
|
80 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
cosine_scores = util.cos_sim(question_embedding, knowledge_base_embeddings)
|
82 |
-
top_k = min(
|
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 |
-
|
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 |
-
|
95 |
-
|
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 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
|
141 |
-
#
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
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=
|
180 |
|
181 |
-
# ---
|
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()
|