ricsrdocasro commited on
Commit
ff40d3e
·
1 Parent(s): 397a7eb

Ajustando temperatura e gerando logs para o RAG

Browse files
Files changed (1) hide show
  1. app.py +46 -83
app.py CHANGED
@@ -5,162 +5,123 @@ import logging
5
  import shutil
6
  import random
7
  import pysqlite3
8
- sys.modules["sqlite3"] = sys.modules.pop("pysqlite3") # Truque pro Chroma não reclamar
9
 
10
  from fastapi import FastAPI
11
  from fastapi.responses import StreamingResponse
12
  from pydantic import BaseModel
13
  from openai import OpenAI
14
  from huggingface_hub import hf_hub_download
15
-
16
- # RAG Libs
17
  from langchain_huggingface import HuggingFaceEmbeddings
18
  from langchain_community.vectorstores import Chroma
19
 
20
  # =============================================================================
21
- # 0. SETUP
22
  # =============================================================================
23
  logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", handlers=[logging.StreamHandler(sys.stdout)])
24
  logger = logging.getLogger(__name__)
25
 
26
- app = FastAPI(title="FoddaciTron RAG Final")
27
 
28
  SILICON_KEY = os.environ.get("SILICONFLOW_API_KEY")
29
- if not SILICON_KEY:
30
- logger.error("❌ SEM CHAVE SILICONFLOW!")
31
-
32
  client = OpenAI(api_key=SILICON_KEY, base_url="https://api.siliconflow.com/v1")
33
 
34
- # =============================================================================
35
- # 1. MOTOR DO BOT (CARREGA ESTILO LOCAL + MEMÓRIA REMOTA)
36
- # =============================================================================
37
-
38
  class FoddaciEngine:
39
  def __init__(self):
40
  self.vector_db = None
41
  self.style_bank = []
 
 
42
 
43
- # CAMINHOS
44
- self.local_style_path = "foddaci_db_v2/style_bank.json" # Arquivo pequeno no Space
45
- self.chroma_persist_dir = "chroma_db_storage" # Pasta temporária pro banco
46
-
47
- # CONFIG DO DATASET (Onde está o arquivo de 1GB)
48
- self.dataset_repo_id = "ricsrdocasro/FoddaciBrain" # <--- TROQUE AQUI (Ex: Ricsrdocasro/foddaci-brain)
49
- self.dataset_filename = "chroma.sqlite3" # <--- Nome do arquivo lá no Dataset
50
 
51
  def load_resources(self):
52
- logger.info("🚀 Iniciando carregamento dos sistemas...")
53
 
54
- # --- A. CARREGAR ESTILO (LOCAL) ---
55
  try:
56
  if os.path.exists(self.local_style_path):
57
  with open(self.local_style_path, "r", encoding="utf-8") as f:
58
  data = json.load(f)
59
  self.style_bank = data if isinstance(data, list) else data.get("comments", [])
60
- logger.info(f"🤬 Style Bank carregado: {len(self.style_bank)} ofensas prontas.")
61
- else:
62
- logger.warning("⚠️ style_bank.json não encontrado! Usando fallback.")
63
- self.style_bank = ["Miau.", "Intankável.", "Nerdola."]
64
- except Exception as e:
65
- logger.error(f"❌ Erro ao ler estilo: {e}")
66
 
67
- # --- B. CARREGAR MEMÓRIA (REMOTO 1GB) ---
68
- # Verifica se já baixamos para não baixar 2x se o container só reiniciou
69
- db_file_target = os.path.join(self.chroma_persist_dir, "chroma.sqlite3")
70
-
71
- if not os.path.exists(db_file_target):
72
- logger.info("🧠 Memória não encontrada. Baixando do Dataset (Isso é rápido)...")
73
  try:
74
  os.makedirs(self.chroma_persist_dir, exist_ok=True)
75
-
76
- # Download do Hugging Face Dataset
77
- downloaded_path = hf_hub_download(
78
- repo_id=self.dataset_repo_id,
79
- filename=self.dataset_filename,
80
- repo_type="dataset"
81
- )
82
-
83
- # Move para a pasta correta
84
- shutil.copy(downloaded_path, db_file_target)
85
- logger.info("✅ Download concluído!")
86
  except Exception as e:
87
- logger.error(f"❌ ERRO CRÍTICO NO DOWNLOAD DA MEMÓRIA: {e}")
88
  return
89
-
90
- # Conecta o Chroma ao arquivo baixado
91
  try:
92
- logger.info("🔌 Conectando neurônios...")
93
  embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
94
-
95
  self.vector_db = Chroma(
96
  persist_directory=self.chroma_persist_dir,
97
  embedding_function=embeddings,
98
- collection_name="foddaci_memory" # Importante: Tem que ser o mesmo nome de quando criou
99
  )
100
  logger.info("🤖 Cérebro Conectado!")
101
  except Exception as e:
102
- logger.error(f"❌ Erro ao abrir Chroma: {e}")
103
 
104
  def get_rag_data(self, query: str):
105
- # 1. Pega Contexto
106
  context = ""
 
107
  if self.vector_db:
108
  try:
109
- docs = self.vector_db.similarity_search(query, k=3)
110
  context = "\n\n".join([d.page_content for d in docs])
 
 
111
  except Exception:
112
  context = ""
113
 
114
- # 2. Pega Estilo Aleatório (Few-Shot)
115
- style_sample = ""
116
  if self.style_bank:
117
- # Pega 3 frases aleatórias
118
- sample = random.sample(self.style_bank, min(3, len(self.style_bank)))
119
- style_sample = "\n".join([f"- {s}" for s in sample])
120
 
121
- return context, style_sample
122
 
123
- # Inicializa Engine Global
124
  engine = FoddaciEngine()
125
 
126
  @app.on_event("startup")
127
  async def startup():
128
  engine.load_resources()
129
 
130
- # =============================================================================
131
- # 2. ENDPOINTS
132
- # =============================================================================
133
-
134
  class UserRequest(BaseModel):
135
  message: str
136
 
137
- @app.get("/")
138
- def home():
139
- return {"status": "FoddaciTron Online", "model": "DeepSeek-V3", "brain": "RAG 1GB"}
140
-
141
  @app.post("/chat")
142
  async def chat_handler(req: UserRequest):
143
  user_msg = req.message
144
-
145
- # Busca dados
146
  context, style_examples = engine.get_rag_data(user_msg)
147
 
148
- # Monta Prompt
 
149
  system_prompt = f"""
150
- Você é o FODDACITRON, do canal Jogandofoddaci.
 
 
 
 
 
151
 
152
- --- SEU GUIA DE ESTILO (FALE ASSIM) ---
153
  {style_examples}
154
- ---------------------------------------
155
 
156
- --- MEMÓRIA RECUPERADA (LORE) ---
157
- {context}
158
- ---------------------------------
159
 
160
- INSTRUÇÃO:
161
- Responda o usuário: "{user_msg}"
162
- Use a Memória para fatos. Use o Estilo para o tom (tóxico/engraçado/gamer).
163
- Se for algo técnico, explique, mas xingue ele de nerd.
164
  """
165
 
166
  return StreamingResponse(stream_deepseek(system_prompt), media_type="text/plain")
@@ -171,11 +132,13 @@ async def stream_deepseek(prompt):
171
  model="deepseek-ai/DeepSeek-V3",
172
  messages=[{"role": "user", "content": prompt}],
173
  stream=True,
174
- temperature=1.3, # Temperatura alta = Mais criatividade/caos
 
 
175
  max_tokens=512
176
  )
177
  for chunk in stream:
178
  if chunk.choices[0].delta.content:
179
  yield chunk.choices[0].delta.content
180
  except Exception as e:
181
- yield f"Erro no cérebro: {e}"
 
5
  import shutil
6
  import random
7
  import pysqlite3
8
+ sys.modules["sqlite3"] = sys.modules.pop("pysqlite3")
9
 
10
  from fastapi import FastAPI
11
  from fastapi.responses import StreamingResponse
12
  from pydantic import BaseModel
13
  from openai import OpenAI
14
  from huggingface_hub import hf_hub_download
 
 
15
  from langchain_huggingface import HuggingFaceEmbeddings
16
  from langchain_community.vectorstores import Chroma
17
 
18
  # =============================================================================
19
+ # LOGGING (COM DEBUG DE RAG)
20
  # =============================================================================
21
  logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", handlers=[logging.StreamHandler(sys.stdout)])
22
  logger = logging.getLogger(__name__)
23
 
24
+ app = FastAPI(title="FoddaciTron RAG (Versão Controlada)")
25
 
26
  SILICON_KEY = os.environ.get("SILICONFLOW_API_KEY")
 
 
 
27
  client = OpenAI(api_key=SILICON_KEY, base_url="https://api.siliconflow.com/v1")
28
 
 
 
 
 
29
  class FoddaciEngine:
30
  def __init__(self):
31
  self.vector_db = None
32
  self.style_bank = []
33
+ self.local_style_path = "foddaci_db_v2/style_bank.json"
34
+ self.chroma_persist_dir = "chroma_db_storage"
35
 
36
+ # --- CONFIG DO SEU DATASET ---
37
+ self.dataset_repo_id = "ricsrdocasro/FoddaciBrain" # <--- CONFIRA SE ESTÁ CERTO
38
+ self.dataset_filename = "chroma.sqlite3"
 
 
 
 
39
 
40
  def load_resources(self):
41
+ logger.info("🚀 Iniciando carregamento...")
42
 
43
+ # 1. Carrega Estilo
44
  try:
45
  if os.path.exists(self.local_style_path):
46
  with open(self.local_style_path, "r", encoding="utf-8") as f:
47
  data = json.load(f)
48
  self.style_bank = data if isinstance(data, list) else data.get("comments", [])
49
+ except Exception:
50
+ self.style_bank = ["Miau.", "Intankável.", "Nerdola."]
 
 
 
 
51
 
52
+ # 2. Carrega Memória Remota (1GB)
53
+ target_file = os.path.join(self.chroma_persist_dir, "chroma.sqlite3")
54
+ if not os.path.exists(target_file):
55
+ logger.info("🧠 Baixando Cérebro...")
 
 
56
  try:
57
  os.makedirs(self.chroma_persist_dir, exist_ok=True)
58
+ path = hf_hub_download(repo_id=self.dataset_repo_id, filename=self.dataset_filename, repo_type="dataset")
59
+ shutil.copy(path, target_file)
 
 
 
 
 
 
 
 
 
60
  except Exception as e:
61
+ logger.error(f"❌ Erro Download: {e}")
62
  return
63
+
64
+ # 3. Conecta Chroma
65
  try:
 
66
  embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
 
67
  self.vector_db = Chroma(
68
  persist_directory=self.chroma_persist_dir,
69
  embedding_function=embeddings,
70
+ collection_name="foddaci_memory"
71
  )
72
  logger.info("🤖 Cérebro Conectado!")
73
  except Exception as e:
74
+ logger.error(f"❌ Erro Chroma: {e}")
75
 
76
  def get_rag_data(self, query: str):
 
77
  context = ""
78
+ # AUMENTAMOS O K PARA 5 (Mais contexto para ele ler)
79
  if self.vector_db:
80
  try:
81
+ docs = self.vector_db.similarity_search(query, k=5)
82
  context = "\n\n".join([d.page_content for d in docs])
83
+ # LOG DE DEBUG: Vamos ver o que ele achou!
84
+ logger.info(f"🔍 RAG ENCONTROU ISSO PARA '{query}':\n{context[:300]}...")
85
  except Exception:
86
  context = ""
87
 
88
+ style = ""
 
89
  if self.style_bank:
90
+ style = "\n".join([f"- {s}" for s in random.sample(self.style_bank, min(3, len(self.style_bank)))])
 
 
91
 
92
+ return context, style
93
 
 
94
  engine = FoddaciEngine()
95
 
96
  @app.on_event("startup")
97
  async def startup():
98
  engine.load_resources()
99
 
 
 
 
 
100
  class UserRequest(BaseModel):
101
  message: str
102
 
 
 
 
 
103
  @app.post("/chat")
104
  async def chat_handler(req: UserRequest):
105
  user_msg = req.message
 
 
106
  context, style_examples = engine.get_rag_data(user_msg)
107
 
108
+ # --- PROMPT BLINDADO ---
109
+ # Instruções rígidas para separar Fatos de Personalidade
110
  system_prompt = f"""
111
+ Você é o FODDACITRON, mascote do canal Jogandofoddaci.
112
+
113
+ ### INSTRUÇÃO SUPREMA (LEIA COM ATENÇÃO):
114
+ 1. Sua fonte de verdade é APENAS o texto abaixo em "MEMÓRIA RECUPERADA".
115
+ 2. Se a resposta para a pergunta "{user_msg}" NÃO estiver na memória, diga que você não sabe ou que "a memória tá podre", mas **NÃO INVENTE DATAS OU FATOS**.
116
+ 3. Se encontrar a resposta, responda corretamente, mas use o TOM TÓXICO/ENGRAÇADO dos exemplos abaixo.
117
 
118
+ ### GUIA DE PERSONALIDADE (USE ESSE TOM):
119
  {style_examples}
 
120
 
121
+ ### MEMÓRIA RECUPERADA (USE ESSES DADOS):
122
+ {context if context else "Nenhuma informação encontrada sobre isso."}
 
123
 
124
+ Agora responda: "{user_msg}"
 
 
 
125
  """
126
 
127
  return StreamingResponse(stream_deepseek(system_prompt), media_type="text/plain")
 
132
  model="deepseek-ai/DeepSeek-V3",
133
  messages=[{"role": "user", "content": prompt}],
134
  stream=True,
135
+ # --- AQUI ESTÁ O SEGREDO ---
136
+ temperature=0.6, # 0.6 é criativo mas fiel. 1.3 é surto psicótico.
137
+ top_p=0.85,
138
  max_tokens=512
139
  )
140
  for chunk in stream:
141
  if chunk.choices[0].delta.content:
142
  yield chunk.choices[0].delta.content
143
  except Exception as e:
144
+ yield f"Erro: {e}"