Laravel AI v0.11.0 ajoute ToolSearch, contribution de behzadsp via la pull request #697. Jusqu'ici, chaque définition d'outil exposée par un agent était envoyée au provider à chaque requête, un coût fixe qui devient lourd avec des dizaines d'outils et réduit la précision du modèle dans le choix des outils. Le wrapper s'appuie sur la recherche d'outils hébergée qu'OpenAI et Anthropic proposent déjà : le provider reçoit une entrée de recherche plus des définitions différées, et ne charge la définition complète d'un outil que lorsqu'il décide de l'utiliser.
use Laravel\Ai\Providers\Tools\ToolSearch;
public function tools(): iterable
{
return [
new LookupAccount,
new ToolSearch(tools: [
new IssueRefund,
new ChangePlan,
new ResendInvoice,
new TransferSeat,
]),
];
}ToolSearch prend les outils à différer comme premier argument du constructeur. Tout ce qui reste en dehors du wrapper est envoyé comme avant, et les classes d'outils n'ont besoin d'aucune modification : ni interface, ni option par outil. Une même classe peut être différée dans un agent et envoyée directement dans un autre. Un second argument choisit la stratégie de recherche d'Anthropic, regex (par défaut) ou bm25, validée à la construction avec une InvalidArgumentException pour toute autre valeur. Les champs provider supplémentaires comme cache_control passent par withProviderOptions() ; chez Anthropic, le wrapper est le seul endroit possible pour un point d'arrêt de cache, car leur API rejette les outils portant à la fois defer_loading: true et cache_control.
Chez OpenAI, le wrapper devient une entrée {"type": "tool_search"} ; chez Anthropic, un type versionné comme tool_search_tool_regex_20251119. Les outils différés suivent comme des définitions ordinaires marquées defer_loading: true. Quand le modèle appelle un outil différé, la passerelle le résout par son nom depuis le wrapper, l'exécution est donc identique à celle d'un outil de premier niveau. Anthropic rapporte la recherche via des blocs server_tool_use et tool_search_tool_result (auxquels il ne faut pas répondre par un tool_result), OpenAI via des items tool_search_call et tool_search_output ; le SDK ne gère que le côté requête et n'analyse aucune de ces formes.
Seuls OpenAiProvider et AnthropicProvider implémentent le marqueur SupportsToolSearch. Tous les autres providers, dont Azure, Groq, DeepSeek, Mistral, OpenRouter, Gemini, xAI, Bedrock et Ollama, lèvent une LogicException avant toute requête. Trois règles supplémentaires s'appliquent : la vérification de support s'exécute même pour un wrapper vide, un seul ToolSearch est autorisé par requête, et chez OpenAI le package refuse ToolSearch combiné à store=false, car la recherche hébergée exige des réponses stockées. Un wrapper vide sur un provider pris en charge n'émet rien.
ToolSearch::budget() convertit chaque wrapper en son nombre d'outils différés lors du calcul du budget maxSteps par défaut, de sorte que l'emballage de vingt outils ne réduit pas le budget. Les outils différés n'ajoutent jamais d'étape propre, car le provider les charge dans son propre appel. Pour tester, il suffit de simuler l'appel HTTP et de vérifier que les définitions différées portent defer_loading: true ; les noms proviennent du ToolNameResolver, qui utilise le nom court de la classe sauf si celle-ci définit une méthode name().
Le conseil de l'article : le différé ne vaut le coup que pour les grands catalogues. Quatre outils ne le justifient pas, car le modèle doit d'abord chercher. Les chaînes de failover lèvent une exception dès qu'elles atteignent un provider non pris en charge, et les applications utilisant store=false ne peuvent pas utiliser la recherche hébergée d'OpenAI. Une approche de classement côté client, compatible avec tous les providers, a été proposée dans la PR #805 mais fermée sans fusion. ToolSearch est sorti dans la v0.11.0 avec les événements de cycle de vie des runs, un failover élargi et la relecture stateless des sorties pour OpenAI.
Commentaires
Pas encore de commentaire — écris le premier.
Lance la discussion
Pas de compte ni de mot de passe — saisis simplement ton adresse e-mail et nous t’envoyons un lien de connexion à usage unique. Première visite ? Tout se met en place automatiquement.
Ton évaluation sera appliquée automatiquement après ta connexion.
Vérifie ta boîte mail
Nous avons envoyé un lien de connexion à …. Ouvre-le sur cet appareil — cet onglet te connectera automatiquement.
Rien reçu ? Vérifiez le dossier spam — et marquez le message « Non spam » pour qu'il arrive directement la prochaine fois.