Spaces:
Running
Running
Ilyas KHIAT
commited on
Commit
·
c2f2340
1
Parent(s):
9b707db
kg
Browse files- app.py +2 -1
- audit_page/compte_rendu.py +129 -0
- audit_page/knowledge_graph.py +49 -34
- utils/audit/audit_doc.py +2 -2
- utils/kg/construct_kg.py +5 -2
app.py
CHANGED
@@ -11,13 +11,14 @@ def main():
|
|
11 |
audit_page = st.Page("audit_page/audit.py", title="Audit", icon="📋", default=True)
|
12 |
kg_page = st.Page("audit_page/knowledge_graph.py", title="Graphe de connaissance", icon="🧠")
|
13 |
agents_page = st.Page("agents_page/catalogue.py", title="Catalogue des agents", icon="📇")
|
|
|
14 |
recommended_agents = st.Page("agents_page/recommended_agent.py", title="Agents recommandés", icon="⭐")
|
15 |
chatbot = st.Page("chatbot_page/chatbot.py", title="Chatbot", icon="💬")
|
16 |
documentation = st.Page("doc_page/documentation.py", title="Documentation", icon="📚")
|
17 |
|
18 |
pg = st.navigation(
|
19 |
{
|
20 |
-
"Audit de contenus": [audit_page, kg_page],
|
21 |
"Equipe d'agents IA": [recommended_agents],
|
22 |
"Chatbot": [chatbot],
|
23 |
"Documentation": [documentation]
|
|
|
11 |
audit_page = st.Page("audit_page/audit.py", title="Audit", icon="📋", default=True)
|
12 |
kg_page = st.Page("audit_page/knowledge_graph.py", title="Graphe de connaissance", icon="🧠")
|
13 |
agents_page = st.Page("agents_page/catalogue.py", title="Catalogue des agents", icon="📇")
|
14 |
+
compte_rendu = st.Page("audit_page/compte_rendu.py", title="Compte rendu", icon="📝")
|
15 |
recommended_agents = st.Page("agents_page/recommended_agent.py", title="Agents recommandés", icon="⭐")
|
16 |
chatbot = st.Page("chatbot_page/chatbot.py", title="Chatbot", icon="💬")
|
17 |
documentation = st.Page("doc_page/documentation.py", title="Documentation", icon="📚")
|
18 |
|
19 |
pg = st.navigation(
|
20 |
{
|
21 |
+
"Audit de contenus": [audit_page, compte_rendu, kg_page],
|
22 |
"Equipe d'agents IA": [recommended_agents],
|
23 |
"Chatbot": [chatbot],
|
24 |
"Documentation": [documentation]
|
audit_page/compte_rendu.py
ADDED
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from textwrap import dedent
|
3 |
+
from utils.audit.rag import get_text_from_content_for_doc,get_text_from_content_for_audio
|
4 |
+
from utils.audit.response_llm import generate_response_via_langchain
|
5 |
+
from langchain_core.messages import AIMessage, HumanMessage
|
6 |
+
import pyperclip
|
7 |
+
|
8 |
+
|
9 |
+
def cr_main():
|
10 |
+
st.title("Compte rendu")
|
11 |
+
|
12 |
+
if "audit" not in st.session_state or st.session_state.audit == {}:
|
13 |
+
st.error("Veuillez d'abord effectuer un audit pour générer un compte rendu.")
|
14 |
+
return
|
15 |
+
|
16 |
+
if "cr" not in st.session_state:
|
17 |
+
st.session_state.cr = ""
|
18 |
+
|
19 |
+
if "cr_chat_history" not in st.session_state:
|
20 |
+
st.session_state.cr_chat_history = [
|
21 |
+
]
|
22 |
+
|
23 |
+
audit = st.session_state.audit_simplified
|
24 |
+
content = st.session_state.audit["content"]
|
25 |
+
|
26 |
+
if audit["type de fichier"] == "pdf":
|
27 |
+
text = get_text_from_content_for_doc(content)
|
28 |
+
elif audit["type de fichier"] == "audio":
|
29 |
+
text = get_text_from_content_for_audio(content)
|
30 |
+
|
31 |
+
prompt_cr = dedent(f'''
|
32 |
+
|
33 |
+
À partir du document ci-dessous, générez un compte rendu détaillé contenant les sections suivantes :
|
34 |
+
|
35 |
+
2. **Résumé** : Fournissez un résumé concis du document, en mettant en avant les points principaux, les relations essentielles, les concepts , les dates et les lieux, les conclusions et les détails importants.
|
36 |
+
|
37 |
+
3. **Notes** :
|
38 |
+
- Présentez les points clés sous forme de liste à puces avec des émojis pertinents pour souligner la nature de chaque point.
|
39 |
+
- Incluez des sous-points (sans émojis) sous les points principaux pour offrir des détails ou explications supplémentaires.
|
40 |
+
|
41 |
+
4. **Actions** : Identifiez et listez les actions spécifiques, tâches ou étapes recommandées ou nécessaires selon le contenu du document.
|
42 |
+
|
43 |
+
**Document :**
|
44 |
+
|
45 |
+
{text}
|
46 |
+
|
47 |
+
**Format de sortie :**
|
48 |
+
|
49 |
+
|
50 |
+
### Résumé :
|
51 |
+
[Fournissez un résumé concis du document ici.]
|
52 |
+
|
53 |
+
### Notes :
|
54 |
+
- 📌 **Point Principal 1**
|
55 |
+
- Sous-point A
|
56 |
+
- Sous-point B
|
57 |
+
- 📈 **Point Principal 2**
|
58 |
+
- Sous-point C
|
59 |
+
- Sous-point D
|
60 |
+
- 📝 **Point Principal 3**
|
61 |
+
- Sous-point E
|
62 |
+
- Sous-point F
|
63 |
+
|
64 |
+
### Actions :
|
65 |
+
1. [Action 1]
|
66 |
+
2. [Action 2]
|
67 |
+
3. [Action 3]
|
68 |
+
4. ...
|
69 |
+
|
70 |
+
---
|
71 |
+
''')
|
72 |
+
|
73 |
+
|
74 |
+
|
75 |
+
if st.button("Générer compte rendu"):
|
76 |
+
|
77 |
+
with st.spinner("Génération du compte rendu..."):
|
78 |
+
cr = generate_response_via_langchain(prompt_cr,stream=False,model="gpt-4o")
|
79 |
+
st.session_state.cr = cr
|
80 |
+
st.session_state.cr_chat_history = []
|
81 |
+
|
82 |
+
else:
|
83 |
+
cr = st.session_state.cr
|
84 |
+
|
85 |
+
if cr:
|
86 |
+
col1, col2 = st.columns([2.5, 1.5])
|
87 |
+
|
88 |
+
with col1.container(border=True,height=800):
|
89 |
+
st.markdown("##### Compte rendu")
|
90 |
+
st.markdown("### Mots clés extraits:")
|
91 |
+
st.write(f"- {audit['Mots clés'].strip()}")
|
92 |
+
st.write(cr)
|
93 |
+
if st.button("📋",key="copy_transcription"):
|
94 |
+
pyperclip.copy(content["transcription"])
|
95 |
+
st.success("Transcription copiée dans le presse-papier")
|
96 |
+
|
97 |
+
with col2.container(border=True,height=800):
|
98 |
+
st.markdown("##### Dialoguer avec le CR")
|
99 |
+
|
100 |
+
user_query = st.chat_input("Par ici ...")
|
101 |
+
if user_query is not None and user_query != "":
|
102 |
+
st.session_state.cr_chat_history.append(HumanMessage(content=user_query))
|
103 |
+
|
104 |
+
with st.container(height=650, border=False):
|
105 |
+
for message in st.session_state.cr_chat_history:
|
106 |
+
if isinstance(message, AIMessage):
|
107 |
+
with st.chat_message("AI"):
|
108 |
+
st.markdown(message.content)
|
109 |
+
elif isinstance(message, HumanMessage):
|
110 |
+
with st.chat_message("Moi"):
|
111 |
+
st.write(message.content)
|
112 |
+
|
113 |
+
#check if last message is human message
|
114 |
+
if len(st.session_state.cr_chat_history) > 0:
|
115 |
+
last_message = st.session_state.cr_chat_history[-1]
|
116 |
+
if isinstance(last_message, HumanMessage):
|
117 |
+
with st.chat_message("AI"):
|
118 |
+
retreive = st.session_state.vectorstore.as_retriever()
|
119 |
+
context = retreive.invoke(last_message.content)
|
120 |
+
wrapped_prompt = f'''Étant donné le contexte suivant {context} et le compte rendu du document {cr}, {last_message.content}'''
|
121 |
+
response = st.write_stream(generate_response_via_langchain(wrapped_prompt,stream=True))
|
122 |
+
st.session_state.cr_chat_history.append(AIMessage(content=response))
|
123 |
+
|
124 |
+
|
125 |
+
cr_main()
|
126 |
+
|
127 |
+
|
128 |
+
|
129 |
+
|
audit_page/knowledge_graph.py
CHANGED
@@ -6,6 +6,7 @@ import random
|
|
6 |
import math
|
7 |
from utils.audit.response_llm import generate_response_via_langchain
|
8 |
from langchain_core.messages import AIMessage, HumanMessage
|
|
|
9 |
|
10 |
def if_node_exists(nodes, node_id):
|
11 |
"""
|
@@ -150,8 +151,13 @@ def kg_main():
|
|
150 |
st.error("Veuillez d'abord effectuer un audit pour visualiser le graphe de connaissance.")
|
151 |
return
|
152 |
|
|
|
|
|
|
|
|
|
153 |
if "graph" not in st.session_state:
|
154 |
st.session_state.graph = None
|
|
|
155 |
st.title("Graphe de connaissance")
|
156 |
|
157 |
if "node_types" not in st.session_state:
|
@@ -164,12 +170,14 @@ def kg_main():
|
|
164 |
st.session_state.chat_graph_history = []
|
165 |
|
166 |
audit = st.session_state.audit_simplified
|
167 |
-
content = st.session_state.audit["content"]
|
168 |
|
169 |
-
if audit["type de fichier"] == "pdf":
|
170 |
-
|
171 |
-
elif audit["type de fichier"] == "audio":
|
172 |
-
|
|
|
|
|
173 |
|
174 |
#summary_prompt = f"Voici un ensemble de documents : {text}. À partir de ces documents, veuillez fournir des résumés concis en vous concentrant sur l'extraction des relations essentielles et des événements. Il est crucial d'inclure les dates des actions ou des événements, car elles seront utilisées pour l'analyse chronologique. Par exemple : 'Sam a été licencié par le conseil d'administration d'OpenAI le 17 novembre 2023 (17 novembre, vendredi)', ce qui illustre la relation entre Sam et OpenAI ainsi que la date de l'événement."
|
175 |
|
@@ -179,7 +187,9 @@ def kg_main():
|
|
179 |
# st.session_state.summary = sum
|
180 |
|
181 |
with st.spinner("Génération du graphe..."):
|
182 |
-
|
|
|
|
|
183 |
st.session_state.graph = graph
|
184 |
|
185 |
node_types = get_node_types(graph[0])
|
@@ -212,34 +222,39 @@ def kg_main():
|
|
212 |
with col2.container(border=True,height=800):
|
213 |
st.markdown("##### Dialoguer avec le graphe")
|
214 |
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
st.
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
|
|
|
|
|
|
|
|
|
|
243 |
|
244 |
|
245 |
|
|
|
6 |
import math
|
7 |
from utils.audit.response_llm import generate_response_via_langchain
|
8 |
from langchain_core.messages import AIMessage, HumanMessage
|
9 |
+
from langchain_core.prompts import PromptTemplate
|
10 |
|
11 |
def if_node_exists(nodes, node_id):
|
12 |
"""
|
|
|
151 |
st.error("Veuillez d'abord effectuer un audit pour visualiser le graphe de connaissance.")
|
152 |
return
|
153 |
|
154 |
+
if "cr" not in st.session_state:
|
155 |
+
st.error("Veuillez d'abord effectuer un compte rendu pour visualiser le graphe de connaissance.")
|
156 |
+
return
|
157 |
+
|
158 |
if "graph" not in st.session_state:
|
159 |
st.session_state.graph = None
|
160 |
+
|
161 |
st.title("Graphe de connaissance")
|
162 |
|
163 |
if "node_types" not in st.session_state:
|
|
|
170 |
st.session_state.chat_graph_history = []
|
171 |
|
172 |
audit = st.session_state.audit_simplified
|
173 |
+
# content = st.session_state.audit["content"]
|
174 |
|
175 |
+
# if audit["type de fichier"] == "pdf":
|
176 |
+
# text = get_text_from_content_for_doc(content)
|
177 |
+
# elif audit["type de fichier"] == "audio":
|
178 |
+
# text = get_text_from_content_for_audio(content)
|
179 |
+
|
180 |
+
text = st.session_state.cr + "mots clés" + audit["Mots clés"]
|
181 |
|
182 |
#summary_prompt = f"Voici un ensemble de documents : {text}. À partir de ces documents, veuillez fournir des résumés concis en vous concentrant sur l'extraction des relations essentielles et des événements. Il est crucial d'inclure les dates des actions ou des événements, car elles seront utilisées pour l'analyse chronologique. Par exemple : 'Sam a été licencié par le conseil d'administration d'OpenAI le 17 novembre 2023 (17 novembre, vendredi)', ce qui illustre la relation entre Sam et OpenAI ainsi que la date de l'événement."
|
183 |
|
|
|
187 |
# st.session_state.summary = sum
|
188 |
|
189 |
with st.spinner("Génération du graphe..."):
|
190 |
+
keywords_list = audit["Mots clés"].strip().split(",")
|
191 |
+
allowed_nodes_types =keywords_list+ ["Person","Organization","Location","Event","Date","Time","Ressource","Concept"]
|
192 |
+
graph = get_graph(text,allowed_nodes=allowed_nodes_types)
|
193 |
st.session_state.graph = graph
|
194 |
|
195 |
node_types = get_node_types(graph[0])
|
|
|
222 |
with col2.container(border=True,height=800):
|
223 |
st.markdown("##### Dialoguer avec le graphe")
|
224 |
|
225 |
+
user_query = st.chat_input("Par ici ...")
|
226 |
+
if user_query is not None and user_query != "":
|
227 |
+
st.session_state.chat_graph_history.append(HumanMessage(content=user_query))
|
228 |
+
|
229 |
+
with st.container(height=650, border=False):
|
230 |
+
for message in st.session_state.chat_graph_history:
|
231 |
+
if isinstance(message, AIMessage):
|
232 |
+
with st.chat_message("AI"):
|
233 |
+
st.markdown(message.content)
|
234 |
+
elif isinstance(message, HumanMessage):
|
235 |
+
with st.chat_message("Moi"):
|
236 |
+
st.write(message.content)
|
237 |
+
|
238 |
+
#check if last message is human message
|
239 |
+
if len(st.session_state.chat_graph_history) > 0:
|
240 |
+
last_message = st.session_state.chat_graph_history[-1]
|
241 |
+
if isinstance(last_message, HumanMessage):
|
242 |
+
with st.chat_message("AI"):
|
243 |
+
retreive = st.session_state.vectorstore.as_retriever()
|
244 |
+
context = retreive.invoke(last_message.content)
|
245 |
+
wrapped_prompt = f"Étant donné le contexte suivant {context}, et le graph de connaissance: {graph}, {last_message.content}"
|
246 |
+
response = st.write_stream(generate_response_via_langchain(wrapped_prompt,stream=True))
|
247 |
+
st.session_state.chat_graph_history.append(AIMessage(content=response))
|
248 |
+
|
249 |
+
if selected is not None:
|
250 |
+
with st.chat_message("AI"):
|
251 |
+
st.markdown(f" EXPLORER LES DONNEES CONTENUES DANS **{selected}**")
|
252 |
+
|
253 |
+
prompts = [f"Extrait moi toutes les informations du noeud ''{selected}'' ➡️",
|
254 |
+
f"Montre moi les conversations autour du noeud ''{selected}'' ➡️"]
|
255 |
+
|
256 |
+
for i,prompt in enumerate(prompts):
|
257 |
+
button = st.button(prompt,key=f"p_{i}",on_click=lambda i=i: st.session_state.chat_graph_history.append(HumanMessage(content=prompts[i])))
|
258 |
|
259 |
|
260 |
|
utils/audit/audit_doc.py
CHANGED
@@ -170,8 +170,8 @@ def audit_descriptif_pdf(file,max_img_width) -> dict:
|
|
170 |
text = " ".join([page["texte"] for page in doc_content.values()])
|
171 |
key_words = extract_keywords(text)
|
172 |
list_key_words_text = "\n".join(key_words[:10])
|
173 |
-
prompt = f'''Voici
|
174 |
-
- {
|
175 |
Veuillez extraire les cinq mots clés les plus pertinents de cette liste. Chaque mot clé doit contenir au maximum deux mots.
|
176 |
|
177 |
TA REPONSE DOIT RESPECTER LE FORMAT SUIVANT :
|
|
|
170 |
text = " ".join([page["texte"] for page in doc_content.values()])
|
171 |
key_words = extract_keywords(text)
|
172 |
list_key_words_text = "\n".join(key_words[:10])
|
173 |
+
prompt = f'''Voici le document:
|
174 |
+
- {text}
|
175 |
Veuillez extraire les cinq mots clés les plus pertinents de cette liste. Chaque mot clé doit contenir au maximum deux mots.
|
176 |
|
177 |
TA REPONSE DOIT RESPECTER LE FORMAT SUIVANT :
|
utils/kg/construct_kg.py
CHANGED
@@ -3,11 +3,14 @@ from langchain_experimental.graph_transformers import LLMGraphTransformer
|
|
3 |
from langchain_openai import ChatOpenAI
|
4 |
from langchain_core.documents import Document
|
5 |
|
6 |
-
def get_graph(text):
|
7 |
|
8 |
llm = ChatOpenAI(temperature=0, model_name="gpt-4o")
|
9 |
|
10 |
-
|
|
|
|
|
|
|
11 |
documents = [Document(page_content=text)]
|
12 |
|
13 |
graph_documents = llm_transformer.convert_to_graph_documents(documents)
|
|
|
3 |
from langchain_openai import ChatOpenAI
|
4 |
from langchain_core.documents import Document
|
5 |
|
6 |
+
def get_graph(text,allowed_nodes=None,prompt=None):
|
7 |
|
8 |
llm = ChatOpenAI(temperature=0, model_name="gpt-4o")
|
9 |
|
10 |
+
if allowed_nodes:
|
11 |
+
llm_transformer = LLMGraphTransformer(llm=llm,allowed_nodes=allowed_nodes)
|
12 |
+
else:
|
13 |
+
llm_transformer = LLMGraphTransformer(llm=llm)
|
14 |
documents = [Document(page_content=text)]
|
15 |
|
16 |
graph_documents = llm_transformer.convert_to_graph_documents(documents)
|