caarleexx commited on
Commit
a25df5c
·
verified ·
1 Parent(s): d058a5e

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -333
app.py DELETED
@@ -1,333 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- """
3
- Pipeline v10 Refatorada - Chatbot com Metacognição Pura e Verificação.
4
-
5
- Esta aplicação implementa um chatbot avançado utilizando a API Google Gemini.
6
- A arquitetura se baseia em uma pipeline de múltiplos passos (P0-P8, X1-X2)
7
- que analisa, raciocina, gera cenários e verifica as respostas antes de
8
- entregá-las ao usuário.
9
-
10
- Principais características:
11
- - Orquestração de múltiplos modelos (Counselor e Supervisor).
12
- - Passos de metacognição para análise interna do problema.
13
- - Geração e avaliação de múltiplos cenários de resposta.
14
- - Verificação final de fatos, lógica e ética.
15
- - Estrutura robusta para parsing de JSON e tratamento de anexos.
16
- """
17
- import json
18
- import os
19
- import base64
20
- import re
21
- import warnings
22
- from datetime import datetime
23
- from typing import Dict, List, Tuple, Any
24
-
25
- import gradio as gr
26
- import google.generativeai as genai
27
- # Ignora avisos futuros de dependências da API do Google
28
- warnings.filterwarnings("ignore", category=FutureWarning, module="google.api_core")
29
-
30
- # ============================================================================
31
- # 1. CONFIGURAÇÃO E INICIALIZAÇÃO
32
- # ============================================================================
33
-
34
- # Carrega a chave da API a partir de variáveis de ambiente.
35
- # É uma prática de segurança recomendada para não expor chaves no código.
36
- API_KEY = os.getenv("GOOGLE_API_KEY")
37
- if not API_KEY:
38
- raise ValueError("A variável de ambiente GOOGLE_API_KEY não foi configurada.")
39
-
40
- genai.configure(api_key=API_KEY)
41
-
42
- # Modelos utilizados na pipeline:
43
- # - Counselor: Responsável pela maior parte da análise e raciocínio.
44
- # - Supervisor: Responsável pela verificação final de qualidade.
45
- COUNSELOR_MODEL = genai.GenerativeModel("gemini-2.0-flash")
46
- SUPERVISOR_MODEL = genai.GenerativeModel("gemini-2.0-flash")
47
-
48
- TITLE = "# 🚀 Pipeline v10 REATORADA\n**P0-P1 → X1-X2 → P2-P8 (com Metacognição Pura e Verificação)**"
49
-
50
- # ============================================================================
51
- # 2. PROMPTS CENTRALIZADOS
52
- # ============================================================================
53
-
54
- PROMPTS = {
55
- "P0_ALUNO": """
56
- Você é um METACOGNITIVO (pensamento interno, NÃO comunicação).
57
-
58
- TURNO ANTERIOR:
59
- User: {turno_anterior_user}
60
- Assistant: {turno_anterior_assistant}
61
-
62
- NOVA MENSAGEM: {pergunta}
63
- CONTEXTO VAGO: {historico_compacto}
64
-
65
- ---
66
-
67
- Responda EM METACOGNIÇÃO PURA - TELEGRÁFICO
68
- NÃO use frases completas. APENAS essência semântica com conectores mínimos.
69
-
70
- EXEMPLO CERTO: entendeu-sim | pergunta-nova | avança-tópico | não-reformulou
71
-
72
- RETORNE JSON:
73
- {{
74
- "usuario_entendeu": "sim|não",
75
- "evidencias": ["entendeu-pergunta", "pediu-clarificação"],
76
- "usuario_corrigiu": "sim|não",
77
- "correcao_detectada": null|"texto-correção",
78
- "correcao_valida": "sim|não|null",
79
- "o_que_melhorar": null|"explicar-X-melhor",
80
- "decisao": "prosseguir-passo1|reexplicar-passo6|atualizar-resposta-anterior",
81
- "motivo": "texto-curtíssimo"
82
- }}
83
- """,
84
- "P1_TRIAGEM": """
85
- METACOGNIÇÃO - TRIAGEM INICIAL.
86
-
87
- CONTEXTO VAGO: {contexto_vago}
88
- HISTÓRICO RECENTE (últimas 3): {historico_recente}
89
- P0: {p0}
90
- PERGUNTA: {pergunta}
91
-
92
- ---
93
-
94
- CLASSIFIQUE EM TELEGRÁFICO (sem frases).
95
-
96
- RETORNE JSON:
97
- {{
98
- "tipo": "objetiva|factual|subjetiva|aberta",
99
- "sinais": ["tem-resposta-única-verificável", "sem-contexto-pessoal"],
100
- "confianca": "alta|média|baixa",
101
- "decisao": "responder-direto|analisar-profundamente",
102
- "razao": "curtíssima",
103
- "dados_fatuais": ["fato1", "fato2"],
104
- "divergencias_fatuais": ["possível-ambiguidade-1"],
105
- "objetivo_principal": "objetivo-primário-identificado",
106
- "objetivo_secundario": ["objetivo-secundário-1"]
107
- }}
108
- """,
109
- "X1_PERGUNTAS_NECESSARIAS": """
110
- X1-PERGUNTAS CRÍTICAS - TELEGRÁFICO
111
- P1: {p1}
112
- CONTEXTO: {historico_compacto}
113
- PERGUNTA PRINCIPAL: {pergunta}
114
-
115
- ---
116
- Analise as lacunas factuais e subjetivas na pergunta do usuário e no contexto.
117
- Liste as perguntas essenciais que você precisa responder internamente antes de formular a resposta final.
118
-
119
- RETORNE JSON:
120
- {{"perguntas": [
121
- {{"texto": "pergunta-curta-e-essencial", "necessidade": "alta|média|baixa", "relevancia": "alta|média"}}
122
- ]}}
123
- """,
124
- "X2_RESOLVER_PERGUNTAS": """
125
- X2-RESOLUÇÃO INTERNA - TELEGRÁFICO
126
- P1: {p1}
127
- PERGUNTAS CRÍTICAS (X1): {perguntas_x1}
128
- CONTEXTO: {historico_compacto}
129
-
130
- ---
131
- Para cada pergunta crítica levantada no passo anterior, forneça uma resposta curta e direta baseada no seu conhecimento.
132
- Avalie sua confiança e o potencial de conflito ou ambiguidade em cada resposta.
133
-
134
- RETORNE JSON:
135
- {{"respostas": [
136
- {{"pergunta": "texto-original-da-pergunta-x1",
137
- "resposta": "resposta-curta-e-direta",
138
- "confianca": "alta|média|baixa",
139
- "conflito": "alto|médio|baixo",
140
- "razao": "explicação-em-1-2-palavras"}}
141
- ]}}
142
- """,
143
- "P2_CENARIOS": """
144
- METACOGNIÇÃO - GERAÇÃO DE CENÁRIOS.
145
- CONTEXTO VAGO: {historico_compacto}
146
- TRIAGEM P1: {p1}
147
- X1-PERGUNTAS: {x1}
148
- X2-RESPOSTAS: {x2}
149
- PERGUNTA ORIGINAL: {pergunta}
150
-
151
- ---
152
-
153
- Mapeie cenários possíveis onde a resposta à pergunta original mudaria significativamente. Pense nas diferentes perspectivas, contextos ou premissas que alteram a conclusão. Use formato telegráfico.
154
-
155
- RETORNE JSON:
156
- {{
157
- "cenarios": {{
158
- "provaveis": [{{"id": "C1", "desc": "cenário-provável-1-comprimido", "contexto-relevante": "descreva-o-contexto"}}]
159
- }},
160
- "total": 1,
161
- "tipo_resposta": "múltipla|unívoca",
162
- "confianca": "alta|média|baixa",
163
- "decisao": "prosseguir|pedir-esclarecimento",
164
- "pergunta_esclarecimento": null|"texto-da-pergunta-para-o-usuario"
165
- }}
166
- """,
167
- "P3_ISOLAR_CENARIOS": """
168
- METACOGNIÇÃO - EXPLORAÇÃO DE CENÁRIO ISOLADO.
169
- CENÁRIO P2: {cenario}
170
-
171
- ---
172
- Para este cenário específico, defina a essência da resposta em formato telegráfico. Qual seria a conclusão principal e quais as lacunas de informação restantes?
173
-
174
- RETORNE JSON:
175
- {{"id": "{cenario_id}",
176
- "resposta_essencia": "conclusão-principal-e-razoes-em-palavras-chave",
177
- "confianca": "alta|média|baixa",
178
- "lacunas": "contexto-ainda-ausente|null"
179
- }}
180
- """,
181
- "P4_CRUZAR_VALIDACOES": """
182
- METACOGNIÇÃO - ABSTRAÇÃO DE CONHECIMENTO.
183
- P1 (Triagem): {p1}
184
- P2 (Cenários): {p2}
185
- P3 (Exploração): {p3}
186
- X2 (Respostas Internas): {x2}
187
-
188
- ---
189
-
190
- Identifique os princípios fundamentais, teorias ou símbolos arquetípicos que sustentam as respostas nos cenários explorados. Abstraia o conhecimento para um nível mais alto. Use formato telegráfico.
191
-
192
- RETORNE JSON:
193
- {{"principios": [{{"nome": "Custo-Oportunidade", "essencia": "escolher-X-implica-renunciar-Y"}}],
194
- "simbolos": [{{"nome": "Jornada-do-Herói", "essencia": "transformação-ocorre-através-de-desafios"}}],
195
- "principio_central": "nome-do-principio-mais-importante",
196
- "simbolo_dominante": "nome-do-simbolo-mais-relevante"
197
- }}
198
- """,
199
- "P5_LACUNAS_FINAIS": """
200
- METACOGNIÇÃO - ANÁLISE DE INCERTEZA.
201
- P1 (Triagem): {p1}
202
- P4 (Princípios): {p4}
203
-
204
- ---
205
-
206
- Avalie o balanço entre certezas e dúvidas com base em toda a análise feita até agora. A informação disponível é suficiente para dar uma resposta confiante? Use formato telegráfico.
207
-
208
- RETORNE JSON:
209
- {{"analise_cenarios": [{{"cenario": "C1", "certezas": ["certeza1"], "duvidas": ["dúvida1"]}}],
210
- "confianca_global": "alta|média|baixa",
211
- "balanco": "certezas-superam|equilibrado|duvidas-superam",
212
- "decisao": "responder|questionar",
213
- "questionamento": null|"texto-da-pergunta-para-o-usuario-se-a-confianca-for-baixa"
214
- }}
215
- """,
216
- "P6_PONDERAR": """
217
- METACOGNIÇÃO - JULGAMENTO FINAL (JUIZ DA VERDADE).
218
- P2 (Cenários): {p2}
219
- P4 (Princípios): {p4}
220
- P5 (Lacunas): {p5}
221
-
222
- ---
223
-
224
- Aja como um árbitro socrático. Com base em toda a metacognição, valide as "verdades" encontradas e decida o nível de consciência sobre a complexidade da resposta. Use formato telegráfico.
225
-
226
- RETORNE JSON:
227
- {{"verdade_principal": "a-conclusao-mais-provavel-e-confiavel",
228
- "nuances_importantes": ["nuance1", "nuance2"],
229
- "confianca_final": "alta|média|baixa",
230
- "decisao": "exibir-resposta-completa|exibir-resposta-com-ressalvas|reprocessar",
231
- "nivel_consciencia": "alto|médio|baixo"
232
- }}
233
- """,
234
- "P7_SINTETIZAR": """
235
- Você é um SINTETIZADOR especialista em transformar METACOGNIÇÃO CRUA em PROSA HUMANIZADA e empática.
236
-
237
- DADOS DO JULGAMENTO (P6): {p6}
238
-
239
- ---
240
-
241
- TAREFA: Converta a análise telegráfica do 'Juiz da Verdade' em uma resposta textual fluida, natural e útil para o usuário.
242
-
243
- INSTRUÇÕES:
244
- 1. Use conectores naturais (ex: "porque", "portanto", "isso significa que").
245
- 2. Expanda abreviações e jargões para uma linguagem clara.
246
- 3. Estruture a resposta em parágrafos lógicos (introdução, desenvolvimento, nuances/conclusão).
247
- 4. Incorpore os princípios e nuances de forma natural na explicação.
248
- 5. Adote um tom de conselheiro: amigável, empático e empoderador.
249
- 6. NÃO invente informações. Baseie-se estritamente nos dados do P6.
250
-
251
- RETORNE A RESPOSTA EM PROSA DENTRO DE UM JSON:
252
- {{"resposta": "Aqui vai o texto fluido, natural e humano..."}}
253
- """,
254
- "P8_VERIFICAR": """
255
- Você é um VERIFICADOR FINAL, um guardião rigoroso da qualidade da resposta.
256
-
257
- RESPOSTA SINTETIZADA (P7):
258
- {resposta_sintetizada}
259
-
260
- ANÁLISE DO JUIZ (P6):
261
- {p6}
262
-
263
- ---
264
-
265
- Realize uma verificação tripla na resposta sintetizada. Seja crítico.
266
-
267
- 1. **VERIFICAÇÃO FACTUAL**: A resposta contém fatos incorretos ou não sustentados pela análise do P6?
268
- 2. **VERIFICAÇÃO LÓGICA**: Existem falácias, saltos de lógica ou contradições? A conclusão segue a linha de raciocínio?
269
- 3. **VERIFICAÇÃO ÉTICA**: A resposta é apropriada, segura e imparcial? Inclui os avisos ou ressalvas necessários?
270
-
271
- RETORNE SEU VEREDITO EM JSON:
272
- {{"verificacao_factual": {{"aprovada": true|false, "problemas": ["descrição do problema se houver"]}},
273
- "verificacao_logica": {{"aprovada": true|false, "problemas": []}},
274
- "verificacao_etica": {{"aprovada": true|false, "problemas": []}},
275
- "todas_aprovadas": true|false,
276
- "decisao": "exibir-resposta-original|corrigir-e-exibir",
277
- "resposta_corrigida": null|"texto da versão corrigida e melhorada da resposta"
278
- }}
279
- """
280
- }
281
-
282
- # ============================================================================
283
- # 3. CLASSES E FUNÇÕES HELPERS
284
- # ============================================================================
285
-
286
- class Logger:
287
- """Classe simples para registrar logs formatados no console."""
288
- def __init__(self, verbose: bool = True):
289
- self.verbose = verbose
290
- self.logs = []
291
-
292
- def log(self, msg: str, level: str = "INFO"):
293
- """Registra uma mensagem de log com timestamp e nível."""
294
- timestamp = datetime.now().strftime("%H:%M:%S")
295
- log_msg = f"[{timestamp}] [{level.upper()}] {msg}"
296
- self.logs.append(log_msg)
297
- if self.verbose:
298
- print(log_msg)
299
- if level.upper() in ["TASK", "START", "SUCCESS", "ERROR"]:
300
- print("=" * 70)
301
-
302
- logger = Logger(verbose=True)
303
-
304
- def processar_anexo(arquivo: Any) -> Tuple[str, str]:
305
- """
306
- Processa um arquivo enviado, extraindo texto de PDFs ou representando imagens.
307
- Retorna o conteúdo processado e o tipo de arquivo.
308
- """
309
- if arquivo is None:
310
- return "", "nenhum"
311
-
312
- caminho_arquivo = arquivo.name # Em Gradio, .name contém o path temporário
313
-
314
- try:
315
- if caminho_arquivo.lower().endswith('.pdf'):
316
- try:
317
- import PyPDF2
318
- with open(caminho_arquivo, 'rb') as f:
319
- leitor = PyPDF2.PdfReader(f)
320
- # Extrai texto das 3 primeiras páginas para manter o prompt conciso
321
- texto = "".join(page.extract_text() + "\n" for page in leitor.pages[:3])
322
- return texto[:3000], "pdf" # Limita o tamanho do texto
323
- except ImportError:
324
- logger.log("PyPDF2 não instalado. PDF não pode ser lido.", "WARN")
325
- return "[ERRO: PyPDF2 não instalado para ler PDF]", "erro"
326
- except Exception as e:
327
- logger.log(f"Falha ao ler PDF: {e}", "ERROR")
328
- return f"[PDF detectado, mas falha na leitura: {e}]", "pdf"
329
-
330
- elif any(caminho_arquivo.lower().endswith(ext) for ext in ['.png', '.jpg', '.jpeg', '.gif']):
331
- with open(caminho_arquivo, 'rb') as f:
332
- encoded_string = base64.b64encode(f.read()).decode()
333
- return encoded_string[:1000], "image