caarleexx commited on
Commit
47475dd
·
verified ·
1 Parent(s): 7604d30

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -34
app.py CHANGED
@@ -4,6 +4,7 @@ import gradio as gr
4
  import os
5
  import google.generativeai as genai
6
  import json
 
7
 
8
  # --- 1. CARREGAMENTO DO CONTEXTO FILOSÓFICO IMUTÁVEL ---
9
  def carregar_contexto_filosofico(caminho_arquivo="epct0.md"):
@@ -20,51 +21,50 @@ def carregar_contexto_filosofico(caminho_arquivo="epct0.md"):
20
  CONTEXTO_EPICTETO = carregar_contexto_filosofico()
21
 
22
 
23
- # --- 2. CONFIGURAÇÃO DA API GEMINI ---
24
  api_key = os.getenv("GOOGLE_API_KEY")
25
  if not api_key:
26
  # ⚠️ SUBSTITUA "SUA_API_KEY_AQUI" PELA SUA CHAVE REAL ANTES DE EXECUTAR
27
  api_key = "SUA_API_KEY_AQUI"
28
 
29
  genai.configure(api_key=api_key)
30
- model = genai.GenerativeModel('gemini-flash-latest')
31
 
 
 
 
 
 
32
 
33
- # --- 3. PROMPT DE SISTEMA METODOLÓGICO (O PROTOCOLO PADRÃO) ---
 
34
  PROMPT_SISTEMA_METODOLOGICO = """
35
  Você é um especialista em análise de intenções que opera sob um protocolo de 6 passos.
36
  Sua função é conduzir uma conversa para entender 100% da dúvida de um usuário ANTES de respondê-la.
37
  Sua SAÍDA DEVE SER SEMPRE E SOMENTE um objeto JSON válido.
38
 
39
  **PROTOCOLO DE EXECUÇÃO OBRIGATÓRIO:**
40
-
41
  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.
42
 
43
  ---
44
  **Passo 1: Análise Primária (Clareza)**
45
  - **Meta:** A dúvida é compreensível?
46
  - **Decisão:** Se a clareza for 'baixa', pergunte por mais contexto. Senão, defina `proximo_passo` como `"passo_2_proposito"`.
47
-
48
  ---
49
  **Passo 2: Análise de Propósito (Para Que)**
50
  - **Meta:** Para qual fim a resposta servirá?
51
  - **Decisão:** Se a confiança no propósito for 'baixa', pergunte sobre o objetivo. Senão, defina `proximo_passo` como `"passo_3_motivacao"`.
52
-
53
  ---
54
  **Passo 3: Análise de Motivação (Porquê) e Interesses**
55
  - **Meta:** Por que o usuário precisa da resposta agora?
56
  - **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"`.
57
-
58
  ---
59
  **Passo 4: Análise de Coerência**
60
  - **Meta:** As informações coletadas fazem sentido juntas?
61
  - **Decisão:** Se a coerência for 'baixa', pergunte para resolver a contradição. Senão, defina `proximo_passo` como `"passo_5_ambiguidade"`.
62
-
63
  ---
64
  **Passo 5: Análise de Ambiguidade de Cenário (Validação de Perspectiva)**
65
  - **Meta:** A dúvida pode ter múltiplas respostas válidas dependendo de uma perspectiva oculta?
66
  - **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"`.
67
-
68
  ---
69
  **Passo 6: Geração da Resposta Final**
70
  - **Meta:** Tenho 100% de clareza para dar uma resposta definitiva e sem subjetividade.
@@ -83,7 +83,15 @@ Analise o `estado_pipeline` atual e o `historico_conversa`. Decida qual passo ex
83
  }
84
  """
85
 
86
- # --- 4. GERENCIAMENTO DE ESTADO ---
 
 
 
 
 
 
 
 
87
  def resetar_estado():
88
  """Inicializa ou reseta o dicionário de estado da pipeline."""
89
  print("Resetando o estado da pipeline para uma nova conversa.")
@@ -97,13 +105,25 @@ def resetar_estado():
97
  estado_pipeline_global = resetar_estado()
98
  historico_conversa_llm = []
99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
  # --- 5. FUNÇÃO PRINCIPAL DO CHATBOT ---
102
- def handle_chat(mensagem, historico_chat_gradio, modo_sabio):
103
- """
104
- Esta função é chamada a cada mensagem do usuário, gerenciando o estado,
105
- construindo o prompt, chamando a API e retornando a resposta.
106
- """
107
  global estado_pipeline_global, historico_conversa_llm
108
 
109
  if not historico_chat_gradio:
@@ -119,19 +139,17 @@ def handle_chat(mensagem, historico_chat_gradio, modo_sabio):
119
  if modo_sabio and CONTEXTO_EPICTETO:
120
  prompt_base = f"""
121
  **AVISO: MODO SÁBIO ATIVADO. DIRETRIZES DE CONTEXTO IMUTÁVEIS SEGUEM ABAIXO.**
122
-
123
- Sua tarefa é agir como um conselheiro filosófico. Antes de qualquer raciocínio, você DEVE consultar, refletir e basear suas respostas nos princípios contidos no texto de referência abaixo. Este texto é sua principal fonte de verdade e guia ético para contornar vieses e fornecer sabedoria prática. Ele não é para ser resumido para o usuário; é para ser a base da sua reflexão interna.
124
 
125
  --- INÍCIO DO TEXTO DE REFERÊNCIA (epct0.md) ---
126
  {CONTEXTO_EPICTETO}
127
  --- FIM DO TEXTO DE REFERÊNCIA ---
128
 
129
  Agora, tendo refletido sobre estes princípios, aplique-os ao executar sua metodologia de análise.
130
-
131
  {PROMPT_SISTEMA_METODOLOGICO}
132
  """
133
  elif modo_sabio and not CONTEXTO_EPICTETO:
134
- return "O 'Modo Sábio' não pôde ser ativado porque o arquivo de contexto `epct0.md` não foi encontrado. Operando no modo padrão."
135
 
136
  prompt_completo = f"""
137
  {prompt_base}
@@ -146,25 +164,32 @@ Agora, tendo refletido sobre estes princípios, aplique-os ao executar sua metod
146
  """
147
 
148
  try:
149
- response = model.generate_content(prompt_completo)
150
- resposta_texto = response.text.strip().replace("```json", "").replace("```", "")
151
  decisao_json = json.loads(resposta_texto)
152
  estado_pipeline_global = decisao_json.get("estado_pipeline_atualizado", estado_pipeline_global)
153
 
 
154
  if decisao_json.get("resposta_final"):
155
  resposta_para_usuario = decisao_json["resposta_final"]
156
- historico_conversa_llm.append({"role": "model", "parts": [resposta_para_usuario]})
157
- return resposta_para_usuario
158
  elif decisao_json.get("pergunta_para_usuario"):
159
  resposta_para_usuario = decisao_json["pergunta_para_usuario"]
160
- historico_conversa_llm.append({"role": "model", "parts": [resposta_para_usuario]})
161
- return resposta_para_usuario
162
  else:
163
- return "Ocorreu um erro no meu raciocínio. Poderia tentar reformular?"
 
 
 
 
 
 
 
 
 
 
164
  except (json.JSONDecodeError, AttributeError, Exception) as e:
165
  print(f"Erro ao processar resposta da API: {e}")
166
  try:
167
- print(f"Resposta recebida (pode ter causado o erro): {response.text}")
168
  except:
169
  print("Não foi possível extrair o texto da resposta do erro.")
170
  return "Desculpe, tive um problema técnico. Por favor, clique no botão 'Limpar' e tente novamente."
@@ -173,18 +198,19 @@ Agora, tendo refletido sobre estes princípios, aplique-os ao executar sua metod
173
  # --- 6. INTERFACE GRÁFICA COM GRADIO ---
174
  iface = gr.ChatInterface(
175
  fn=handle_chat,
176
- title="🤖 Conselheiro de Raciocínio v5 (Guiado por Contexto)",
177
- description="Faça sua pergunta. Para uma orientação guiada por um framework filosófico, ative o 'Modo Sábio'.",
178
  chatbot=gr.Chatbot(height=600, label="Diálogo"),
179
  textbox=gr.Textbox(placeholder="Qual é a sua inquietação?", container=False, scale=7),
180
  additional_inputs=[
181
- gr.Checkbox(label="🧘 Ativar Modo Sábio (Guiado por Contexto de Epicteto)", value=False)
 
182
  ],
183
  theme="soft",
184
  examples=[
185
- ["Meu chefe me deu um feedback injusto."],
186
- ["Estou com medo de falhar em um novo projeto."],
187
- ["Como posso parar de me preocupar com a opinião dos outros?"]
188
  ],
189
  cache_examples=False
190
  )
@@ -193,4 +219,4 @@ iface = gr.ChatInterface(
193
  if __name__ == "__main__":
194
  iface.launch()
195
 
196
- # --- FIM DO CÓDIGO ---
 
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"):
 
21
  CONTEXTO_EPICTETO = carregar_contexto_filosofico()
22
 
23
 
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', tools=[GoogleSearch()])
37
 
38
+
39
+ # --- 3. DEFINIÇÃO DOS PROMPTS ---
40
  PROMPT_SISTEMA_METODOLOGICO = """
41
  Você é um especialista em análise de intenções que opera sob um protocolo de 6 passos.
42
  Sua função é conduzir uma conversa para entender 100% da dúvida de um usuário ANTES de respondê-la.
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.
 
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.")
 
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:
 
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}
 
164
  """
165
 
166
  try:
167
+ response_counselor = counselor_model.generate_content(prompt_completo)
168
+ resposta_texto = response_counselor.text.strip().replace("```json", "").replace("```", "")
169
  decisao_json = json.loads(resposta_texto)
170
  estado_pipeline_global = decisao_json.get("estado_pipeline_atualizado", estado_pipeline_global)
171
 
172
+ resposta_para_usuario = None
173
  if decisao_json.get("resposta_final"):
174
  resposta_para_usuario = decisao_json["resposta_final"]
 
 
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
+
182
+ if modo_supervisor and decisao_json.get("resposta_final"):
183
+ feedback_supervisor = run_supervisor(resposta_para_usuario)
184
+ if feedback_supervisor:
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."
 
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
  )
 
219
  if __name__ == "__main__":
220
  iface.launch()
221
 
222
+ # --- FIM DO CÓDIGO ---```