Spaces:
Build error
Build error
File size: 6,288 Bytes
f15d84d |
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 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
import pandas as pd
import streamlit as st
from langchain.docstore.document import Document
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
from langchain_community.llms import HuggingFaceHub
import os
from huggingface_hub import HfApi
# Configuration Streamlit
st.set_page_config(page_title="Assistant Support Client", page_icon="🤖", layout="wide")
# Récupération du token depuis les secrets de l'espace
HUGGINGFACE_API_TOKEN = st.secrets["HUGGINGFACE_API_TOKEN"]
# Création du dossier data s'il n'existe pas
DATA_DIR = "data"
os.makedirs(DATA_DIR, exist_ok=True)
EMBEDDINGS_FILE = os.path.join(DATA_DIR, "faq_embeddings.pkl")
# Configuration du client HF Hub
hf_api = HfApi(token=HUGGINGFACE_API_TOKEN)
@st.cache_resource
def load_faq_data():
"""Charge les données FAQ depuis un CSV"""
try:
df = pd.read_csv('data/customer_support_faq.csv')
documents = []
for _, row in df.iterrows():
question = row['question']
answer = row['answer']
documents.append(Document(page_content=f"Q: {question} A: {answer}"))
return documents
except Exception as e:
st.error(f"Erreur lors du chargement des données FAQ: {str(e)}")
return []
@st.cache_resource
def initialize_embeddings(_documents):
"""Initialise ou charge les embeddings"""
try:
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
)
vector_store = FAISS.from_documents(_documents, embeddings)
return vector_store
except Exception as e:
st.error(f"Erreur lors de l'initialisation des embeddings: {str(e)}")
return None
@st.cache_resource
def initialize_qa_chain(vector_store):
"""Initialise la chaîne de question-réponse"""
try:
# Initialisation du modèle
llm = HuggingFaceHub(
repo_id="bigscience/bloom", # Vous pouvez changer le modèle
huggingfacehub_api_token=HUGGINGFACE_API_TOKEN,
model_kwargs={"temperature": 0.5, "max_length": 512}
)
# Template de prompt
prompt_template = """Utilise le contexte suivant pour répondre à la question.
Si la réponse n'est pas dans le contexte, réponds "Je ne sais pas."
Contexte: {context}
Question: {question}
Réponse:"""
PROMPT = PromptTemplate(
template=prompt_template,
input_variables=["context", "question"]
)
# Création de la chaîne QA
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=vector_store.as_retriever(),
chain_type_kwargs={"prompt": PROMPT},
return_source_documents=False,
)
return qa_chain
except Exception as e:
st.error(f"Erreur lors de l'initialisation de la chaîne QA: {str(e)}")
return None
# CSS personnalisé
st.markdown("""
<style>
.stApp {
background-color: #1E1E1E;
}
.user_message {
color: white;
background-color: #F85046;
padding: 10px;
border-radius: 10px;
margin: 10px 20px 10px auto;
text-align: left;
word-wrap: break-word;
display: inline-block;
max-width: 80%;
}
.bot_message {
color: #1E1E1E;
background-color: white;
padding: 10px;
border-radius: 10px;
margin: 10px 20px;
text-align: left;
word-wrap: break-word;
display: inline-block;
max-width: 80%;
}
.header {
font-size: 40px;
color: white;
padding: 20px;
text-align: center;
border-radius: 10px;
font-weight: bold;
}
.the_text {
color: #F9F8FD;
font-size: 20px;
margin-top: 20px;
}
.the_conv {
color: #F9F8FD;
font-size: 30px;
}
</style>
""", unsafe_allow_html=True)
# Interface utilisateur
st.markdown('<div class="header">Assistant Support Client</div>', unsafe_allow_html=True)
st.markdown('<div class="the_text">Posez votre question ci-dessous :</div>', unsafe_allow_html=True)
# Initialisation de la session state
if 'conversation' not in st.session_state:
st.session_state.conversation = []
# Chargement des composants
documents = load_faq_data()
if documents:
vector_store = initialize_embeddings(documents)
if vector_store:
qa_chain = initialize_qa_chain(vector_store)
if qa_chain:
# Champ de saisie
user_query = st.text_input("", key="user_input")
# Bouton pour obtenir la réponse
if st.button("Obtenir une réponse", key="submit"):
if user_query:
try:
# Obtention de la réponse
response = qa_chain({"query": user_query})
answer = response["result"]
# Ajout à l'historique
st.session_state.conversation.append({
"user": user_query,
"bot": answer
})
# Affichage de la conversation
st.markdown('<div class="the_conv">Conversation :</div>', unsafe_allow_html=True)
for chat in st.session_state.conversation:
st.markdown(
f'<div class="user_message">🤵 : {chat["user"]}</div>',
unsafe_allow_html=True
)
st.markdown(
f'<div class="bot_message">🤖 : {chat["bot"]}</div>',
unsafe_allow_html=True
)
except Exception as e:
st.error(f"Erreur lors du traitement de la requête: {str(e)}")
else:
st.warning("Veuillez entrer une question.") |