Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
import os
|
2 |
-
from typing import Optional, Tuple
|
3 |
import gradio as gr
|
4 |
from langchain_community.document_loaders import PyPDFLoader, DirectoryLoader
|
5 |
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
@@ -31,8 +31,9 @@ class RAGSystem:
|
|
31 |
model=self.model,
|
32 |
tokenizer=self.tokenizer,
|
33 |
max_length=512,
|
34 |
-
temperature=0.
|
35 |
-
top_p=0.95
|
|
|
36 |
)
|
37 |
|
38 |
self.llm = HuggingFacePipeline(pipeline=pipe)
|
@@ -104,6 +105,26 @@ class RAGSystem:
|
|
104 |
print(f"Erro ao processar PDF: {str(e)}")
|
105 |
return None
|
106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
def generate_response(self, file_obj, query: str, progress=gr.Progress()) -> Tuple[str, str, str]:
|
108 |
"""Retorna (resposta, status, tempo_decorrido)"""
|
109 |
if not query.strip():
|
@@ -111,42 +132,68 @@ class RAGSystem:
|
|
111 |
|
112 |
start_time = time.time()
|
113 |
try:
|
114 |
-
progress(0, desc="
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
|
116 |
# Processa documento
|
117 |
-
|
118 |
-
if file_obj is not None:
|
119 |
db = self.process_pdf(file_obj)
|
120 |
if db is None:
|
121 |
return "Não foi possível processar o PDF.", "❌ Erro no processamento", "0s"
|
122 |
-
elif self.base_db is not None:
|
123 |
-
db = self.base_db
|
124 |
else:
|
125 |
-
|
126 |
|
127 |
progress(0.4, desc="Buscando informações relevantes...")
|
|
|
|
|
128 |
qa_chain = RetrievalQA.from_chain_type(
|
129 |
llm=self.llm,
|
130 |
chain_type="stuff",
|
131 |
retriever=db.as_retriever(
|
132 |
-
search_kwargs={
|
|
|
|
|
|
|
|
|
133 |
),
|
134 |
return_source_documents=True
|
135 |
)
|
136 |
|
137 |
progress(0.6, desc="Gerando resposta...")
|
138 |
-
prompt = f"""Baseado nos documentos fornecidos, responda em português à seguinte pergunta:
|
139 |
-
{query}
|
140 |
|
141 |
-
|
142 |
-
|
143 |
-
|
|
|
|
|
|
|
|
|
|
|
144 |
|
|
|
145 |
result = qa_chain({"query": prompt})
|
146 |
-
elapsed_time = f"{time.time() - start_time:.1f}s"
|
147 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
progress(1.0, desc="Concluído!")
|
149 |
-
|
|
|
150 |
|
151 |
except Exception as e:
|
152 |
elapsed_time = f"{time.time() - start_time:.1f}s"
|
@@ -162,7 +209,7 @@ def create_demo():
|
|
162 |
"""
|
163 |
# 🤖 Assistente de Documentos Inteligente
|
164 |
|
165 |
-
|
166 |
"""
|
167 |
)
|
168 |
|
@@ -180,14 +227,16 @@ def create_demo():
|
|
180 |
)
|
181 |
info = gr.Markdown(
|
182 |
f"""
|
183 |
-
ℹ️
|
|
|
|
|
184 |
"""
|
185 |
)
|
186 |
|
187 |
with gr.Group():
|
188 |
gr.Markdown("### ❓ Sua Pergunta")
|
189 |
query_input = gr.Textbox(
|
190 |
-
placeholder="Digite sua pergunta
|
191 |
lines=3,
|
192 |
max_lines=6,
|
193 |
show_label=False,
|
@@ -227,10 +276,10 @@ def create_demo():
|
|
227 |
with gr.Accordion("📚 Exemplos de Perguntas", open=False):
|
228 |
gr.Examples(
|
229 |
examples=[
|
230 |
-
[None, "
|
231 |
-
[None, "
|
232 |
-
[None, "
|
233 |
-
[None, "
|
234 |
],
|
235 |
inputs=[file_input, query_input],
|
236 |
)
|
@@ -239,11 +288,11 @@ def create_demo():
|
|
239 |
gr.Markdown(
|
240 |
"""
|
241 |
---
|
242 |
-
### 🔧
|
243 |
-
*
|
244 |
-
* Processamento de documentos
|
245 |
-
*
|
246 |
-
*
|
247 |
"""
|
248 |
)
|
249 |
|
|
|
1 |
import os
|
2 |
+
from typing import Optional, Tuple, Dict
|
3 |
import gradio as gr
|
4 |
from langchain_community.document_loaders import PyPDFLoader, DirectoryLoader
|
5 |
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
|
|
31 |
model=self.model,
|
32 |
tokenizer=self.tokenizer,
|
33 |
max_length=512,
|
34 |
+
temperature=0.3, # Reduzido para respostas mais precisas
|
35 |
+
top_p=0.95,
|
36 |
+
repetition_penalty=1.2
|
37 |
)
|
38 |
|
39 |
self.llm = HuggingFacePipeline(pipeline=pipe)
|
|
|
105 |
print(f"Erro ao processar PDF: {str(e)}")
|
106 |
return None
|
107 |
|
108 |
+
def format_response(self, raw_response: str, source_type: str, context_found: bool) -> str:
|
109 |
+
"""Formata a resposta para um formato padronizado e claro"""
|
110 |
+
if not context_found:
|
111 |
+
return "🔍 Não foram encontradas informações suficientes nos documentos para responder esta pergunta."
|
112 |
+
|
113 |
+
prefix = ""
|
114 |
+
if source_type == "pdf":
|
115 |
+
prefix = "📄 [Resposta baseada no PDF enviado]\n\n"
|
116 |
+
elif source_type == "base":
|
117 |
+
prefix = "📚 [Resposta baseada na base de documentos]\n\n"
|
118 |
+
elif source_type == "both":
|
119 |
+
prefix = "📚📄 [Resposta baseada em ambas as fontes]\n\n"
|
120 |
+
|
121 |
+
# Limpa e formata a resposta
|
122 |
+
response = raw_response.strip()
|
123 |
+
if not response:
|
124 |
+
return "🔍 Não foi possível gerar uma resposta adequada com as informações disponíveis."
|
125 |
+
|
126 |
+
return f"{prefix}{response}"
|
127 |
+
|
128 |
def generate_response(self, file_obj, query: str, progress=gr.Progress()) -> Tuple[str, str, str]:
|
129 |
"""Retorna (resposta, status, tempo_decorrido)"""
|
130 |
if not query.strip():
|
|
|
132 |
|
133 |
start_time = time.time()
|
134 |
try:
|
135 |
+
progress(0.2, desc="Processando documentos...")
|
136 |
+
|
137 |
+
# Determina a fonte dos documentos
|
138 |
+
has_pdf = file_obj is not None
|
139 |
+
has_base = self.base_db is not None
|
140 |
+
source_type = "both" if has_pdf and has_base else "pdf" if has_pdf else "base" if has_base else None
|
141 |
+
|
142 |
+
if not source_type:
|
143 |
+
return "Nenhuma fonte de documentos disponível.", "❌ Sem documentos", "0s"
|
144 |
|
145 |
# Processa documento
|
146 |
+
if has_pdf:
|
|
|
147 |
db = self.process_pdf(file_obj)
|
148 |
if db is None:
|
149 |
return "Não foi possível processar o PDF.", "❌ Erro no processamento", "0s"
|
|
|
|
|
150 |
else:
|
151 |
+
db = self.base_db
|
152 |
|
153 |
progress(0.4, desc="Buscando informações relevantes...")
|
154 |
+
|
155 |
+
# Configuração do RAG
|
156 |
qa_chain = RetrievalQA.from_chain_type(
|
157 |
llm=self.llm,
|
158 |
chain_type="stuff",
|
159 |
retriever=db.as_retriever(
|
160 |
+
search_kwargs={
|
161 |
+
"k": 4,
|
162 |
+
"fetch_k": 6,
|
163 |
+
"score_threshold": 0.5 # Filtra resultados pouco relevantes
|
164 |
+
}
|
165 |
),
|
166 |
return_source_documents=True
|
167 |
)
|
168 |
|
169 |
progress(0.6, desc="Gerando resposta...")
|
|
|
|
|
170 |
|
171 |
+
# Prompt mais estruturado
|
172 |
+
prompt = f"""Instruções:
|
173 |
+
1. Analise cuidadosamente os documentos fornecidos
|
174 |
+
2. Responda à seguinte pergunta em português de forma clara e direta: {query}
|
175 |
+
3. Use apenas informações encontradas nos documentos
|
176 |
+
4. Se não houver informações suficientes, indique explicitamente
|
177 |
+
5. Mantenha a resposta objetiva e baseada em fatos
|
178 |
+
6. Cite exemplos específicos dos documentos quando relevante"""
|
179 |
|
180 |
+
# Gera resposta
|
181 |
result = qa_chain({"query": prompt})
|
|
|
182 |
|
183 |
+
# Verifica se encontrou contexto relevante
|
184 |
+
context_found = bool(result.get("source_documents", []))
|
185 |
+
|
186 |
+
# Formata a resposta
|
187 |
+
formatted_response = self.format_response(
|
188 |
+
result["result"],
|
189 |
+
source_type,
|
190 |
+
context_found
|
191 |
+
)
|
192 |
+
|
193 |
+
elapsed_time = f"{time.time() - start_time:.1f}s"
|
194 |
progress(1.0, desc="Concluído!")
|
195 |
+
|
196 |
+
return formatted_response, "✅ Sucesso", elapsed_time
|
197 |
|
198 |
except Exception as e:
|
199 |
elapsed_time = f"{time.time() - start_time:.1f}s"
|
|
|
209 |
"""
|
210 |
# 🤖 Assistente de Documentos Inteligente
|
211 |
|
212 |
+
Sistema de consulta avançada que responde perguntas sobre seus documentos usando RAG.
|
213 |
"""
|
214 |
)
|
215 |
|
|
|
227 |
)
|
228 |
info = gr.Markdown(
|
229 |
f"""
|
230 |
+
ℹ️ O sistema consulta:
|
231 |
+
- PDFs enviados por você
|
232 |
+
- Documentos na pasta `{DOCS_DIR}`
|
233 |
"""
|
234 |
)
|
235 |
|
236 |
with gr.Group():
|
237 |
gr.Markdown("### ❓ Sua Pergunta")
|
238 |
query_input = gr.Textbox(
|
239 |
+
placeholder="Digite sua pergunta sobre os documentos...",
|
240 |
lines=3,
|
241 |
max_lines=6,
|
242 |
show_label=False,
|
|
|
276 |
with gr.Accordion("📚 Exemplos de Perguntas", open=False):
|
277 |
gr.Examples(
|
278 |
examples=[
|
279 |
+
[None, "Quais são os principais tópicos abordados neste documento?"],
|
280 |
+
[None, "Resuma as conclusões mais importantes."],
|
281 |
+
[None, "O que o documento diz sobre [tema específico]?"],
|
282 |
+
[None, "Quais são as recomendações apresentadas?"],
|
283 |
],
|
284 |
inputs=[file_input, query_input],
|
285 |
)
|
|
|
288 |
gr.Markdown(
|
289 |
"""
|
290 |
---
|
291 |
+
### 🔧 Informações do Sistema
|
292 |
+
* Respostas geradas usando tecnologia RAG (Retrieval-Augmented Generation)
|
293 |
+
* Processamento inteligente de documentos PDF
|
294 |
+
* Respostas baseadas exclusivamente no conteúdo dos documentos
|
295 |
+
* Suporte a múltiplos documentos e contextos
|
296 |
"""
|
297 |
)
|
298 |
|