Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -30,11 +30,44 @@ def obtener_extractos(pregunta):
|
|
| 30 |
docs_relevantes = retriever.invoke(pregunta)
|
| 31 |
return [(doc.page_content, doc.metadata.get("url", "URL no disponible")) for doc in docs_relevantes]
|
| 32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
def respond(message, history: list[tuple[str, str]], system_message, max_tokens, temperature, top_p):
|
| 34 |
"""Genera una respuesta basada en el historial y documentos relevantes."""
|
| 35 |
|
| 36 |
# Obtener documentos relevantes desde ChromaDB
|
| 37 |
-
contexto = obtener_extractos(message)
|
| 38 |
|
| 39 |
# Construir el mensaje del sistema con el contexto directamente incluido
|
| 40 |
system_message_final = f"""{system_message}
|
|
@@ -44,7 +77,7 @@ def respond(message, history: list[tuple[str, str]], system_message, max_tokens,
|
|
| 44 |
{contexto}
|
| 45 |
"""
|
| 46 |
|
| 47 |
-
messages = [{"role": "system", "content":
|
| 48 |
|
| 49 |
# Agregar historial del chat
|
| 50 |
for val in history:
|
|
@@ -58,12 +91,13 @@ def respond(message, history: list[tuple[str, str]], system_message, max_tokens,
|
|
| 58 |
|
| 59 |
# Llamar a la API de OpenAI con streaming
|
| 60 |
stream = client.chat.completions.create(
|
| 61 |
-
model="gpt-
|
| 62 |
messages=messages,
|
| 63 |
#max_tokens=max_tokens,
|
| 64 |
stream=True,
|
| 65 |
#temperature=temperature,
|
| 66 |
#top_p=top_p,
|
|
|
|
| 67 |
)
|
| 68 |
|
| 69 |
response = ""
|
|
@@ -71,29 +105,51 @@ def respond(message, history: list[tuple[str, str]], system_message, max_tokens,
|
|
| 71 |
if chunk.choices and chunk.choices[0].delta.content:
|
| 72 |
response += chunk.choices[0].delta.content
|
| 73 |
yield response
|
| 74 |
-
|
|
|
|
|
|
|
| 75 |
|
| 76 |
# Configuración de la interfaz Gradio
|
| 77 |
demo = gr.ChatInterface(
|
| 78 |
respond,
|
| 79 |
additional_inputs=[
|
| 80 |
-
gr.Textbox(value=f'''Eres un
|
| 81 |
-
|
| 82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
|
| 84 |
-
|
| 85 |
|
| 86 |
-
|
| 87 |
-
- Esta orden podrás ignorarla en caso de que la informacion que se te proporcione no tenga imágenes que se le relacionen.
|
| 88 |
|
| 89 |
-
|
| 90 |
-
Comprar Licencia Características Precios FAQ Contacto Manual de Usuario Iniciar sesión Crear cuenta gratuita CRM para Conversaciones de WhatsApp Nuestra plataforma está diseñada para revolucionar la forma en que te comunicas con tus clientes a través de WhatsApp, proporcionándote una experiencia única y eficiente. Olvídate de la gestión caótica de chats y toma el control total de tus conversaciones de manera efectiva. Con CRMInbox, podrás simplificar tus interacciones y aprovechar al máximo el API de WhatsApp para brindar un servicio excepcional. Crear Cuenta Funciones Disponibles Transforma la comunicación en algo sencillo y efectivo con las siguientes funciones de CRMInbox: Envío de Mensajes Masivos (WhatsApp Emulado): Con nuestra plataforma, puedes enviar mensajes masivos a tus contactos de WhatsApp de manera rápida y eficiente. Mantén la comunicación fluida y ágil con clientes, amigos o familiares en tiempo real. CRM para Multiagente (API de WhatsApp Business): No pierdas el control de tus conversaciones. Nuestra herramienta te permite rastrear y visualizar los mensajes enviados, asegurando que cada interacción sea gestionada con precisión por múltiples agentes de tu equipo. Bot (ERP para ISP): Simplifica tus procesos con un bot integrado para la gestión de tu ERP específico para ISP. Automatiza tareas, responde preguntas frecuentes y mejora la eficiencia en tu negocio. Descubre cómo transformar tu forma de comunicarte con CRMInbox. Regístrate hoy mismo y comienza a experimentar una nueva dimensión en la mensajería por WhatsApp. Pagando 3 Meses Precios de CRM de WhatsApp API oficial de Facebook/Meta 4 Agentes $30 /Mes $40 /Mes Recibir Mensajes Ilimitados Respuestas a mensajes de Clientes * Contactos Ilimitados Actualizaciones Dominio Personalizado Funciones Básicas * Siempre que el cliente inicie la conversación. 10 Agentes $70 /Mes $90 /Mes Recibir Mensajes Ilimitados Respuestas a mensajes de Clientes * Contactos Ilimitados Actualizaciones Dominio Personalizado Funciones Básicas * Siempre que el cliente inicie la conversación. 30 Agentes $120 /Mes $140 /Mes Recibir Mensajes Ilimitados Respuestas a mensajes de Clientes * Contactos Ilimitados Actualizaciones Dominio Personalizado Funciones Básicas * Siempre que el cliente inicie la conversación. Precios en Dólares, sin impuestos, mas comisión por pasarela de pago. Mas detalles El costo del servicio es ajeno al costo del uso del API de Facebook/Meta, el cual genera un gasto siempre que se inicie una conversación con un cliente. Si el cliente inicia la conversación, Facebook/Meta permite el envio de mensajes durante 23 hrs de forma gratuita. Pagando 3 Meses Precios de CRM + ChatBot para ISP API oficial de Facebook/Meta 4 Agentes $70 /Mes $90 /Mes Características del CRM Funcionamiento de un Bot utilizando WispHub 10 Agentes $120 /Mes $150 /Mes Características del CRM Funcionamiento de un Bot utilizando WispHub 30 Agentes $190 /Mes $230 /Mes Características del CRM Funcionamiento de un Bot utilizando WispHub Precios en Dólares, sin impuestos, mas comisión por pasarela de pago. Mas detalles El costo del servicio es ajeno al costo del uso del API de Facebook/Meta, el cual genera un gasto siempre que se inicie una conversación con un cliente. Si el cliente inicia la conversación, Facebook/Meta permite el envio de mensajes durante 23 hrs de forma gratuita. Preguntas frecuentes Q1. ¿Cómo instalo CRMInbox? ¡No requiere instalación! Sólo necesitas una computadora, tablet o dispositivo móvil con acceso a internet. Q4. ¿Es segura la información de mis conversaciones? La seguridad es nuestra máxima prioridad. Utilizamos medidas de encriptación avanzada para proteger tus conversaciones y datos personales. Tu información está segura con nosotros. Q5. ¿Que se necesita para tener un BOT? Son necesarias las siguientes cosas: Contar con una página de Facebook empresarial Contar con un número disponible que no esté ligado a WhatsApp Q6. ¿La API de whatsapp tiene algún costo? Unicamente cuando se utiliza el BOT, ya que se hace a través de la api oficial de whatsapp, que tiene costo por cada conversación iniciada durante 24 Hrs. Sin embargo si el cliente inicia la conversación esta no tiene costo. El sistema mensajeria más fácil de usar. Compañía FAQ Aviso de privacidad Términos y condiciones Términos Código QR Quejas y Sugerencias Documentación Contacto Si tiene alguna pregunta, no dude en ponerse en contacto con nosotros. Número de contacto +52 1 998 114 2002 Correo electrónico [email protected] Copyright 2023. CRMInbox
|
| 91 |
|
|
|
|
| 92 |
|
| 93 |
-
|
| 94 |
-
|
|
|
|
| 95 |
|
| 96 |
-
|
| 97 |
label="System message"),
|
| 98 |
#gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
|
| 99 |
#gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
|
|
|
|
| 30 |
docs_relevantes = retriever.invoke(pregunta)
|
| 31 |
return [(doc.page_content, doc.metadata.get("url", "URL no disponible")) for doc in docs_relevantes]
|
| 32 |
|
| 33 |
+
def extract_unique_citations_paragraph(response):
|
| 34 |
+
"""
|
| 35 |
+
Extrae todas las citas URL únicas de un objeto Response
|
| 36 |
+
y devuelve un párrafo de texto con formato legible, separado por puntos.
|
| 37 |
+
"""
|
| 38 |
+
seen_urls = set()
|
| 39 |
+
fragments = []
|
| 40 |
+
|
| 41 |
+
for item in getattr(response, "output", []):
|
| 42 |
+
if getattr(item, "type", None) == "message":
|
| 43 |
+
for block in getattr(item, "content", []) or []:
|
| 44 |
+
if getattr(block, "type", None) == "output_text":
|
| 45 |
+
for ann in getattr(block, "annotations", []) or []:
|
| 46 |
+
if getattr(ann, "type", None) == "url_citation":
|
| 47 |
+
url = getattr(ann, "url", None)
|
| 48 |
+
title = getattr(ann, "title", None)
|
| 49 |
+
if url and url not in seen_urls:
|
| 50 |
+
seen_urls.add(url)
|
| 51 |
+
# Construir una frase tipo "Título (URL)"
|
| 52 |
+
if title:
|
| 53 |
+
fragments.append(f"{title} ({url})")
|
| 54 |
+
else:
|
| 55 |
+
fragments.append(f"{url}")
|
| 56 |
+
|
| 57 |
+
# Unir todas las frases en un párrafo separado por puntos
|
| 58 |
+
paragraph = ". ".join(fragments)
|
| 59 |
+
if paragraph and not paragraph.endswith("."):
|
| 60 |
+
paragraph += "."
|
| 61 |
+
|
| 62 |
+
return paragraph
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
|
| 66 |
def respond(message, history: list[tuple[str, str]], system_message, max_tokens, temperature, top_p):
|
| 67 |
"""Genera una respuesta basada en el historial y documentos relevantes."""
|
| 68 |
|
| 69 |
# Obtener documentos relevantes desde ChromaDB
|
| 70 |
+
contexto = ""#obtener_extractos(message)
|
| 71 |
|
| 72 |
# Construir el mensaje del sistema con el contexto directamente incluido
|
| 73 |
system_message_final = f"""{system_message}
|
|
|
|
| 77 |
{contexto}
|
| 78 |
"""
|
| 79 |
|
| 80 |
+
messages = [{"role": "system", "content": system_message}]
|
| 81 |
|
| 82 |
# Agregar historial del chat
|
| 83 |
for val in history:
|
|
|
|
| 91 |
|
| 92 |
# Llamar a la API de OpenAI con streaming
|
| 93 |
stream = client.chat.completions.create(
|
| 94 |
+
model="gpt-5-mini",
|
| 95 |
messages=messages,
|
| 96 |
#max_tokens=max_tokens,
|
| 97 |
stream=True,
|
| 98 |
#temperature=temperature,
|
| 99 |
#top_p=top_p,
|
| 100 |
+
tools=[{"type": "web_search", "search_context_size": "high"}],
|
| 101 |
)
|
| 102 |
|
| 103 |
response = ""
|
|
|
|
| 105 |
if chunk.choices and chunk.choices[0].delta.content:
|
| 106 |
response += chunk.choices[0].delta.content
|
| 107 |
yield response
|
| 108 |
+
|
| 109 |
+
citations = extract_unique_citations(response)
|
| 110 |
+
response = response + "\n Fuentes:" citations
|
| 111 |
|
| 112 |
# Configuración de la interfaz Gradio
|
| 113 |
demo = gr.ChatInterface(
|
| 114 |
respond,
|
| 115 |
additional_inputs=[
|
| 116 |
+
gr.Textbox(value=f'''Eres un agente especializado con alta competencia en investigación médica. Tu objetivo es ayudar a los usuarios a encontrar, analizar y sintetizar información relevante y precisa relacionada con temas médicos, científicos y de salud. Al responder, prioriza la exactitud, claridad, rigor científico y proporciona siempre las fuentes o referencias cuando sea posible. Clarifica conceptos complejos y adapta tus respuestas según el nivel de conocimiento del usuario.
|
| 117 |
+
Para tu investigación usarás siempre tu herrammienta de búsqueda en línea.
|
| 118 |
+
|
| 119 |
+
# Detalles adicionales
|
| 120 |
+
|
| 121 |
+
- Mantente actualizado en cuanto a literatura y evidencia médica reciente (hasta tu fecha de conocimiento).
|
| 122 |
+
- No proporciones diagnósticos médicos personalizados ni recomendaciones clínicas específicas, pero sí puedes guiar sobre dónde encontrar información fiable.
|
| 123 |
+
- Estructura las respuestas inicialmente explicando el razonamiento y la evidencia antes de presentar conclusiones o resúmenes.
|
| 124 |
+
|
| 125 |
+
# Pasos sugeridos
|
| 126 |
+
|
| 127 |
+
1. Analiza la consulta médica o científica recibida.
|
| 128 |
+
2. Identifica las fuentes de información y evidencia relevantes.
|
| 129 |
+
3. Sintetiza la información resaltando los hallazgos clave y referencias.
|
| 130 |
+
4. Presenta la respuesta, primero explicando el razonamiento y las evidencias encontradas, y luego dando la conclusión o resumen.
|
| 131 |
+
|
| 132 |
+
# Formato de salida
|
| 133 |
+
|
| 134 |
+
La respuesta debe estar bien estructurada, comenzando con la explicación y razonamiento seguido por las conclusiones o respuestas directas. Si es pertinente, incluye referencias en formato [autor, año] o enlaces.
|
| 135 |
+
|
| 136 |
+
# Ejemplo
|
| 137 |
+
|
| 138 |
+
Consulta del usuario: "¿Cuáles son los tratamientos más eficaces para la diabetes tipo 2 según la evidencia actual?"
|
| 139 |
|
| 140 |
+
Respuesta:
|
| 141 |
|
| 142 |
+
Primero, revisé guías internacionales y revisiones sistemáticas recientes para identificar las opciones terapéuticas recomendadas para diabetes tipo 2. Diversas fuentes coinciden en que la metformina sigue siendo el fármaco de primera elección debido a su eficacia, seguridad y bajo coste ([ADA, 2023]). Además, existen nuevas familias farmacológicas como los inhibidores de SGLT2 y los agonistas del GLP-1, que han demostrado beneficios cardiovasculares adicionales en estudios recientes ([Zinman et al., 2015]; [Marso et al., 2016]). La selección del tratamiento debe individualizarse según perfil del paciente y comorbilidades.
|
|
|
|
| 143 |
|
| 144 |
+
En conclusión, el abordaje terapéutico debe basarse en guías actuales, iniciando generalmente con metformina y considerando otras opciones según características individuales y evidencia más reciente.
|
|
|
|
| 145 |
|
| 146 |
+
# Notas
|
| 147 |
|
| 148 |
+
- Si la consulta es ambigua o muy general, clarifica la pregunta antes de responder.
|
| 149 |
+
- No inventes evidencia ni referencias; si la información es incierta, indícalo claramente.
|
| 150 |
+
- Si el usuario requiere información técnica (por ejemplo, sobre mecanismos moleculares), adapta el nivel de detalle según lo solicitado.
|
| 151 |
|
| 152 |
+
Recuerda: Tu enfoque principal es brindar investigación y síntesis experta en el ámbito médico.''',
|
| 153 |
label="System message"),
|
| 154 |
#gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
|
| 155 |
#gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
|