SELIGROUP commited on
Commit
f15d84d
·
verified ·
1 Parent(s): cb72c1d

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +188 -0
app.py ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import streamlit as st
3
+ from langchain.docstore.document import Document
4
+ from langchain_huggingface import HuggingFaceEmbeddings
5
+ from langchain_community.vectorstores import FAISS
6
+ from langchain.chains import RetrievalQA
7
+ from langchain.prompts import PromptTemplate
8
+ from langchain_community.llms import HuggingFaceHub
9
+ import os
10
+ from huggingface_hub import HfApi
11
+
12
+ # Configuration Streamlit
13
+ st.set_page_config(page_title="Assistant Support Client", page_icon="🤖", layout="wide")
14
+
15
+ # Récupération du token depuis les secrets de l'espace
16
+ HUGGINGFACE_API_TOKEN = st.secrets["HUGGINGFACE_API_TOKEN"]
17
+
18
+ # Création du dossier data s'il n'existe pas
19
+ DATA_DIR = "data"
20
+ os.makedirs(DATA_DIR, exist_ok=True)
21
+ EMBEDDINGS_FILE = os.path.join(DATA_DIR, "faq_embeddings.pkl")
22
+
23
+ # Configuration du client HF Hub
24
+ hf_api = HfApi(token=HUGGINGFACE_API_TOKEN)
25
+
26
+ @st.cache_resource
27
+ def load_faq_data():
28
+ """Charge les données FAQ depuis un CSV"""
29
+ try:
30
+ df = pd.read_csv('data/customer_support_faq.csv')
31
+ documents = []
32
+ for _, row in df.iterrows():
33
+ question = row['question']
34
+ answer = row['answer']
35
+ documents.append(Document(page_content=f"Q: {question} A: {answer}"))
36
+ return documents
37
+ except Exception as e:
38
+ st.error(f"Erreur lors du chargement des données FAQ: {str(e)}")
39
+ return []
40
+
41
+ @st.cache_resource
42
+ def initialize_embeddings(_documents):
43
+ """Initialise ou charge les embeddings"""
44
+ try:
45
+ embeddings = HuggingFaceEmbeddings(
46
+ model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
47
+ )
48
+ vector_store = FAISS.from_documents(_documents, embeddings)
49
+ return vector_store
50
+ except Exception as e:
51
+ st.error(f"Erreur lors de l'initialisation des embeddings: {str(e)}")
52
+ return None
53
+
54
+ @st.cache_resource
55
+ def initialize_qa_chain(vector_store):
56
+ """Initialise la chaîne de question-réponse"""
57
+ try:
58
+ # Initialisation du modèle
59
+ llm = HuggingFaceHub(
60
+ repo_id="bigscience/bloom", # Vous pouvez changer le modèle
61
+ huggingfacehub_api_token=HUGGINGFACE_API_TOKEN,
62
+ model_kwargs={"temperature": 0.5, "max_length": 512}
63
+ )
64
+
65
+ # Template de prompt
66
+ prompt_template = """Utilise le contexte suivant pour répondre à la question.
67
+ Si la réponse n'est pas dans le contexte, réponds "Je ne sais pas."
68
+
69
+ Contexte: {context}
70
+
71
+ Question: {question}
72
+
73
+ Réponse:"""
74
+
75
+ PROMPT = PromptTemplate(
76
+ template=prompt_template,
77
+ input_variables=["context", "question"]
78
+ )
79
+
80
+ # Création de la chaîne QA
81
+ qa_chain = RetrievalQA.from_chain_type(
82
+ llm=llm,
83
+ chain_type="stuff",
84
+ retriever=vector_store.as_retriever(),
85
+ chain_type_kwargs={"prompt": PROMPT},
86
+ return_source_documents=False,
87
+ )
88
+
89
+ return qa_chain
90
+ except Exception as e:
91
+ st.error(f"Erreur lors de l'initialisation de la chaîne QA: {str(e)}")
92
+ return None
93
+
94
+ # CSS personnalisé
95
+ st.markdown("""
96
+ <style>
97
+ .stApp {
98
+ background-color: #1E1E1E;
99
+ }
100
+ .user_message {
101
+ color: white;
102
+ background-color: #F85046;
103
+ padding: 10px;
104
+ border-radius: 10px;
105
+ margin: 10px 20px 10px auto;
106
+ text-align: left;
107
+ word-wrap: break-word;
108
+ display: inline-block;
109
+ max-width: 80%;
110
+ }
111
+ .bot_message {
112
+ color: #1E1E1E;
113
+ background-color: white;
114
+ padding: 10px;
115
+ border-radius: 10px;
116
+ margin: 10px 20px;
117
+ text-align: left;
118
+ word-wrap: break-word;
119
+ display: inline-block;
120
+ max-width: 80%;
121
+ }
122
+ .header {
123
+ font-size: 40px;
124
+ color: white;
125
+ padding: 20px;
126
+ text-align: center;
127
+ border-radius: 10px;
128
+ font-weight: bold;
129
+ }
130
+ .the_text {
131
+ color: #F9F8FD;
132
+ font-size: 20px;
133
+ margin-top: 20px;
134
+ }
135
+ .the_conv {
136
+ color: #F9F8FD;
137
+ font-size: 30px;
138
+ }
139
+ </style>
140
+ """, unsafe_allow_html=True)
141
+
142
+ # Interface utilisateur
143
+ st.markdown('<div class="header">Assistant Support Client</div>', unsafe_allow_html=True)
144
+ st.markdown('<div class="the_text">Posez votre question ci-dessous :</div>', unsafe_allow_html=True)
145
+
146
+ # Initialisation de la session state
147
+ if 'conversation' not in st.session_state:
148
+ st.session_state.conversation = []
149
+
150
+ # Chargement des composants
151
+ documents = load_faq_data()
152
+ if documents:
153
+ vector_store = initialize_embeddings(documents)
154
+ if vector_store:
155
+ qa_chain = initialize_qa_chain(vector_store)
156
+ if qa_chain:
157
+ # Champ de saisie
158
+ user_query = st.text_input("", key="user_input")
159
+
160
+ # Bouton pour obtenir la réponse
161
+ if st.button("Obtenir une réponse", key="submit"):
162
+ if user_query:
163
+ try:
164
+ # Obtention de la réponse
165
+ response = qa_chain({"query": user_query})
166
+ answer = response["result"]
167
+
168
+ # Ajout à l'historique
169
+ st.session_state.conversation.append({
170
+ "user": user_query,
171
+ "bot": answer
172
+ })
173
+
174
+ # Affichage de la conversation
175
+ st.markdown('<div class="the_conv">Conversation :</div>', unsafe_allow_html=True)
176
+ for chat in st.session_state.conversation:
177
+ st.markdown(
178
+ f'<div class="user_message">🤵 : {chat["user"]}</div>',
179
+ unsafe_allow_html=True
180
+ )
181
+ st.markdown(
182
+ f'<div class="bot_message">🤖 : {chat["bot"]}</div>',
183
+ unsafe_allow_html=True
184
+ )
185
+ except Exception as e:
186
+ st.error(f"Erreur lors du traitement de la requête: {str(e)}")
187
+ else:
188
+ st.warning("Veuillez entrer une question.")