Upload 3 files
Browse files- chatbot.py +424 -0
- model_mt5.py +26 -0
- requirements.txt +54 -0
chatbot.py
ADDED
|
@@ -0,0 +1,424 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# chatbot_enhanced.py
|
| 2 |
+
|
| 3 |
+
import random
|
| 4 |
+
import re
|
| 5 |
+
from datetime import datetime
|
| 6 |
+
from model_mt5 import call_mt5_model
|
| 7 |
+
|
| 8 |
+
class HumanChatbot:
|
| 9 |
+
def __init__(self):
|
| 10 |
+
self.conversation_history = []
|
| 11 |
+
self.user_name = None
|
| 12 |
+
self.context = {}
|
| 13 |
+
|
| 14 |
+
def get_time_greeting(self):
|
| 15 |
+
"""Retourne un salut adapté à l'heure"""
|
| 16 |
+
hour = datetime.now().hour
|
| 17 |
+
if 5 <= hour < 12:
|
| 18 |
+
return {"fr": "Bonjour", "en": "Good morning", "es": "Buenos días", "de": "Guten Morgen"}
|
| 19 |
+
elif 12 <= hour < 18:
|
| 20 |
+
return {"fr": "Bonjour", "en": "Good afternoon", "es": "Buenas tardes", "de": "Guten Tag"}
|
| 21 |
+
else:
|
| 22 |
+
return {"fr": "Bonsoir", "en": "Good evening", "es": "Buenas noches", "de": "Guten Abend"}
|
| 23 |
+
|
| 24 |
+
def detect_language(self, text):
|
| 25 |
+
"""Détecte la langue principale du texte"""
|
| 26 |
+
text_lower = text.lower()
|
| 27 |
+
|
| 28 |
+
# Mots clés par langue
|
| 29 |
+
lang_indicators = {
|
| 30 |
+
"fr": ["bonjour", "salut", "merci", "comment", "ça", "va", "oui", "non", "je", "tu", "vous"],
|
| 31 |
+
"en": ["hello", "hi", "thank", "how", "are", "you", "yes", "no", "i", "you", "the"],
|
| 32 |
+
"es": ["hola", "gracias", "cómo", "estás", "sí", "no", "yo", "tú", "el", "la"],
|
| 33 |
+
"de": ["hallo", "danke", "wie", "geht", "ja", "nein", "ich", "du", "der", "die"]
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
scores = {}
|
| 37 |
+
for lang, words in lang_indicators.items():
|
| 38 |
+
scores[lang] = sum(1 for word in words if word in text_lower)
|
| 39 |
+
|
| 40 |
+
return max(scores, key=scores.get) if max(scores.values()) > 0 else "fr"
|
| 41 |
+
|
| 42 |
+
def extract_user_name(self, text):
|
| 43 |
+
"""Extrait le nom de l'utilisateur"""
|
| 44 |
+
patterns = [
|
| 45 |
+
r"je m'appelle (\w+)",
|
| 46 |
+
r"mon nom est (\w+)",
|
| 47 |
+
r"i'?m (\w+)",
|
| 48 |
+
r"my name is (\w+)",
|
| 49 |
+
r"me llamo (\w+)",
|
| 50 |
+
r"ich heiße (\w+)"
|
| 51 |
+
]
|
| 52 |
+
|
| 53 |
+
for pattern in patterns:
|
| 54 |
+
match = re.search(pattern, text.lower())
|
| 55 |
+
if match:
|
| 56 |
+
return match.group(1).capitalize()
|
| 57 |
+
return None
|
| 58 |
+
|
| 59 |
+
def get_emotional_response(self, user_input, lang):
|
| 60 |
+
"""Génère une réponse émotionnelle selon le contexte"""
|
| 61 |
+
input_lower = user_input.lower()
|
| 62 |
+
|
| 63 |
+
# Détection d'émotions
|
| 64 |
+
emotions = {
|
| 65 |
+
"happy": {
|
| 66 |
+
"keywords": ["content", "heureux", "joie", "super", "génial", "happy", "great", "awesome", "feliz", "genial"],
|
| 67 |
+
"responses": {
|
| 68 |
+
"fr": ["C'est formidable ! 😊", "Je suis ravi de l'entendre ! 🎉", "Ça me fait plaisir ! ✨"],
|
| 69 |
+
"en": ["That's wonderful! 😊", "I'm so happy to hear that! 🎉", "That's great news! ✨"],
|
| 70 |
+
"es": ["¡Qué maravilloso! 😊", "¡Me alegra escuchar eso! 🎉", "¡Qué buena noticia! ✨"],
|
| 71 |
+
"de": ["Das ist wunderbar! 😊", "Das freut mich sehr! 🎉", "Tolle Neuigkeiten! ✨"]
|
| 72 |
+
}
|
| 73 |
+
},
|
| 74 |
+
"sad": {
|
| 75 |
+
"keywords": ["triste", "mal", "difficile", "problème", "sad", "bad", "difficult", "problem", "triste", "mal", "schwierig"],
|
| 76 |
+
"responses": {
|
| 77 |
+
"fr": ["Je suis désolé de l'entendre... 😔", "Ça doit être difficile pour vous.", "Je comprends votre situation."],
|
| 78 |
+
"en": ["I'm sorry to hear that... 😔", "That must be difficult for you.", "I understand your situation."],
|
| 79 |
+
"es": ["Lamento escuchar eso... 😔", "Debe ser difícil para ti.", "Entiendo tu situación."],
|
| 80 |
+
"de": ["Das tut mir leid zu hören... 😔", "Das muss schwierig für Sie sein.", "Ich verstehe Ihre Situation."]
|
| 81 |
+
}
|
| 82 |
+
},
|
| 83 |
+
"confused": {
|
| 84 |
+
"keywords": ["comprends pas", "confus", "don't understand", "confused", "no entiendo", "verstehe nicht"],
|
| 85 |
+
"responses": {
|
| 86 |
+
"fr": ["Pas de souci, je vais essayer d'être plus clair.", "Laissez-moi reformuler ça.", "Je peux vous expliquer autrement."],
|
| 87 |
+
"en": ["No worries, let me try to be clearer.", "Let me rephrase that.", "I can explain it differently."],
|
| 88 |
+
"es": ["No te preocupes, intentaré ser más claro.", "Déjame reformular eso.", "Puedo explicarlo de otra manera."],
|
| 89 |
+
"de": ["Kein Problem, ich versuche klarer zu sein.", "Lassen Sie mich das umformulieren.", "Ich kann es anders erklären."]
|
| 90 |
+
}
|
| 91 |
+
}
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
for emotion, data in emotions.items():
|
| 95 |
+
if any(keyword in input_lower for keyword in data["keywords"]):
|
| 96 |
+
return random.choice(data["responses"][lang])
|
| 97 |
+
|
| 98 |
+
return None
|
| 99 |
+
|
| 100 |
+
def detect_problem_keywords(self, user_input, lang):
|
| 101 |
+
"""Détecte si l'utilisateur présente un problème technique ou demande de l'aide"""
|
| 102 |
+
input_lower = user_input.lower()
|
| 103 |
+
|
| 104 |
+
problem_keywords = {
|
| 105 |
+
"fr": [
|
| 106 |
+
"problème", "pb", "erreur", "bug", "panne", "défaut", "dysfonctionnement",
|
| 107 |
+
"ça marche pas", "ne fonctionne pas", "ne marche pas", "cassé", "bloqué",
|
| 108 |
+
"aide", "aider", "comment", "comment faire", "solution", "résoudre",
|
| 109 |
+
"pourquoi", "expliquer", "expliquez", "que faire", "urgent", "besoin d'aide"
|
| 110 |
+
],
|
| 111 |
+
"en": [
|
| 112 |
+
"problem", "issue", "error", "bug", "broken", "not working", "doesn't work",
|
| 113 |
+
"help", "how to", "how do", "solution", "solve", "fix", "explain",
|
| 114 |
+
"why", "what to do", "urgent", "need help", "trouble", "difficulty"
|
| 115 |
+
],
|
| 116 |
+
"es": [
|
| 117 |
+
"problema", "error", "fallo", "no funciona", "roto", "bloqueado",
|
| 118 |
+
"ayuda", "ayudar", "cómo", "solución", "resolver", "explicar",
|
| 119 |
+
"por qué", "qué hacer", "urgente", "necesito ayuda"
|
| 120 |
+
],
|
| 121 |
+
"de": [
|
| 122 |
+
"problem", "fehler", "bug", "kaputt", "funktioniert nicht", "geht nicht",
|
| 123 |
+
"hilfe", "helfen", "wie", "lösung", "lösen", "erklären",
|
| 124 |
+
"warum", "was tun", "dringend", "brauche hilfe"
|
| 125 |
+
]
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
# Vérifier si le message contient des mots-clés de problème
|
| 129 |
+
keywords = problem_keywords.get(lang, problem_keywords["fr"])
|
| 130 |
+
return any(keyword in input_lower for keyword in keywords)
|
| 131 |
+
|
| 132 |
+
def get_contextual_response(self, user_input, lang):
|
| 133 |
+
"""Génère une réponse contextuelle"""
|
| 134 |
+
input_lower = user_input.lower()
|
| 135 |
+
|
| 136 |
+
# NOUVEAU: Détection de problèmes - transmettre directement au modèle
|
| 137 |
+
if self.detect_problem_keywords(user_input, lang):
|
| 138 |
+
return None # Retourner None pour passer au modèle MT5
|
| 139 |
+
|
| 140 |
+
# Questions sur le chatbot
|
| 141 |
+
if any(word in input_lower for word in ["qui es-tu", "what are you", "quién eres", "wer bist du"]):
|
| 142 |
+
responses = {
|
| 143 |
+
"fr": "Je suis votre assistant virtuel ! Je suis là pour discuter et vous aider du mieux que je peux. 🤖",
|
| 144 |
+
"en": "I'm your virtual assistant! I'm here to chat and help you as best I can. 🤖",
|
| 145 |
+
"es": "¡Soy tu asistente virtual! Estoy aquí para charlar y ayudarte lo mejor que pueda. 🤖",
|
| 146 |
+
"de": "Ich bin Ihr virtueller Assistent! Ich bin hier, um zu plaudern und Ihnen zu helfen, so gut ich kann. 🤖"
|
| 147 |
+
}
|
| 148 |
+
return responses[lang]
|
| 149 |
+
|
| 150 |
+
# Questions sur l'humeur
|
| 151 |
+
if any(word in input_lower for word in ["comment tu vas", "how are you", "cómo estás", "wie geht es dir"]):
|
| 152 |
+
responses = {
|
| 153 |
+
"fr": ["Je vais bien, merci ! Et vous ? 😊", "Ça va très bien ! Comment allez-vous ?", "Parfait, merci de demander ! Et vous ?"],
|
| 154 |
+
"en": ["I'm doing well, thanks! How about you? 😊", "I'm great! How are you doing?", "Perfect, thanks for asking! And you?"],
|
| 155 |
+
"es": ["¡Estoy bien, gracias! ¿Y tú? 😊", "¡Muy bien! ¿Cómo estás?", "¡Perfecto, gracias por preguntar! ¿Y tú?"],
|
| 156 |
+
"de": ["Mir geht es gut, danke! Und Ihnen? 😊", "Mir geht es sehr gut! Wie geht es Ihnen?", "Perfekt, danke der Nachfrage! Und Ihnen?"]
|
| 157 |
+
}
|
| 158 |
+
return random.choice(responses[lang])
|
| 159 |
+
|
| 160 |
+
# Expressions de politesse
|
| 161 |
+
if any(word in input_lower for word in ["s'il vous plaît", "please", "por favor", "bitte"]):
|
| 162 |
+
responses = {
|
| 163 |
+
"fr": "Bien sûr, avec plaisir ! 😊",
|
| 164 |
+
"en": "Of course, with pleasure! 😊",
|
| 165 |
+
"es": "¡Por supuesto, con mucho gusto! 😊",
|
| 166 |
+
"de": "Natürlich, gerne! 😊"
|
| 167 |
+
}
|
| 168 |
+
return responses[lang]
|
| 169 |
+
|
| 170 |
+
return None
|
| 171 |
+
|
| 172 |
+
def get_rule_based_response(self, user_input):
|
| 173 |
+
"""Version améliorée des réponses basées sur des règles"""
|
| 174 |
+
input_lower = user_input.lower()
|
| 175 |
+
lang = self.detect_language(user_input)
|
| 176 |
+
|
| 177 |
+
# Extraction du nom si présent
|
| 178 |
+
name = self.extract_user_name(user_input)
|
| 179 |
+
if name:
|
| 180 |
+
self.user_name = name
|
| 181 |
+
responses = {
|
| 182 |
+
"fr": f"Ravi de faire votre connaissance, {name} ! 😊",
|
| 183 |
+
"en": f"Nice to meet you, {name}! 😊",
|
| 184 |
+
"es": f"¡Encantado de conocerte, {name}! 😊",
|
| 185 |
+
"de": f"Schön Sie kennenzulernen, {name}! 😊"
|
| 186 |
+
}
|
| 187 |
+
return responses[lang]
|
| 188 |
+
|
| 189 |
+
# Réponse émotionnelle
|
| 190 |
+
emotional_response = self.get_emotional_response(user_input, lang)
|
| 191 |
+
if emotional_response:
|
| 192 |
+
return emotional_response
|
| 193 |
+
|
| 194 |
+
# Réponse contextuelle
|
| 195 |
+
contextual_response = self.get_contextual_response(user_input, lang)
|
| 196 |
+
if contextual_response:
|
| 197 |
+
return contextual_response
|
| 198 |
+
|
| 199 |
+
# Salutations avec variation
|
| 200 |
+
greetings = {
|
| 201 |
+
"fr": ["bonjour", "salut", "bonsoir", "coucou", "hey"],
|
| 202 |
+
"en": ["hello", "hi", "good morning", "good evening", "hey"],
|
| 203 |
+
"es": ["hola", "buenos días", "buenas tardes", "hey"],
|
| 204 |
+
"de": ["hallo", "guten tag", "guten morgen", "hey"]
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
for language, keywords in greetings.items():
|
| 208 |
+
if any(word in input_lower for word in keywords):
|
| 209 |
+
time_greetings = self.get_time_greeting()
|
| 210 |
+
name_part = f" {self.user_name}" if self.user_name else ""
|
| 211 |
+
|
| 212 |
+
if language == "fr":
|
| 213 |
+
responses = [f"{time_greetings['fr']}{name_part} ! 👋", f"Salut{name_part} ! Comment allez-vous ? 😊"]
|
| 214 |
+
elif language == "en":
|
| 215 |
+
responses = [f"{time_greetings['en']}{name_part}! 👋", f"Hi{name_part}! How are you doing? 😊"]
|
| 216 |
+
elif language == "es":
|
| 217 |
+
responses = [f"¡{time_greetings['es']}{name_part}! 👋", f"¡Hola{name_part}! ¿Cómo estás? 😊"]
|
| 218 |
+
else: # de
|
| 219 |
+
responses = [f"{time_greetings['de']}{name_part}! 👋", f"Hallo{name_part}! Wie geht es Ihnen? 😊"]
|
| 220 |
+
|
| 221 |
+
return random.choice(responses)
|
| 222 |
+
|
| 223 |
+
# Remerciements avec variation
|
| 224 |
+
thanks = {
|
| 225 |
+
"fr": ["merci", "merci beaucoup"],
|
| 226 |
+
"en": ["thank you", "thanks", "thank you very much"],
|
| 227 |
+
"es": ["gracias", "muchas gracias"],
|
| 228 |
+
"de": ["danke", "vielen dank"]
|
| 229 |
+
}
|
| 230 |
+
|
| 231 |
+
for language, keywords in thanks.items():
|
| 232 |
+
if any(word in input_lower for word in keywords):
|
| 233 |
+
responses = {
|
| 234 |
+
"fr": ["De rien ! 😊", "Avec plaisir !", "C'est tout naturel !", "Je vous en prie !"],
|
| 235 |
+
"en": ["You're welcome! 😊", "My pleasure!", "No problem!", "Anytime!"],
|
| 236 |
+
"es": ["¡De nada! 😊", "¡Con mucho gusto!", "¡No hay problema!", "¡Cuando quieras!"],
|
| 237 |
+
"de": ["Gern geschehen! 😊", "Gerne!", "Kein Problem!", "Jederzeit!"]
|
| 238 |
+
}
|
| 239 |
+
return random.choice(responses[language])
|
| 240 |
+
|
| 241 |
+
# Adieux avec variation
|
| 242 |
+
farewell = {
|
| 243 |
+
"fr": ["au revoir", "à bientôt", "salut", "bye", "ciao"],
|
| 244 |
+
"en": ["goodbye", "see you", "bye", "farewell", "take care"],
|
| 245 |
+
"es": ["adiós", "hasta luego", "bye", "ciao", "cuídate"],
|
| 246 |
+
"de": ["tschüss", "auf wiedersehen", "bye", "ciao", "mach's gut"]
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
for language, keywords in farewell.items():
|
| 250 |
+
if any(word in input_lower for word in keywords):
|
| 251 |
+
name_part = f" {self.user_name}" if self.user_name else ""
|
| 252 |
+
responses = {
|
| 253 |
+
"fr": [f"Au revoir{name_part} ! 👋", f"À bientôt{name_part} ! 😊", "Passez une excellente journée ! ✨"],
|
| 254 |
+
"en": [f"Goodbye{name_part}! 👋", f"See you later{name_part}! 😊", "Have a wonderful day! ✨"],
|
| 255 |
+
"es": [f"¡Adiós{name_part}! 👋", f"¡Hasta luego{name_part}! 😊", "¡Que tengas un día maravilloso! ✨"],
|
| 256 |
+
"de": [f"Auf Wiedersehen{name_part}! 👋", f"Bis bald{name_part}! 😊", "Haben Sie einen wunderbaren Tag! ✨"]
|
| 257 |
+
}
|
| 258 |
+
return random.choice(responses[language])
|
| 259 |
+
|
| 260 |
+
return None
|
| 261 |
+
|
| 262 |
+
def get_bot_response(self, user_input):
|
| 263 |
+
"""Fonction principale du chatbot amélioré"""
|
| 264 |
+
# Ajouter à l'historique
|
| 265 |
+
self.conversation_history.append({"user": user_input, "timestamp": datetime.now()})
|
| 266 |
+
|
| 267 |
+
lang = self.detect_language(user_input)
|
| 268 |
+
|
| 269 |
+
# PRIORITÉ 1: Vérifier si c'est un problème technique - directement au modèle MT5
|
| 270 |
+
if self.detect_problem_keywords(user_input, lang):
|
| 271 |
+
print(f"[DEBUG] Problème détecté, transmission au modèle MT5...")
|
| 272 |
+
|
| 273 |
+
# Préfixes pour introduire la réponse du modèle
|
| 274 |
+
problem_prefixes = {
|
| 275 |
+
"fr": [
|
| 276 |
+
"Je comprends votre problème. Laissez-moi vous aider :",
|
| 277 |
+
"Voici ce que je peux vous proposer :",
|
| 278 |
+
"D'après votre description, voici ma recommandation :",
|
| 279 |
+
"Je vais analyser votre problème :"
|
| 280 |
+
],
|
| 281 |
+
"en": [
|
| 282 |
+
"I understand your problem. Let me help you:",
|
| 283 |
+
"Here's what I can suggest:",
|
| 284 |
+
"Based on your description, here's my recommendation:",
|
| 285 |
+
"Let me analyze your problem:"
|
| 286 |
+
],
|
| 287 |
+
"es": [
|
| 288 |
+
"Entiendo tu problema. Déjame ayudarte:",
|
| 289 |
+
"Esto es lo que puedo sugerir:",
|
| 290 |
+
"Basándome en tu descripción, esta es mi recomendación:",
|
| 291 |
+
"Voy a analizar tu problema:"
|
| 292 |
+
],
|
| 293 |
+
"de": [
|
| 294 |
+
"Ich verstehe Ihr Problem. Lassen Sie mich Ihnen helfen:",
|
| 295 |
+
"Hier ist was ich vorschlagen kann:",
|
| 296 |
+
"Basierend auf Ihrer Beschreibung, hier ist meine Empfehlung:",
|
| 297 |
+
"Ich werde Ihr Problem analysieren:"
|
| 298 |
+
]
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
+
# Obtenir la réponse du modèle MT5
|
| 302 |
+
model_response = call_mt5_model(user_input)
|
| 303 |
+
|
| 304 |
+
# Ajouter un préfixe approprié
|
| 305 |
+
prefix = random.choice(problem_prefixes[lang])
|
| 306 |
+
final_response = f"{prefix}\n\n{model_response}"
|
| 307 |
+
|
| 308 |
+
self.conversation_history.append({"bot": final_response, "timestamp": datetime.now()})
|
| 309 |
+
return final_response
|
| 310 |
+
|
| 311 |
+
# PRIORITÉ 2: Essayer les réponses basées sur des règles (salutations, politesse, etc.)
|
| 312 |
+
rule_response = self.get_rule_based_response(user_input)
|
| 313 |
+
if rule_response:
|
| 314 |
+
self.conversation_history.append({"bot": rule_response, "timestamp": datetime.now()})
|
| 315 |
+
return rule_response
|
| 316 |
+
|
| 317 |
+
# PRIORITÉ 3: Questions générales - utiliser le modèle mT5 avec préfixe conversationnel
|
| 318 |
+
print(f"[DEBUG] Question générale, utilisation du modèle MT5...")
|
| 319 |
+
|
| 320 |
+
# Préfixes pour rendre la réponse plus naturelle
|
| 321 |
+
general_prefixes = {
|
| 322 |
+
"fr": ["Hmm, laissez-moi réfléchir...", "Intéressant !", "Bonne question !", "Voici ce que je pense :", ""],
|
| 323 |
+
"en": ["Hmm, let me think...", "Interesting!", "Good question!", "Here's what I think:", ""],
|
| 324 |
+
"es": ["Hmm, déjame pensar...", "¡Interesante!", "¡Buena pregunta!", "Esto es lo que pienso:", ""],
|
| 325 |
+
"de": ["Hmm, lass mich nachdenken...", "Interessant!", "Gute Frage!", "Das denke ich:", ""]
|
| 326 |
+
}
|
| 327 |
+
|
| 328 |
+
# Obtenir la réponse du modèle
|
| 329 |
+
model_response = call_mt5_model(user_input)
|
| 330 |
+
|
| 331 |
+
# Ajouter un préfixe occasionnel pour plus de naturel
|
| 332 |
+
prefix = random.choice(general_prefixes[lang])
|
| 333 |
+
if prefix and random.random() < 0.3: # 30% de chance d'ajouter un préfixe
|
| 334 |
+
final_response = f"{prefix} {model_response}"
|
| 335 |
+
else:
|
| 336 |
+
final_response = model_response
|
| 337 |
+
|
| 338 |
+
self.conversation_history.append({"bot": final_response, "timestamp": datetime.now()})
|
| 339 |
+
return final_response
|
| 340 |
+
|
| 341 |
+
def get_conversation_summary(self):
|
| 342 |
+
"""Retourne un résumé de la conversation"""
|
| 343 |
+
if not self.conversation_history:
|
| 344 |
+
return "Aucune conversation en cours."
|
| 345 |
+
|
| 346 |
+
user_messages = len([msg for msg in self.conversation_history if "user" in msg])
|
| 347 |
+
bot_messages = len([msg for msg in self.conversation_history if "bot" in msg])
|
| 348 |
+
|
| 349 |
+
return f"Conversation: {user_messages} messages utilisateur, {bot_messages} réponses du bot"
|
| 350 |
+
|
| 351 |
+
# Utilisation
|
| 352 |
+
def create_chatbot():
|
| 353 |
+
"""Crée une nouvelle instance du chatbot"""
|
| 354 |
+
return HumanChatbot()
|
| 355 |
+
|
| 356 |
+
# Exemple d'utilisation avec détection de problèmes
|
| 357 |
+
if __name__ == "__main__":
|
| 358 |
+
bot = create_chatbot()
|
| 359 |
+
|
| 360 |
+
# Test des salutations
|
| 361 |
+
print("=== Test Salutations ===")
|
| 362 |
+
print("User: Bonjour !")
|
| 363 |
+
print("Bot:", bot.get_bot_response("Bonjour !"))
|
| 364 |
+
|
| 365 |
+
print("\nUser: Je m'appelle Marie")
|
| 366 |
+
print("Bot:", bot.get_bot_response("Je m'appelle Marie"))
|
| 367 |
+
|
| 368 |
+
# Test des problèmes - vont directement au modèle MT5
|
| 369 |
+
print("\n=== Test Problèmes (vont au modèle MT5) ===")
|
| 370 |
+
print("User: J'ai un problème avec mon ordinateur")
|
| 371 |
+
print("Bot:", bot.get_bot_response("J'ai un problème avec mon ordinateur"))
|
| 372 |
+
|
| 373 |
+
print("\nUser: Comment résoudre une erreur 404 ?")
|
| 374 |
+
print("Bot:", bot.get_bot_response("Comment résoudre une erreur 404 ?"))
|
| 375 |
+
|
| 376 |
+
print("\nUser: Mon logiciel ne fonctionne pas, que faire ?")
|
| 377 |
+
print("Bot:", bot.get_bot_response("Mon logiciel ne fonctionne pas, que faire ?"))
|
| 378 |
+
|
| 379 |
+
print("\nUser: I need help with my code")
|
| 380 |
+
print("Bot:", bot.get_bot_response("I need help with my code"))
|
| 381 |
+
|
| 382 |
+
# Test des questions générales
|
| 383 |
+
print("\n=== Test Questions Générales ===")
|
| 384 |
+
print("User: Comment allez-vous ?")
|
| 385 |
+
print("Bot:", bot.get_bot_response("Comment allez-vous ?"))
|
| 386 |
+
|
| 387 |
+
print("\nUser: Merci beaucoup !")
|
| 388 |
+
print("Bot:", bot.get_bot_response("Merci beaucoup !"))
|
| 389 |
+
|
| 390 |
+
print("\nUser: Au revoir !")
|
| 391 |
+
print("Bot:", bot.get_bot_response("Au revoir !"))
|
| 392 |
+
|
| 393 |
+
|
| 394 |
+
|
| 395 |
+
# Ajoutez ces lignes à la fin de votre chatbot.py pour maintenir la compatibilité
|
| 396 |
+
|
| 397 |
+
# Instance globale pour la compatibilité avec l'ancien code
|
| 398 |
+
_global_chatbot = None
|
| 399 |
+
|
| 400 |
+
def get_bot_response(user_input):
|
| 401 |
+
"""
|
| 402 |
+
Fonction wrapper pour maintenir la compatibilité avec l'ancien code
|
| 403 |
+
Utilise une instance globale du chatbot
|
| 404 |
+
"""
|
| 405 |
+
global _global_chatbot
|
| 406 |
+
|
| 407 |
+
# Créer l'instance si elle n'existe pas
|
| 408 |
+
if _global_chatbot is None:
|
| 409 |
+
_global_chatbot = HumanChatbot()
|
| 410 |
+
|
| 411 |
+
# Retourner la réponse
|
| 412 |
+
return _global_chatbot.get_bot_response(user_input)
|
| 413 |
+
|
| 414 |
+
def reset_chatbot():
|
| 415 |
+
"""Réinitialise le chatbot global"""
|
| 416 |
+
global _global_chatbot
|
| 417 |
+
_global_chatbot = None
|
| 418 |
+
|
| 419 |
+
def get_chatbot_stats():
|
| 420 |
+
"""Retourne les statistiques du chatbot global"""
|
| 421 |
+
global _global_chatbot
|
| 422 |
+
if _global_chatbot is None:
|
| 423 |
+
return "Aucune conversation en cours."
|
| 424 |
+
return _global_chatbot.get_conversation_summary()
|
model_mt5.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from transformers import MT5ForConditionalGeneration, MT5Tokenizer
|
| 3 |
+
|
| 4 |
+
# Chemin vers ton modèle local (dossier contenant config.json, pytorch_model.bin, etc.)
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
model = MT5ForConditionalGeneration.from_pretrained("mt5_model", local_files_only=True)
|
| 8 |
+
import os
|
| 9 |
+
tokenizer = MT5Tokenizer.from_pretrained(os.path.join(os.path.dirname(__file__), "mt5_model"), local_files_only=True)
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def call_mt5_model(user_input: str, target_language: str = "fr") -> str:
|
| 16 |
+
|
| 17 |
+
# Préparation de l'entrée (tu peux personnaliser le format selon ton entraînement)
|
| 18 |
+
input_text = f"translate {target_language}: {user_input}"
|
| 19 |
+
|
| 20 |
+
# Encodage et génération
|
| 21 |
+
inputs = tokenizer.encode(input_text, return_tensors="pt", max_length=512, truncation=True)
|
| 22 |
+
outputs = model.generate(inputs, max_length=128, num_beams=4, early_stopping=True)
|
| 23 |
+
|
| 24 |
+
# Décodage
|
| 25 |
+
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
|
| 26 |
+
return response
|
requirements.txt
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
altair==5.5.0
|
| 2 |
+
attrs==25.3.0
|
| 3 |
+
blinker==1.9.0
|
| 4 |
+
cachetools==5.5.2
|
| 5 |
+
certifi==2025.4.26
|
| 6 |
+
charset-normalizer==3.4.2
|
| 7 |
+
click==8.2.1
|
| 8 |
+
colorama==0.4.6
|
| 9 |
+
filelock==3.18.0
|
| 10 |
+
fsspec==2025.5.1
|
| 11 |
+
gitdb==4.0.12
|
| 12 |
+
GitPython==3.1.44
|
| 13 |
+
huggingface-hub==0.32.4
|
| 14 |
+
idna==3.10
|
| 15 |
+
Jinja2==3.1.6
|
| 16 |
+
jsonschema==4.24.0
|
| 17 |
+
jsonschema-specifications==2025.4.1
|
| 18 |
+
MarkupSafe==3.0.2
|
| 19 |
+
mpmath==1.3.0
|
| 20 |
+
narwhals==1.41.0
|
| 21 |
+
networkx==3.4.2
|
| 22 |
+
numpy==2.2.6
|
| 23 |
+
packaging==24.2
|
| 24 |
+
pandas==2.3.0
|
| 25 |
+
pillow==11.2.1
|
| 26 |
+
protobuf==6.31.1
|
| 27 |
+
pyarrow==20.0.0
|
| 28 |
+
pydeck==0.9.1
|
| 29 |
+
python-dateutil==2.9.0.post0
|
| 30 |
+
pytz==2025.2
|
| 31 |
+
PyYAML==6.0.2
|
| 32 |
+
referencing==0.36.2
|
| 33 |
+
regex==2024.11.6
|
| 34 |
+
requests==2.32.3
|
| 35 |
+
rpds-py==0.25.1
|
| 36 |
+
safetensors==0.5.3
|
| 37 |
+
sentencepiece==0.2.0
|
| 38 |
+
six==1.17.0
|
| 39 |
+
smmap==5.0.2
|
| 40 |
+
streamlit==1.45.1
|
| 41 |
+
sympy==1.14.0
|
| 42 |
+
tenacity==9.1.2
|
| 43 |
+
tokenizers==0.21.1
|
| 44 |
+
toml==0.10.2
|
| 45 |
+
torch==2.7.1+cpu
|
| 46 |
+
torchaudio==2.7.1+cpu
|
| 47 |
+
torchvision==0.22.1+cpu
|
| 48 |
+
tornado==6.5.1
|
| 49 |
+
tqdm==4.67.1
|
| 50 |
+
transformers==4.52.4
|
| 51 |
+
typing_extensions==4.14.0
|
| 52 |
+
tzdata==2025.2
|
| 53 |
+
urllib3==2.4.0
|
| 54 |
+
watchdog==6.0.0
|