Cherchez une fois, posez trois questions : tool_search multi-requêtes avec racinisation

Votre agent a besoin d’un outil — peut-être doit-il créer une issue GitHub, envoyer un message Slack et chercher sur le web, tout dans une même tâche. Avec l’ancien système, c’étaient trois appels tool_search séparés, et s’il écorchait une requête (« issuse » au lieu d’« issues ») ou cherchait un mot qui ne correspondait pas exactement au nom de l’outil, il revenait bredouille et devait réessayer. Chaque échec coûte des tokens et de la latence. Hermes v0.20.6 corrige cela avec une sérieuse mise à niveau de tool_search (commit e455e4afd0) : recherche multi-requêtes, describe groupé et racinisation Snowball.
Le changement est petit par la forme et grand par le comportement : tool_search accepte désormais queries: string[] cherchées en parallèle dans le même catalogue ; les résultats reviennent groupés par requête, avec une carte d’outils partagée unique contenant la source, la description et les noms de paramètres requis de chaque outil trouvé. tool_describe accepte names: string[] et renvoie une carte indexée par nom — si bien qu’un seul mauvais nom ne fait plus échouer tout l’appel. Et la racinisation Snowball fait correspondre une requête pour « issues » à un outil nommé create_issue, et « browsing » trouve browser_exec. Voyons ce qui a changé et pourquoi c’est important.
L’ancienne méthode vs la nouvelle
Avant : une requête par appel, correspondance approximative, repli par réponse lorsqu’une requête manquait :
tool_search("browser") → une liste de correspondances
tool_search("web search") → un autre appel, une autre liste
tool_search("read pdf") → un troisième appel
Après : un appel, plusieurs requêtes, résultats groupés :
{ "queries": ["browser snapshot", "web search cache", "read pdf"] }
Chaque requête est cherchée indépendamment dans le même catalogue, la limite s’applique par requête (5 par défaut, plafonnée au maximum configuré de 25), et la réponse groupe les noms d’outils correspondants par requête tandis qu’une carte tools partagée unique porte la source, la description (plafond de 400 caractères) et les noms de paramètres requis de chaque outil — chargée une seule fois, non répétée par requête. Lorsque certaines requêtes manquent, un bloc unique de niveau supérieur available_sources + indication remplace l’ancien repli par réponse.
Le schema, tiré directement de la définition de l’outil :
queries: tableau de chaînes, « chacune quelques mots-clés décrivant une capacité (par ex.['create github issue', 'send slack message']). Cherchées en parallèle ; les résultats reviennent groupés par requête. Une chaîne unique est acceptée et traitée comme une requête. »limit: « Nombre maximum de correspondances par requête. Par défaut 5 et plafonné au maximum configuré (25 par défaut). »
Racinisation : correspondre à ce que vous voulez dire, pas à ce que vous tapez
Le héros discret de ce changement est la racinisation Snowball (anglais). Le raciniseur est appliqué à l’identique sur le chemin d’indexation (à la construction du catalogue) et sur le chemin de requête, si bien qu’une requête pour « issues » correspond à un outil nommé create_issue, « browsing » correspond à browser_exec, et « searches » correspond à web_search. Vous n’avez plus besoin de deviner la forme verbale exacte ou le pluriel — le moteur normalise les deux côtés.
Détail d’implémentation qui vaut la peine d’être noté : les instances du raciniseur Snowball conservent un état d’analyse mutable, elles ne sont donc pas sûres à partager entre threads — et la dispatch du bridge peut tourner sur des threads d’appels d’outils parallèles. Hermes crée un raciniseur par thread, paresseusement — une petite correction de justesse bien réelle, cachée dans la fonctionnalité.
tool_describe : noms groupés, échec en douceur
tool_describe reçoit le même traitement : il accepte désormais names: string[] et renvoie une carte indexée par nom. Les noms inconnus se regroupent dans not_found (avec l’indication de rafraîchissement), et les noms non reportables conservent leur erreur de vérification orthographique par nom dans errors — un seul mauvais nom ne fait plus échouer tout l’appel. Les doublons sont dédupliqués silencieusement. Ainsi, après un tool_search multi-requêtes, l’agent peut décrire plusieurs candidats en un seul appel, et un nom mal orthographié coûte une note, pas une nouvelle tentative.
Ce que cela signifie en pratique
Trois gains concrets :
- Moins d’allers-retours. Une tâche qui a besoin de trois capacités obtient un appel
tool_searchau lieu de trois, puis untool_describegroupé. Moins d’appels = moins de latence et moins de chances que le modèle perde le fil. - Découverte moins coûteuse. La carte d’outils partagée signifie que les métadonnées de chaque outil trouvé sont envoyées une seule fois, non répétées par requête — et sur le fil, les définitions d’outils elles-mêmes ont maigri à l’occasion de ce changement (le travail plus large d’allègement du schema dans la même fenêtre a réduit
browser_execde 803 à 663 tokens par appel). La découverte est l’une des parties les plus gourmandes en tokens d’une longue exécution d’agent ; ce changement la taille. - Meilleur rappel. La racinisation tue la classe d’échecs « presque bon mais pas exact » : « issues » →
create_issue, « browsing » →browser_exec, « searches » →web_search. L’agent trouve le bon outil même lorsqu’il formule la requête légèrement de travers.
Pourquoi c’est important pour vos workflows
La découverte d’outils est une plomberie invisible — vous ne la voyez jamais sauf si elle échoue, et quand elle échoue, l’agent soit patauge, soit choisit un outil faux mais proche. Multi-requêtes + racinisation + describe groupé éliminent la plus grande partie de cette surface d’échec. C’est le genre de mise à niveau qui rend les longues exécutions autonomes (tâches par lots, jobs cron, sous-tâches déléguées) nettement moins fragiles : l’agent a besoin d’un outil browser, d’un outil de recherche et d’un lecteur PDF pour une même tâche, et trouve les trois d’un coup.
Pour en savoir plus sur les outils eux-mêmes, voir notre panorama des commandes pour toute la surface de ce que tool_search peut trouver, le budget de snapshot du browser pour la façon dont les sessions browser restent bon marché, et l’article sur le cache de recherche web pour la mise à niveau de caching sœur dans la même fenêtre. Le récapitulatif complet de la v0.20.6 est dans nos notes de version.
Un appel, trois requêtes, racinisées, groupées, dédupliquées — l’agent trouve le bon outil plus vite et à moindre coût, et « je n’ai pas trouvé d’outil pour ça » devient un peu plus rare chaque jour.