ReAct : la carte des intentions : Intent Map Améliorer la sélection des outils en se fondant sur l’intention

, par Bertrand Degoy

Dans la sélection d’un outil par le LLM, le nom de l’outil est prioritaire, la description est secondaire. Il va falloir opérer une pré-sélection des outils sur une meilleure base, avant de les passer au LLM. 
C’est ici qu’apparaît la carte des intentions (Intent Map).


Dans la sélection d’un outil par le LLM, il apparaît que le nom de l’outil est prioritaire, et que la description est secondaire [1]. De toute évidence, la description ne sert au LLM qu’en deuxième intention, le plus souvent sur une reprise après erreur. La première sélection de l’outil est fondée sur une base trop sommaire.

La carte des intentions (Intent Map)

Puisque le LLM ne fait pas le travail avec suffisamment de discernement, il va falloir opérer une pré-sélection des outils au niveau de l’orchestrateur, avant de les passer au LLM.  Il convient également de limiter le nombre d’outils passés avec le prompt afin de maîtriser le nombre de tokens envoyés au LLM.

C’est ici qu’apparaît la carte des intentions (Intent Map).

L’Intent Map fait le lien entre les noms techniques des outils et leur intention métier explicite. C’est un dictionnaire de la forme :

  1. ```
  2. intent_map = {
  3.     "readable_dates_to_timestamps_ms": "Convert a list of human-readable dates into a list of UNIX timestamp expressed in milliseconds."
  4.     "extract_dates": "Extraire une plage de dates à partir d’un texte",
  5.     "filter_by_range": "Filtrer une liste d’interventions selon une période",
  6.     "summarize_notes": "Résumer une série de notes médicales",
  7. }
  8. ```

Télécharger

Pour les toolbox que nous gérons, l’Intent Map pourra être générée automatiquement à partir d’une métadonnée ’intent’ des outils, ou d’une propriété ’intent_map’ de la toolbox. Sinon, l’Intent Map devra être écrite manuellement.

L’Intent Map permet à l’orchestrateur (classe ToolRouter) de sélectionner les outils selon l’intention.

De plus, notre outil de création de macro-outil (classe MacroToolBuilder) pourra créer automatiquement la Docstring macroscopique en se fondant sur les intentions des outils qui la composent.

Des cas où l’Intent Map est essentielle !

ToolFactory : Dans cet article ReAct : ToolFactory nous montrons comment la classe ToolFactory peut créer automatiquement des outils à partir de fonctions des bibliothèques Python. On peut constater que les descriptions des fonctions sont particulièrement pauvres et parfois inadaptées à la sélection par un LLM. Dans ce cas, une Intent Map sera essentielle à la bonne sélection des outils. Il est à craindre qu’il faille la construire manuellement !

MCP : Dans le cas des outils MCP (Model Context Protocole), les noms d’outils et leur description sont gérés du côté du serveur MCP, possiblement hors de portée de l’organisation. Si les descriptions sont mal rédigées, ou rédigées avec un vocabulaire hors du métier, une Intent Map sera essentielle à la bonne sélection des outils. Il faudra évidemment la construire manuellement.

Comprendre la sélection des outils

Il est important de considérer la manière dont un agent ReAct sélectionne et priorise les outils. Ce sera la même méthode pour la pré-sélection au niveau de l’orchestrateur.

C’est tool.metadata.description qui est envoyée au LLM. 

Le LLM lit la description pour choisir un outil, pas pour comprendre toute la documentation. Lorsqu’un agent ReAct doit choisir un outil, il cherche une correspondance sémantique forte sur les points suivants :

  • Quel est le nom de l’outil ?
  • Quelle est l’action principale ?
  • Sur quel type d’objet travaille-t-il ?

Seule l’intention est réellement utile pour la sélection d’outil.

Le reste (détails, paramètres, avertissements) n’aide pas à la sélection, au contraire : plus la description est longue, plus on augmente le risque d’erreurs de sélection. Une description longue rend l’outil moins distinctif dans l’espace vectoriel du modèle et abouti à une moindre précision dans la sélection.

Bonnes pratiques pour la rédaction des Intentions :**

  • Les valeurs doivent être des descriptions métier claires, pas des signatures techniques.
  • Elles doivent être formulées à l’infinitif.
  • Elles doivent éviter les termes ambigus.
  • Bien définir le vocabulaire (les mots et leur sémantique) dans un lexique du métier, et s’y conformer.

Exemple concret (de ce qu’il ne faut pas faire) :

Si on envoie ceci :

extract_values_by_key(dict_list, key)
Extract all values associated with a given key from a list of dictionaries.
Retrieve the values corresponding to a specific key within a collection of objects.
Iterates through a list of items and returns only the values for which:
- the item is a dictionary
- the key exists

On augmente les collisions avec d’autres outils. :

  • “collection of objects” → outil générique
  • “iterate through items” → ressemble à un filtre
  • “values” → ressemble à un extracteur
  • “dictionary” → structure spécifique
  • “key exists” → condition logique
  • “list” → structure séquentielle

Ce qu’il faut écrire :

extract_values_by_key(dict_list, key)
Extract all values associated with a given key from a list of dictionaries.

C’est tout !

La génération systématique de la description

Il faut considérer deux champs : tool.description et tool.metadata.description.

Si on ne définit pas le champ ’description’ de l’outil, tool.metadata.description sera élaboré par LlamaIndex à partir de la Docstring, en lui appliquant des heuristiques qui ajoutent parfois la signature, reformate, supprime certains éléments, interprète le Markdown, modifie l’ordre des lignes etc.. Bref : on ne peut se fonder dessus pour fournir l’intention.

Pour garantir que la première ligne soit un résumé clair, LlamaIndex ajoute parfois la signature en appliquant cette heuristique :

  • Si la docstring commence par une phrase simple → pas de signature
  • Si la docstring commence par du Markdown, une ligne vide, un titre, du gras, etc. → signature ajoutée. Ce comportement est : non documenté, non stable, différent selon les versions, influencé par le format de la docstring. De plus, la signature est sans valeur sémantique, elle ajoute du bruit et dégradera la sélection.

metadata.description doit n’avoir que l’intention sur une ligne

Pour reprendre le contrôle, il faut toujours définir le champ description, et ce, sous la forme d’une Intention. cela écrasera metadata.description. Le LLM verra exactement ce que l’on veut qu’il voie.

La meilleure pratique :

  • Garder la docstring pour les humains et pour la deuxième intention.
  • Pour le LLM, fournir explicitement `metadata.description='intention' en une phrase.

Le rôle de la docstring pour la deuxième intention

Il s'agit d'un un autre mécanisme de LlamaIndex qui entre en jeu uniquement après une erreur.

Quand un outil échoue (exception Python, mauvais arguments, etc.), LlamaIndex renvoie au LLM un Tool Error Message. Ce message contient :

  • l’erreur Python,
  • la docstring complète de l’outil (ou une version nettoyée),
  • parfois la signature,
  • parfois des instructions supplémentaires.

En effet, pour poursuivre le raisonnement en le modifiant (ne pas répéter l'erreur), le LLM doit être capable de :

  • comprendre pourquoi l’appel a échoué,
  • reformuler un appel correct,
  • réessayer avec les bons arguments,
  • ajuster son comportement.

Et pour ça, il a besoin d’informations plus détaillées que celles utilisées pour la sélection initiale.

Première intention : sélection d’outil → intention courte
Deuxième intention : correction d’erreur → docstring détaillée

En résumé :

  • Le LLM ne voit que metadata.description pour choisir un outil.
  • Le LLM voit la docstring complète uniquement après une erreur.
  • il faut écrire des docstrings détaillées.
  • on doit mettre uniquement l’intention dans metadata.description.

Sur ce sujet, voir également :
 ReAct : le nommage des outils.

Notes

[1En revanche, la description sera utile pour définir le schéma d’entrées attendues par l’outil.