Woziii commited on
Commit
d8a3eeb
·
verified ·
1 Parent(s): 85815e9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +111 -97
app.py CHANGED
@@ -34,7 +34,7 @@ project_state = {
34
  }
35
 
36
  # Chargement du modèle
37
- manager_model_name = "meta-llama/Llama-3.2-3B-Instruct"
38
  manager_model = AutoModelForCausalLM.from_pretrained(
39
  manager_model_name,
40
  device_map="auto",
@@ -43,126 +43,139 @@ manager_model = AutoModelForCausalLM.from_pretrained(
43
  manager_tokenizer = AutoTokenizer.from_pretrained(manager_model_name)
44
 
45
  # Paramètres de génération
46
- MAX_NEW_TOKENS = 250
47
  TEMPERATURE = 0.7
48
  TOP_P = 0.95
49
 
50
- # --- System Prompt Simplifié ---
51
- base_prompt = """
52
- Vous êtes l'AgentManager, un assistant collaboratif et bienveillant du système multi-agent Chorege.
53
- Votre rôle est d'aider l'utilisateur à structurer ses projets, accéder aux variables partagées, et proposer des idées claires et pertinentes.
54
- Adoptez un ton chaleureux et humain, comme un conseiller bien intentionné.
55
- """
56
-
57
- # --- Analyse des Inputs ---
58
- def detect_task(user_input):
59
- """
60
- Analyse l'input utilisateur et retourne la tâche appropriée.
61
- """
62
- user_input_lower = user_input.lower()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
- # Détection des requêtes liées aux variables
65
- if "montre-moi" in user_input_lower or "variables" in user_input_lower:
66
- return "access_variables"
67
- elif "modifie" in user_input_lower or "change" in user_input_lower:
68
- return "modify_variables"
69
 
70
- # Détection des requêtes pour un résumé structuré
71
- if "résumé" in user_input_lower or "résumer" in user_input_lower or "structure" in user_input_lower:
72
- return "structure"
73
 
74
- # Par défaut, si aucune autre correspondance n'est trouvée
75
- return "exchange"
 
76
 
77
  # Fonctions utilitaires
78
  def get_variables_context():
79
  """Récupère le contexte des variables globales."""
80
  return json.dumps(project_state, indent=2, ensure_ascii=False)
81
 
82
- def update_variable(variable_path, new_value):
83
- """Met à jour une variable donnée avec une nouvelle valeur."""
84
- keys = variable_path.split('.')
85
- target = project_state
86
- for key in keys[:-1]:
87
- target = target.setdefault(key, {})
88
- target[keys[-1]] = new_value
89
- return f"La variable {variable_path} est mise à jour à : {new_value}"
90
-
91
- def build_dynamic_instructions(task, few_shot_examples):
92
- """Construit des instructions dynamiques basées sur la tâche et les exemples few-shot."""
93
- instructions = {
94
- "exchange": "Posez des questions pertinentes pour clarifier ou enrichir la requête de l'utilisateur. Limitez-vous à une ou deux questions par réponse.",
95
- "structure": "Générez un résumé structuré clair et organisé basé sur les informations collectées.",
96
- "access_variables": "Accédez aux variables demandées et affichez leur contenu de manière claire et concise.",
97
- "modify_variables": "Appliquez les modifications demandées aux variables et confirmez à l'utilisateur."
98
- }
99
- return f"{instructions[task]}\n\n### Exemples :\n" + "\n".join(few_shot_examples)
100
-
101
- def clean_output(response, system_prompt, dynamic_instructions):
102
  """Nettoie les éléments inutiles de la sortie."""
103
- response = response.replace(system_prompt, "").replace(dynamic_instructions, "").strip()
 
 
104
  return response
105
 
 
 
 
 
 
 
 
106
  def agent_manager(chat_history, user_input):
107
- """Gère les interactions utilisateur et assistant avec instructions dynamiques."""
108
- # Déterminer la tâche à partir de l'input utilisateur
109
- task = detect_task(user_input)
110
-
111
- # Génération des instructions dynamiques
112
- few_shot_examples = []
113
- if task == "exchange":
114
- few_shot_examples = [
115
- "Utilisateur : Je veux une application pour analyser les sentiments.",
116
- "Assistant : Super idée ! 😀 Quels aspects des sentiments souhaitez-vous analyser ?"
117
- ]
118
- elif task == "structure":
119
- few_shot_examples = [
120
- "Utilisateur : Peux-tu me donner un résumé ?",
121
- "Assistant : Voici un résumé structuré :\n- **Objectif principal :** Analyse des sentiments sur Twitter.\n- **Étapes clés :**\n 1. Collecter les tweets.\n 2. Analyser les sentiments."
122
- ]
123
- elif task == "access_variables":
124
- few_shot_examples = [
125
- "Utilisateur : Montre-moi les variables.",
126
- "Assistant : Voici l'état actuel des variables :\n{contenu_variables}"
127
- ]
128
- elif task == "modify_variables":
129
- few_shot_examples = [
130
- "Utilisateur : Modifie la variable AgentAnalyzer.analysis_report à ‘Analyse terminée’.",
131
- "Assistant : La modification est effectuée. La variable AgentAnalyzer.analysis_report est maintenant ‘Analyse terminée’."
132
- ]
133
-
134
- dynamic_instructions = build_dynamic_instructions(task, few_shot_examples)
135
-
136
- # Préparation du prompt
137
- system_prompt = f"{base_prompt}\n\n### Instructions :\n{dynamic_instructions}"
138
  variables_context = get_variables_context()
139
- chat_history_context = "\n".join(
 
 
140
  [f"Utilisateur : {turn['user']}\nAssistant : {turn['assistant']}" for turn in chat_history[-3:]]
141
  )
142
- full_prompt = f"{system_prompt}\n\nVariables actuelles :\n{variables_context}\n\nHistorique récent :\n{chat_history_context}\n\nUtilisateur : {user_input}\nAssistant :"
143
 
144
- # Préparation des tokens et streaming
145
- inputs = manager_tokenizer(full_prompt, return_tensors="pt").to(manager_model.device)
 
 
 
 
 
 
 
 
 
 
146
  streamer = TextIteratorStreamer(manager_tokenizer, skip_special_tokens=True)
147
 
148
- generation_thread = Thread(target=manager_model.generate, kwargs={
149
- "inputs": inputs.input_ids,
150
- "attention_mask": inputs.attention_mask,
151
- "max_new_tokens": MAX_NEW_TOKENS,
152
- "temperature": TEMPERATURE,
153
- "top_p": TOP_P,
154
- "streamer": streamer
155
- })
 
 
 
 
156
  generation_thread.start()
157
 
158
  partial_response = ""
159
  for new_text in streamer:
160
  partial_response += new_text
161
- clean_partial_response = clean_output(partial_response, system_prompt, dynamic_instructions)
 
 
 
162
  chat_history[-1]["assistant"] = clean_partial_response
163
  yield clean_partial_response, json.dumps(chat_history), get_variables_context()
164
 
165
- # Interface Gradio
166
  def gradio_interface(user_input, chat_history):
167
  chat_history = json.loads(chat_history) if chat_history else []
168
  response_generator = agent_manager(chat_history, user_input)
@@ -170,17 +183,18 @@ def gradio_interface(user_input, chat_history):
170
  yield response, updated_chat_history, variables_context
171
 
172
  with gr.Blocks() as demo:
173
- gr.Markdown("## AgentManager - Test avec Instructions Dynamiques")
174
  with gr.Row():
175
  with gr.Column():
176
- user_input = gr.Textbox(label="Entrée utilisateur", placeholder="Entrez une requête.")
177
- chat_history = gr.Textbox(label="Historique", value="[]", visible=False)
178
  submit = gr.Button("Envoyer")
179
  with gr.Column():
180
- output = gr.Textbox(label="Réponse de l'AgentManager")
181
- variables = gr.Textbox(label="Variables actuelles", interactive=False, lines=10)
182
-
183
  submit.click(gradio_interface, inputs=[user_input, chat_history], outputs=[output, chat_history, variables])
184
 
 
185
  if __name__ == "__main__":
186
  demo.queue().launch()
 
34
  }
35
 
36
  # Chargement du modèle
37
+ manager_model_name = "meta-llama/Llama-3.1-8B-Instruct"
38
  manager_model = AutoModelForCausalLM.from_pretrained(
39
  manager_model_name,
40
  device_map="auto",
 
43
  manager_tokenizer = AutoTokenizer.from_pretrained(manager_model_name)
44
 
45
  # Paramètres de génération
46
+ MAX_NEW_TOKENS = 300 # Augmenté pour éviter les réponses tronquées
47
  TEMPERATURE = 0.7
48
  TOP_P = 0.95
49
 
50
+ # Prompt optimisé avec instructions supplémentaires
51
+ manager_prompt_template = """
52
+ Vous êtes l'AgentManager, un assistant collaboratif du système multi-agent Chorege. Votre rôle est d'aider l'utilisateur à clarifier ses projets, accéder aux variables partagées, structurer les idées, et répondre à ses demandes avec clarté et efficacité.
53
+
54
+ ### Règles :
55
+ 1. Posez des questions pertinentes pour clarifier ou enrichir les idées de l'utilisateur.
56
+ 2. Limitez-vous à une ou deux questions à la fois.
57
+ 3. Donnez des réponses claires et concises, avec un ton chaleureux et engageant.
58
+ 4. Accédez aux variables partagées si demandé et affichez leur contenu de manière simple et lisible.
59
+ 5. Modifiez les variables lorsque l'utilisateur en fait la demande et confirmez le changement.
60
+ 6. Proposez un résumé structuré clair lorsque nécessaire et demandez une validation explicite.
61
+
62
+ ### Fewshot prompting :
63
+ #### Clarification d'une idée :
64
+ Utilisateur : Je veux développer une application pour analyser les sentiments.
65
+ Assistant : Super idée ! 😊 Quels aspects des sentiments voulez-vous analyser, comme le positif, négatif ou neutre ?
66
+
67
+ #### Structuration d'un résumé :
68
+ Utilisateur : Peux-tu résumer ce projet ?
69
+ Assistant : Voici un résumé structuré :
70
+ - **Objectif** : Analyser les sentiments exprimés sur Twitter.
71
+ - **Étapes** :
72
+ 1. Collecte des tweets.
73
+ 2. Analyse des sentiments avec un modèle NLP.
74
+ 3. Visualisation des tendances par catégorie.
75
+
76
+ #### Accès aux variables :
77
+ Utilisateur : Montre-moi les variables.
78
+ Assistant : Voici l'état actuel :
79
+ {
80
+ "AgentManager": {"structured_summary": null},
81
+ "AgentResearcher": {"search_results": null},
82
+ "AgentAnalyzer": {"analysis_report": null},
83
+ "AgentCoder": {"final_code": null}
84
+ }
85
 
86
+ #### Modification des variables :
87
+ Utilisateur : Modifie la variable AgentAnalyzer.analysis_report à "Rapport préliminaire terminé".
88
+ Assistant : La variable AgentAnalyzer.analysis_report est mise à jour avec succès : "Rapport préliminaire terminé".
 
 
89
 
90
+ Variables actuelles du projet :
91
+ {variables_context}
 
92
 
93
+ Historique des échanges récents :
94
+ {conversation_context}
95
+ """
96
 
97
  # Fonctions utilitaires
98
  def get_variables_context():
99
  """Récupère le contexte des variables globales."""
100
  return json.dumps(project_state, indent=2, ensure_ascii=False)
101
 
102
+ def update_project_state_from_input(user_input):
103
+ """Met à jour les variables du projet en fonction de l'entrée de l'utilisateur."""
104
+ match = re.match(r"Modifie la variable (\S+) à [‘'](.+)[’']", user_input)
105
+ if match:
106
+ var_path, new_value = match.groups()
107
+ keys = var_path.split('.')
108
+ target = project_state
109
+ for key in keys[:-1]:
110
+ target = target.setdefault(key, {})
111
+ target[keys[-1]] = new_value
112
+
113
+ def clean_output(response, system_prompt, conversation_context):
 
 
 
 
 
 
 
 
114
  """Nettoie les éléments inutiles de la sortie."""
115
+ response = response.replace(system_prompt, "").replace(conversation_context, "").strip()
116
+ # Supprimer les rôles
117
+ response = re.sub(r"(Utilisateur|AgentManager) ?: ?", "", response)
118
  return response
119
 
120
+ def format_response(response):
121
+ """Formate les questions de l'AgentManager pour une meilleure clarté."""
122
+ # Ajoute un saut de ligne avant les questions
123
+ response = re.sub(r"(\?)(\s|$)", r"\1\n\n🔹 **Question :** ", response)
124
+ return response.strip()
125
+
126
+ # Fonction principale avec streaming
127
  def agent_manager(chat_history, user_input):
128
+ """Gère les interactions utilisateur et assistant avec streaming."""
129
+ # Mettre à jour les variables du projet si nécessaire
130
+ update_project_state_from_input(user_input)
131
+
132
+ # Préparer le contexte des variables
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  variables_context = get_variables_context()
134
+
135
+ # Générer le contexte de conversation
136
+ conversation_context = "\n".join(
137
  [f"Utilisateur : {turn['user']}\nAssistant : {turn['assistant']}" for turn in chat_history[-3:]]
138
  )
 
139
 
140
+ # Créer le prompt complet
141
+ system_prompt = manager_prompt_template.format(
142
+ variables_context=variables_context,
143
+ conversation_context=conversation_context
144
+ )
145
+
146
+ # Ajouter l'entrée utilisateur actuelle
147
+ chat_history.append({"user": user_input, "assistant": ""})
148
+
149
+ # Préparation des tokens et du streamer
150
+ inputs = manager_tokenizer(system_prompt + "\nUtilisateur : " + user_input + "\nAssistant : ", return_tensors="pt").to(manager_model.device)
151
+ attention_mask = inputs.attention_mask
152
  streamer = TextIteratorStreamer(manager_tokenizer, skip_special_tokens=True)
153
 
154
+ # Thread pour la génération
155
+ generation_kwargs = dict(
156
+ input_ids=inputs.input_ids,
157
+ attention_mask=attention_mask,
158
+ max_new_tokens=MAX_NEW_TOKENS,
159
+ temperature=TEMPERATURE,
160
+ top_p=TOP_P,
161
+ eos_token_id=manager_tokenizer.eos_token_id,
162
+ pad_token_id=manager_tokenizer.pad_token_id,
163
+ streamer=streamer
164
+ )
165
+ generation_thread = Thread(target=manager_model.generate, kwargs=generation_kwargs)
166
  generation_thread.start()
167
 
168
  partial_response = ""
169
  for new_text in streamer:
170
  partial_response += new_text
171
+ # Nettoyer la réponse partielle pour exclure toute autogénération de l'utilisateur
172
+ clean_partial_response = clean_output(partial_response, system_prompt, conversation_context)
173
+ # Formatage des questions pour plus de clarté
174
+ clean_partial_response = format_response(clean_partial_response)
175
  chat_history[-1]["assistant"] = clean_partial_response
176
  yield clean_partial_response, json.dumps(chat_history), get_variables_context()
177
 
178
+ # Interface Gradio avec Streaming
179
  def gradio_interface(user_input, chat_history):
180
  chat_history = json.loads(chat_history) if chat_history else []
181
  response_generator = agent_manager(chat_history, user_input)
 
183
  yield response, updated_chat_history, variables_context
184
 
185
  with gr.Blocks() as demo:
186
+ gr.Markdown("## AgentManager - Test d'Interactions Collaboratives avec Streaming")
187
  with gr.Row():
188
  with gr.Column():
189
+ user_input = gr.Textbox(label="Entrée utilisateur", placeholder="Entrez une requête ou une instruction.")
190
+ chat_history = gr.Textbox(label="Historique de conversation", value="[]", visible=False)
191
  submit = gr.Button("Envoyer")
192
  with gr.Column():
193
+ output = gr.Textbox(label="Réponse de l'AgentManager", interactive=False)
194
+ variables = gr.Textbox(label="Variables globales actuelles", interactive=False, lines=20)
195
+
196
  submit.click(gradio_interface, inputs=[user_input, chat_history], outputs=[output, chat_history, variables])
197
 
198
+ # Lancer l'interface
199
  if __name__ == "__main__":
200
  demo.queue().launch()