Tool Search : outils dynamiques
Tool Search : outils dynamiques
Quand votre agent dispose de dizaines ou centaines de tools, les envoyer tous au modèle à chaque requête devient inefficace et coûteux en tokens. Le Tool Search résout ce problème en sélectionnant dynamiquement les tools pertinents pour chaque requête.
Le problème des nombreux tools
Imaginons un agent avec 50 tools. À chaque appel API, les schémas de ces 50 tools sont envoyés dans le prompt. Cela consomme des milliers de tokens et peut confondre le modèle :
# Problème : trop de tools
agent = Agent(
name="Super agent",
instructions="Vous pouvez tout faire.",
tools=[tool_1, tool_2, tool_3, ... , tool_50], # 50 tools = beaucoup de tokens
)
Activer Tool Search
Le Tool Search utilise un index sémantique pour sélectionner les tools pertinents selon la requête :
from agents import Agent, Runner, function_tool
# Définir de nombreux tools
@function_tool
def creer_facture(client: str, montant: float) -> str:
"""Crée une facture pour un client."""
return f"Facture créée pour {client}: {montant}€"
@function_tool
def envoyer_relance(facture_id: str) -> str:
"""Envoie une relance de paiement pour une facture impayée."""
return f"Relance envoyée pour la facture {facture_id}"
@function_tool
def generer_rapport_rh(mois: str) -> str:
"""Génère un rapport des ressources humaines pour un mois donné."""
return f"Rapport RH généré pour {mois}"
@function_tool
def planifier_entretien(candidat: str, date: str) -> str:
"""Planifie un entretien d'embauche avec un candidat."""
return f"Entretien planifié avec {candidat} le {date}"
# Beaucoup d'autres tools...
agent = Agent(
name="Agent entreprise",
instructions="Vous gérez les opérations de l'entreprise.",
tools=[
creer_facture,
envoyer_relance,
generer_rapport_rh,
planifier_entretien,
# ... 50 autres tools
],
tool_use_behavior="auto", # Le modèle sélectionne dynamiquement
)
Pattern : sélection manuelle de tools
Si vous voulez un contrôle total sur la sélection des tools, implémentez votre propre logique :
from agents import Agent, Runner, function_tool
# Grouper les tools par domaine
tools_comptabilite = [creer_facture, envoyer_relance]
tools_rh = [generer_rapport_rh, planifier_entretien]
# Un agent routeur qui sélectionne le domaine
routeur = Agent(
name="Routeur",
instructions="""Déterminez le domaine de la demande.
Répondez uniquement 'comptabilite' ou 'rh'.""",
model="o4-mini", # Rapide et pas cher pour le routage
output_type=str,
)
async def traiter_requete(message: str):
# Étape 1 : déterminer le domaine
route = await Runner.run(routeur, message)
domaine = route.final_output.strip().lower()
# Étape 2 : créer l'agent spécialisé avec les bons tools
if domaine == "comptabilite":
tools = tools_comptabilite
instructions = "Vous gérez la comptabilité de l'entreprise."
elif domaine == "rh":
tools = tools_rh
instructions = "Vous gérez les ressources humaines."
else:
tools = tools_comptabilite + tools_rh
instructions = "Vous gérez les opérations de l'entreprise."
agent_specialise = Agent(
name=f"Agent {domaine}",
instructions=instructions,
tools=tools,
model="gpt-5.3",
)
result = await Runner.run(agent_specialise, message)
return result.final_output
Pattern : tools dynamiques selon le contexte
Vous pouvez aussi adapter les tools disponibles selon l’utilisateur connecté :
from dataclasses import dataclass
@dataclass
class ContexteUtilisateur:
role: str # "admin", "manager", "employee"
departement: str
def obtenir_tools_pour_role(ctx: ContexteUtilisateur) -> list:
"""Retourne les tools autorisés selon le rôle."""
tools_de_base = [rechercher_document, consulter_planning]
if ctx.role in ("admin", "manager"):
tools_de_base.extend([creer_facture, generer_rapport_rh])
if ctx.role == "admin":
tools_de_base.extend([modifier_permissions, supprimer_compte])
if ctx.departement == "commercial":
tools_de_base.extend([rechercher_client, creer_devis])
return tools_de_base
async def creer_agent_pour_utilisateur(ctx: ContexteUtilisateur):
tools = obtenir_tools_pour_role(ctx)
return Agent(
name="Agent personnalisé",
instructions=f"Vous assistez un {ctx.role} du département {ctx.departement}.",
tools=tools,
model="gpt-5.3",
)
Optimiser les descriptions de tools
La qualité des descriptions de vos tools impacte directement la pertinence de la sélection :
# Mauvais : description vague
@function_tool
def process_data(data: str) -> str:
"""Traite les données."""
return "OK"
# Bon : description précise et contextualisée
@function_tool
def calculer_marge_brute(chiffre_affaires: float, cout_production: float) -> str:
"""Calcule la marge brute en pourcentage à partir du chiffre d'affaires
et du coût de production. Utile pour l'analyse financière trimestrielle."""
marge = ((chiffre_affaires - cout_production) / chiffre_affaires) * 100
return f"Marge brute : {marge:.1f}% (CA: {chiffre_affaires}€, coûts: {cout_production}€)"
Une bonne description de tool est comme une bonne docstring : elle explique quand utiliser le tool, pas seulement ce qu’il fait.
Points clés à retenir
- Le Tool Search sélectionne dynamiquement les tools pertinents pour chaque requête
- Avec beaucoup de tools, un routeur agent peut déterminer le domaine en amont
- Adaptez les tools disponibles selon le rôle et le contexte de l’utilisateur
- La qualité des descriptions de tools impacte la précision de la sélection
- Utilisez o4-mini pour le routage rapide et gpt-5.3 pour l’exécution