Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from huggingface_hub import InferenceClient | |
| import chromadb | |
| from langchain_community.vectorstores import Chroma | |
| from langchain_openai import OpenAIEmbeddings | |
| import os | |
| import time | |
| from uuid import uuid4 | |
| from openai import OpenAI | |
| import json | |
| # Configurar la API Key de OpenAI | |
| OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") | |
| ASSISTANT_ID = os.getenv("OPENAI_ASSISTANT_ID") | |
| # Inicializar el cliente de OpenAI | |
| client = OpenAI(api_key=OPENAI_API_KEY) | |
| # Inicializar el cliente de ChromaDB | |
| chroma_client = chromadb.PersistentClient(path="chroma_db") | |
| # Cargar la base de datos de Chroma como un vector store | |
| vectorstore = Chroma( | |
| client=chroma_client, | |
| collection_name="docs_medicina", | |
| embedding_function=OpenAIEmbeddings(model="text-embedding-3-small", openai_api_key=OPENAI_API_KEY) | |
| ) | |
| # Crear un retriever | |
| retriever = vectorstore.as_retriever() | |
| # Función para obtener extractos relevantes | |
| def obtener_extractos(pregunta): | |
| docs_relevantes = retriever.get_relevant_documents(pregunta) | |
| return [ | |
| (doc.page_content, | |
| f"Libro: {doc.metadata.get('nombre_libro', 'N/A')}, Página: {doc.metadata.get('numero_pagina', 'N/A')}") | |
| for doc in docs_relevantes | |
| ] | |
| # Diccionario para almacenar threads por sesión | |
| session_threads = {} | |
| # Diccionario para rastrear el número de mensajes ya procesados por thread | |
| thread_message_count = {} | |
| def respond(message, history: list[tuple[str, str]], system_message): | |
| # Generar un ID de sesión basado en el historial | |
| session_id = str(hash(json.dumps(history, sort_keys=True))) | |
| # Obtener o crear thread único por sesión | |
| thread_id = session_threads.get(session_id) | |
| if not thread_id: | |
| # Crear nuevo thread | |
| thread = client.beta.threads.create() | |
| thread_id = thread.id | |
| session_threads[session_id] = thread_id | |
| thread_message_count[thread_id] = 0 | |
| # Agregar historial completo solo para threads nuevos | |
| for user_msg, assistant_msg in history: | |
| client.beta.threads.messages.create( | |
| thread_id=thread_id, | |
| role="user", | |
| content=user_msg | |
| ) | |
| client.beta.threads.messages.create( | |
| thread_id=thread_id, | |
| role="assistant", | |
| content=assistant_msg | |
| ) | |
| thread_message_count[thread_id] += 2 | |
| else: | |
| # Para threads existentes, solo agregar mensajes nuevos | |
| current_history_length = len(history) * 2 # Multiplicar por 2 porque cada intercambio son 2 mensajes | |
| messages_in_thread = thread_message_count.get(thread_id, 0) | |
| # Agregar solo los mensajes nuevos que no están en el thread | |
| if current_history_length > messages_in_thread: | |
| # Calcular cuántos intercambios nuevos hay | |
| new_exchanges = (current_history_length - messages_in_thread) // 2 | |
| # Agregar solo los intercambios nuevos | |
| for i in range(-new_exchanges, 0): | |
| user_msg, assistant_msg = history[i] | |
| client.beta.threads.messages.create( | |
| thread_id=thread_id, | |
| role="user", | |
| content=user_msg | |
| ) | |
| client.beta.threads.messages.create( | |
| thread_id=thread_id, | |
| role="assistant", | |
| content=assistant_msg | |
| ) | |
| thread_message_count[thread_id] += 2 | |
| # Agregar el nuevo mensaje del usuario | |
| client.beta.threads.messages.create( | |
| thread_id=thread_id, | |
| role="user", | |
| content=message | |
| ) | |
| thread_message_count[thread_id] += 1 | |
| # Ejecutar el assistant | |
| with client.beta.threads.runs.stream( | |
| thread_id=thread_id, | |
| assistant_id=ASSISTANT_ID | |
| ) as stream: | |
| response = "" | |
| for event in stream: | |
| if event.event == 'thread.message.delta': | |
| delta = event.data.delta | |
| if delta.content: | |
| chunk = delta.content[0].text.value | |
| response += chunk | |
| yield response # Respuesta acumulativa | |
| # Obtener la respuesta más reciente | |
| messages = client.beta.threads.messages.list(thread_id=thread_id, limit=1) | |
| if messages.data: | |
| latest_message = messages.data[0] | |
| if latest_message.role == "assistant": | |
| thread_message_count[thread_id] += 1 # Incrementar contador por la respuesta del assistant | |
| yield latest_message.content[0].text.value | |
| return | |
| # Configuración de la interfaz Gradio | |
| demo = gr.ChatInterface( | |
| respond, | |
| additional_inputs=[ | |
| gr.Textbox(value="""Eres un asistente especializado en medicina. | |
| Uso de fuentes: Utiliza la información del contexto médico proporcionado. | |
| Citación obligatoria: En cada respuesta debes incluir: | |
| Nombre exacto del libro/documento de referencia | |
| Número de página específica | |
| Capítulo o sección cuando sea relevante | |
| Formato: "[Fuente: Título del Libro, Página X, Capítulo Y]" | |
| Ejemplo de respuesta: | |
| "Según la información disponible, [respuesta médica]. Esta información se encuentra en [Fuente: Título del Libro, Página X].""", label="System Message") | |
| ], | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() |