Routage

, par Bertrand Degoy

Objectif : épargner les ressources et l’environnement.
Il s’agit de créer un pipeline hybride avec Llama-index où :
 Les requêtes simples sont traitées directement par un agent ou un outil léger.
 Les requêtes complexes sont routées vers un ReAct agent (avec les outils), le routeur fondé sur un LLM décidant dynamiquement du chemin à suivre.

Note : le routage étant l’articulation des traitements, plusieurs des articles précédents vont être ré-écrits pour s’y rattacher.

Objectif et principe du routage

Un marteau-pilon pour une mouche ?
Le routage intervient en amont de ReAct, le but étant d’éviter d’utiliser un marteau-pilon pour écraser une mouche. Avec sa conséquence pour l’environnement :

Nous décrirons :
 la classification de la requête,
 la logique du routage,
 l’intégration des outils.

Classification de la requête

On commence par classer la requête avec un LLM router (ou Query Classifier). Nous distinguons trois classifications : ’direct’, ’tool’, ’react’.

  1. class ComplexityRouter:
  2.     def __init__(self, tools: list[FunctionTool]):
  3.         self.tools = tools
  4.  
  5.     def route(self, query: str) -> list[FunctionTool]:
  6.         # Heuristique simple : route selon mots-clés
  7.         if any(word in query.lower() for word in ["moyenne", "écart", "tendance"]):
  8.             return [t for t in self.tools if getattr(t, "complexity", None) == "tool"]
  9.         elif any(word in query.lower() for word in ["tva", "prix", "ht", "ttc"]):
  10.             return [t for t in self.tools if getattr(t, "complexity", None) == "simple"]
  11.         elif any(word in query.lower() for word in ["croiser", "relier", "jointure"]):
  12.             return [t for t in self.tools if getattr(t, "complexity", None) == "react"]
  13.         else:
  14.             # Fallback : tout proposer
  15.             return self.tools

Télécharger

Ce code est simpliste : dans un scénario réel, on développera le routage en s’appuyant de façon dynamique, toujours avec un appel au LLM, sur la description des outils sélectionnés ou créés pour les besoins du scénario.
On comprend que la classification va dépendre étroitement de l’application, raison pour laquelle nous avons défini des thèmes permettant des configurations particularisées dans une approche multi-utilisateurs.

  1. def classify_query(query: str) -> str:
  2.     prompt = f"""Classify the following query:
  3.    - If it's factual/simple, return 'direct'
  4.    - If it needs a tool (search, calculator, etc.), return 'tool'
  5.    - If it needs reasoning and tool use, return 'react' :
  6.    Query: {query}
  7.    Classification:"""
  8.     return llm.predict(prompt).strip().lower()

Télécharger

Pourquoi un LLM est pertinent ici ?
 Il comprend le langage naturel dans sa richesse.
 Il peut détecter des requêtes multi-étapes, même si elles sont formulées subtilement.
 Il peut juger si une requête nécessite du raisonnement, de la planification, ou une coordination d’outils.

Logique du routage

  1. def route_query(query: str):
  2.     category = classify_query(query)
  3.  
  4.     if category == "direct":
  5.         return direct_agent.query(query)
  6.     elif category == "tool":
  7.         return tool_agent.query(query)
  8.     else category == "react":
  9.         return react_agent.query(query)

Télécharger

On observera que ReAct devra traiter non seulement les questions complexes, mais également, en dernier ressort, celles qui n’auront pas été classifiées comme ’simple’ ou ’tool’.

Il est important de noter que, si ReAct est mis en jeu, tous les outils pourront être sélectionnés aux étapes du raisonnement.

intégration des outils

Une de ces trois classes d’agent sera utilisée en fonction de la classification :

Direct Agent
On retrouvera dans cette classe notre agent RAG : un moteur de requête sur un VectorStoreIndex.

Tool Agent
Agent outil : utilise ToolNode ou QueryTool avec des API externes, en particulier fournies par Model Context Protocol (MCP) .

ReAct Agent
 Agent ReAct : utilise LLMRouter et ReActAgent du framework d’agents LlamaIndex.
Tous les outils seront mis à disposition de la boucle ReAct.

La classification "react" est spéciale : elle ne décrit pas un outil en soi, mais plutôt une stratégie de raisonnement. Autrement dit :
 Un outil "simple" : répond directement (recherche, calcul, transformation),
 Un outil "tool" : interagit avec une source externe ou fait un traitement structuré,
 Un outil "react" : n’est pas un outil, mais une combinaison d’outils orchestrée par un agent ReAct.

Le processus de sélection et d’exécution de ReAct se déroule comme ceci :