Publié le
OpenAI Agents SDK

Maîtriser le SDK Python OpenAI Agents : Construisez des flux de travail IA intelligents avec des outils, des garde-fous et la coordination multi-agents

Image de l'article

Index

SDK Python OpenAI Agents – Tutoriel complet

Introduction

Le SDK OpenAI Agents est un framework Python pour construire des systèmes IA basés sur des agents qui combinent de grands modèles de langage (LLM) avec des outils et des flux de travail structurés. Il fournit un ensemble léger de primitivesAgents, Transferts (Handoffs) et Garde-fous – qui peuvent être composés pour créer des applications IA complexes et orientées objectifs (OpenAI Agents SDK). Un Agent dans ce SDK est essentiellement un LLM (comme GPT-4 ou GPT-3.5) configuré avec des instructions et équipé d'outils qu'il peut utiliser (OpenAI Agents SDK) (Orchestration de plusieurs agents - OpenAI Agents SDK). Ces agents fonctionnent dans une boucle agent : ils reçoivent une entrée (par exemple une question utilisateur), décident des actions (comme appeler un outil ou déléguer à un autre agent), et poursuivent la boucle jusqu'à ce qu'une réponse finale soit produite (Exécution des agents - OpenAI Agents SDK) (Exécution des agents - OpenAI Agents SDK).

Les concepts architecturaux clés incluent :

  • Agents : Les acteurs principaux de votre application. Un agent se compose d'un LLM plus un ensemble d'instructions (souvent fournies sous forme de prompt système) et d'outils optionnels qu'il peut invoquer. Face à une tâche, un agent peut planifier de manière autonome comment la résoudre en raisonnant sur le problème, en appelant des outils pour assistance, et en générant des réponses (Orchestration de plusieurs agents - OpenAI Agents SDK). Par exemple, vous pouvez avoir un agent configuré comme un « Assistant de recherche » qui utilise un outil de recherche web pour trouver des informations puis répondre à la requête.

  • Outils : Fonctions ou capacités qu'un agent peut utiliser pour effectuer des actions au-delà des connaissances intégrées du LLM (OpenAI Agents SDK). Les outils peuvent être de simples fonctions Python (I/O fichiers, calculs mathématiques), des appels API externes (consultation météo), ou même d'autres agents (permettant à un agent de déléguer des sous-tâches). Le SDK Agents facilite la transformation de toute fonction Python en outil et la gestion des entrées/sorties d'outils via l'appel de fonction (Outils - OpenAI Agents SDK). Les outils permettent aux agents d'interagir avec le monde (par exemple, rechercher sur le web, interroger des bases de données, exécuter du code) plutôt que de simplement générer du texte.

  • Transferts (Handoffs) : Un mécanisme permettant à un agent de déléguer ou transférer le contrôle à un autre agent en cours de tâche (OpenAI Agents SDK). Grâce aux transferts, vous pouvez composer plusieurs agents spécialisés dans un flux de travail – par exemple, un agent de triage qui transfère à un agent facturation ou remboursement selon la demande de l'utilisateur (OpenAI Agents SDK — Premiers pas). Les transferts permettent des systèmes multi-agents modulaires où chaque agent se concentre sur un domaine ou une compétence spécifique.

  • Garde-fous : Des vérifications de validation et de sécurité intégrées qui s'exécutent parallèlement aux agents (OpenAI Agents SDK). Les garde-fous peuvent filtrer les entrées (pour empêcher les requêtes malveillantes ou hors sujet) et valider les sorties (pour garantir la justesse ou la conformité aux politiques) (OpenAI Agents SDK — Premiers pas). Si un contrôle de garde-fou échoue (appelé tripwire), le SDK peut interrompre l'exécution de l'agent ou lever une exception avant toute action indésirable (Garde-fous - OpenAI Agents SDK) (Garde-fous - OpenAI Agents SDK). Cela aide à maintenir la fiabilité et la sécurité dans les applications en production.

  • Traçage : Le SDK intègre un support de traçage pour le débogage et l'analyse (OpenAI Agents SDK — Premiers pas). Chaque étape du raisonnement d'un agent – utilisation d'outils, décisions, messages LLM – peut être enregistrée sous forme de trace. Les développeurs peuvent inspecter ces traces (par exemple via le tableau de bord OpenAI) pour comprendre le comportement de l'agent, mesurer la performance, et améliorer itérativement les prompts ou le code (OpenAI Agents SDK — Premiers pas). Le traçage est activé par défaut, vous donnant une visibilité sur le processus de pensée et les actions de l'agent.

Ces composants fonctionnent ensemble pour former une architecture système basée sur des agents. Un agent reçoit un objectif ou une requête, utilise son noyau LLM pour raisonner sur la tâche, appelle des outils ou délègue à d'autres agents selon les besoins, et produit finalement un résultat. Grâce à la conception du SDK, une grande partie de cette complexité est gérée pour vous par la boucle agent et le runtime du SDK. Vous pouvez commencer simplement (un agent unique répondant à des questions) et ajouter progressivement des outils, plusieurs agents, des garde-fous et des contrôles personnalisés à mesure que votre application gagne en sophistication. Le SDK met l'accent sur la flexibilité avec une abstraction minimale – il « fonctionne très bien dès la sortie de la boîte » mais vous permet de personnaliser chaque partie du flux de travail si nécessaire (OpenAI Agents SDK) (OpenAI Agents SDK).

Dans le reste de ce tutoriel, nous explorerons toutes les fonctionnalités majeures du SDK Python OpenAI Agents et démontrerons comment les utiliser efficacement. Nous commencerons par installer le SDK et créer un agent simple. Puis nous approfondirons la configuration d'agents personnalisés, l'ajout et la création d'outils, la gestion du contexte et de l'état de l'agent (mémoire), la gestion de l'orchestration multi-agents avec transferts, l'intégration des garde-fous pour la sécurité, et plus encore. Des exemples de code sont fournis tout au long, et à la fin nous combinerons ces concepts dans un projet complet. Commençons !

Installation et configuration

Avant d'utiliser le SDK Agents, vous devez l'installer. Le nom du paquet est openai-agents. Installez-le via pip :

pip install openai-agents
``` ([OpenAI Agents SDK](https://openai.github.io/openai-agents-python/#installation#:~:text=pip%20install%20openai))

Cela installera le SDK principal et ses dépendances. Par défaut, le SDK utilisera l'API OpenAI pour les appels LLM, donc vous devez avoir une clé API OpenAI prête. Définissez la variable d'environnement `OPENAI_API_KEY` avec votre clé API (ou utilisez la méthode programmatique du SDK pour la configurer, montrée ci-dessous) avant d'exécuter les agents :

```bash
export OPENAI_API_KEY="sk-YourOpenAIAPIKey"

Dépendances optionnelles : Si vous prévoyez d'utiliser LiteLLM (un système de plugins pour intégrer d'autres fournisseurs de modèles ou modèles open source) ou des fonctionnalités vocales, il y a des dépendances supplémentaires. Par exemple, pour activer le support LiteLLM (permettant l'utilisation de modèles non-OpenAI), installez avec l'option litellm :

pip install "openai-agents[litellm]"

Nous aborderons l'utilisation de modèles personnalisés via LiteLLM dans une section ultérieure. Pour l'instant, avec le SDK installé et votre clé API configurée, nous pouvons passer à la création d'agents.

Création et configuration d'un agent

Créer un agent basique est simple. Le SDK fournit une classe Agent, que vous pouvez instancier avec un nom et des paramètres optionnels comme instructions, outils, transferts et garde-fous. Au minimum, un agent a besoin d'un nom (utilisé pour l'identification et la journalisation) et peut avoir une invite d'instruction qui guide son comportement.

Créons un agent simple :

from agents import Agent, Runner

# Créer un agent basique avec un nom et des instructions de rôle
agent = Agent(
    name="Assistant",
    instructions="Vous êtes un assistant utile."
)

Dans cet exemple, nous configurons l'agent pour qu'il se comporte comme un assistant utile en fournissant une instruction brève (qui agit comme un prompt système). Si nous exécutons cet agent sur une requête utilisateur, il utilisera un modèle OpenAI GPT en arrière-plan pour générer une réponse suivant cette instruction.

Exécution de l'agent : Le Runner du SDK est utilisé pour exécuter les agents. Vous pouvez appeler Runner.run_sync(agent, input) pour un appel synchrone rapide, ou utiliser await Runner.run(agent, input) dans un contexte asynchrone. Par exemple :

result = Runner.run_sync(agent, "Écris un haïku sur la récursion en programmation.")
print(result.final_output)

Cela invitera l'agent à répondre à la requête. En coulisses, le LLM de l'agent est appelé avec les instructions système et la question utilisateur, puis la boucle agent gère la réponse. Avec notre configuration simple, l'agent répondra directement. L'objet result (de type RunResult) contient la sortie finale dans result.final_output. Dans ce cas, il pourrait imprimer un haïku tel que :

# Code dans le code,
# Fonctions s'appelant elles-mêmes,
# Danse de la boucle infinie.

(Cet exemple est le « hello world » de la documentation (OpenAI Agents SDK).)

Par défaut, Agent() sans spécifier de modèle utilisera le modèle de chat OpenAI (gpt-3.5-turbo ou gpt-4 via l'API Responses) comme LLM. Assurez-vous que votre clé API OpenAI est configurée pour que l'agent puisse appeler le modèle. Vous pouvez changer le modèle ou l'API utilisée – nous y reviendrons bientôt.

Options de configuration de l'agent : La classe Agent fournit plusieurs paramètres pour personnaliser son comportement :

  • name (str) : Un nom descriptif pour l'agent (par exemple, "ResearchAgent"). Ce nom est aussi utilisé lorsque l'agent est utilisé comme outil ou dans les journaux/traces.

  • instructions (str ou callable) : Le prompt ou message système qui définit le rôle de l'agent. Cela peut être une chaîne fixe ou une fonction qui génère une chaîne (potentiellement en utilisant un contexte dynamique). Les instructions sont placées en haut du contexte du LLM (en tant que rôle système) (Gestion du contexte - OpenAI Agents SDK). De bonnes instructions sont cruciales pour guider le comportement de l'agent et l'informer des outils disponibles ou des contraintes.

  • tools (liste) : Une liste d'outils que l'agent peut utiliser. Les outils peuvent être ajoutés ici comme références de fonction (pour les outils fonctionnels) ou instances d'outils (pour certains outils intégrés). Nous discuterons des outils en détail dans la section suivante. Si aucun outil n'est fourni, l'agent ne peut compter que sur ses propres connaissances et son raisonnement LLM.

  • handoffs (liste) : Une liste d'autres agents ou configurations de transfert auxquels cet agent peut déléguer. En spécifiant des transferts, vous permettez à votre agent de transférer le contrôle à un autre agent dans certaines situations. Nous explorerons les transferts dans la section Orchestration multi-agents et transferts.

  • guardrails (liste) : Une liste de fonctions de garde-fous (garde-fous d'entrée ou de sortie) à appliquer pour cet agent. Les garde-fous sont utilisés pour appliquer une validation sur les entrées ou sorties – par exemple, empêcher l'agent de résoudre les devoirs mathématiques d'un utilisateur ou garantir que la sortie est dans un certain format. Les garde-fous sont abordés dans la section Garde-fous et validation des sorties ci-dessous.

  • model : Par défaut, chaque agent utilise le modèle global par défaut (GPT d'OpenAI via l'API Responses). Vous pouvez remplacer cela par agent en passant un paramètre model. Le SDK inclut des classes de modèles comme OpenAIChatCompletions et OpenAIResponsesModel, et avec LiteLLM vous pouvez utiliser des modèles d'Anthropic, etc. Par exemple, vous pouvez faire Agent(model=OpenAIChatCompletionsModel()) pour forcer l'utilisation de l'API Chat Completions, ou Agent(model=LitellmModel(...)) pour utiliser un modèle d'un autre fournisseur. Si vous êtes satisfait du défaut, vous pouvez omettre ce paramètre.

  • output_type : (Optionnel) Un modèle Pydantic ou un type de données spécifiant la structure attendue de la sortie finale. Si fourni, le SDK tentera d'analyser la réponse finale de l'agent dans ce type (et le LLM sera instruit pour formater sa réponse en conséquence). Cela est utile pour imposer des sorties structurées (comme des réponses JSON avec des champs spécifiques). C'est une fonctionnalité avancée – pour la plupart des cas basiques, la sortie finale sera simplement une chaîne.

  • Autres réglages : L'Agent peut aussi accepter des paramètres comme max_turns (pour limiter le nombre d'itérations de boucle avant arrêt), ou max_tokens, etc., via ses paramètres de modèle. Beaucoup de ces paramètres peuvent aussi être contrôlés globalement lors de l'exécution de l'agent (via les options de Runner.run). Nous y reviendrons dans le contexte.

Avec un agent basique défini, passons à lui donner plus de capacités avec des outils.

Ajout et utilisation d'outils

Une des fonctionnalités les plus puissantes des systèmes agentiques est la capacité des agents à utiliser des outils. Les outils étendent ce qu'un agent LLM peut faire – ils permettent à l'agent d'effectuer des actions comme naviguer sur le web, faire des calculs, récupérer des informations depuis des bases de données, ou même exécuter du code. Dans le SDK OpenAI Agents, les outils sont implémentés comme des fonctions (appelables Python) que l'agent peut invoquer via une interface standardisée (pensez au mécanisme d'appel de fonction d'OpenAI).

Il y a deux principaux types d'outils dans ce SDK :

  1. Outils hébergés (intégrés) – Outils fournis par OpenAI via l'API, tels que la recherche web, la récupération de fichiers, ou le contrôle d'ordinateur. Ceux-ci s'exécutent côté OpenAI dans l'environnement de l'« API Responses » (Outils - OpenAI Agents SDK).
  2. Outils fonctionnels (personnalisés) – Outils que vous implémentez en Python. Le SDK facilite l'exposition d'une fonction Python (ou coroutine) comme un outil qu'un agent peut appeler (Outils - OpenAI Agents SDK).

Explorons chaque type et comment les utiliser.

Outils hébergés intégrés

L'API Responses d'OpenAI offre quelques outils intégrés que les agents peuvent utiliser sans que vous écriviez de code pour ces capacités. Actuellement, les outils intégrés incluent :

  • Recherche Web – Permet à un agent de rechercher sur le web et récupérer des informations en direct (Outils - OpenAI Agents SDK).
  • Recherche de fichiers (Récupération) – Permet d'interroger un magasin vectoriel de documents (utile pour la génération augmentée par récupération avec vos propres données) (Outils - OpenAI Agents SDK).
  • Ordinateur (Opération) – Permet à un agent de simuler l'utilisation d'un ordinateur (actions souris, clavier) pour effectuer des tâches dans un environnement virtuel (Outils - OpenAI Agents SDK).

Pour utiliser les outils hébergés, le modèle de votre agent doit être le modèle OpenAI Responses API (qui est le défaut). Par exemple, pour activer la recherche web et la recherche de fichiers dans un agent :

from agents import Agent, Runner, WebSearchTool, FileSearchTool

# Agent pouvant utiliser les outils de recherche web et de fichiers
agent = Agent(
    name="ResearchAgent",
    instructions="Vous êtes un assistant de recherche qui trouve des informations en ligne et dans des documents.",
    tools=[
        WebSearchTool(),  # active les recherches web
        FileSearchTool(
            max_num_results=3,
            vector_store_ids=["<VOTRE_ID_MAGASIN_VECTORIEL>"]  # spécifiez vos magasins vectoriels
        )
    ]
)

result = Runner.run_sync(
    agent,
    "Quel café devrais-je choisir, en tenant compte de mes préférences et de la météo aujourd'hui à SF ?"
)
print(result.final_output)

Dans ce code, nous avons créé un ResearchAgent qui a accès à deux outils : une recherche web et une recherche de fichiers. Les instructions de l'agent suggèrent qu'il doit utiliser ces outils selon les besoins. Lorsqu'on l'exécute avec une requête, l'agent peut choisir d'appeler WebSearchTool pour rechercher des cafés et vérifier la météo, ou utiliser FileSearchTool si des données pertinentes sont stockées dans une base vectorielle. La sortie finale sera la réponse de l'agent à la question, vraisemblablement en utilisant les informations recueillies.

Note : Les outils hébergés comme WebSearchTool et FileSearchTool sont exécutés par les systèmes d'OpenAI (le modèle « se connecte » à eux) plutôt que localement. Ils peuvent entraîner des coûts ou limites d'utilisation supplémentaires (par exemple, OpenAI facture séparément l'utilisation de l'outil File Search (Nouveaux outils pour construire des agents | OpenAI)). Assurez-vous de consulter la documentation des outils OpenAI et d'avoir les accès appropriés si vous les utilisez. Si votre cas d'usage ne nécessite pas ces outils spécifiques ou si vous préférez un contrôle local complet, vous pouvez implémenter des fonctionnalités similaires comme outils fonctionnels personnalisés (par exemple, en utilisant la bibliothèque requests pour la recherche web ou une bibliothèque locale de base vectorielle).

Outils fonctionnels personnalisés

Pour la plupart des cas d'usage, vous créerez vos propres outils en écrivant des fonctions Python. Le SDK Agents peut automatiquement convertir une fonction Python en interface d'outil que le LLM peut appeler. Il utilise l'introspection Python et Pydantic pour générer un schéma JSON pour les arguments de la fonction, et utilise même la docstring de la fonction comme description de l'outil (Outils - OpenAI Agents SDK) (Outils - OpenAI Agents SDK). C'est similaire à l'appel de fonction OpenAI – le LLM reçoit le nom de la fonction, la description, et le schéma des paramètres, et s'il décide d'appeler la fonction, il produit une charge JSON que le SDK analyse puis appelle votre fonction Python avec.

Pour déclarer une fonction comme outil, décorez-la simplement avec @function_tool (importé de agents). Par exemple :

from typing_extensions import TypedDict
from agents import Agent, Runner, function_tool

# Définir un TypedDict pour une entrée structurée (si nécessaire)
class Location(TypedDict):
    lat: float
    long: float

@function_tool
async def fetch_weather(location: Location) -> str:
    """Récupère la météo pour un emplacement donné.

    Args:
        location: L'emplacement pour lequel récupérer la météo (avec 'lat' et 'long').
    """
    # Dans une implémentation réelle, appeler une API météo avec les coordonnées.
    # Ici, on retourne juste une réponse factice.
    return "Il fait actuellement ensoleillé à l'emplacement donné."

@function_tool(name_override="fetch_data")
def read_file(path: str, directory: str | None = None) -> str:
    """Lit le contenu d'un fichier.

    Args:
        path: Le chemin du fichier à lire.
        directory: Le répertoire depuis lequel lire le fichier (optionnel).
    """
    # Dans une implémentation réelle, ouvrir et lire le fichier depuis le disque ou stockage.
    return "<contenu du fichier>"

Décomposons ce qui se passe :

  • Nous importons function_tool et l'utilisons comme décorateur sur nos fonctions fetch_weather et read_file. Cela indique au SDK de traiter ces fonctions comme des outils.

  • La fonction fetch_weather est async et prend un Location TypedDict avec des floats lat et long, retournant une chaîne. Nous lui avons donné une docstring décrivant son fonctionnement. Le SDK créera automatiquement un outil nommé "fetch_weather" (par défaut correspondant au nom de la fonction) avec une description prise de la docstring, et un schéma JSON pour un argument location (avec lat et long comme propriétés requises) (Outils - OpenAI Agents SDK) (Outils - OpenAI Agents SDK). Quand l'agent appelle cet outil, le SDK fournira le paramètre location sous forme de dict Python selon le schéma.

  • La fonction read_file est synchrone (peut être sync ou async, les deux conviennent) et montre l'utilisation de name_override dans le décorateur. Nous remplaçons le nom de l'outil par "fetch_data" pour présenter un nom plus sémantique au LLM, au lieu du nom de fonction read_file. Cet outil lit un fichier à partir d'un chemin donné (avec un répertoire optionnel). Sa docstring sera utilisée comme description sauf si on désactive cette fonctionnalité. Le SDK générera un schéma pour deux paramètres : path (chaîne) et directory (chaîne optionnelle).

Après avoir défini les outils, intégrez-les avec un agent :

agent = Agent(
    name="UtilityAgent",
    instructions="Vous êtes un assistant utile avec accès aux informations de fichiers et météo.",
    tools=[fetch_weather, read_file]  # on passe les objets fonction eux-mêmes
)

# Exécuter l'agent pour tester les outils
result = Runner.run_sync(agent, "Quelle est la météo à la latitude 37.77, longitude -122.42 et montre-moi le contenu du fichier README.md ?")
for tool in agent.tools:
    print(f"Outil chargé : {tool.name} - {tool.description}")
print("Réponse finale :", result.final_output)

Quand l'agent reçoit la question, il pourrait décider d'appeler fetch_weather avec les coordonnées données, puis appeler fetch_data (notre read_file) avec "README.md". Le SDK gère les appels de fonction : il analysera les requêtes du LLM, exécutera fetch_weather et read_file, récupérera leurs valeurs de retour, et les fournira au LLM comme résultats de fonction. Le LLM de l'agent incorpore ensuite ces résultats dans sa réponse finale. La sortie imprimée listera les outils et leurs descriptions et schémas auto-générés, et la réponse finale pourrait ressembler à une réponse combinée météo et contenu de fichier (selon la formulation du prompt et le raisonnement de l'agent).

Comment ça marche : Le SDK utilise le module Python inspect et la bibliothèque griffe pour extraire les noms de paramètres, types, et docstrings de votre fonction afin de construire un schéma (Outils - OpenAI Agents SDK). Le décorateur @function_tool peut être configuré avec des paramètres comme name_override (comme montré) ou use_docstring_info=False si vous ne souhaitez pas utiliser automatiquement la docstring pour les descriptions. En coulisses, quand un agent avec des outils fonctionnels s'exécute, le LLM reçoit les définitions de fonction (noms, descriptions, spécifications des paramètres) et il produira un JSON spécial s'il décide d'invoquer une fonction. Le SDK capture cela, appelle votre fonction Python, puis renvoie la valeur de retour (ou l'erreur) au LLM. Cette boucle continue jusqu'à ce que le LLM produise une sortie finale non fonctionnelle (Exécution des agents - OpenAI Agents SDK). Tout cela est abstrait pour que vous puissiez simplement vous concentrer sur l'écriture de la fonction Python pour la logique de l'outil.

Gestion des erreurs dans les outils : Si votre fonction outil lève une exception ou retourne des données invalides, comment l'agent le gère-t-il ? Par défaut, le SDK informe le LLM qu'une erreur est survenue dans l'appel d'outil (cela se fait via un gestionnaire d'erreur par défaut qui renvoie un message d'erreur au LLM) (Outils - OpenAI Agents SDK). Vous pouvez personnaliser ce comportement. Le décorateur @function_tool accepte un paramètre failure_error_function où vous pouvez spécifier une fonction de gestion d'erreur personnalisée. Par exemple, vous pourriez vouloir gérer certaines exceptions et retourner un message d'erreur spécifique à l'agent, ou même décider de ne pas la capturer du tout. Si vous passez failure_error_function=None, l'exception brute remontera (par exemple, une ModelBehaviorError si l'appel de fonction du modèle était mal formé, ou UserError si votre code outil a planté) (Outils - OpenAI Agents SDK). Dans la plupart des cas, laisser le comportement par défaut est suffisant – l'agent verra simplement un résultat « erreur » et pourra décider de s'excuser ou d'essayer une autre stratégie.

Agents comme outils

Outre les outils fonctionnels classiques, vous pouvez aussi traiter un Agent lui-même comme un outil pour un autre agent. C'est une façon de créer une hiérarchie d'agents : un agent de niveau supérieur peut appeler des agents spécialisés comme s'il appelait une fonction. La différence entre un transfert (handoff) et un agent-outil (agent-comme-outil) est qu'avec un transfert, le sous-agent prend complètement le relais (nouveau contexte de conversation), alors qu'avec un agent-outil, l'agent principal reste en contrôle et reçoit simplement le résultat du sous-agent comme résultat de fonction.

Cas d'usage : Supposons que vous vouliez un agent orchestrateur central qui peut appeler des agents traducteurs spécialisés pour différentes langues, mais que vous ne voulez pas transférer complètement le contrôle (pour que l'agent principal puisse potentiellement appeler plusieurs traducteurs puis combiner les résultats). Vous pouvez faire cela en ajoutant des agents comme outils.

Exemple :

from agents import Agent, Runner

# Définir deux agents spécialisés (qui pourraient aussi être exécutés seuls)
spanish_agent = Agent(name="SpanishAgent", instructions="Traduisez le message de l'utilisateur en espagnol.")
french_agent  = Agent(name="FrenchAgent",  instructions="Traduisez le message de l'utilisateur en français.")

# Créer un agent orchestrateur qui peut utiliser les agents ci-dessus comme outils
orchestrator = Agent(
    name="OrchestratorAgent",
    instructions=(
        "Vous êtes un orchestrateur de traduction. Vous avez des outils pour traduire en espagnol ou en français. "
        "Si l'utilisateur demande une traduction, appelez l'outil pertinent. Sinon, répondez simplement."
    ),
    tools=[
        spanish_agent.as_tool(tool_name="translate_to_spanish",
                               tool_description="Traduire le message de l'utilisateur en espagnol"),
        french_agent.as_tool(tool_name="translate_to_french",
                              tool_description="Traduire le message de l'utilisateur en français")
    ]
)

result = Runner.run_sync(orchestrator, "Veuillez dire 'Bonjour, comment ça va ?' en français et en espagnol.")
print(result.final_output)
# L'orchestrateur pourrait utiliser les deux outils et produire quelque chose comme :
# "Espagnol : Hola, ¿cómo estás?\nFrançais : Bonjour, comment ça va ?"

Ici, nous avons utilisé agent.as_tool() pour envelopper chaque sous-agent comme un outil avec un nom et une description donnés (Outils - OpenAI Agents SDK). En interne, quand l'agent Orchestrator décide d'appeler translate_to_french, le SDK exécutera le french_agent (en utilisant le texte de la requête comme entrée) et renverra sa sortie finale comme « résultat de fonction » à Orchestrator. Cela permet de chaîner les agents sans transfert formel.

Personnalisation des agents-outils : La méthode as_tool est une commodité pour les cas simples. Elle peut ne pas exposer toute la configuration de l'agent. Par exemple, vous pourriez vouloir que le sous-agent s'exécute avec une limite max_turns spécifique ou utilise un modèle différent pour cet appel. Dans ces cas, vous pouvez toujours créer une fonction outil personnalisée qui appelle Runner.run sur un agent. Par exemple :

from agents import function_tool

@function_tool
async def run_my_agent(subquery: str) -> str:
    """Exécute un agent personnalisé avec un prompt donné."""
    custom_agent = Agent(name="MathAgent", instructions="Résoudre des problèmes mathématiques étape par étape.")
    result = await Runner.run(custom_agent, subquery, max_turns=5)
    return str(result.final_output)

Cela définit un outil run_my_agent qui, lorsqu'il est appelé par un agent, lancera en interne un nouveau MathAgent et l'exécutera sur la subquery fournie (Outils - OpenAI Agents SDK) (Outils - OpenAI Agents SDK). Cette technique vous donne un contrôle total : vous pouvez définir le modèle, la température, les tours, etc., pour l'appel du sous-agent. Le compromis est que la logique est maintenant à votre charge (alors que agent.as_tool le faisait automatiquement avec des valeurs par défaut).

En résumé, les outils – qu'ils soient intégrés, personnalisés ou basés sur des agents – sont la façon dont vous donnez à votre agent la capacité d'agir. Ensuite, nous verrons comment gérer plusieurs agents plus directement via les transferts, et comment maintenir le contexte et l'état entre ces interactions.

Gestion du contexte et de l'état de l'agent

Dans toute application non triviale, vous aurez une notion de contexte ou d'état dont l'agent doit être conscient ou qu'il doit porter entre les étapes. Il y a deux principaux types de contexte à considérer dans le SDK Agents (Gestion du contexte - OpenAI Agents SDK) :

  1. Contexte local (état de l'environnement) – données et dépendances côté Python dont vos outils ou callbacks ont besoin.
  2. Contexte LLM (état de la conversation) – informations que le LLM voit dans son prompt (historique de conversation, instructions système, etc.) qui constituent la « mémoire » du modèle.

Le SDK fournit des mécanismes pour gérer les deux types de contexte.

Contexte local (données de l'environnement Python)

Le contexte local est tout objet ou donnée Python que vous souhaitez passer dans l'exécution de l'agent, qui peut ensuite être accessible dans les fonctions outils ou les hooks du cycle de vie (comme un callback on_handoff). Par exemple, vous pourriez avoir une connexion base de données, un profil utilisateur, ou un simple indicateur que vos outils doivent utiliser. Vous ne voulez pas intégrer cela dans le prompt LLM, mais vous voulez que votre code l'ait à disposition.

Le SDK Agents gère cela via RunContextWrapper et le passage de contexte dans l'appel Runner.run (Gestion du contexte - OpenAI Agents SDK) :

  • Vous pouvez créer un objet Python arbitraire (un dict simple, une dataclass, etc.) qui contient vos données de contexte.
  • Lors de l'appel à Runner.run (ou run_sync), passez cet objet via l'argument context=.
  • Toute fonction outil qui a besoin d'utiliser ce contexte peut déclarer un paramètre de type RunContextWrapper[VotreType]. Le SDK passera alors un objet wrapper à cet outil, via lequel vous pouvez accéder à votre contexte (wrapper.context donne l'objet sous-jacent) (Gestion du contexte - OpenAI Agents SDK).

Exemple :

from dataclasses import dataclass
from agents import Agent, RunContextWrapper, Runner, function_tool

@dataclass
class UserInfo:
    name: str
    id: int

# Un outil qui utilise le contexte pour récupérer des infos spécifiques à l'utilisateur
@function_tool
def fetch_user_data(ctx: RunContextWrapper[UserInfo]) -> str:
    user = ctx.context  # c'est l'objet UserInfo
    # Utilisation des données du contexte (ces données NE sont PAS visibles par le LLM directement)
    return f"L'utilisateur {user.name} (id={user.id}) a 42 notifications."

# Créer un agent qui a cet outil
agent = Agent[UserInfo](
    name="PersonalAssistant",
    instructions="Vous êtes un assistant qui connaît les infos de l'utilisateur.",
    tools=[fetch_user_data]
)

# Préparer un objet contexte
user_info = UserInfo(name="Alice", id=123)

# Exécuter l'agent avec le contexte
result = Runner.run_sync(agent, "Combien de notifications ai-je ?", context=user_info)
print(result.final_output)
# Sortie attendue utilisant le résultat de l'outil : "L'utilisateur Alice (id=123) a 42 notifications."

Points clés dans cet exemple :

  • Nous définissons une dataclass UserInfo pour contenir des données spécifiques à l'utilisateur.
  • L'outil fetch_user_data a un paramètre ctx: RunContextWrapper[UserInfo]. Quand l'agent appelle cet outil, il recevra un RunContextWrapper qui enveloppe notre objet UserInfo. Nous récupérons le contexte réel via ctx.context.
  • L'agent est défini comme Agent[UserInfo] – utilisant un type générique Python pour l'agent. Cela aide à la vérification statique de type (cela garantit que les outils et le contexte de l'agent attendent tous le même type UserInfo) (Gestion du contexte - OpenAI Agents SDK) (Gestion du contexte - OpenAI Agents SDK). Ce n'est pas strictement obligatoire d'utiliser le générique, mais c'est une belle fonctionnalité pour éviter les erreurs.
  • Nous appelons Runner.run_sync avec context=user_info. Cela attache notre objet UserInfo à l'exécution. Tous les appels d'outil, vérifications de garde-fous, et callbacks de transfert durant cette exécution porteront cet objet contexte via le wrapper.

L'objet contexte local n'est jamais envoyé au LLM (Gestion du contexte - OpenAI Agents SDK). Il est purement pour l'usage de votre code Python. Cela signifie que vous pouvez y mettre des données sensibles ou volumineuses sans crainte – le LLM ne les verra pas sauf si vous les fournissez explicitement via un outil ou un prompt.

Usages courants du contexte local :

  • Passer une session base de données ou un client API que les outils peuvent utiliser.
  • Fournir des données spécifiques à l'utilisateur (préférences, profil) que certains outils pourraient utiliser pour personnaliser les réponses.
  • Mettre en cache des données entre appels d'outils, ou accumuler des résultats.

Rappelez-vous que tous les composants dans une même exécution d'agent doivent partager le même type de contexte (Gestion du contexte - OpenAI Agents SDK). Si vous démarrez un agent avec un certain type d'objet contexte, vous ne devez pas appeler un outil qui attend un type de contexte différent dans cette même ex

Continuer la lecture

Articles similaires