Le traitement des erreurs dans ReActEngine
Dans ReActEngine, les erreurs sont traitées de deux manières, à deux niveaux et de façon indépendante : les Exceptions et les Thoughts injectés.
A - Exceptions
Pour corriger la sortie ReAct mal formée avant même qu’elle n’entre dans le flux. Exceptions = correction structurelle.
Aucune erreur survenant au cours de l’exécution de take_step() ( ce qui inclut de nombreux modules tels que les ToolBox, MCP etc. ) ne doit lever une exception de classe générale. Seules deux classes d’exceptions peuvent être utilisées, et doivent être traitées dans ce module :
-
RetryException Indique qu’une erreur récupérable s’est produite ( une réponse du LLM incomplète ou mal formée, une erreur d’outil etc. ). La même étape ReAct doit être ré-essayée, à charge du LLM de trouver un contournement en se basant sur les indications du message d’erreur.
-
ForceFinalizeException Indique qu’une erreur non récupérable s’est produite ( un état ReAct invalide, une erreur d’outil sans contournement possible etc. ) et que le LLM doit produire directement une réponse finale.
Exemple d’exception levée par un outil :
- if date_str_s.isdigit():
- raise RetryException("Invalid input: this function expects a readable date, not a timestamp, retry with ISO 8601 formats (`YYYY-MM-DD`, `YYYY-MM-DDTHH:MM:SS`).")
Exemples de situations récupérables :
- Action Input manquant
- Thought sans Action
- JSON invalide
- protocole ReAct violé
- output tronqué en streaming
- outil mal appellé ou mal utilisé
Dans ces cas, le LLM reçoit les informations nécessaires pour régénérer une étape ReAct correcte.
B - Thought injecté
Pour corriger le raisonnement, pas la forme. Thought = correction cognitive
Exemple :
- if block.type in {ReActType.OBSERVATION, ReActType.FINAL_ANSWER} and not block.content.strip(): #x
- yield ReActBlock(
- type=ReActType.THOUGHT,
- content="Je constate que je n’ai obtenu aucune réponse. Peut-être devrais-je vérifier les paramètres ou reformuler ma demande."
- )
- continue
Cas d’usage :
-
bouclage sur un outil en erreur
-
observation vide ( pertinente ou résultant d’une erreur )
-
itérations excessives
-
action répétée
-
modèle qui "tourne en rond"
Dans ces cas, on veut reprendre le flux, pas relancer le LLM.
Diagramme du traitement des erreurs
Les deux modes influencent le raisonnement, mais à des niveaux différents du pipeline. La différence entre ces deux modes et leur indépendance apparaît clairement dans ce diagramme :
Les exceptions RetryException et ForceFinalizeException agissent entre 3 et 7 ( interne au ReActAgent ), l’insertion des Thoughts entre 8 et 12 ( le niveau d(orchestration par le Finalizer).