jeysshon commited on
Commit
afe4ed6
verified
1 Parent(s): 91d533f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +88 -85
app.py CHANGED
@@ -1,10 +1,10 @@
1
  import os
2
- import inspect
3
  import chainlit as cl
4
  import PyPDF2
5
  import httpx
6
  import requests
7
- from typing import List, Dict, Any, Optional
 
8
 
9
  from langchain.text_splitter import RecursiveCharacterTextSplitter
10
  from langchain.vectorstores import Chroma
@@ -15,9 +15,9 @@ from langchain.prompts.chat import (
15
  HumanMessagePromptTemplate,
16
  )
17
 
18
- # Configuraci贸n Deepseek
19
  DEEPSEEK_API_KEY = os.environ.get("DEEPSEEK_API_KEY")
20
- EMBEDDINGS_URL = "https://api.deepseek.com/v1/embeddings"
21
  CHAT_URL = "https://api.deepseek.com/v1/chat/completions"
22
 
23
  class DeepseekEmbeddings:
@@ -30,19 +30,17 @@ class DeepseekEmbeddings:
30
  "Content-Type": "application/json"
31
  }
32
 
33
- embeddings = []
34
- for text in texts:
35
- data = {
36
- "input": text,
37
- "model": "text-embedding-001",
38
- "encoding_type": "float"
39
- }
40
- response = requests.post(EMBEDDINGS_URL, json=data, headers=headers)
41
- if response.status_code == 200:
42
- embeddings.append(response.json()['data'][0]['embedding'])
43
- else:
44
- raise ValueError(f"Error en embeddings: {response.text}")
45
- return embeddings
46
 
47
  class DeepseekChat:
48
  def __init__(self, api_key: str):
@@ -68,31 +66,24 @@ class DeepseekChat:
68
  return response.json()['choices'][0]['message']['content']
69
  raise ValueError(f"Error en el chat: {response.text}")
70
 
71
- system_template = """Analiza en profundidad los siguientes documentos para responder la pregunta. Realiza:
72
- 1. Comparaci贸n cr铆tica entre fuentes
73
- 2. Detecci贸n de patrones y contradicciones
74
- 3. S铆ntesis de informaci贸n cruzada
75
- 4. Inferencias l贸gicas basadas en el contexto
76
- 5. Identificaci贸n de relaciones impl铆citas
77
-
78
- Incluye siempre:
79
- - Conclusiones fundamentadas
80
- - Evaluaci贸n de consistencia entre documentos
81
- - Posibles implicaciones pr谩cticas
82
- - FUENTES utilizadas (m谩ximo 3 relevantes)
83
 
84
- Ejemplo de respuesta:
85
- [An谩lisis principal]
86
- [Comparaci贸n de enfoques]
87
- [Conclusiones]
88
- FUENTES: x, y, z
89
 
90
- Contexto:
91
  {summaries}"""
92
 
93
  messages = [
94
  SystemMessagePromptTemplate.from_template(system_template),
95
- HumanMessagePromptTemplate.from_template("Pregunta: {question}\nRespuesta completa:")
96
  ]
97
  prompt = ChatPromptTemplate.from_messages(messages)
98
 
@@ -100,91 +91,103 @@ text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=20
100
 
101
  @cl.on_chat_start
102
  async def on_chat_start():
103
- await cl.Message(content="Bienvenido al analizador avanzado de gesti贸n de conflictos").send()
104
 
105
  pdf_paths = [
106
- 'gestios de conflictos.pdf',
107
- 'Managing Conflict with Your Boss .pdf'
108
  ]
109
 
110
  all_texts = []
111
  all_metadatas = []
112
 
113
  for path in pdf_paths:
114
- base_name = os.path.basename(path)
115
- with open(path, "rb") as f:
116
- reader = PyPDF2.PdfReader(f)
117
- pdf_text = " ".join([page.extract_text() for page in reader.pages if page.extract_text()])
118
- chunks = text_splitter.split_text(pdf_text)
119
- all_texts.extend(chunks)
120
- all_metadatas.extend([{
121
- "source": base_name,
122
- "page": (i // 3) + 1 # Estimaci贸n de p谩gina
123
- } for i, _ in enumerate(chunks)])
 
 
 
 
124
 
125
- embeddings = DeepseekEmbeddings(DEEPSEEK_API_KEY)
126
- docsearch = await cl.make_async(Chroma.from_texts)(
127
- all_texts,
128
- embeddings,
129
- metadatas=all_metadatas,
130
- collection_metadata={"hnsw:space": "cosine"}
131
- )
 
 
 
132
 
133
- chain = RetrievalQAWithSourcesChain.from_chain_type(
134
- DeepseekChat(DEEPSEEK_API_KEY),
135
- chain_type="stuff",
136
- retriever=docsearch.as_retriever(search_kwargs={"k": 5}),
137
- return_source_documents=True,
138
- chain_type_kwargs={"prompt": prompt}
139
- )
 
 
 
 
140
 
141
  cl.user_session.set("chain", chain)
142
  cl.user_session.set("metadatas", all_metadatas)
143
  cl.user_session.set("texts", all_texts)
144
 
145
- await cl.Message(content="Sistema listo. Puedes realizar preguntas complejas para an谩lisis detallado").send()
146
 
147
  @cl.on_message
148
  async def main(message: cl.Message):
149
  query = message.content
150
  chain = cl.user_session.get("chain")
151
- cb = cl.AsyncLangchainCallbackHandler()
152
 
153
  try:
154
- res = await chain.acall(query, callbacks=[cb])
155
  answer = res["answer"]
156
- sources = res.get("sources", "").split(",")
157
 
 
 
 
 
 
158
  metadatas = cl.user_session.get("metadatas")
159
  texts = cl.user_session.get("texts")
160
 
161
- source_details = []
162
  unique_sources = set()
163
- for src in sources:
 
164
  src = src.strip()
165
- if not src:
166
- continue
167
- matches = [i for i, m in enumerate(metadatas) if m["source"] == src]
168
- if matches:
169
- unique_sources.add(src)
170
- source_details.extend([
171
- cl.Text(
172
- content=texts[i],
173
- name=f"{src} (P谩gina {metadatas[i]['page']})"
174
- ) for i in matches[:2] # Mostrar m谩ximo 2 fragmentos por fuente
175
- ])
176
 
177
  if unique_sources:
178
- answer += f"\n\nFUENTES ANALIZADAS: {', '.join(sorted(unique_sources))}"
179
- answer += "\n\nFragmentos relevantes:"
180
 
181
  await cl.Message(
182
- content=answer,
183
- elements=source_details[:4] # Mostrar m谩ximo 4 fragmentos
 
184
  ).send()
185
 
186
  except Exception as e:
187
- await cl.Message(content=f"Error en el an谩lisis: {str(e)}").send()
188
 
189
  if __name__ == "__main__":
190
  from chainlit.cli import run_chainlit
 
1
  import os
 
2
  import chainlit as cl
3
  import PyPDF2
4
  import httpx
5
  import requests
6
+ from typing import List, Dict, Any
7
+ from markdown import markdown
8
 
9
  from langchain.text_splitter import RecursiveCharacterTextSplitter
10
  from langchain.vectorstores import Chroma
 
15
  HumanMessagePromptTemplate,
16
  )
17
 
18
+ # Configuraci贸n Deepseek Actualizada
19
  DEEPSEEK_API_KEY = os.environ.get("DEEPSEEK_API_KEY")
20
+ EMBEDDINGS_URL = "https://api.deepseek.com/v1/embeddings" # URL corregida
21
  CHAT_URL = "https://api.deepseek.com/v1/chat/completions"
22
 
23
  class DeepseekEmbeddings:
 
30
  "Content-Type": "application/json"
31
  }
32
 
33
+ data = {
34
+ "input": texts,
35
+ "model": "deepseek-embedding", # Modelo actualizado
36
+ "encoding_type": "float"
37
+ }
38
+
39
+ response = requests.post(EMBEDDINGS_URL, json=data, headers=headers)
40
+ if response.status_code == 200:
41
+ return [item["embedding"] for item in response.json()["data"]]
42
+ else:
43
+ raise ValueError(f"Error en embeddings: {response.text}")
 
 
44
 
45
  class DeepseekChat:
46
  def __init__(self, api_key: str):
 
66
  return response.json()['choices'][0]['message']['content']
67
  raise ValueError(f"Error en el chat: {response.text}")
68
 
69
+ system_template = """Eres un experto en gesti贸n de conflictos con habilidades avanzadas de an谩lisis. Puedes:
70
+ 1. Responder preguntas generales y t茅cnicas
71
+ 2. Generar tablas comparativas en markdown
72
+ 3. Analizar documentos en profundidad
73
+ 4. Combinar m煤ltiples fuentes de informaci贸n
 
 
 
 
 
 
 
74
 
75
+ Instrucciones:
76
+ - Usa formato markdown para tablas y listas
77
+ - Para preguntas t茅cnicas, usa los documentos como fuente principal
78
+ - Incluye siempre fuentes relevantes
79
+ - Si no hay informaci贸n suficiente, indica qu茅 aspectos no est谩n cubiertos en los documentos
80
 
81
+ Contexto documental:
82
  {summaries}"""
83
 
84
  messages = [
85
  SystemMessagePromptTemplate.from_template(system_template),
86
+ HumanMessagePromptTemplate.from_template("**Pregunta:** {question}\n**Respuesta (usar markdown si es necesario):**")
87
  ]
88
  prompt = ChatPromptTemplate.from_messages(messages)
89
 
 
91
 
92
  @cl.on_chat_start
93
  async def on_chat_start():
94
+ await cl.Message(content="Bienvenido al sistema experto en gesti贸n de conflictos").send()
95
 
96
  pdf_paths = [
97
+ "gestion de conflictos.pdf",
98
+ "Managing Conflict with Your Boss .pdf"
99
  ]
100
 
101
  all_texts = []
102
  all_metadatas = []
103
 
104
  for path in pdf_paths:
105
+ try:
106
+ base_name = os.path.basename(path)
107
+ with open(path, "rb") as f:
108
+ reader = PyPDF2.PdfReader(f)
109
+ pdf_text = " ".join([page.extract_text() or "" for page in reader.pages])
110
+ chunks = text_splitter.split_text(pdf_text)
111
+ all_texts.extend(chunks)
112
+ all_metadatas.extend([{
113
+ "source": base_name,
114
+ "page": (i // 3) + 1
115
+ } for i, _ in enumerate(chunks)])
116
+ except Exception as e:
117
+ await cl.Message(content=f"Error cargando {path}: {str(e)}").send()
118
+ return
119
 
120
+ try:
121
+ embeddings = DeepseekEmbeddings(DEEPSEEK_API_KEY)
122
+ docsearch = await cl.make_async(Chroma.from_texts)(
123
+ all_texts,
124
+ embeddings,
125
+ metadatas=all_metadatas
126
+ )
127
+ except Exception as e:
128
+ await cl.Message(content=f"Error creando embeddings: {str(e)}").send()
129
+ return
130
 
131
+ try:
132
+ chain = RetrievalQAWithSourcesChain.from_chain_type(
133
+ DeepseekChat(DEEPSEEK_API_KEY),
134
+ chain_type="stuff",
135
+ retriever=docsearch.as_retriever(search_kwargs={"k": 3}),
136
+ return_source_documents=True,
137
+ chain_type_kwargs={"prompt": prompt}
138
+ )
139
+ except Exception as e:
140
+ await cl.Message(content=f"Error configurando la cadena: {str(e)}").send()
141
+ return
142
 
143
  cl.user_session.set("chain", chain)
144
  cl.user_session.set("metadatas", all_metadatas)
145
  cl.user_session.set("texts", all_texts)
146
 
147
+ await cl.Message(content="Sistema listo. Puedes hacer preguntas o pedir an谩lisis con tablas").send()
148
 
149
  @cl.on_message
150
  async def main(message: cl.Message):
151
  query = message.content
152
  chain = cl.user_session.get("chain")
 
153
 
154
  try:
155
+ res = await chain.acall(query)
156
  answer = res["answer"]
 
157
 
158
+ # Formatear markdown
159
+ formatted_answer = markdown(answer)
160
+
161
+ # Manejo de fuentes
162
+ sources = res.get("sources", "")
163
  metadatas = cl.user_session.get("metadatas")
164
  texts = cl.user_session.get("texts")
165
 
166
+ source_elements = []
167
  unique_sources = set()
168
+
169
+ for src in sources.split(","):
170
  src = src.strip()
171
+ if src:
172
+ matches = [i for i, m in enumerate(metadatas) if m["source"] == src]
173
+ if matches:
174
+ unique_sources.add(src)
175
+ source_elements.append(cl.Text(
176
+ content=texts[matches[0]],
177
+ name=f"{src} (P谩gina {metadatas[matches[0]]['page']})"
178
+ ))
 
 
 
179
 
180
  if unique_sources:
181
+ formatted_answer += f"\n\n**Fuentes verificadas:** {', '.join(unique_sources)}"
 
182
 
183
  await cl.Message(
184
+ content=formatted_answer,
185
+ elements=source_elements[:3],
186
+ language="markdown"
187
  ).send()
188
 
189
  except Exception as e:
190
+ await cl.Message(content=f"Error procesando la consulta: {str(e)}").send()
191
 
192
  if __name__ == "__main__":
193
  from chainlit.cli import run_chainlit