Aller au contenu principal

Anatomie du SDK : Agent, Runner, Tool, Guardrail

Anatomie du SDK : Agent, Runner, Tool, Guardrail

Le Agents SDK repose sur quatre concepts fondamentaux : Agent, Runner, Tool et Guardrail. Comprendre comment ces briques s’articulent est essentiel pour construire des agents robustes.

1

Agent — Le cerveau

Définit les instructions, le modèle, les tools et les guardrails. C'est la configuration de votre agent.

2

Runner — Le moteur d'exécution

Orchestre la boucle de raisonnement : envoie les requêtes, exécute les tools, gère les handoffs.

3

Tool — Les capacités

Les fonctions que l'agent peut appeler : recherche web, exécution de code, appels API, etc.

4

Guardrail — La sécurité

Valide les entrées et sorties de l'agent. Bloque les requêtes dangereuses ou hors sujet.

Agent : la configuration

La classe Agent encapsule tout ce qui définit le comportement de votre agent :

from agents import Agent, function_tool, WebSearchTool

@function_tool
def obtenir_prix(produit: str) -> str:
    """Récupère le prix d'un produit."""
    prix = {"widget": "29.99€", "gadget": "49.99€"}
    return prix.get(produit, "Produit inconnu")

agent = Agent(
    name="Agent de vente",
    instructions="""Vous êtes un agent commercial pour une boutique en ligne.
    Aidez les clients à trouver des produits et à connaître les prix.
    Répondez toujours en français avec un ton professionnel.""",
    model="gpt-5.3",
    tools=[obtenir_prix, WebSearchTool()],
    handoff_description="Agent spécialisé dans la vente de produits",
    output_type=None,  # ou un type Pydantic pour forcer un format de sortie
)

Les paramètres clés de Agent :

  • name : identifiant lisible de l’agent
  • instructions : le prompt système qui définit le comportement
  • model : le modèle à utiliser (gpt-5.3, gpt-5.4, o3-pro, o4-mini)
  • tools : la liste des outils disponibles
  • handoff_description : description pour les handoffs entre agents
  • output_type : type Pydantic pour structurer la sortie

Runner : l’exécution

Le Runner est le moteur qui fait tourner votre agent. Il gère la boucle complète :

from agents import Runner

# Mode synchrone (développement)
result = Runner.run_sync(agent, "Quel est le prix du widget ?")

# Mode asynchrone (production)
result = await Runner.run(agent, "Quel est le prix du widget ?")

# Mode streaming (temps réel)
result = Runner.run_streamed(agent, "Quel est le prix du widget ?")

Le RunResult retourné contient :

result = Runner.run_sync(agent, "Quel est le prix du widget ?")

# La réponse finale de l'agent
print(result.final_output)

# L'historique complet des échanges
print(result.to_input_list())

# Le dernier agent actif (utile avec les handoffs)
print(result.last_agent.name)

Tool : les capacités

Les tools se déclarent de trois façons dans le SDK :

1. Function tools (le plus courant)

from agents import function_tool

@function_tool
def envoyer_email(destinataire: str, sujet: str, corps: str) -> str:
    """Envoie un email à un destinataire."""
    # Votre logique d'envoi ici
    return f"Email envoyé à {destinataire}"

2. Tools hébergés par OpenAI

from agents import WebSearchTool, FileSearchTool, CodeInterpreterTool

tools = [
    WebSearchTool(),                               # Recherche web
    FileSearchTool(vector_store_ids=["vs_123"]),   # Recherche fichiers
    CodeInterpreterTool(),                          # Exécution code
]

3. Agents comme tools

Un agent peut utiliser un autre agent comme outil :

agent_recherche = Agent(
    name="Chercheur",
    instructions="Vous cherchez des informations précises.",
    tools=[WebSearchTool()],
)

agent_principal = Agent(
    name="Coordinateur",
    instructions="Vous coordonnez les recherches.",
    tools=[agent_recherche.as_tool(
        tool_name="rechercher",
        tool_description="Effectue une recherche approfondie"
    )],
)

Guardrail : la sécurité

Les guardrails valident les entrées et sorties :

from agents import Agent, InputGuardrail, GuardrailFunctionOutput, Runner

guardrail_agent = Agent(
    name="Vérificateur",
    instructions="Déterminez si la requête concerne les ventes. Répondez true ou false.",
    output_type=bool,
)

async def verifier_sujet(ctx, agent, input_data):
    result = await Runner.run(guardrail_agent, input_data, context=ctx)
    return GuardrailFunctionOutput(
        output_info=result.final_output,
        tripwire_triggered=not result.final_output,
    )

agent_protege = Agent(
    name="Agent ventes protégé",
    instructions="Vous êtes un agent commercial.",
    input_guardrails=[
        InputGuardrail(guardrail_function=verifier_sujet),
    ],
)

Si le guardrail est déclenché (tripwire_triggered=True), l’exécution s’arrête et une exception InputGuardrailTripwireTriggered est levée.

Comment ces briques interagissent

Le flux complet est le suivant :

  1. Vous appelez Runner.run(agent, message)
  2. Le Runner vérifie les input guardrails
  3. Le Runner envoie le message au modèle de l’Agent
  4. Si le modèle demande un tool, le Runner l’exécute
  5. Le Runner renvoie le résultat au modèle (retour à l’étape 3)
  6. Quand le modèle produit une réponse finale, le Runner vérifie les output guardrails
  7. Le RunResult est retourné

Points clés à retenir

  • Agent définit le comportement (instructions, modèle, tools)
  • Runner orchestre l’exécution de la boucle agent
  • Les tools se déclarent avec @function_tool, les classes built-in, ou .as_tool()
  • Les guardrails valident les entrées et sorties pour la sécurité
  • Le RunResult contient la réponse finale et l’historique complet