import streamlit as st from llama_index.core import StorageContext, load_index_from_storage, VectorStoreIndex, SimpleDirectoryReader, ChatPromptTemplate from llama_index.llms.huggingface import HuggingFaceInferenceAPI from dotenv import load_dotenv from llama_index.embeddings.huggingface import HuggingFaceEmbedding from llama_index.core import Settings import os import base64 # Cargar variables de entorno load_dotenv() # Configurar los modelos de LLM y Embeddings Settings.llm = HuggingFaceInferenceAPI( model_name="mistralai/Mistral-7B-Instruct-v0.3", tokenizer_name="mistralai/Mistral-7B-Instruct-v0.3", context_window=4000, # Ventana de contexto del modelo token=os.getenv("HF_TOKEN"), # Tu token de Hugging Face max_new_tokens=512, # Puedes ajustarlo según tu necesidad generate_kwargs={"temperature": 0.1}, ) Settings.embed_model = HuggingFaceEmbedding( model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2" # Modelo en español de Hugging Face ) # Definir los directorios para almacenamiento persistente y datos PERSIST_DIR = "./db" DATA_DIR = "data" # Asegurar que los directorios existan os.makedirs(DATA_DIR, exist_ok=True) os.makedirs(PERSIST_DIR, exist_ok=True) # Ruta fija para el archivo PDF FIXED_PDF_PATH = os.path.join(DATA_DIR, "saved_pdf.pdf") # Ingestar datos una vez al inicio @st.cache_data def load_data(): documents = SimpleDirectoryReader(DATA_DIR).load_data() storage_context = StorageContext.from_defaults() index = VectorStoreIndex.from_documents(documents) index.storage_context.persist(persist_dir=PERSIST_DIR) return index # Manejar consultas de usuario def handle_query(query, index): chat_text_qa_msgs = [ ( "user", """Responde en español con un máximo de 80 palabras y agrega que para más información lea el documento. Recuerda que Informática Educativa no es virtual, sino a distancia los fines de semana. Simplifica y resume para ser conciso, preciso y directo. Eres Lobito, asistente de la UPNFM. Proporciona respuestas precisas basadas en el contexto dado sobre la UPNFM y la DFP. Si la pregunta no coincide, sugiere reformularla. Identifica las secciones relevantes del contexto y organiza las respuestas lógicamente si abarcan varias secciones. Contexto: {context_str} Pregunta: {query_str} """ ) ] text_qa_template = ChatPromptTemplate.from_messages(chat_text_qa_msgs) query_engine = index.as_query_engine(text_qa_template=text_qa_template) answer = query_engine.query(query) # Extraer la respuesta del objeto answer if hasattr(answer, 'response'): response = answer.response elif isinstance(answer, dict) and 'response' in answer: response = answer['response'] else: return "Lo siento, no pude procesar tu pregunta. ¿Podrías reformularla o hacer una pregunta diferente?" # Palabras y frases a evitar en las respuestas palabras_prohibidas = [ "en el contexto proporcionado no hay información", "empty response", "the provided text does not contain", "en el contexto proporcionado, no hay información" ] # Verificar si la respuesta contiene alguna de las palabras o frases prohibidas if any(palabra in response.lower() for palabra in palabras_prohibidas): return "No comprendí la pregunta o encontré información específica sobre eso en mis datos. ¿Podrías hacer tu pregunta de otra forma o preguntar sobre otro tema relacionado con la UPNFM y sus programas DFP?" return response # Inicializar el estado de la sesión if 'messages' not in st.session_state: st.session_state.messages = [{'role': 'assistant', "content": '¡Hola!, me llamo Lobito. Soy tu asesor personalizado.'}] # Inicialización de la aplicación Streamlit st.title("Chatbot de dudas DFP") st.markdown("Resuelvo dudas sobre el régimen económico y admisión de la Dirección de Formación Permanente.") st.markdown("""
""", unsafe_allow_html=True) # Actualización de la URL en Markdown a un enlace HTML descriptivo st.markdown(""" Toda la información en el documento: Aquí la información """, unsafe_allow_html=True) # Mostrar el PDF fijo si existe if os.path.exists(FIXED_PDF_PATH): index = load_data() else: st.error("No pude cargar la información.") # Entrada de chat user_prompt = st.chat_input("¿En qué te puedo ayudar?:") if user_prompt: st.session_state.messages.append({'role': 'user', "content": user_prompt}) response = handle_query(user_prompt, index) st.session_state.messages.append({'role': 'assistant', "content": response}) # Mostrar los mensajes de la sesión for message in st.session_state.messages: with st.chat_message(message['role']): st.write(message['content']) # Información adicional st.markdown("Desarrollado por el Profesor Marco Medina Rajo.", unsafe_allow_html=True) st.markdown('

La información generada por el chatbot puede ser incorrecta. Revisa el documento.

', unsafe_allow_html=True)