[email protected] commited on
Commit
ab998fb
·
1 Parent(s): 5871c76

feat: update config.yaml and chatbot logic to enhance budget handling and improve message formatting

Browse files
Files changed (4) hide show
  1. config.yaml +38 -27
  2. pages/chatbot.py +33 -5
  3. rag.py +14 -7
  4. vectore_store/PineconeConnector.py +1 -1
config.yaml CHANGED
@@ -66,8 +66,8 @@ variables:
66
  - label: "Type d'activité"
67
  nature: 'selectbox'
68
  key: type_activite
69
- options: ["Agriculture", "Elevage", "Viticulture"]
70
- value: "Agriculture"
71
 
72
  - label: "Spécificités et/ou Certifications"
73
  nature: 'multiselect'
@@ -114,13 +114,23 @@ variables:
114
  options: ["Innovation", "Durabilité", "Développement", "Formation"]
115
  value:
116
 
117
- - label: "Budget total estimé"
118
- nature: 'slider'
119
- key: projet_budget
120
- value: [] # Valeur par défaut
121
- min: 0
122
- max: 50000
123
- step: 500
 
 
 
 
 
 
 
 
 
 
124
 
125
 
126
  - name: "Critères de Subvention"
@@ -145,36 +155,37 @@ variables:
145
  value: "Tous"
146
 
147
 
148
- prompt_system: ""
149
-
150
- prompt_template: "
151
-
152
  Informations générales de l'exploitation agricole :
153
-
154
- Nom de l'exploitation : {exploitation_name}
155
- Localisation : {localisation}
156
- Type d'activité : {type_activite}
157
- Spécificités et/ou Certifications : {specificite_certifications}
158
- Date de création de l'entreprise : {date_creation}
159
- Chiffre d'affaires annuel (en €) : {ca_annuel}
160
- EBE (Excédent Brut d'Exploitation, en €) : {ebe}
161
- Total Bilan : {total_bilan}
162
- Nombre de salarié : {nb_salaries}
163
-
164
- Projet en cours : L'exploitation souhaite développer un projet décrit comme suit : {projet_description}. Ce projet est catégorisé sous {projet_categorie} avec une tranche de budget estimée entre {projet_budget} €. L'impact de ce projet est important pour l'entreprise et nécessite un soutien financier approprié.
165
 
166
  Pour obtenir les subventions les plus adaptées, l'utilisateur a spécifié les critères suivants :
167
  - Périmètre géographique de recherche : {recherche_geo}
168
  - Type de subvention souhaitée : {subvention_type}
169
  - Thématique de l'aide : {subvention_thematic}
 
 
 
170
 
171
  Les informations supplémentaires pertinentes, issues des données préexistantes sur les subventions et les documents fournis, sont les suivantes :
172
  - Documents partagés : {commonContext}
173
  L'utilisateur a monté le document suivant : {documentContext}
174
 
175
  Répond à l'utilisateur en te basant sur les subventions récupérer dans {commonContext}
176
-
177
- {prompt_system}
 
 
178
 
179
  Afin de bien cerner les attentes de l’utilisateur et de proposer des subventions alignées avec ses besoins, voici un rappel de ses précédentes questions et attentes :
180
  - Historique des messages : {messages}
 
66
  - label: "Type d'activité"
67
  nature: 'selectbox'
68
  key: type_activite
69
+ options: [ "Toutes", "Cereales", "Elevage", "Equin", "Forestier", "Peche", "Viticole" ]
70
+ value: ""
71
 
72
  - label: "Spécificités et/ou Certifications"
73
  nature: 'multiselect'
 
114
  options: ["Innovation", "Durabilité", "Développement", "Formation"]
115
  value:
116
 
117
+ - label: "Budget Minimum"
118
+ nature: 'numeric'
119
+ key: budget_minimum
120
+ value: 1000
121
+
122
+ - label: "Budget Maximum"
123
+ nature: 'numeric'
124
+ key: budget_maximum
125
+ value: 6000000
126
+
127
+ # - label: "Budget total estimé"
128
+ # nature: 'slider'
129
+ # key: projet_budget
130
+ # value: [] # Valeur par défaut
131
+ # min: 0
132
+ # max: 50000
133
+ # step: 500
134
 
135
 
136
  - name: "Critères de Subvention"
 
155
  value: "Tous"
156
 
157
 
158
+ prompt_system: "
 
 
 
159
  Informations générales de l'exploitation agricole :
160
+ Nom de l'exploitation : {exploitation_name}\n\n
161
+ Localisation : {localisation}\n\n
162
+ Type d'activité : {type_activite}\n\n
163
+ Spécificités et/ou Certifications : {specificite_certifications}\n\n
164
+ Date de création de l'entreprise : {date_creation}\n\n
165
+ Chiffre d'affaires annuel (en €) : {ca_annuel}\n\n
166
+ EBE (Excédent Brut d'Exploitation, en €) : {ebe}\n\n
167
+ Total Bilan : {total_bilan}\n\n
168
+ Nombre de salarié : {nb_salaries}\n\n
169
+
170
+ Projet en cours : L'exploitation souhaite développer un projet décrit comme suit : {projet_description}. Ce projet est catégorisé sous {projet_categorie} avec une tranche de budget estimée entre {budget_minimum} et {budget_maximum} €. L'impact de ce projet est important pour l'entreprise et nécessite un soutien financier approprié.
 
171
 
172
  Pour obtenir les subventions les plus adaptées, l'utilisateur a spécifié les critères suivants :
173
  - Périmètre géographique de recherche : {recherche_geo}
174
  - Type de subvention souhaitée : {subvention_type}
175
  - Thématique de l'aide : {subvention_thematic}
176
+ "
177
+
178
+ prompt_template: "
179
 
180
  Les informations supplémentaires pertinentes, issues des données préexistantes sur les subventions et les documents fournis, sont les suivantes :
181
  - Documents partagés : {commonContext}
182
  L'utilisateur a monté le document suivant : {documentContext}
183
 
184
  Répond à l'utilisateur en te basant sur les subventions récupérer dans {commonContext}
185
+ Répond en n'oubliant pas, au minimum, pour chaque aide/subvention :
186
+ - Le nom
187
+ - Le lien
188
+ - La source
189
 
190
  Afin de bien cerner les attentes de l’utilisateur et de proposer des subventions alignées avec ses besoins, voici un rappel de ses précédentes questions et attentes :
191
  - Historique des messages : {messages}
pages/chatbot.py CHANGED
@@ -1,5 +1,6 @@
1
  import streamlit as st
2
- from langchain_core.messages import AIMessage, HumanMessage
 
3
  from model import selector
4
  from util import getYamlConfig
5
  from st_copy_to_clipboard import st_copy_to_clipboard
@@ -20,6 +21,10 @@ def display_messages():
20
  with st.chat_message("Moi"):
21
  st.write(message.content)
22
 
 
 
 
 
23
  def show_retrieved_documents(query: str = ''):
24
  if query == '':
25
  return
@@ -32,7 +37,7 @@ def show_retrieved_documents(query: str = ''):
32
  if 'query' in item:
33
  if item["query"] == query:
34
  for doc in item.get("documents", []):
35
- expander.write(doc)
36
 
37
 
38
  def launchQuery(query: str = None):
@@ -41,7 +46,7 @@ def launchQuery(query: str = None):
41
  full_response = st.write_stream(
42
  st.session_state["assistant"].ask(
43
  query,
44
- prompt_system=st.session_state.prompt_system,
45
  messages=st.session_state["chat_history"] if "chat_history" in st.session_state else [],
46
  variables=st.session_state["data_dict"]
47
  ))
@@ -63,6 +68,18 @@ def show_prompts():
63
  if expander.button(item, key=f"button_{item}"):
64
  launchQuery(item)
65
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
  def page():
68
  st.subheader("Posez vos questions")
@@ -70,8 +87,19 @@ def page():
70
  if "assistant" not in st.session_state:
71
  st.text("Assistant non initialisé")
72
 
73
- if "chat_history" not in st.session_state:
74
- st.session_state["chat_history"] = []
 
 
 
 
 
 
 
 
 
 
 
75
 
76
  st.markdown("<style>iframe{height:50px;}</style>", unsafe_allow_html=True)
77
 
 
1
  import streamlit as st
2
+ from langchain_core.messages import AIMessage, HumanMessage, SystemMessage
3
+ from langchain.prompts import PromptTemplate
4
  from model import selector
5
  from util import getYamlConfig
6
  from st_copy_to_clipboard import st_copy_to_clipboard
 
21
  with st.chat_message("Moi"):
22
  st.write(message.content)
23
 
24
+ # elif isinstance(message, SystemMessage):
25
+ # with st.chat_message("System"):
26
+ # st.write(message.content)
27
+
28
  def show_retrieved_documents(query: str = ''):
29
  if query == '':
30
  return
 
37
  if 'query' in item:
38
  if item["query"] == query:
39
  for doc in item.get("documents", []):
40
+ expander.write(doc["metadata"]["source"])
41
 
42
 
43
  def launchQuery(query: str = None):
 
46
  full_response = st.write_stream(
47
  st.session_state["assistant"].ask(
48
  query,
49
+ # prompt_system=st.session_state.prompt_system,
50
  messages=st.session_state["chat_history"] if "chat_history" in st.session_state else [],
51
  variables=st.session_state["data_dict"]
52
  ))
 
68
  if expander.button(item, key=f"button_{item}"):
69
  launchQuery(item)
70
 
71
+ def remplir_texte(texte: str, variables: dict) -> str:
72
+ # Convertir les valeurs en chaînes de caractères pour éviter les erreurs avec format()
73
+ variables_str = {key: (', '.join(value) if isinstance(value, list) else value if value else 'Non spécifié')
74
+ for key, value in variables.items()}
75
+
76
+ # Remplacer les variables dynamiques dans le texte
77
+ try:
78
+ texte_rempli = texte.format(**variables_str)
79
+ except KeyError as e:
80
+ raise ValueError(f"Clé manquante dans le dictionnaire : {e}")
81
+
82
+ return texte_rempli
83
 
84
  def page():
85
  st.subheader("Posez vos questions")
 
87
  if "assistant" not in st.session_state:
88
  st.text("Assistant non initialisé")
89
 
90
+ if "chat_history" not in st.session_state or len(st.session_state["chat_history"]) == 1:
91
+
92
+ print("got here")
93
+ if st.session_state["data_dict"] is not None:
94
+ # Convertir la liste en dictionnaire avec 'key' comme clé et 'value' comme valeur
95
+ vars = {item['key']: item['value'] for item in st.session_state["data_dict"] if 'key' in item and 'value' in item}
96
+
97
+ system_template = st.session_state.prompt_system
98
+ full = remplir_texte(system_template, vars)
99
+
100
+ st.session_state["chat_history"] = [
101
+ SystemMessage(content=full),
102
+ ]
103
 
104
  st.markdown("<style>iframe{height:50px;}</style>", unsafe_allow_html=True)
105
 
rag.py CHANGED
@@ -73,22 +73,29 @@ class Rag:
73
  self.retriever = document_vector_store.as_retriever(
74
  search_type="similarity_score_threshold",
75
  search_kwargs={
76
- "k": 3,
77
- "score_threshold": 0.5,
78
  },
79
  )
80
 
81
- def ask(self, query: str, prompt_system: str, messages: list, variables: list = None):
82
  self.chain = self.prompt | self.model | StrOutputParser()
83
-
 
 
 
 
 
 
84
  # Retrieve the context document
85
  if self.retriever is None:
86
  documentContext = ''
87
  else:
88
- documentContext = self.retriever.invoke(query)
 
89
 
90
  # Retrieve the VectoreStore
91
- contextCommon = self.vector_store.retriever(query, self.embedding)
92
 
93
  st.session_state["retrived_documents"].append({ "query": query, "documents": contextCommon })
94
 
@@ -97,7 +104,7 @@ class Rag:
97
  "query": query,
98
  "documentContext": documentContext,
99
  "commonContext": contextCommon,
100
- "prompt_system": prompt_system,
101
  "messages": messages
102
  }
103
 
 
73
  self.retriever = document_vector_store.as_retriever(
74
  search_type="similarity_score_threshold",
75
  search_kwargs={
76
+ "k": 5,
77
+ "score_threshold": 0.6,
78
  },
79
  )
80
 
81
+ def ask(self, query: str, prompt_system: str = '', messages: list = [], variables: list = None):
82
  self.chain = self.prompt | self.model | StrOutputParser()
83
+
84
+ if len(messages) > 0:
85
+ systemMessage = messages[0]
86
+ empower_query = systemMessage.content + " " + query
87
+ else:
88
+ empower_query = query
89
+
90
  # Retrieve the context document
91
  if self.retriever is None:
92
  documentContext = ''
93
  else:
94
+ documentContext = self.retriever.invoke(empower_query)
95
+
96
 
97
  # Retrieve the VectoreStore
98
+ contextCommon = self.vector_store.retriever(empower_query, self.embedding)
99
 
100
  st.session_state["retrived_documents"].append({ "query": query, "documents": contextCommon })
101
 
 
104
  "query": query,
105
  "documentContext": documentContext,
106
  "commonContext": contextCommon,
107
+ # "prompt_system": prompt_system,
108
  "messages": messages
109
  }
110
 
vectore_store/PineconeConnector.py CHANGED
@@ -88,7 +88,7 @@ class PineconeConnector(ConnectorStrategy):
88
 
89
  retriever = vector_store.as_retriever(
90
  search_type="similarity_score_threshold",
91
- search_kwargs={"k": 3, "score_threshold": 0.6},
92
  )
93
 
94
  return retriever.invoke(query)
 
88
 
89
  retriever = vector_store.as_retriever(
90
  search_type="similarity_score_threshold",
91
+ search_kwargs={"k": 5, "score_threshold": 0.6},
92
  )
93
 
94
  return retriever.invoke(query)