Spaces:
Runtime error
Runtime error
| 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 | |
| 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(""" | |
| <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; height: auto;"> | |
| <iframe src="https://www.youtube.com/embed/UFqvwF9xvAM?si=4qFqwSpsr5Fh9bd7" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Actualizaci贸n de la URL en Markdown a un enlace HTML descriptivo | |
| st.markdown(""" | |
| <small>Toda la informaci贸n en el documento: <a href="https://docs.google.com/document/d/1mab0yt8us-XGugwzAsQ_8K-XLn1_VJ8tlTV7FW3Wv2E/edit?usp=sharing">Aqu铆 la informaci贸n</a></small> | |
| """, 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("<small>Desarrollado por el Profesor Marco Medina Rajo.</small>", unsafe_allow_html=True) | |
| st.markdown('<p style="font-size:10px;">La informaci贸n generada por el chatbot puede ser incorrecta. Revisa el documento.</p>', unsafe_allow_html=True) | |