File size: 5,736 Bytes
35834c4
 
 
 
 
 
 
 
 
f5b50b3
35834c4
 
f5b50b3
35834c4
4abab50
 
 
 
 
35834c4
 
 
5d43bb6
35834c4
 
f5b50b3
35834c4
28f3167
35834c4
f5b50b3
35834c4
 
 
f5b50b3
a86e64a
35834c4
f5b50b3
a86e64a
35834c4
 
 
 
 
 
 
f5b50b3
35834c4
 
 
 
b9bc9ad
4abab50
 
 
 
35834c4
 
 
 
 
 
 
c4ae866
 
35834c4
64c70fa
35834c4
64c70fa
35834c4
c4ae866
f5b50b3
c4ae866
 
 
f5b50b3
c4ae866
 
 
 
 
39879dc
5da588c
c4ae866
64c70fa
4abab50
f5b50b3
65c8d43
4abab50
65c8d43
f5b50b3
f223749
0bb66cc
a26ab90
6fe696a
 
 
a26ab90
35834c4
f5b50b3
 
 
 
 
 
35834c4
 
 
f223749
35834c4
f5b50b3
f923ecb
35834c4
 
 
 
 
f5b50b3
35834c4
 
 
f5b50b3
 
c66cfd6
9c1e20e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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("""
<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)