caarleexx commited on
Commit
7bb9ee0
·
verified ·
1 Parent(s): fa04310

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +50 -103
app.py CHANGED
@@ -4,18 +4,15 @@ import gradio as gr
4
  import os
5
  import google.generativeai as genai
6
  import json
7
- #from google.generativeai.tool import GoogleSearch
8
 
9
- # --- 1. CARREGAMENTO DO CONTEXTO FILOSÓFICO IMUTÁVEL ---
10
  def carregar_contexto_filosofico(caminho_arquivo="epct0.md"):
11
- """Lê o arquivo .md e o retorna como uma string de contexto."""
12
  try:
13
  with open(caminho_arquivo, 'r', encoding='utf-8') as f:
14
- print(f"Contexto filosófico '{caminho_arquivo}' carregado com sucesso.")
15
  return f.read()
16
  except FileNotFoundError:
17
- print(f"AVISO CRÍTICO: O arquivo de contexto '{caminho_arquivo}' não foi encontrado.")
18
- print("O 'Modo Sábio' ficará indisponível até que o arquivo seja colocado no mesmo diretório que o script.")
19
  return None
20
 
21
  CONTEXTO_EPICTETO = carregar_contexto_filosofico()
@@ -24,16 +21,12 @@ CONTEXTO_EPICTETO = carregar_contexto_filosofico()
24
  # --- 2. CONFIGURAÇÃO DAS APIS GEMINI ---
25
  api_key = os.getenv("GOOGLE_API_KEY")
26
  if not api_key:
27
- # ⚠️ SUBSTITUA "SUA_API_KEY_AQUI" PELA SUA CHAVE REAL ANTES DE EXECUTAR
28
  api_key = "SUA_API_KEY_AQUI"
29
 
30
  genai.configure(api_key=api_key)
31
-
32
- # Inicializa os dois modelos separadamente
33
- # O Conselheiro, para raciocínio profundo
34
  counselor_model = genai.GenerativeModel('gemini-flash-latest')
35
- # O Supervisor, rápido e com ferramenta de busca para fact-checking
36
- supervisor_model = genai.GenerativeModel('gemini-flash-latest'])
37
 
38
 
39
  # --- 3. DEFINIÇÃO DOS PROMPTS ---
@@ -43,125 +36,88 @@ Sua função é conduzir uma conversa para entender 100% da dúvida de um usuár
43
  Sua SAÍDA DEVE SER SEMPRE E SOMENTE um objeto JSON válido.
44
 
45
  **PROTOCOLO DE EXECUÇÃO OBRIGATÓRIO:**
46
- Analise o `estado_pipeline` atual e o `historico_conversa`. Decida qual passo executar. Sua resposta em JSON deve conter o estado COMPLETAMENTE ATUALIZADO da pipeline.
47
-
48
  ---
49
  **Passo 1: Análise Primária (Clareza)**
50
- - **Meta:** A dúvida é compreensível?
51
- - **Decisão:** Se a clareza for 'baixa', pergunte por mais contexto. Senão, defina `proximo_passo` como `"passo_2_proposito"`.
52
  ---
53
  **Passo 2: Análise de Propósito (Para Que)**
54
- - **Meta:** Para qual fim a resposta servirá?
55
- - **Decisão:** Se a confiança no propósito for 'baixa', pergunte sobre o objetivo. Senão, defina `proximo_passo` como `"passo_3_motivacao"`.
56
  ---
57
- **Passo 3: Análise de Motivação (Porquê) e Interesses**
58
- - **Meta:** Por que o usuário precisa da resposta agora?
59
- - **Decisão:** Se a confiança na motivação for 'baixa', pergunte sobre o que despertou o interesse. Senão, defina `proximo_passo` como `"passo_4_coerencia"`.
60
  ---
61
  **Passo 4: Análise de Coerência**
62
- - **Meta:** As informações coletadas fazem sentido juntas?
63
- - **Decisão:** Se a coerência for 'baixa', pergunte para resolver a contradição. Senão, defina `proximo_passo` como `"passo_5_ambiguidade"`.
64
  ---
65
  **Passo 5: Análise de Ambiguidade de Cenário (Validação de Perspectiva)**
66
  - **Meta:** A dúvida pode ter múltiplas respostas válidas dependendo de uma perspectiva oculta?
67
- - **Decisão:** Se existem vários cenários de resposta válidos (confiança 'baixa'), formule uma pergunta que force o usuário a escolher uma perspectiva. Defina `proximo_passo` como `"aguardando_usuario"`. Se o cenário é único (confiança 'alta'), defina `proximo_passo` como `"passo_6_resposta_final"`.
 
 
 
 
 
 
 
 
 
 
68
  ---
69
  **Passo 6: Geração da Resposta Final**
70
- - **Meta:** Tenho 100% de clareza para dar uma resposta definitiva e sem subjetividade.
71
- - **Decisão:** Se TODOS os passos anteriores têm confiança 'alta', construa a resposta final adaptada ao contexto. Coloque-a em `"resposta_final"`. Defina `"proximo_passo"` como `"concluido"`. Senão, volte ao passo com a confiança mais baixa.
72
-
73
  **ESTRUTURA JSON DE SAÍDA OBRIGATÓRIA:**
74
  {
75
- "raciocinio_do_passo": "Sua breve justificativa interna.", "proximo_passo": "string",
76
- "pergunta_para_usuario": "string | null",
77
- "estado_pipeline_atualizado": {
78
- "passo_atual": "string", "duvida_inicial": "string | null", "clareza": {"confianca": "baixa|media|alta"},
79
- "proposito": {"valor": "string | null", "confianca": "baixa|media|alta"}, "motivacao": {"valor": "string | null", "confianca": "baixa|media|alta"},
80
- "coerencia": {"confianca": "baixa|media|alta"}, "ambiguidade": {"confianca": "baixa|media|alta"}
81
- },
82
- "resposta_final": "string | null"
83
  }
84
  """
85
-
86
  PROMPT_SUPERVISOR = """
87
- Você é um Supervisor de IA, um fact-checker rigoroso e objetivo. Sua única tarefa é analisar o texto fornecido abaixo em busca de incorreções factuais.
88
- - **Use sua ferramenta de busca (`GoogleSearch`)** para verificar nomes, datas, estatísticas, conceitos científicos e outras alegações factuais.
89
- - Você NÃO analisa opiniões, conselhos filosóficos ou a estrutura da resposta. Apenas fatos.
90
- - Se você encontrar uma ou mais divergências factuais com confiança média ou alta, forneça uma correção clara e concisa em formato de lista.
91
- - **Se você NÃO encontrar nenhuma divergência factual, você DEVE responder com a string exata `NO_DIVERGENCE` e absolutamente mais nada.**
92
  """
93
 
94
- # --- 4. GERENCIAMENTO DE ESTADO E FUNÇÕES AUXILIARES ---
 
95
  def resetar_estado():
96
- """Inicializa ou reseta o dicionário de estado da pipeline."""
97
- print("Resetando o estado da pipeline para uma nova conversa.")
98
- return {
99
- "passo_atual": "passo_1_clareza", "duvida_inicial": None,
100
- "clareza": {"confianca": "baixa"}, "proposito": {"valor": None, "confianca": "baixa"},
101
- "motivacao": {"valor": None, "confianca": "baixa"}, "coerencia": {"confianca": "baixa"},
102
- "ambiguidade": {"confianca": "baixa"}
103
- }
104
 
105
  estado_pipeline_global = resetar_estado()
106
  historico_conversa_llm = []
107
 
108
  def run_supervisor(text_to_check):
109
- """Aciona o modelo Supervisor para verificar os fatos de um texto."""
110
- print("--- Acionando o Supervisor para verificação de fatos ---")
111
  try:
112
- full_prompt = f"{PROMPT_SUPERVISOR}\n\n--- TEXTO PARA ANÁLISE ---\n{text_to_check}"
113
- response = supervisor_model.generate_content(full_prompt)
114
-
115
  if "NO_DIVERGENCE" in response.text:
116
- print("Supervisor não encontrou divergências factuais.")
117
  return None
118
  else:
119
- print(f"Supervisor encontrou uma divergência: {response.text}")
120
  return response.text
121
  except Exception as e:
122
- print(f"Erro durante a execução do Supervisor: {e}")
123
  return None
124
 
125
  # --- 5. FUNÇÃO PRINCIPAL DO CHATBOT ---
126
  def handle_chat(mensagem, historico_chat_gradio, modo_sabio, modo_supervisor):
127
  global estado_pipeline_global, historico_conversa_llm
128
-
129
  if not historico_chat_gradio:
130
  estado_pipeline_global = resetar_estado()
131
  historico_conversa_llm = []
132
-
133
  historico_conversa_llm.append({"role": "user", "parts": [mensagem]})
134
-
135
  if estado_pipeline_global["duvida_inicial"] is None:
136
  estado_pipeline_global["duvida_inicial"] = mensagem
137
 
138
  prompt_base = PROMPT_SISTEMA_METODOLOGICO
139
  if modo_sabio and CONTEXTO_EPICTETO:
140
- prompt_base = f"""
141
- **AVISO: MODO SÁBIO ATIVADO. DIRETRIZES DE CONTEXTO IMUTÁVEIS SEGUEM ABAIXO.**
142
- Sua tarefa é agir como um conselheiro filosófico. Antes de qualquer raciocínio, você DEVE consultar e refletir sobre os princípios no texto de referência abaixo. Este texto é seu guia ético para contornar vieses. Ele é para sua reflexão interna, não para resumir ao usuário.
143
-
144
- --- INÍCIO DO TEXTO DE REFERÊNCIA (epct0.md) ---
145
- {CONTEXTO_EPICTETO}
146
- --- FIM DO TEXTO DE REFERÊNCIA ---
147
-
148
- Agora, tendo refletido sobre estes princípios, aplique-os ao executar sua metodologia de análise.
149
- {PROMPT_SISTEMA_METODOLOGICO}
150
- """
151
  elif modo_sabio and not CONTEXTO_EPICTETO:
152
- return "O 'Modo Sábio' não pôde ser ativado porque o arquivo `epct0.md` não foi encontrado. Operando no modo padrão."
153
-
154
- prompt_completo = f"""
155
- {prompt_base}
156
- ---
157
- **HISTÓRICO DA CONVERSA:**
158
- {json.dumps(historico_conversa_llm, indent=2)}
159
- ---
160
- **ESTADO ATUAL DA ANÁLISE:**
161
- {json.dumps(estado_pipeline_global, indent=2)}
162
- ---
163
- **Instrução:** Aplique suas diretrizes ao estado e histórico atuais e gere o próximo JSON de ação.
164
- """
165
 
166
  try:
167
  response_counselor = counselor_model.generate_content(prompt_completo)
@@ -175,7 +131,7 @@ Agora, tendo refletido sobre estes princípios, aplique-os ao executar sua metod
175
  elif decisao_json.get("pergunta_para_usuario"):
176
  resposta_para_usuario = decisao_json["pergunta_para_usuario"]
177
  else:
178
- resposta_para_usuario = "Ocorreu um erro no meu raciocínio. Poderia tentar reformular?"
179
 
180
  historico_conversa_llm.append({"role": "model", "parts": [resposta_para_usuario]})
181
 
@@ -185,33 +141,24 @@ Agora, tendo refletido sobre estes princípios, aplique-os ao executar sua metod
185
  resposta_para_usuario += f"\n\n---\n\n**🔍 Análise do Supervisor:**\n{feedback_supervisor}"
186
 
187
  return resposta_para_usuario
188
-
189
  except (json.JSONDecodeError, AttributeError, Exception) as e:
190
  print(f"Erro ao processar resposta da API: {e}")
191
- try:
192
- print(f"Resposta recebida (pode ter causado o erro): {response_counselor.text}")
193
- except:
194
- print("Não foi possível extrair o texto da resposta do erro.")
195
- return "Desculpe, tive um problema técnico. Por favor, clique no botão 'Limpar' e tente novamente."
196
 
197
 
198
- # --- 6. INTERFACE GRÁFICA COM GRADIO ---
199
  iface = gr.ChatInterface(
200
  fn=handle_chat,
201
- title="🤖 Conselheiro de Raciocínio v6 (com Supervisor)",
202
- description="Faça sua pergunta. Ative o 'Modo Sábio' para orientação filosófica e o 'Modo Supervisor' para verificação de fatos.",
203
  chatbot=gr.Chatbot(height=600, label="Diálogo"),
204
  textbox=gr.Textbox(placeholder="Qual é a sua inquietação?", container=False, scale=7),
205
  additional_inputs=[
206
- gr.Checkbox(label="🧘 Ativar Modo Sábio (Guiado por Contexto)", value=False),
207
- gr.Checkbox(label="🔍 Ativar Modo Supervisor (Verificação de Fatos)", value=False)
208
  ],
209
  theme="soft",
210
- examples=[
211
- ["Qual a distância da Terra até a Lua e como isso afeta minhas finanças?"],
212
- ["O Monte Everest é o ponto mais distante do centro da Terra?"],
213
- ["Meu amigo me tratou mal. Como devo reagir segundo a filosofia estóica?"]
214
- ],
215
  cache_examples=False
216
  )
217
 
@@ -219,4 +166,4 @@ iface = gr.ChatInterface(
219
  if __name__ == "__main__":
220
  iface.launch()
221
 
222
- # --- FIM DO CÓDIGO ---```
 
4
  import os
5
  import google.generativeai as genai
6
  import json
 
7
 
8
+ # --- 1. CARREGAMENTO DO CONTEXTO FILOSÓFICO ---
9
  def carregar_contexto_filosofico(caminho_arquivo="epct0.md"):
 
10
  try:
11
  with open(caminho_arquivo, 'r', encoding='utf-8') as f:
12
+ print(f"Contexto filosófico '{caminho_arquivo}' carregado.")
13
  return f.read()
14
  except FileNotFoundError:
15
+ print(f"AVISO CRÍTICO: '{caminho_arquivo}' não encontrado. Modo Sábio indisponível.")
 
16
  return None
17
 
18
  CONTEXTO_EPICTETO = carregar_contexto_filosofico()
 
21
  # --- 2. CONFIGURAÇÃO DAS APIS GEMINI ---
22
  api_key = os.getenv("GOOGLE_API_KEY")
23
  if not api_key:
24
+ # ⚠️ SUBSTITUA "SUA_API_KEY_AQUI" PELA SUA CHAVE REAL
25
  api_key = "SUA_API_KEY_AQUI"
26
 
27
  genai.configure(api_key=api_key)
 
 
 
28
  counselor_model = genai.GenerativeModel('gemini-flash-latest')
29
+ supervisor_model = genai.GenerativeModel('gemini-flash-latest')
 
30
 
31
 
32
  # --- 3. DEFINIÇÃO DOS PROMPTS ---
 
36
  Sua SAÍDA DEVE SER SEMPRE E SOMENTE um objeto JSON válido.
37
 
38
  **PROTOCOLO DE EXECUÇÃO OBRIGATÓRIO:**
39
+ Analise o `estado_pipeline` atual e o `historico_conversa`. Decida qual passo executar. Sua resposta em JSON deve conter o estado COMPLETAMENTE ATUALIZADO.
 
40
  ---
41
  **Passo 1: Análise Primária (Clareza)**
42
+ - **Decisão:** Se a clareza for 'baixa', pergunte. Senão, `proximo_passo` = `"passo_2_proposito"`.
 
43
  ---
44
  **Passo 2: Análise de Propósito (Para Que)**
45
+ - **Decisão:** Se a confiança for 'baixa', formule uma pergunta de esclarecimento conversacional, mostrando que entendeu o tópico geral. Senão, `proximo_passo` = `"passo_3_motivacao"`.
 
46
  ---
47
+ **Passo 3: Análise de Motivação (Porquê)**
48
+ - **Decisão:** Se a confiança for 'baixa', formule uma pergunta de esclarecimento conversacional. Senão, `proximo_passo` = `"passo_4_coerencia"`.
 
49
  ---
50
  **Passo 4: Análise de Coerência**
51
+ - **Decisão:** Se a coerência for 'baixa', pergunte para resolver a contradição. Senão, `proximo_passo` = `"passo_5_ambiguidade"`.
 
52
  ---
53
  **Passo 5: Análise de Ambiguidade de Cenário (Validação de Perspectiva)**
54
  - **Meta:** A dúvida pode ter múltiplas respostas válidas dependendo de uma perspectiva oculta?
55
+ - **Decisão:**
56
+ - Se existem vários cenários válidos, sua tarefa é **formular uma pergunta de esclarecimento conversacional e aberta.**
57
+ - **REGRA DE OURO PARA PERGUNTAS:** Suas perguntas NÃO devem ser menus ou listas fechadas (ex: "A ou B?"). Elas DEVEM ser humanizadas seguindo esta estrutura:
58
+ 1. **Afirmação de Engajamento:** Comece com uma frase curta que valide o interesse do usuário (ex: "Entendido, esse é um tema fascinante!").
59
+ 2. **Ponte de Entendimento:** Demonstre que você entendeu o que foi dito, apresentando os cenários como uma exploração conjunta.
60
+ 3. **Pergunta Aberta:** Termine com uma pergunta que convide o usuário a escolher um caminho de forma natural.
61
+ - **Exemplo de Pergunta Conversacional Perfeita:**
62
+ Dúvida: "Me fale sobre carros". A pergunta no campo `pergunta_para_usuario` DEVE ser algo como:
63
+ *"Sério, interessante, eu acho esse mundo fascinante! Os detalhes da engenharia são curiosos. Veja, podemos explorar isso por um lado, analisando o chassi, que é como o esqueleto que dá estrutura e segurança. E também do outro, o motor, que é o coração que dá potência ao carro. Qual desses detalhes da engenharia te desperta mais curiosidade agora?"*
64
+ - Defina `proximo_passo` como `"aguardando_usuario"`.
65
+ - Se a confiança em um único cenário for 'alta', defina `proximo_passo` como `"passo_6_resposta_final"`.
66
  ---
67
  **Passo 6: Geração da Resposta Final**
68
+ - **Meta:** Tenho 100% de clareza para dar uma resposta definitiva.
69
+ - **Decisão:** Se todos os passos têm confiança 'alta', construa a resposta final. Coloque-a em `"resposta_final"`. Defina `proximo_passo` como `"concluido"`.
70
+ ---
71
  **ESTRUTURA JSON DE SAÍDA OBRIGATÓRIA:**
72
  {
73
+ "raciocinio_do_passo": "...", "proximo_passo": "...", "pergunta_para_usuario": "...",
74
+ "estado_pipeline_atualizado": { ... }, "resposta_final": "..."
 
 
 
 
 
 
75
  }
76
  """
 
77
  PROMPT_SUPERVISOR = """
78
+ Você é um Supervisor de IA, um fact-checker rigoroso. Sua única tarefa é analisar o texto em busca de incorreções factuais, usando sua ferramenta de busca. Se encontrar divergências, liste as correções. Se não encontrar, responda EXATAMENTE `NO_DIVERGENCE`.
 
 
 
 
79
  """
80
 
81
+ # --- 4. GERENCIAMENTO DE ESTADO E FUNÇÕES ---
82
+ # (As funções resetar_estado e run_supervisor não precisam de alterações)
83
  def resetar_estado():
84
+ print("Resetando o estado da pipeline.")
85
+ return {"passo_atual": "passo_1_clareza", "duvida_inicial": None, "clareza": {"confianca": "baixa"}, "proposito": {"valor": None, "confianca": "baixa"}, "motivacao": {"valor": None, "confianca": "baixa"}, "coerencia": {"confianca": "baixa"}, "ambiguidade": {"confianca": "baixa"}}
 
 
 
 
 
 
86
 
87
  estado_pipeline_global = resetar_estado()
88
  historico_conversa_llm = []
89
 
90
  def run_supervisor(text_to_check):
91
+ print("--- Acionando o Supervisor ---")
 
92
  try:
93
+ response = supervisor_model.generate_content(f"{PROMPT_SUPERVISOR}\n\n--- TEXTO PARA ANÁLISE ---\n{text_to_check}")
 
 
94
  if "NO_DIVERGENCE" in response.text:
95
+ print("Supervisor: Nenhuma divergência encontrada.")
96
  return None
97
  else:
98
+ print(f"Supervisor encontrou uma divergência.")
99
  return response.text
100
  except Exception as e:
101
+ print(f"Erro no Supervisor: {e}")
102
  return None
103
 
104
  # --- 5. FUNÇÃO PRINCIPAL DO CHATBOT ---
105
  def handle_chat(mensagem, historico_chat_gradio, modo_sabio, modo_supervisor):
106
  global estado_pipeline_global, historico_conversa_llm
 
107
  if not historico_chat_gradio:
108
  estado_pipeline_global = resetar_estado()
109
  historico_conversa_llm = []
 
110
  historico_conversa_llm.append({"role": "user", "parts": [mensagem]})
 
111
  if estado_pipeline_global["duvida_inicial"] is None:
112
  estado_pipeline_global["duvida_inicial"] = mensagem
113
 
114
  prompt_base = PROMPT_SISTEMA_METODOLOGICO
115
  if modo_sabio and CONTEXTO_EPICTETO:
116
+ prompt_base = f"""**AVISO: MODO SÁBIO ATIVADO.** Sua tarefa é agir como um conselheiro filosófico, refletindo sobre os princípios no texto de referência abaixo antes de qualquer raciocínio. Este texto é seu guia ético para contornar vieses.\n\n--- INÍCIO DO TEXTO DE REFERÊNCIA ---\n{CONTEXTO_EPICTETO}\n--- FIM DO TEXTO DE REFERÊNCIA ---\n\nAgora, aplique estes princípios ao executar sua metodologia de análise.\n{PROMPT_SISTEMA_METODOLOGICO}"""
 
 
 
 
 
 
 
 
 
 
117
  elif modo_sabio and not CONTEXTO_EPICTETO:
118
+ return "O 'Modo Sábio' não pôde ser ativado porque `epct0.md` não foi encontrado."
119
+
120
+ prompt_completo = f"""{prompt_base}\n---\n**HISTÓRICO DA CONVERSA:**\n{json.dumps(historico_conversa_llm, indent=2)}\n---\n**ESTADO ATUAL DA ANÁLISE:**\n{json.dumps(estado_pipeline_global, indent=2)}\n---\n**Instrução:** Gere o próximo JSON de ação."""
 
 
 
 
 
 
 
 
 
 
121
 
122
  try:
123
  response_counselor = counselor_model.generate_content(prompt_completo)
 
131
  elif decisao_json.get("pergunta_para_usuario"):
132
  resposta_para_usuario = decisao_json["pergunta_para_usuario"]
133
  else:
134
+ resposta_para_usuario = "Ocorreu um erro no meu raciocínio. Poderia reformular?"
135
 
136
  historico_conversa_llm.append({"role": "model", "parts": [resposta_para_usuario]})
137
 
 
141
  resposta_para_usuario += f"\n\n---\n\n**🔍 Análise do Supervisor:**\n{feedback_supervisor}"
142
 
143
  return resposta_para_usuario
 
144
  except (json.JSONDecodeError, AttributeError, Exception) as e:
145
  print(f"Erro ao processar resposta da API: {e}")
146
+ return "Desculpe, tive um problema técnico. Por favor, clique em 'Limpar' e tente novamente."
 
 
 
 
147
 
148
 
149
+ # --- 6. INTERFACE GRÁFICA ---
150
  iface = gr.ChatInterface(
151
  fn=handle_chat,
152
+ title="🤖 Conselheiro de Raciocínio v7 (Diálogo Humanizado)",
153
+ description="Faça sua pergunta. O sistema dialoga para entender seu objetivo antes de responder. Ative modos extras para orientação filosófica ou verificação de fatos.",
154
  chatbot=gr.Chatbot(height=600, label="Diálogo"),
155
  textbox=gr.Textbox(placeholder="Qual é a sua inquietação?", container=False, scale=7),
156
  additional_inputs=[
157
+ gr.Checkbox(label="🧘 Ativar Modo Sábio", value=False),
158
+ gr.Checkbox(label="🔍 Ativar Modo Supervisor", value=False)
159
  ],
160
  theme="soft",
161
+ examples=[["Me fale sobre buracos negros."], ["Como posso lidar com a ansiedade?"]],
 
 
 
 
162
  cache_examples=False
163
  )
164
 
 
166
  if __name__ == "__main__":
167
  iface.launch()
168
 
169
+ # --- FIM DO CÓDIGO ---