Spaces:
Sleeping
Sleeping
[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- config.yaml +38 -27
- pages/chatbot.py +33 -5
- rag.py +14 -7
- 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: ["
|
70 |
-
value: "
|
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
|
118 |
-
nature: '
|
119 |
-
key:
|
120 |
-
value:
|
121 |
-
|
122 |
-
|
123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
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 |
-
|
|
|
|
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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":
|
77 |
-
"score_threshold": 0.
|
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(
|
|
|
89 |
|
90 |
# Retrieve the VectoreStore
|
91 |
-
contextCommon = self.vector_store.retriever(
|
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":
|
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)
|