Architecture de la réduction contexte

Architecture uniquement, pas implémenté
This commit is contained in:
2026-02-09 00:11:52 +01:00
parent 8b32c0ac64
commit 8655359add
4 changed files with 39 additions and 22 deletions

View File

@@ -22,21 +22,28 @@ def getGraph()->CompiledStateGraph:
workflow.add_node(inject_preparation_prompt) workflow.add_node(inject_preparation_prompt)
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("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) workflow.add_node("weekly_report_tools", weekly_report_tools)
workflow.add_node(context_shortener) # Réduit la taille du contexte
workflow.add_node("context_shortener_2", context_shortener) # Le même, sous un autre nom pour le différencier dans le graphe
# Arrêtes # Arrêtes
workflow.set_conditional_entry_point(is_resumes_reports_already_initialised, { workflow.set_conditional_entry_point(is_resumes_reports_already_initialised, {
"résumés non disponibles": "inject_preparation_prompt", "résumés non disponibles": "inject_preparation_prompt", # Résumés non générés
"résumés déjà générés": "user_prompt" "résumés déjà générés": "user_prompt" # Résumés déjà prêts, je peux aller direct à la partie principale
}) })
workflow.add_edge("inject_preparation_prompt", "preparation_docs") workflow.add_edge("inject_preparation_prompt", "preparation_docs")
workflow.add_conditional_edges("preparation_docs", should_continue, { workflow.add_conditional_edges("preparation_docs", should_continue, {
"tools":"weekly_report_tools", "tools":"weekly_report_tools",
"no_tools":"user_prompt" "no_tools":"context_shortener" # FIN de la préparation, on réduit le contexte avant de passer à la suite
}) })
workflow.add_edge("context_shortener", "user_prompt") # Et ici, je rejoins la partie principale qui rédigera le rapport
workflow.add_edge("user_prompt", "LLM_central") workflow.add_edge("user_prompt", "LLM_central")
workflow.add_edge("weekly_report_tools", "preparation_docs") workflow.add_edge("weekly_report_tools", "preparation_docs")
workflow.add_edge("tool_node", "LLM_central") workflow.add_conditional_edges("tool_node", should_shorten, {
'sous la limite': "LLM_central",
'réduire contexte': "context_shortener_2"
})
workflow.add_edge("context_shortener_2", "LLM_central")
workflow.add_conditional_edges("LLM_central", should_continue, { workflow.add_conditional_edges("LLM_central", should_continue, {
"tools":"tool_node", "tools":"tool_node",
"no_tools":END "no_tools":END

View File

@@ -3,11 +3,12 @@ from langgraph.graph import MessagesState
from langgraph.prebuilt import ToolNode from langgraph.prebuilt import ToolNode
from langchain.chat_models import init_chat_model from langchain.chat_models import init_chat_model
from langgraph.graph import START, END from langgraph.graph import START, END
from langchain.messages import HumanMessage, AIMessage, SystemMessage from langchain.messages import HumanMessage, AIMessage, SystemMessage, ToolMessage
from langgraph.types import interrupt from langgraph.types import interrupt
import os import os
import sys import sys
from pathlib import Path from pathlib import Path
import json
from .tools import getTools, getWeeklyReportTools from .tools import getTools, getWeeklyReportTools
from .state import CustomState from .state import CustomState
@@ -66,6 +67,30 @@ def LLM_central(state: MessagesState):
# Appel du LLM # Appel du LLM
return {"messages": [model.invoke(state["messages"])]} return {"messages": [model.invoke(state["messages"])]}
def context_shortener(state: CustomState):
""" Noeud visant à réduire la taille du contexte pour éviter une explosion de la taille de la mémoire court-terme/contexte """
raise NotImplementedError('TODO, faut que je le fasse')
# fonction de routage
def should_shorten(state: CustomState)->str:
"""
Fonction de routage, permet de savoir s'il est temps de résumer la contexte de la conversation
Args:
state (CustomState): Le State actuel
Returns:
str: Faut-il réduire le contexte ?
"""
TAILLE_CONTEXTE_MAX = 20000 #charactères
count = 0
for msg in state['messages']: count += len(msg.content) # Compter le nombre total de caractères dans le contexte
if count < TAILLE_CONTEXTE_MAX:
# OK
return 'sous la limite'
return 'réduire contexte'
# fonction de routage : Après reponse_question, si le LLM veut appeler un outil, on va au tool_node # fonction de routage : Après reponse_question, si le LLM veut appeler un outil, on va au tool_node
def should_continue(state: MessagesState): def should_continue(state: MessagesState):
""" """
@@ -82,21 +107,6 @@ def should_continue(state: MessagesState):
return "tools" return "tools"
return "no_tools" return "no_tools"
def task_ended(state: MessagesState):
"""
Vérifier si l'agent a terminé son cycle, ou s'il faut le relancer
"""
if isinstance(state, list):
ai_message = state[-1]
elif messages := state.get("messages", []):
ai_message = messages[-1]
else:
raise ValueError(f"No messages found in input state to tool_edge: {state}")
if "terminé" in ai_message.content.lower():
return END
return "continue"
weekly_report_tools = ToolNode(tools=getWeeklyReportTools()) weekly_report_tools = ToolNode(tools=getWeeklyReportTools())
tool_node = ToolNode(tools=getTools()) tool_node = ToolNode(tools=getTools())
@@ -127,8 +137,7 @@ class BasicToolNode: # De mon ancien projet, https://github.com/LJ5O/Assistant/b
) )
return {"messages": outputs} return {"messages": outputs}
# UTILS # fonction de routage
def is_resumes_reports_already_initialised(state: CustomState)->str: def is_resumes_reports_already_initialised(state: CustomState)->str:
"""Permet de savoirr si les résumés de comptes-rendu ont déjà été générés. """Permet de savoirr si les résumés de comptes-rendu ont déjà été générés.
S'ils le sont, inutile de recréer ce dossier. S'ils le sont, inutile de recréer ce dossier.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 50 KiB

View File

@@ -22,6 +22,7 @@
## Amélioration de l'agent ## Amélioration de l'agent
- [ ] Cross-encoding sur la sortie du **RAG** - [ ] Cross-encoding sur la sortie du **RAG**
- [ ] Sauvegarde de l'état de l'agent - [ ] Sauvegarde de l'état de l'agent
- [ ] Lecture d'un `skills.md`
- [ ] Système de redémarrage après un arrêt - [ ] Système de redémarrage après un arrêt
- [ ] Détection de *prompt injection* - [ ] Détection de *prompt injection*
- [ ] Génération d'un PDF en sortie du système - [ ] Génération d'un PDF en sortie du système