Spaces:
Running
Running
Florian.Moret
commited on
Commit
·
e66f9f2
1
Parent(s):
f056b9f
update prompts et interface sans cadre refs
Browse files
app.py
CHANGED
@@ -3,25 +3,24 @@ import streamlit as st
|
|
3 |
import os
|
4 |
from mistralai import Mistral
|
5 |
|
6 |
-
MISTRAL_API_KEY = os.getenv("api_mistral")
|
7 |
model = 'mistral-large-latest'
|
8 |
mistral_client = Mistral(api_key=MISTRAL_API_KEY)
|
9 |
MAX_TOKENS = 1500
|
10 |
#endregion
|
11 |
|
12 |
#region# Définition des prompts
|
13 |
-
def generate_prompts(score:str, type: str, annee_min: str, annee_max:str ):
|
14 |
"""
|
15 |
Genere les prefixes et suffixes des prompts pour Mistral en fonction du score de vulgarisation, du type d'espece, et les années des documents
|
16 |
-
|
17 |
Args:
|
18 |
score (str): 1 = vulgarisé, 2 = intermédiaire, 3 = technique
|
19 |
-
type (str): '
|
20 |
annee_min (str): annee min de publication
|
21 |
annee_max (str): annee max de publication
|
22 |
|
23 |
"""
|
24 |
-
|
25 |
if type == "Ponte":
|
26 |
type_description = "volailles pondeuses"
|
27 |
elif type == "Chair":
|
@@ -30,36 +29,41 @@ def generate_prompts(score:str, type: str, annee_min: str, annee_max:str ):
|
|
30 |
raise ValueError("Type must be either 'Ponte' or 'Chair'")
|
31 |
|
32 |
if score == "1":
|
33 |
-
prefix_prompt = f"""Tu es un assistant IA spécialisé en nutrition de la volaille. Ton utilisateur est un chercheur travaillant sur
|
34 |
-
alimentaires pour optimiser la santé et la croissance des {type_description}.
|
35 |
-
Réponds en fournissant
|
36 |
-
|
37 |
-
suffix_prompt = """Réponds en français et donne une réponse directe et claire
|
|
|
38 |
elif score == "2":
|
39 |
-
prefix_prompt = f"""Tu es un assistant IA spécialisé en nutrition de la volaille. Ton utilisateur est un chercheur travaillant sur
|
40 |
-
alimentaires pour optimiser la santé et la croissance des {type_description}.
|
41 |
-
Réponds en fournissant des explications
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
|
|
|
|
46 |
elif score == "3":
|
47 |
-
prefix_prompt = f"""Tu es un assistant IA spécialisé en nutrition de la volaille. Ton utilisateur est un chercheur travaillant sur
|
48 |
-
alimentaires pour optimiser la santé et la croissance des {type_description}.
|
49 |
Réponds en fournissant des explications détaillées et précises, adaptées à la complexité de la question posée.
|
50 |
N'oublie pas de citer à la fin de ta réponse les références sur lesquelles tu t'es basé avec son année (entre {annee_min} et {annee_max}).
|
51 |
-
|
52 |
-
suffix_prompt = """
|
53 |
-
|
|
|
|
|
|
|
54 |
else:
|
55 |
raise ValueError("Score must be 1, 2, or 3")
|
56 |
|
57 |
return prefix_prompt, suffix_prompt
|
58 |
-
|
59 |
-
def send_prompt_to_mistral(type_reponse: str, user_prompt: str, temperature:int, n_comp:int, prefix_prompt: str, suffix_prompt:str, verbose=True):
|
60 |
"""
|
61 |
Envoie un prompt à Mistral pour obtenir une réponse
|
62 |
-
|
63 |
Args:
|
64 |
type_reponse (str): Le rôle de l'utilisateur, peut être 'technicien' ou 'chercheur'.
|
65 |
Si le rôle ne correspond pas à l'un de ces deux, une exception sera levée.
|
@@ -68,14 +72,13 @@ def send_prompt_to_mistral(type_reponse: str, user_prompt: str, temperature:int,
|
|
68 |
verbose (bool): Print la reponse avant le return
|
69 |
prefixe (str): Prefixe du prompt
|
70 |
suffixe (str): Suffixe du prompt
|
71 |
-
|
72 |
Returns:
|
73 |
dict: La réponse du modèle Mistral à partir du prompt fourni.
|
74 |
-
|
75 |
Raises:
|
76 |
ValueError: Si le rôle spécifié n'est pas 'technicien' ou 'chercheur'.
|
77 |
"""
|
78 |
-
|
|
|
79 |
# Création du message à envoyer à Mistral
|
80 |
messages = [{"role": type_reponse, "content": suffix_prompt}]
|
81 |
|
@@ -86,7 +89,7 @@ def send_prompt_to_mistral(type_reponse: str, user_prompt: str, temperature:int,
|
|
86 |
{"role": "system", "content": prefix_prompt},
|
87 |
{"role": "user", "content": user_prompt + suffix_prompt},
|
88 |
],
|
89 |
-
|
90 |
#response_format={
|
91 |
# 'type': 'json_object'
|
92 |
#},
|
@@ -96,12 +99,12 @@ def send_prompt_to_mistral(type_reponse: str, user_prompt: str, temperature:int,
|
|
96 |
stream=False
|
97 |
#stop='\n'
|
98 |
)
|
99 |
-
|
100 |
if verbose:
|
101 |
print(chat_response)
|
102 |
-
|
103 |
return chat_response
|
104 |
-
|
105 |
def is_valid_mistral_response(response: dict) -> bool:
|
106 |
"""
|
107 |
Vérifie si la réponse de l'API Mistral est valide.
|
@@ -142,33 +145,60 @@ def is_valid_mistral_response(response: dict) -> bool:
|
|
142 |
return False
|
143 |
|
144 |
return True
|
145 |
-
|
146 |
def print_pretty_response(response: dict, verbose=True):
|
147 |
-
|
148 |
pretty = response.choices[0].message.content
|
149 |
-
|
150 |
if verbose:
|
151 |
print(pretty)
|
152 |
|
153 |
return pretty
|
154 |
-
|
155 |
def response_details(response, verbose=True):
|
156 |
"""
|
157 |
Envoie les details techniques du prompt
|
158 |
"""
|
159 |
-
|
160 |
details = {}
|
161 |
details["id"] = response.id
|
162 |
details["total_tokens"] = response.usage.total_tokens
|
163 |
details["prefix"] = response.choices[0].message.prefix
|
164 |
details["role"] = response.choices[0].message.role
|
165 |
-
|
166 |
if verbose:
|
167 |
print(details)
|
168 |
-
|
169 |
return details
|
170 |
-
|
171 |
-
def prompt_pipeline(user_prompt: str, niveau_detail: str, type_reponse: str, souche: str, annee_publication_min: str, annee_publication_max: str):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
"""
|
173 |
Fonction visible de l'application pour appeler un prompt et obtenir sa reponse
|
174 |
|
@@ -241,7 +271,7 @@ if st.button("Envoyer la question..."):
|
|
241 |
)
|
242 |
print(response0["reponse_propre"])
|
243 |
response = response0["reponse_propre"]
|
244 |
-
bot_response = response
|
245 |
|
246 |
# st.markdown("**Bot :** \\t " + bot_response)
|
247 |
# Afficher un titre
|
@@ -250,19 +280,20 @@ if st.button("Envoyer la question..."):
|
|
250 |
# Ajouter du texte Markdown avec un cadre
|
251 |
st.markdown(f"""
|
252 |
<div style="border: 2px solid #453103; padding: 15px; border-radius: 10px;">
|
253 |
-
{bot_response
|
254 |
</div>
|
255 |
""", unsafe_allow_html=True)
|
|
|
|
|
|
|
|
|
256 |
|
257 |
-
#
|
258 |
-
st.
|
259 |
-
|
260 |
-
#
|
261 |
-
|
262 |
-
|
263 |
-
{bot_response[1]}
|
264 |
-
</div>
|
265 |
-
""", unsafe_allow_html=True)
|
266 |
|
267 |
#encadré Reviews
|
268 |
# st.markdown("""
|
@@ -278,28 +309,4 @@ if st.button("Envoyer la question..."):
|
|
278 |
st.warning("Veuillez compléter les paramètres dans le bandeau latéral de gauche!")
|
279 |
#endregion
|
280 |
|
281 |
-
|
282 |
-
|
283 |
-
#region# Markdown
|
284 |
-
# st.markdown("""
|
285 |
-
# <style>
|
286 |
-
# p {
|
287 |
-
# color: #555555;
|
288 |
-
# }
|
289 |
-
|
290 |
-
# .st-bx {
|
291 |
-
# background-color: #f1f1f1;
|
292 |
-
# border-radius: 10px;
|
293 |
-
# padding: 10px;
|
294 |
-
# margin: 10px 0;
|
295 |
-
# }
|
296 |
-
# .st-bx h2 {
|
297 |
-
# color: #4CAF50;
|
298 |
-
# }
|
299 |
-
# .st-bx p {
|
300 |
-
# color: #555;
|
301 |
-
# }
|
302 |
-
# </style>
|
303 |
-
# """, unsafe_allow_html=True)
|
304 |
-
|
305 |
-
#endregion
|
|
|
3 |
import os
|
4 |
from mistralai import Mistral
|
5 |
|
6 |
+
MISTRAL_API_KEY = 'DFtRafUrJnASg1cqrEWNtSMKAjZT4Njp' #os.getenv("api_mistral")
|
7 |
model = 'mistral-large-latest'
|
8 |
mistral_client = Mistral(api_key=MISTRAL_API_KEY)
|
9 |
MAX_TOKENS = 1500
|
10 |
#endregion
|
11 |
|
12 |
#region# Définition des prompts
|
13 |
+
def generate_prompts(score:str, type: str, annee_min: str, annee_max:str ) -> dict:
|
14 |
"""
|
15 |
Genere les prefixes et suffixes des prompts pour Mistral en fonction du score de vulgarisation, du type d'espece, et les années des documents
|
|
|
16 |
Args:
|
17 |
score (str): 1 = vulgarisé, 2 = intermédiaire, 3 = technique
|
18 |
+
type (str): 'Ponte' ou 'Chair'
|
19 |
annee_min (str): annee min de publication
|
20 |
annee_max (str): annee max de publication
|
21 |
|
22 |
"""
|
23 |
+
|
24 |
if type == "Ponte":
|
25 |
type_description = "volailles pondeuses"
|
26 |
elif type == "Chair":
|
|
|
29 |
raise ValueError("Type must be either 'Ponte' or 'Chair'")
|
30 |
|
31 |
if score == "1":
|
32 |
+
prefix_prompt = f"""Tu es un assistant IA spécialisé en nutrition de la volaille. Ton utilisateur est un chercheur travaillant sur
|
33 |
+
l'amélioration des régimes alimentaires pour optimiser la santé et la croissance des {type_description}.
|
34 |
+
Réponds en fournissant en vulgarisant les informations.
|
35 |
+
Pour fournir la réponse, tu dois te baser sur des publications/articles qui ont une date de publication entre {annee_min} et {annee_max}."""
|
36 |
+
suffix_prompt = """Réponds en français et donne une réponse directe et claire.
|
37 |
+
Fini par faire une bibliographie avec les références bibliographiquesque tu as utilisé."""
|
38 |
elif score == "2":
|
39 |
+
prefix_prompt = f"""Tu es un assistant IA spécialisé en nutrition de la volaille. Ton utilisateur est un chercheur travaillant sur
|
40 |
+
l'amélioration des régimes alimentaires pour optimiser la santé et la croissance des {type_description}.
|
41 |
+
Réponds en fournissant des explications claires et concises, adaptées à la question posée.
|
42 |
+
Pour fournir la réponse, tu dois te baser sur des publications/articles qui ont une date de publication entre {annee_min} et {annee_max}.
|
43 |
+
Tes réponses doivent être structurées, complètes et adaptées aux professionnels du secteur."""
|
44 |
+
suffix_prompt = """Présente une réponse claire et concise, en commençant par une explication des causes du problème,
|
45 |
+
suivie d'une analyse des facteurs de risque, et termine par des recommandations. Utilise un ton
|
46 |
+
professionnel, clair et rigoureux. Réponds en français.
|
47 |
+
Fini par faire une bibliographie avec les références bibliographiques que tu as utilisé."""
|
48 |
elif score == "3":
|
49 |
+
prefix_prompt = f"""Tu es un assistant IA spécialisé en nutrition de la volaille. Ton utilisateur est un chercheur travaillant sur
|
50 |
+
l'amélioration des régimes alimentaires pour optimiser la santé et la croissance des {type_description}.
|
51 |
Réponds en fournissant des explications détaillées et précises, adaptées à la complexité de la question posée.
|
52 |
N'oublie pas de citer à la fin de ta réponse les références sur lesquelles tu t'es basé avec son année (entre {annee_min} et {annee_max}).
|
53 |
+
Tes réponses doivent être structurées, complètes et adaptées aux professionnels du secteur."""
|
54 |
+
suffix_prompt = """Présente une réponse détaillée et complète, en commençant par une explication des causes du problème,
|
55 |
+
suivie d'une analyse des facteurs de risque, et termine par des recommandations pratiques et éprouvées. Utilise un ton
|
56 |
+
professionnel, clair et rigoureux. Si possible, inclue des chiffres, des études ou des références pertinentes pour renforcer
|
57 |
+
la crédibilité de la réponse. Réponds en français.
|
58 |
+
Fini par faire une bibliographie avec les références bibliographiques que tu as utilisé."""
|
59 |
else:
|
60 |
raise ValueError("Score must be 1, 2, or 3")
|
61 |
|
62 |
return prefix_prompt, suffix_prompt
|
63 |
+
|
64 |
+
def send_prompt_to_mistral(type_reponse: str, user_prompt: str, temperature:int, n_comp:int, prefix_prompt: str, suffix_prompt:str, verbose=True) -> str:
|
65 |
"""
|
66 |
Envoie un prompt à Mistral pour obtenir une réponse
|
|
|
67 |
Args:
|
68 |
type_reponse (str): Le rôle de l'utilisateur, peut être 'technicien' ou 'chercheur'.
|
69 |
Si le rôle ne correspond pas à l'un de ces deux, une exception sera levée.
|
|
|
72 |
verbose (bool): Print la reponse avant le return
|
73 |
prefixe (str): Prefixe du prompt
|
74 |
suffixe (str): Suffixe du prompt
|
|
|
75 |
Returns:
|
76 |
dict: La réponse du modèle Mistral à partir du prompt fourni.
|
|
|
77 |
Raises:
|
78 |
ValueError: Si le rôle spécifié n'est pas 'technicien' ou 'chercheur'.
|
79 |
"""
|
80 |
+
|
81 |
+
|
82 |
# Création du message à envoyer à Mistral
|
83 |
messages = [{"role": type_reponse, "content": suffix_prompt}]
|
84 |
|
|
|
89 |
{"role": "system", "content": prefix_prompt},
|
90 |
{"role": "user", "content": user_prompt + suffix_prompt},
|
91 |
],
|
92 |
+
|
93 |
#response_format={
|
94 |
# 'type': 'json_object'
|
95 |
#},
|
|
|
99 |
stream=False
|
100 |
#stop='\n'
|
101 |
)
|
102 |
+
|
103 |
if verbose:
|
104 |
print(chat_response)
|
105 |
+
|
106 |
return chat_response
|
107 |
+
|
108 |
def is_valid_mistral_response(response: dict) -> bool:
|
109 |
"""
|
110 |
Vérifie si la réponse de l'API Mistral est valide.
|
|
|
145 |
return False
|
146 |
|
147 |
return True
|
148 |
+
|
149 |
def print_pretty_response(response: dict, verbose=True):
|
150 |
+
|
151 |
pretty = response.choices[0].message.content
|
152 |
+
|
153 |
if verbose:
|
154 |
print(pretty)
|
155 |
|
156 |
return pretty
|
157 |
+
|
158 |
def response_details(response, verbose=True):
|
159 |
"""
|
160 |
Envoie les details techniques du prompt
|
161 |
"""
|
162 |
+
|
163 |
details = {}
|
164 |
details["id"] = response.id
|
165 |
details["total_tokens"] = response.usage.total_tokens
|
166 |
details["prefix"] = response.choices[0].message.prefix
|
167 |
details["role"] = response.choices[0].message.role
|
168 |
+
|
169 |
if verbose:
|
170 |
print(details)
|
171 |
+
|
172 |
return details
|
173 |
+
|
174 |
+
def prompt_pipeline(user_prompt: str, niveau_detail: str, type_reponse: str, souche: str, annee_publication_min: str, annee_publication_max: str) -> dict:
|
175 |
+
"""
|
176 |
+
Fonction visible de l'application pour appeler un prompt et obtenir sa reponse
|
177 |
+
Args:
|
178 |
+
prompt (str): Prompt utilisateur
|
179 |
+
niveau_detail (str): Niveau de detail de la requete : 1, 2, 3. Plus haut = plus d'infos
|
180 |
+
type_reponse (str): 'Ponte', 'Chair'
|
181 |
+
Returns:
|
182 |
+
Dict
|
183 |
+
"""
|
184 |
+
|
185 |
+
prefix_prompt, suffix_prompt = generate_prompts(score=niveau_detail, type=type_reponse, annee_min=annee_publication_min, annee_max=annee_publication_max)
|
186 |
+
|
187 |
+
reponse_mistral = send_prompt_to_mistral(
|
188 |
+
type_reponse=type_reponse,
|
189 |
+
user_prompt=user_prompt,
|
190 |
+
temperature=0.10,
|
191 |
+
n_comp=1,
|
192 |
+
verbose=False,
|
193 |
+
prefix_prompt=prefix_prompt,
|
194 |
+
suffix_prompt=suffix_prompt
|
195 |
+
)
|
196 |
+
|
197 |
+
to_return = {}
|
198 |
+
to_return["reponse_propre"] = print_pretty_response(reponse_mistral, verbose=True)
|
199 |
+
to_return["details"] = response_details(reponse_mistral, verbose=False)
|
200 |
+
|
201 |
+
return to_return
|
202 |
"""
|
203 |
Fonction visible de l'application pour appeler un prompt et obtenir sa reponse
|
204 |
|
|
|
271 |
)
|
272 |
print(response0["reponse_propre"])
|
273 |
response = response0["reponse_propre"]
|
274 |
+
bot_response = response
|
275 |
|
276 |
# st.markdown("**Bot :** \\t " + bot_response)
|
277 |
# Afficher un titre
|
|
|
280 |
# Ajouter du texte Markdown avec un cadre
|
281 |
st.markdown(f"""
|
282 |
<div style="border: 2px solid #453103; padding: 15px; border-radius: 10px;">
|
283 |
+
{bot_response}
|
284 |
</div>
|
285 |
""", unsafe_allow_html=True)
|
286 |
+
|
287 |
+
#encadré sources
|
288 |
+
# # Afficher un titre
|
289 |
+
# st.subheader("Sources :")
|
290 |
|
291 |
+
# # Ajouter du texte Markdown avec un cadre
|
292 |
+
# st.markdown(f"""
|
293 |
+
# <div style="border: 2px solid #453103; padding: 15px; border-radius: 10px;">
|
294 |
+
# {bot_response[1]}
|
295 |
+
# </div>
|
296 |
+
# """, unsafe_allow_html=True)
|
|
|
|
|
|
|
297 |
|
298 |
#encadré Reviews
|
299 |
# st.markdown("""
|
|
|
309 |
st.warning("Veuillez compléter les paramètres dans le bandeau latéral de gauche!")
|
310 |
#endregion
|
311 |
|
312 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|