Appel d'outils : concevoir des outils que l'agent utilise bien
Quand un agent se comporte mal, le réflexe est de réécrire le prompt. D'expérience, le prompt est en cause peut-être une fois sur trois ; le reste du temps, les outils ont été conçus pour un programme et non pour un lecteur qui doit déduire des noms et descriptions ce que fait une fonction.
Les outils sont toute la capacité d'action de l'agent, et leurs définitions font littéralement partie du contexte du modèle. Bien les concevoir est moins cher et bien plus durable que d'ajuster les prompts, car un bon outil contraint le comportement au lieu de le demander.
Sept règles qui évitent la plupart des mauvais appels#
- Un outil, une tâche. `search_orders` et `refund_order` valent mieux qu'un `manage_order` à mode.
- Des types plutôt que de la prose. Énumérations, bornes et formats font ce qu'aucune description ne fera.
- Des noms qui disent ce qui arrive. `send_email_to_customer` est net ; `notify` ne l'est pas.
- Des erreurs en forme d'instruction : ce qui n'allait pas et quoi faire ensuite, en une phrase.
- Les résultats vides sont des résultats. Un non-trouvé explicite vaut mieux qu'une exception.
- Des clés d'idempotence sur tout ce qui a un effet, pour qu'une reprise ne double rien.
- De petits retours. Réduisez aux champs utiles ; 40 Ko de JSON achètent de la confusion.
Avant et après#
| Conception faible | Pourquoi ça casse | Mieux |
|---|---|---|
| `query(sql)` | Pouvoir illimité, non auditable | `get_orders_by_customer(customer_id, limit)` |
| `date: string` | Le modèle invente des formats | `date: string, format AAAA-MM-JJ` |
| `HTTP 500` | N'implique aucune action, réessayé sans fin | `Service commandes indisponible. Dites au client de réessayer.` |
| Retourne tout l'enregistrement | Remplit le contexte, dilue l'attention | Retourne six champs nommés |
| `update_status(id, status)` | N'importe quel statut, n'importe quel enregistrement | `cancel_order(id)` avec contrôle de droits |
Les descriptions sont du prompt#
Le champ description n'est pas de la documentation pour vos collègues : c'est du texte que le modèle lit en décidant. Dites quand utiliser l'outil et quand non, nommez la précondition qui compte et donnez un exemple d'argument. Trois phrases valent mieux que trois paragraphes. Et relisez-les ensemble dans un fichier : des outils sensés isolément se recouvrent souvent d'une manière qui n'apparaît qu'en les lisant comme un ensemble.
Si deux outils peuvent répondre à la même demande, l'agent choisira parfois mal. Fusionnez-les ou rendez la frontière explicite dans les deux descriptions.
Validez toujours avant d'exécuter#
Ne passez jamais une sortie de modèle à un appel système sans contrôle. Validez les arguments contre le schéma, résolvez les identifiants contre des enregistrements que cet utilisateur peut voir, et rejetez ce qui ne correspond pas plutôt que de le forcer. Un rejet clair est un bon résultat : l'agent apprend la contrainte et essaie autre chose. Forcer en silence, c'est mettre à jour le mauvais enregistrement sans que personne ne s'en aperçoive.
Testez les outils à part de l'agent#
Chaque outil avec ses tests : appel valide, arguments invalides, droits refusés, résultat vide, expiration. Testez ensuite l'agent contre une couche simulée pour forcer ces conditions. Presque tous les incidents de production que nous avons examinés se reproduisent trivialement à ce niveau — en particulier le résultat vide, rare en développement et banal un vrai mardi après-midi.
Questions fréquentes
Combien d'outils est-ce trop ?
Au-delà d'une dizaine dans une boucle, la précision de sélection baisse et les descriptions saturent le contexte. Regroupez derrière un routeur étroit ou découpez en agents spécialisés.
Les outils doivent-ils renvoyer les réponses brutes ?
Non. Renvoyez une forme petite et stable avec les champs utiles. Les réponses brutes gaspillent du contexte, exposent des champs risqués et couplent votre comportement à la version d'une API tierce.
Comment empêcher l'invention d'arguments ?
En contraignant : énumérations, formats explicites, identifiants qui doivent se résoudre. Puis validez et rejetez clairement. Un argument inventé signale souvent que l'outil demandait une chose que l'agent ne pouvait pas connaître.
appel d'outilsfunction calling agentsconception d'outilsjson schema outilserreurs d'outils llm