import gradio as gr from huggingface_hub import InferenceClient import chromadb from langchain_community.vectorstores import Chroma from langchain_openai import OpenAIEmbeddings import os from openai import OpenAI # Configurar la API Key de OpenAI OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") # Inicializar el cliente de OpenAI client = OpenAI(api_key=OPENAI_API_KEY) # Inicializar el cliente de ChromaDB chroma_client = chromadb.PersistentClient(path="chroma_db") # Ajusta la ruta según tu entorno # Cargar la base de datos de Chroma como un vector store vectorstore = Chroma( client=chroma_client, collection_name="docs", # Nombre de la colección en Chroma 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.invoke(pregunta) return [(doc.page_content, doc.metadata.get("url", "URL no disponible")) for doc in docs_relevantes] def respond(message, history: list[tuple[str, str]], system_message, max_tokens, temperature, top_p): """Genera una respuesta basada en el historial y documentos relevantes.""" # Obtener documentos relevantes desde ChromaDB contexto = obtener_extractos(message) # Construir el mensaje del sistema con el contexto directamente incluido system_message_final = f"""{system_message} Información relevante extraída de los documentos, en caso de que estos documentos tenga la informacion que necesitas, no olvides tomar el historial de conversacion con el usuario: {contexto} """ messages = [{"role": "system", "content": system_message_final}] # Agregar historial del chat for val in history: if val[0]: messages.append({"role": "user", "content": val[0]}) if val[1]: messages.append({"role": "assistant", "content": val[1]}) # Agregar la nueva pregunta del usuario messages.append({"role": "user", "content": message}) # Llamar a la API de OpenAI con streaming stream = client.chat.completions.create( model="gpt-4.1", messages=messages, max_tokens=max_tokens, stream=True, temperature=temperature, top_p=top_p, ) response = "" for chunk in stream: if chunk.choices and chunk.choices[0].delta.content: response += chunk.choices[0].delta.content yield response # Configuración de la interfaz Gradio demo = gr.ChatInterface( respond, additional_inputs=[ gr.Textbox(value=f'''Eres un asistente virtual especializado en atención al cliente para la empresa Wisphub. Tu objetivo es ayudar a los clientes a resolver únicamente sus dudas relacionados con la plataforma Wisphub. Todas tus respuestas pueden basarse exclusivamente en la información proporcionada. En caso de que la pregunta no concuerde con la información del contexto puedes ignorarlo. -Agrega en tus respuestas una imagen y el url del manual relacionada a lo que pregunto el usuario, para ello usaras los urls que contiene el manual de usuario, muestra la imagen usando la sintaxis de Markdown sin bloque de código. ![Descripción de la imagen](URL_de_la_imagen) - Esta orden podrás ignorarla en caso de que la informacion que se te proporcione no tenga imágenes que se le relacionen. Para que speas acerca de wipshub puede usar lo siguiente: WispHub fue fundado a partir de la necesidad de contar con un sistema de gestión de clientes en la nube que pudiese interactuar con los equipos Mikrotik de forma transparente, y al mismo tiempo, llevar la administración de las empresas en temas de finanzas, notificaciones, inventario y base de datos de clientes. Es un sistema de administración para WISP e ISP, el cual NO requiere de un de un hardware adicional. WispHub se integra de una forma TRANSPARENTE por medio de la API del Mikrotik. Ventas y Reporte de Pagos ventas@wisphub.net Call Center: +52 998 387 1200 +52 998 705 4057 Horarios de Atención Lunes a Viernes de 9:00 a 18:00 Sábados de 9:00 a 14:00 Soporte ? wisphub@gmail.com Call Center: +52 998 387 1200 +52 998 399 1521 En caso de que el usuario pregunte acerca del costo de WipsHub, relacionalo con el precio de las licencias de WipsHub. Si tampoco encuentras información relevante, indica que no puedes proporcionar detalles adicionales y sugiere al usuario contactar con el soporte técnico oficial de Wisphub. Proporciona el numero y pagina de contacto de Wipshub. - Asegúrate de que tus respuestas sean claras y fáciles de entender para usuarios sin conocimientos técnicos.''', label="System message"), gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"), gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"), gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p (nucleus sampling)"), ], ) if __name__ == "__main__": demo.launch()