From fc7f692ba36dd42d5bf82a62884dca7f18b7e448 Mon Sep 17 00:00:00 2001 From: LJ5O <75009579+LJ5O@users.noreply.github.com> Date: Sun, 8 Feb 2026 14:41:22 +0100 Subject: [PATCH] =?UTF-8?q?Noeud=20de=20pr=C3=A9paration=20des=20documents?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pas encore totalement fonctionnel, mais déjà de bons résultats là dessus --- .gitignore | 1 + AgentReact/agent.py | 13 +++++++++++-- AgentReact/start.py | 2 +- AgentReact/utils/StreamGraph.py | 11 +++++++---- AgentReact/utils/nodes.py | 21 ++++++++++++++++++++- AgentReact/utils/state.py | 2 ++ AgentReact/utils/tools.py | 2 +- agent.png | Bin 12190 -> 22081 bytes 8 files changed, 43 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index e6f64b5..1c00b2f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ mlflow.db # Par sécurité documents_projet/ chroma_db/ +AgentReact/rapports_resumes/ # Python __pycache__/ \ No newline at end of file diff --git a/AgentReact/agent.py b/AgentReact/agent.py index 7720f57..5f24eef 100644 --- a/AgentReact/agent.py +++ b/AgentReact/agent.py @@ -2,7 +2,7 @@ from langgraph.graph import START, END from langgraph.graph.state import CompiledStateGraph from langgraph.checkpoint.memory import InMemorySaver -from utils.nodes import call_to_LLM, should_continue, task_ended, BasicToolNode, tool_node +from utils.nodes import call_to_LLM, should_continue, task_ended, BasicToolNode, tool_node, preparation_docs, weekly_report_tools from utils.state import getState from utils.tools import getTools @@ -17,10 +17,19 @@ def getGraph()->CompiledStateGraph: # Définition des sommets du graphe workflow.add_node(call_to_LLM) + workflow.add_node(preparation_docs) workflow.add_node("tool_node", tool_node)# BasicToolNode(tools=getTools())) # N'est pas une fonction, mais une classe instanciée, je dois précisier le nom du node + workflow.add_node("weekly_report_tools", weekly_report_tools) # Arrêtes - workflow.set_entry_point("call_to_LLM") + workflow.set_entry_point("preparation_docs") + workflow.add_conditional_edges("preparation_docs", should_continue, { + "tools":"weekly_report_tools", + "no_tools":"call_to_LLM" + }) + + #workflow.set_entry_point("call_to_LLM") + workflow.add_edge("weekly_report_tools", "preparation_docs") workflow.add_edge("tool_node", "call_to_LLM") workflow.add_conditional_edges("call_to_LLM", should_continue, { "tools":"tool_node", diff --git a/AgentReact/start.py b/AgentReact/start.py index 4020500..aba9b12 100644 --- a/AgentReact/start.py +++ b/AgentReact/start.py @@ -13,7 +13,7 @@ mlflow.set_experiment("TEST PROJET") # VOIR AVEC LA COMMANDE "MLFLOW SERVER" mlflow.langchain.autolog() initial_input = { - 'messages':[HumanMessage("Recherche 'Recette de Monster' sur internet")] + 'messages':[SystemMessage("Salut")] } config={"configurable": {"thread_id": 'yes'}} diff --git a/AgentReact/utils/StreamGraph.py b/AgentReact/utils/StreamGraph.py index 2f7194e..4e287d7 100644 --- a/AgentReact/utils/StreamGraph.py +++ b/AgentReact/utils/StreamGraph.py @@ -5,7 +5,7 @@ from langgraph.types import Command from .InterruptPayload import InterruptPayload # Une fonction pour stream et gérer proprement le graphe -def streamGraph(initial_input:Dict, config:Dict, graphe:CompiledStateGraph): +def streamGraph(initial_input:Dict, config:Dict, graphe:CompiledStateGraph, lastMsgIndex=0): # https://docs.langchain.com/oss/python/langgraph/interrupts#stream-with-human-in-the-loop-hitl-interrupts for mode, state in graphe.stream( initial_input, @@ -15,8 +15,11 @@ def streamGraph(initial_input:Dict, config:Dict, graphe:CompiledStateGraph): ): if mode == "values": # Handle streaming message content - msg = state['messages'][-1] - msg.pretty_print() + i=0 + for msg in state['messages'][lastMsgIndex:]: # Permet de gérer plusieurs nouveaux messages d'un coup + msg.pretty_print() + i+=1 + lastMsgIndex+=i elif mode == "updates": # Check for interrupts @@ -25,7 +28,7 @@ def streamGraph(initial_input:Dict, config:Dict, graphe:CompiledStateGraph): payload = InterruptPayload.fromJSON(payload) # Chargement de la requête depuis sa version JSON payload.humanDisplay() # L'utilisateur peut accepter/modifier/refuser ici - streamGraph(Command(resume=payload.toJSON()), config, graphe) # Je renvois la chaîne JSON, qui sera reconvertie en objet dans l'outil, et je relance le stream récursivement + streamGraph(Command(resume=payload.toJSON()), config, graphe, lastMsgIndex) # Je renvois la chaîne JSON, qui sera reconvertie en objet dans l'outil, et je relance le stream récursivement return # Fin de cette fonction récursive else: diff --git a/AgentReact/utils/nodes.py b/AgentReact/utils/nodes.py index 5171f9a..6513bae 100644 --- a/AgentReact/utils/nodes.py +++ b/AgentReact/utils/nodes.py @@ -3,8 +3,10 @@ from langgraph.graph import MessagesState from langgraph.prebuilt import ToolNode from langchain.chat_models import init_chat_model from langgraph.graph import START, END +from langchain.messages import HumanMessage, AIMessage, SystemMessage -from .tools import getTools +from .tools import getTools, getWeeklyReportTools +from .state import CustomState # LLM principal llm = ChatMistralAI( # LLM sans outils @@ -14,6 +16,22 @@ llm = ChatMistralAI( # LLM sans outils ) # NODES +def preparation_docs(state: CustomState): + """Noeud en charge de préparer les résumés pour chaque semaine des rapports, et la liste des outils et méthodes utilisées""" + model = llm.bind_tools(getWeeklyReportTools()) # LLM en charge de générer des rapports hebdomadaires sur le stage + print(len(state['messages'])) + messages = [m for m in state['messages']] # Tous les messages du stage + + if 'documentsGenerationStarted' not in state.keys(): + # Si ce noeud en est à son premier lancement, je lui donne la consigne de départ + messages.append(HumanMessage("Ton but est de lire les fichiers présents dans la base de données en utilisant l'outil 'search_in_files',\ + afin de générer des rapports sur chaque semaine du stage qui y est décrit. Pour enregistrer chaque semaine du stage, utilise l'outil 'write_week_report'.\ + Une fois terminé, fais une liste de tous les outils, logiciels, méthodes, entreprises, techniques, ect.. utilisés,\ + et fais en une liste avec quelques descriptions que tu devras enregistrer avec l'outil 'write_library_tools_details_on_internship'.")) + + messages.append(model.invoke(messages)) # Invocation LLM + return {'messages': messages, 'documentsGenerationStarted':True} # Je passe une liste de messages, ce qui ne devrait pas ajouter un message mais redéfinir toute la liste + def call_to_LLM(state: MessagesState): """Noeud qui s'occupe de gérer les appels au LLM""" # Initialisation du LLM @@ -53,6 +71,7 @@ def task_ended(state: MessagesState): return END return "continue" +weekly_report_tools = ToolNode(tools=getWeeklyReportTools()) tool_node = ToolNode(tools=getTools()) diff --git a/AgentReact/utils/state.py b/AgentReact/utils/state.py index 3224440..e91964a 100644 --- a/AgentReact/utils/state.py +++ b/AgentReact/utils/state.py @@ -10,6 +10,8 @@ class CustomState(MessagesState): ragQuery: str # Requête envoyée au RAG, pour le cross-encodeur ragDocuments: List[str] # Documents retrouvés par le RAG, pour le cross-encodeur + documentsGenerationStarted:bool# Permet d'indiquer que la consigne de génération des documents a été envoyée + # TODO: Ajouter la source des documents sélectionnés pour la fin du rapport ? diff --git a/AgentReact/utils/tools.py b/AgentReact/utils/tools.py index 082b612..354e4ec 100644 --- a/AgentReact/utils/tools.py +++ b/AgentReact/utils/tools.py @@ -263,4 +263,4 @@ def getWeeklyReportTools()->List['Tools']: """ Récupérer la liste des tools, POUR LE LLM EN CHARGE DE FAIRE LES RAPPORTS DE CHAQUE SEMAINE """ - return [write_week_report, write_library_tools_details_on_internship, internet_search] \ No newline at end of file + return [write_week_report, write_library_tools_details_on_internship, internet_search, search_in_files] \ No newline at end of file diff --git a/agent.png b/agent.png index c9200507b1328f8ebde9e60ecd5c75ed5ac16cd7..1a00776e2c577a88cfd6f00eccc8e03cf93e08b4 100644 GIT binary patch literal 22081 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