routeur_ia_api / graphs /agents /chat_agent.py
Cyril Dupland
feat voice: init
48d6c63
raw
history blame
3.36 kB
"""Chat agent node producing replies using system + RAG contexts + history."""
from typing import Callable, List
from langchain_core.messages import BaseMessage, SystemMessage, AIMessage
from langchain_core.language_models.chat_models import BaseChatModel
from graphs.state import AgentState
from graphs.prompts import SYSTEM_PROMPT_TEMPLATE
def chat_node(llm: BaseChatModel) -> Callable[[AgentState], AgentState]:
"""Factory returning a node that generates a reply with RAG context."""
def _run(state: AgentState) -> AgentState:
messages = list(state.get("messages", []))
sys_msgs: List[BaseMessage] = [SystemMessage(content=SYSTEM_PROMPT_TEMPLATE)]
formation_context = state.get("formation_context", "")
prestation_context = state.get("prestation_context", "")
project_context = state.get("project_context", "")
if project_context:
sys_msgs.append(
SystemMessage(
content=(
"CONTEXTE PROJET (extraits des documents du projet; n'utilise rien d'autre):\n\n"
f"{project_context}\n\n"
"Consignes projet: Ce contenu indique des informations complémentaires à prendre en compte pour répondre à la question. "
)
)
)
if formation_context:
sys_msgs.append(
SystemMessage(
content=(
"CONTEXTE FORMATIONS (extraits du catalogue formations; n'utilise rien d'autre):\n\n"
f"{formation_context}\n\n"
"Consignes formations: Utilise exclusivement ce contexte pour recommander les formations. "
"Cite la page et la source pour chaque recommandation. "
"Une formation = un document."
)
)
)
if prestation_context:
sys_msgs.append(
SystemMessage(
content=(
"CONTEXTE PRESTATIONS (extraits du catalogue services; n'utilise rien d'autre):\n\n"
f"{prestation_context}\n\n"
"Consignes prestations: Utilise exclusivement ce contexte pour recommander les prestations. "
"Cite la page et la source pour chaque recommandation. "
"Un document peut contenir plusieurs prestations."
)
)
)
if state.get("voice_mode"):
sys_msgs.append(SystemMessage(content=(
"IMPORTANT - MODE VOCAL: Ta réponse sera lue à voix haute. "
"Réponds de manière concise et naturelle, comme dans une conversation orale. "
"N'utilise PAS de markdown, pas de listes à puces, pas de tableaux, pas de gras/italique. "
"Pas de numéros de page ni de références documentaires détaillées. "
"Limite ta réponse à quelques phrases claires et directes. "
"Si la question nécessite des détails, propose de les envoyer par écrit."
)))
response = llm.invoke(sys_msgs + messages)
return {"messages": messages + [AIMessage(content=response.content)]}
return _run