Cours
Le domaine de l’intelligence artificielle évolue : on passe de systèmes qui se contentent de répondre aux requêtes à des systèmes capables d’agir de façon autonome. Le nouvel Agents SDK d’OpenAI est à l’avant-garde de cette tendance. Il offre aux développeurs un cadre pratique pour créer des applications d’IA qui prennent des décisions et exécutent des actions par elles-mêmes. Cet ensemble d’outils marque une nouvelle étape du développement en IA, où les systèmes ne se bornent plus à répondre, mais résolvent activement des problèmes.
L’Agents SDK combine des modèles de langage de grande taille avec la capacité d’utiliser des outils et de coordonner des agents spécialisés. Conçu en Python, il allie simplicité et puissance en s’appuyant sur quelques notions clés : agents, outils, handoffs (transferts) et garde-fous. Cette approche le rend accessible aux développeurs qui veulent créer des systèmes d’IA avancés sans gérer toute la complexité des comportements d’agents.
Dans ce tutoriel, nous allons voir comment créer des applications concrètes avec l’OpenAI Agents SDK. Nous commencerons par la création d’un agent basique, puis nous ajouterons des outils, coordonnerons plusieurs agents et assurerons la sécurité grâce à des garde-fous. À la clé : la capacité de développer des systèmes d’IA polyvalents, en phase avec les approches actuelles du développement en IA.
Si vous débutez avec OpenAI, découvrez notre parcours de compétences OpenAI Fundamentals pour aller à l’essentiel. Vous pouvez également consulter notre tutoriel vidéo sur l’OpenAI Agents SDK ci-dessous.
Prérequis pour travailler avec l’OpenAI Agents SDK
Avant de plonger dans l’OpenAI Agents SDK, il est important de maîtriser quelques concepts fondamentaux et de bien configurer votre environnement. Cette section couvre tout ce qu’il faut savoir avant d’écrire votre premier agent.
Connaissances requises
Pour tirer le meilleur parti de ce tutoriel, vous devriez être à l’aise avec :
- Python intermédiaire : compréhension des fonctions, classes, modèles async/await et annotations de type
- Utilisation basique de l’API OpenAI : savoir envoyer des requêtes aux modèles OpenAI et gérer les réponses
- Grands modèles de langage (LLM) : compréhension conceptuelle de leur fonctionnement, de leurs capacités et limites
- Pydantic : des notions de base en validation de données avec Pydantic seront utiles, l’Agents SDK l’utilisant largement
- Programmation asynchrone : familiarité avec les modèles async/await en Python, l’Agents SDK reposant sur l’exécution asynchrone
Si vous souhaitez consolider certaines de ces notions, DataCamp propose d’excellentes ressources :
- Working with the OpenAI API — Apprenez les fondamentaux de l’interaction avec les modèles d’OpenAI.
- OpenAI Fundamentals Track — Une feuille de route complète sur les technologies OpenAI.
- Aperçu de GPT-4.5 — Découvrez les dernières capacités des modèles GPT.
- Function calling with GPT-4.5 — Notions essentielles pour comprendre l’usage des outils par les agents.
- Using the GPT-4.5 API — Guide pratique pour travailler avec des modèles avancés.
Concepts clés pour les agents
Avant de coder, clarifions quelques notions essentielles au cœur de l’Agents SDK :
- Agents : systèmes d’IA capables d’utiliser des outils et de prendre des décisions pour accomplir des tâches
- Outils : fonctions que les agents peuvent appeler pour effectuer des actions (recherche web, accès à des bases de données, etc.)
- Handoffs : mécanismes de transfert de contrôle entre agents spécialisés
- Garde-fous : mesures de sécurité qui valident les entrées et sorties pour garantir un comportement approprié
Comprendre ces concepts et leurs relations vous aidera à concevoir des applications à base d’agents plus efficaces. Pour aller plus loin, consultez notre guide comprendre les agents d’IA.
Configuration de l’environnement OpenAI Agents
Mettons en place notre environnement de développement avec tout le nécessaire pour travailler avec l’OpenAI Agents SDK :
Installation des packages requis
Commencez par créer et activer un environnement virtuel :
# Create and activate a virtual environment (run in your terminal)
python -m venv agents-env
source agents-env/bin/activate # On Windows: agents-env\Scripts\activate
Ensuite, installez l’OpenAI Agents SDK et python-dotenv :
pip install openai-agents python-dotenv
Utiliser python-dotenv pour gérer la clé d’API
Avec des clés d’API, la bonne pratique consiste à ne pas les inclure dans votre code. Le package python-dotenv offre un moyen sûr de gérer les variables d’environnement :
- Créez un fichier nommé
.envà la racine de votre projet - Ajoutez-y votre clé d’API OpenAI :
OPENAI_API_KEY=your-api-key-here
3. Chargez et utilisez ces variables d’environnement dans votre code :
import os
from dotenv import load_dotenv
from agents import Agent, Runner
# Load environment variables from .env file
load_dotenv()
# Access your API key
api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
raise ValueError("OPENAI_API_KEY not found in .env file")
Cette approche empêche toute fuite d’informations sensibles dans votre code, ce qui est particulièrement important si vous partagez ou publiez votre travail.
Travailler avec des fonctions async
L’OpenAI Agents SDK s’appuie massivement sur la programmation asynchrone. Voici comment utiliser des fonctions async selon l’environnement :
Dans les scripts Python (fichiers .py)
Dans des scripts classiques, vous devez utiliser asyncio.run() pour exécuter des fonctions async :
import asyncio
from agents import Agent, Runner
async def main():
agent = Agent(
name="Test Agent",
instructions="You are a helpful assistant that provides concise responses."
)
result = await Runner.run(agent, "Hello! Are you working correctly?")
print(result.final_output)
if __name__ == "__main__":
asyncio.run(main()) # Run the async function
Dans les notebooks Jupyter
Les notebooks Jupyter ont déjà une boucle d’événements active, vous ne devez donc PAS utiliser asyncio.run(). À la place, attendez directement les fonctions async :
from agents import Agent, Runner
# No need for asyncio.run() in notebooks
agent = Agent(
name="Test Agent",
instructions="You are a helpful assistant that provides concise responses."
)
result = await Runner.run(agent, "Hello! Are you working correctly?")
print(result.final_output)
Si vous tentez d’appeler asyncio.run() dans un notebook, vous obtiendrez des erreurs telles que :
RuntimeError: asyncio.run() cannot be called from a running event loop
C’est l’un des ajustements les plus fréquents lorsque vous copiez du code entre scripts et notebooks. Dans ce tutoriel, nous privilégierons la syntaxe adaptée aux notebooks, car la majorité des lecteurs utiliseront Jupyter.
Tester votre installation
Vérifions que tout est correctement configuré :
from agents import Agent, Runner
from dotenv import load_dotenv
load_dotenv()
# For Jupyter notebooks:
agent = Agent(
name="Test Agent",
instructions="You are a helpful assistant that provides concise responses."
)
result = await Runner.run(agent, "Hello! Are you working correctly?")
print(result.final_output)
# For Python scripts, you'd use:
# async def test_installation():
# agent = Agent(
# name="Test Agent",
# instructions="You are a helpful assistant that provides concise responses."
# )
# result = await Runner.run(agent, "Hello! Are you working correctly?")
# print(result.final_output)
#
# if __name__ == "__main__":
# asyncio.run(test_installation())
# Hello! Yes, I'm here and ready to help. How can I assist you today?
Une fois cette configuration en place, vous êtes prêt à créer vos applications avec l’OpenAI Agents SDK.
Premiers pas avec l’OpenAI Agents SDK
Au cœur de l’OpenAI Agents SDK se trouve la classe Agent, votre interface principale pour créer des systèmes d’IA qui comprennent et exécutent des instructions. Voyons comment créer et configurer des agents selon différents scénarios.
Dans ce SDK, un agent représente un système d’IA capable de suivre des instructions et, si besoin, d’utiliser des outils pour accomplir des tâches. Créer un agent basique ne demande que quelques paramètres essentiels :
from agents import Agent
basic_agent = Agent(
name="My First Agent",
instructions="You are a helpful assistant that provides factual information.",
model="gpt-4o" # Optional: defaults to "gpt-4o" if not specified
)
Les trois éléments principaux d’un agent sont :
- Nom : un identifiant utile pour le logging et le débogage
- Instructions : le « system prompt » qui définit le comportement et l’objectif de l’agent
- Modèle : le modèle de langage sous-jacent (par défaut : GPT-4o)
Si cette configuration suffit pour démarrer, la classe Agent propose aussi des options de configuration du modèle pour mieux contrôler le comportement du LLM :
from agents import ModelSettings
advanced_agent = Agent(
name="Advanced Assistant",
instructions="""You are a professional, concise assistant who always provides
accurate information. When you don't know something, clearly state that.
Focus on giving actionable insights when answering questions.""",
model="gpt-4o",
model_settings=ModelSettings(
temperature=0.3, # Lower for more deterministic outputs (0.0-2.0)
max_tokens=1024, # Maximum length of response
),
tools=[] # We'll cover tools in a later section
)
Instructions et configuration
Le paramètre instructions est sans doute l’élément le plus important dans la conception d’un agent. Il joue le rôle de « system prompt » qui guide le comportement, le ton et les capacités de l’agent. Rédiger de bonnes instructions relève à la fois de l’art et de la science :
Bonnes pratiques de rédaction
- Soyez précis : définissez clairement le rôle, la personnalité et les limites de l’agent
- Cadrez le périmètre : indiquez explicitement les sujets ou actions à éviter
- Définissez les schémas d’interaction : précisez comment l’agent gère différents types d’entrées
- Fixez les limites de connaissance : clarifiez ce que l’agent doit savoir et quand admettre une incertitude
L’Agent inclut aussi un paramètre description, une description lisible par l’humain utilisée lorsque l’agent est appelé au sein d’outils/hand-offs.
Options de configuration
Au-delà des instructions, vous pouvez ajuster le comportement de l’agent via plusieurs paramètres :
- temperature : contrôle l’aléa dans les réponses (0,0–2,0)
- Des valeurs basses (0,1–0,4) produisent des réponses plus déterministes et ciblées
- Des valeurs plus hautes (0,7–1,0) favorisent la créativité et la variété
- max_tokens : limite la longueur des réponses
- Utile pour garantir des réponses concises ou maîtriser les coûts
- La valeur par défaut dépend du modèle, généralement suffisante pour la plupart des cas
- model : sélectionne le LLM sous-jacent
- « gpt-4o » offre les meilleures performances dans la plupart des cas
- « gpt-4o-mini » propose un bon compromis entre performance et coût
- « gpt-3.5-turbo » convient aux tâches moins complexes où vitesse et coût priment
Ces options constituent un cadre puissant pour adapter le comportement des agents à vos applications. N’hésitez pas à expérimenter différentes valeurs pour trouver la configuration optimale selon votre usage.
Exemple OpenAI Agents SDK : créer un assistant météo spécialisé
Mettons ces concepts en pratique avec un exemple concret : un assistant spécialisé en informations météorologiques. Il illustre comment définir l’expertise, les capacités et les limites d’un agent :
from agents import Agent, Runner
from dotenv import load_dotenv
# Load environment variables (API key)
load_dotenv()
# Define detailed instructions for our weather assistant
weather_instructions = """
You are a weather information assistant who helps users understand weather patterns and phenomena.
YOUR EXPERTISE:
- Explaining weather concepts and terminology
- Describing how different weather systems work
- Answering questions about climate and seasonal patterns
- Explaining the science behind weather events
LIMITATIONS:
- You cannot provide real-time weather forecasts for specific locations
- You don't have access to current weather data
- You should not make predictions about future weather events
STYLE:
- Use clear, accessible language that non-meteorologists can understand
- Include interesting weather facts when relevant
- Be enthusiastic about meteorology and climate science
"""
# Create our specialized weather assistant
weather_assistant = Agent(
name="WeatherWise",
instructions=weather_instructions,
model="gpt-3.5-turbo",
model_settings=ModelSettings(
temperature=0.5, # Balanced temperature for natural but focused responses
max_tokens=256, # Maximum length of response
)
)
Exécuter votre premier agent
Une fois l’agent créé, vous pouvez l’exécuter avec la classe Runner, qui orchestre les tâches et gère le fil de la conversation :
# For Jupyter notebooks:
result = await Runner.run(
weather_assistant, "Can you tell me about the relationship between climate change and extreme weather events?"
)
print(result.final_output)
—--------
Absolutely! Climate change is closely linked to the increase in frequency and intensity of extreme weather events. As the Earth's climate warms due to the buildup of greenhouse gases in the atmosphere, it disrupts the balance of our planet's climate systems.
Here's how climate change influences extreme weather events:
1. **Heatwaves**: Rising global temperatures lead to more frequent and severe heatwaves. These events can have serious impacts on human health, agriculture, and ecosystems.
2. **Intense Storms**: Warmer oceans provide more energy to fuel hurricanes, typhoons, and other tropical storms, leading to stronger and more destructive events.
3. **Heavy Rainfall**: A warmer atmosphere can hold more moisture, resulting in heavier rainfall during storms. This can lead to flooding and landslides.
4. **Droughts**: Climate change can exacerbate drought conditions in certain regions, impacting water resources, agriculture, and ecosystems.
5. **Wildfires**: Higher temperatures and drier conditions increase the likelihood of wildfires, which can be more frequent and intense.
It's important to note that while climate change doesn't directly cause specific weather events, it can increase the likelihood and severity of extreme weather occurrences. Scientists continue to study these connections to better understand and prepare for the impacts of
Dans des scripts Python, utilisez asyncio :
# For Python scripts:
import asyncio
async def run_agent_example():
result = await Runner.run(weather_assistant, "Can you tell me about the relationship between climate change and extreme weather events?")
print(result.final_output)
if __name__ == "__main__":
asyncio.run(run_agent_example())
Dans cette section, nous avons vu les fondamentaux de la création et de l’exécution d’agents avec l’OpenAI Agents SDK. Dans la suivante, nous ajouterons des outils à nos agents pour démultiplier leurs capacités.
Travailler avec des outils
La vraie puissance de l’OpenAI Agents SDK se révèle lorsque vous dotez vos agents d’outils. Les outils permettent aux agents d’interagir avec des systèmes externes, d’accéder à des données et d’exécuter des actions au-delà de la simple génération de texte. L’Agents SDK prend en charge trois grands types d’outils : outils hébergés, outils fonctionnels et agents utilisés comme outils.
Outils hébergés
Les outils hébergés s’exécutent sur les serveurs d’OpenAI aux côtés des modèles de langage. Ils offrent des capacités prêtes à l’emploi, sans implémenter vous‑même des fonctionnalités complexes.
WebSearchTool : créer un assistant de recherche
Le WebSearchTool donne à votre agent la capacité de rechercher des informations à jour sur le web. C’est particulièrement utile pour des tâches nécessitant des connaissances récentes au-delà des données d’entraînement du modèle.
from agents import Agent, Runner, WebSearchTool
from dotenv import load_dotenv
load_dotenv()
# Create a research assistant with web search capability
research_assistant = Agent(
name="Research Assistant",
instructions="""You are a research assistant that helps users find and summarize information.
When asked about a topic:
1. Search the web for relevant, up-to-date information
2. Synthesize the information into a clear, concise summary
3. Structure your response with headings and bullet points when appropriate
4. Always cite your sources at the end of your response
If the information might be time-sensitive or rapidly changing, mention when the search was performed.
""",
tools=[WebSearchTool()]
)
async def research_topic(topic):
result = await Runner.run(research_assistant, f"Please research and summarize: {topic}. Only return the found links with very minimal text.")
return result.final_output
# Usage example (in Jupyter notebook)
summary = await research_topic("Latest developments in personal productivity apps.")
print(summary[:512])
—----------------
Here are some recent developments in personal productivity apps:
- **AI Integration in Productivity Tools**: Startups like Anthropic are developing AI agents capable of performing routine tasks across different applications, aiming to streamline workflows and reduce the need for multiple apps. ([ft.com](https://www.ft.com/content/a0e54dd5-b270-42cc-8c4c-18a0b8b3e6cc?utm_source=openai))
- **Read AI's Expansion**: Read AI, a productivity startup, secured $50 million in funding, valuing the company at $450 m
Dans cet exemple, nous avons créé un assistant de recherche capable d’explorer le web et de synthétiser l’information en un résumé cohérent. Le WebSearchTool fonctionne sans paramètre, mais vous pouvez personnaliser son comportement :
# Customized search tool with location context
location_aware_search = WebSearchTool(
user_location="San Francisco, CA", # Provides geographic context for local search queries
search_context_size=3 # Number of search results to consider in the response
)
Le paramètre user_location est utile pour les requêtes à dimension géographique (services locaux, informations régionales). search_context_size contrôle le nombre de résultats pris en compte dans la réponse.
Outils fonctionnels
Les outils fonctionnels vous permettent d’étendre votre agent avec n’importe quelle fonction Python. C’est là que la flexibilité de l’Agents SDK s’exprime, avec l’intégration à toute API, base de données ou service local.
Outil de prévision météo
Créons un exemple concret intégrant une API météo tierce :
import os
import requests
from datetime import datetime
from typing import Optional, List
from dataclasses import dataclass
from agents import Agent, Runner, function_tool
from dotenv import load_dotenv
load_dotenv()
@dataclass
class WeatherInfo:
temperature: float
feels_like: float
humidity: int
description: str
wind_speed: float
pressure: int
location_name: str
rain_1h: Optional[float] = None
visibility: Optional[int] = None
@function_tool
def get_weather(lat: float, lon: float) -> str:
"""Get the current weather for a specified location using OpenWeatherMap API.
Args:
lat: Latitude of the location (-90 to 90)
lon: Longitude of the location (-180 to 180)
"""
# Get API key from environment variables
WEATHER_API_KEY = os.getenv("OPENWEATHERMAP_API_KEY")
# Build URL with parameters
url = f"https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={WEATHER_API_KEY}&units=metric"
try:
response = requests.get(url)
response.raise_for_status()
data = response.json()
# Extract weather data from the response
weather_info = WeatherInfo(
temperature=data["main"]["temp"],
feels_like=data["main"]["feels_like"],
humidity=data["main"]["humidity"],
description=data["weather"][0]["description"],
wind_speed=data["wind"]["speed"],
pressure=data["main"]["pressure"],
location_name=data["name"],
visibility=data.get("visibility"),
rain_1h=data.get("rain", {}).get("1h"),
)
# Build the response string
weather_report = f"""
Weather in {weather_info.location_name}:
- Temperature: {weather_info.temperature}°C (feels like {weather_info.feels_like}°C)
- Conditions: {weather_info.description}
- Humidity: {weather_info.humidity}%
- Wind speed: {weather_info.wind_speed} m/s
- Pressure: {weather_info.pressure} hPa
"""
return weather_report
except requests.exceptions.RequestException as e:
return f"Error fetching weather data: {str(e)}"
Cet outil API météo fait le pont entre l’API OpenWeatherMap et notre agent. Il récupère les données météo en temps réel par coordonnées géographiques et les formate en un rapport lisible.
Le code définit une data class WeatherInfo pour structurer des champs typés (température, humidité, etc.), ce qui améliore l’organisation et la maintenabilité. Le décorateur @function_tool transforme la fonction Python en outil utilisable par l’agent, en générant automatiquement un schéma à partir de la signature et de la docstring.
Lors de l’appel, la fonction récupère en toute sécurité la clé d’API depuis les variables d’environnement, effectue la requête HTTP et traite la réponse JSON.
Elle gère proprement les champs optionnels (comme la pluie) et formate un rapport météo clair, avec gestion d’erreurs en cas d’échec de l’API. Ainsi, l’agent peut fournir des informations météo actuelles dans un format cohérent, sans connaître les détails de l’API.
# Create a weather assistant
weather_assistant = Agent(
name="Weather Assistant",
instructions="""You are a weather assistant that can provide current weather information.
When asked about weather, use the get_weather tool to fetch accurate data.
If the user doesn't specify a country code and there might be ambiguity,
ask for clarification (e.g., Paris, France vs. Paris, Texas).
Provide friendly commentary along with the weather data, such as clothing suggestions
or activity recommendations based on the conditions.
""",
tools=[get_weather]
)
Pour exécuter l’assistant météo :
async def main():
runner = Runner()
simple_request = await runner.run(weather_assistant, "What are your capabilities?")
request_with_location = await runner.run(weather_assistant, "What's the weather like in Tashkent right now?")
print(simple_request.final_output)
print("-"*70)
print(request_with_location.final_output)
await main()
Output:
I can provide you with the current weather conditions for any location around the world. Just give me the location details, and I'll fetch the weather data for you. I can also offer tips on activities or clothing based on the weather. If you have a specific city in mind, let me know, and I'll get to work!
----------------------------------------------------------------------
The weather in Tashkent is currently lovely with a clear sky. It's around 19.8°C, but it might feel slightly cooler at 18.6°C. The humidity is quite low at 26%, making it a pleasant day to be outdoors. A gentle breeze is blowing at 3.09 m/s, and the air pressure is steady at 1023 hPa.
It's a great time for a picnic in the park or a leisurely walk. Light clothing should be perfect for this weather. Enjoy your day in Tashkent!
La réponse montre que l’agent a bien utilisé l’outil météo. Il a isolé la ville dans l’invite, trouvé lui‑même ses coordonnées et les a transmises à l’outil sous forme de lat et lon.
Des agents comme outils
L’Agents SDK permet d’utiliser des agents eux‑mêmes comme outils, créant ainsi une hiérarchie où des spécialistes travaillent sous la houlette d’un coordinateur. C’est un schéma puissant pour des workflows complexes.
from agents import Agent, Runner
from dotenv import load_dotenv
load_dotenv()
# Specialist agents
note_taking_agent = Agent(
name="Note Manager",
instructions="You help users take and organize notes efficiently.",
# In a real application, this agent would have note-taking tools
)
task_management_agent = Agent(
name="Task Manager",
instructions="You help users manage tasks, deadlines, and priorities.",
# In a real application, this agent would have task management tools
)
# Coordinator agent that uses specialists as tools
productivity_assistant = Agent(
name="Productivity Assistant",
instructions="""You are a productivity assistant that helps users organize their work and personal life.
For note-taking questions or requests, use the note_taking tool.
For task and deadline management, use the task_management tool.
Help the user decide which tool is appropriate based on their request,
and coordinate between different aspects of productivity.
""",
tools=[
note_taking_agent.as_tool(
tool_name="note_taking",
tool_description="For taking, organizing, and retrieving notes and information"
),
task_management_agent.as_tool(
tool_name="task_management",
tool_description="For managing tasks, setting deadlines, and tracking priorities"
)
]
)
Dans cet exemple :
- Nous créons deux agents spécialistes, chacun sur un domaine précis.
- Nous créons ensuite un agent coordinateur capable de leur déléguer.
- Nous convertissons chaque spécialiste en outil via
.as_tool(), en précisant :
- Un
tool_namepour le référencer côté coordinateur - Une
tool_descriptionpour indiquer quand l’utiliser
Ce schéma vous permet de bâtir des systèmes d’agents complexes tout en maintenant une séparation des responsabilités. Chaque spécialiste peut avoir ses propres outils et son expertise, tandis que le coordinateur gère l’interaction et délègue au bon moment.
Pour utiliser l’assistant de productivité :
async def main():
runner = Runner()
result = await runner.run(productivity_assistant, "I need to keep track of my project deadlines")
print(result.final_output)
await main()
Les outils transforment des assistants conversationnels en systèmes capables d’actions concrètes. Ce que nous avons vu ici n’est qu’un début. Pour un usage avancé, notamment la gestion des erreurs dans les outils fonctionnels, consultez la documentation officielle.
Maintenant que nous savons équiper nos agents d’outils, reste à maîtriser leurs sorties. Dans la prochaine section, nous verrons comment traiter les réponses des agents, du texte libre aux données structurées, pour obtenir exactement le format attendu par vos applications.
Comprendre les sorties des agents OpenAI
Avec des agents, obtenir des informations structurées plutôt que du texte libre rend vos applications plus fiables. L’OpenAI Agents SDK propose un mécanisme intégré pour recevoir directement des sorties structurées.
Sorties structurées avec des modèles Pydantic
Le SDK vous permet de définir précisément la structure de données attendue en spécifiant un paramètre output_type lors de la création d’un agent :
from pydantic import BaseModel
from typing import List, Optional
from agents import Agent, Runner
from dotenv import load_dotenv
load_dotenv()
True
First, we define our data models using Pydantic:
# Define person data model
class Person(BaseModel):
name: str
role: Optional[str]
contact: Optional[str]
# Define meeting data model
class Meeting(BaseModel):
date: str
time: str
location: Optional[str]
duration: Optional[str]
# Define task data model
class Task(BaseModel):
description: str
assignee: Optional[str]
deadline: Optional[str]
priority: Optional[str]
# Define the complete email data model
class EmailData(BaseModel):
subject: str
sender: Person
recipients: List[Person]
main_points: List[str]
meetings: List[Meeting]
tasks: List[Task]
next_steps: Optional[str]
Ces modèles définissent la structure que doivent respecter les données extraites. Chaque classe représente un type d’information à extraire d’un email.
Créons maintenant un agent qui retournera ces données au format structuré en définissant output_type :
# Create an email extraction agent with structured output
email_extractor = Agent(
name="Email Extractor",
instructions="""You are an assistant that extracts structured information from emails.
When given an email, carefully identify:
- Subject and main points
- People mentioned (names, roles, contact info)
- Meetings (dates, times, locations)
- Tasks or action items (with assignees and deadlines)
- Next steps or follow-ups
Extract this information as structured data. If something is unclear or not mentioned,
leave those fields empty rather than making assumptions.
""",
output_type=EmailData, # This tells the agent to return data in EmailData format
)
Quand vous précisez output_type, l’agent produit automatiquement des données structurées plutôt que du texte libre. Plus besoin d’analyse JSON manuelle ou de regex.
Utilisons cet extracteur avec un email d’exemple :
sample_email = """
From: Alex Johnson <alex.j@techcorp.com>
To: Team Development <team-dev@techcorp.com>
CC: Sarah Wong <sarah.w@techcorp.com>, Miguel Fernandez <miguel.f@techcorp.com>
Subject: Project Phoenix Update and Next Steps
Hi team,
I wanted to follow up on yesterday's discussion about Project Phoenix and outline our next steps.
Key points from our discussion:
- The beta testing phase has shown promising results with 85% positive feedback
- We're still facing some performance issues on mobile devices
- The client has requested additional features for the dashboard
Let's schedule a follow-up meeting this Friday, June 15th at 2:00 PM in Conference Room B. The meeting should last about 1.5 hours, and we'll need to prepare the updated project timeline.
Action items:
1. Sarah to address the mobile performance issues by June 20th (High priority)
2. Miguel to create mock-ups for the new dashboard features by next Monday
3. Everyone to review the beta testing feedback document and add comments by EOD tomorrow
If you have any questions before Friday's meeting, feel free to reach out.
Best regards,
Alex Johnson
Senior Project Manager
(555) 123-4567
"""
Le traitement devient alors bien plus simple, le SDK gérant la conversion :
async def process_email(email_text):
runner = Runner()
result = await runner.run(
email_extractor,
f"Please extract information from this email:\n\n{email_text}"
)
# The result is already a structured EmailData object
return result
# Process the sample email
result = await process_email(sample_email)
# Display the extracted information
result = result.final_output
print(f"Subject: {result.subject}")
print(f"From: {result.sender.name} ({result.sender.role})")
print("\nMain points:")
for point in result.main_points:
print(f"- {point}")
print("\nMeetings:")
for meeting in result.meetings:
print(f"- {meeting.date} at {meeting.time}, Location: {meeting.location}")
print("\nTasks:")
for task in result.tasks:
print(f"- {task.description}")
print(
f" Assignee: {task.assignee}, Deadline: {task.deadline}, Priority: {task.priority}"
)
—----------
Subject: Project Phoenix Update and Next Steps
From: Alex Johnson (Senior Project Manager)
Main points:
- 85% positive feedback from beta testing
- Performance issues on mobile devices
- Client requested additional dashboard features
Meetings:
- June 15th at 2:00 PM, Location: Conference Room B
Tasks:
- Address mobile performance issues
Assignee: Sarah, Deadline: June 20th, Priority: High
- Create mock-ups for new dashboard features
Assignee: Miguel, Deadline: Next Monday, Priority: None
- Review beta testing feedback document and add comments
Assignee: Everyone, Deadline: EOD tomorrow, Priority: None
Ce code est bien plus clair que l’approche manuelle, car :
- Inutile d’extraire et d’analyser du JSON à la main.
- Le SDK convertit la sortie de l’agent vers notre modèle Pydantic.
- Nous accédons directement aux propriétés structurées (par ex.
result.final_output.subject). - La validation des types est automatique, garantissant la conformité au modèle.
Gérer différents types de sorties
Le paramètre output_type fonctionne avec tout type enveloppable par un TypeAdapter Pydantic :
# For simple lists
agent_with_list_output = Agent(
name="List Generator",
instructions="Generate lists of items based on the user's request.",
output_type=list[str], # Returns a list of strings
)
# For dictionaries
agent_with_dict_output = Agent(
name="Dictionary Generator",
instructions="Create key-value pairs based on the input.",
output_type=dict[
str, int
], # Returns a dictionary with string keys and integer values
)
# For simple primitive types
agent_with_bool_output = Agent(
name="Decision Maker",
instructions="Answer yes/no questions with True or False.",
output_type=bool, # Returns a boolean
)
Avantages des sorties structurées
L’utilisation de output_type présente plusieurs atouts :
- Intégration directe : les sorties sont disponibles comme objets Python.
- Sécurité de typage : le SDK vérifie la conformité à votre structure.
- Code plus simple : pas d’analyse JSON manuelle ni de gestion d’erreurs associée.
- Meilleures performances : conversion gérée efficacement par le SDK.
- Support IDE : l’autocomplétion fonctionne sur les propriétés de sortie.
En définissant des modèles de données clairs et en utilisant output_type, vos agents peuvent produire exactement les structures dont votre application a besoin, pour une intégration fluide et un code allégé.
Dans la prochaine section, nous verrons les handoffs entre agents pour faire collaborer des spécialistes sur des tâches complexes. Ces handoffs peuvent s’appuyer sur des sorties structurées pour échanger des informations de manière cohérente et typée.
Handoffs : déléguer entre agents
Dans des applications complexes, différentes tâches exigent des expertises variées. L’OpenAI Agents SDK prend en charge les « handoffs », qui permettent à un agent de déléguer le contrôle à un agent spécialisé. C’est particulièrement utile pour des systèmes gérant des demandes diversifiées, comme le support client (facturation, assistance technique, gestion de compte).
Créer des handoffs basiques
À son plus simple, un handoff relie plusieurs agents afin qu’ils se transmettent le contrôle lorsque c’est pertinent. Créons un système de service client avec un agent de triage qui transfère vers des spécialistes :
from agents import Agent, handoff, Runner
from dotenv import load_dotenv
load_dotenv()
# Create specialist agents
billing_agent = Agent(
name="Billing Agent",
instructions="""You are a billing specialist who helps customers with payment issues.
Focus on resolving billing inquiries, subscription changes, and refund requests.
If asked about technical problems or account settings, explain that you specialize
in billing and payment matters only.""",
)
technical_agent = Agent(
name="Technical Agent",
instructions="""You are a technical support specialist who helps with product issues.
Assist users with troubleshooting, error messages, and how-to questions.
Focus on resolving technical problems only.""",
)
# Create a triage agent that can hand off to specialists
triage_agent = Agent(
name="Customer Service",
instructions="""You are the initial customer service contact who helps direct
customers to the right specialist.
If the customer has billing or payment questions, hand off to the Billing Agent.
If the customer has technical problems or how-to questions, hand off to the Technical Agent.
For general inquiries or questions about products, you can answer directly.
Always be polite and helpful, and ensure a smooth transition when handing off to specialists.""",
handoffs=[billing_agent, technical_agent], # Direct handoff to specialist agents
)
Ici, nous créons un système à trois agents :
- Deux spécialistes sur des domaines ciblés
- Un agent de triage capable de déléguer aux spécialistes
Remarquez que nous passons simplement les agents spécialistes au paramètre handoffs de l’agent de triage. L’Agents SDK crée automatiquement les outils de handoff appropriés.
Voyons le système en action :
async def handle_customer_request(request):
runner = Runner()
result = await runner.run(triage_agent, request)
return result
# Example customer inquiries
billing_inquiry = (
"I was charged twice for my subscription last month. Can I get a refund?"
)
technical_inquiry = (
"The app keeps crashing when I try to upload photos. How can I fix this? Give me the shortest solution possible."
)
general_inquiry = "What are your business hours?"
# Process the different types of inquiries
billing_response = await handle_customer_request(billing_inquiry)
print(f"Billing inquiry response:\n{billing_response.final_output}\n")
technical_response = await handle_customer_request(technical_inquiry)
print(f"Technical inquiry response:\n{technical_response.final_output}\n")
general_response = await handle_customer_request(general_inquiry)
print(f"General inquiry response:\n{general_response.final_output}")
Quand l’agent de triage reçoit une question de facturation, il reconnaît que le Billing Agent est le mieux placé et déclenche un handoff. Les questions techniques sont transférées au Technical Agent. Les questions générales sont traitées directement. Voici la sortie :
Billing inquiry response:
I can help with that. Could you please provide the transaction details or the date of the charges? This will help me locate the duplicate charge and process a refund for you.
Technical inquiry response:
Try these steps:
1. Restart the app.
2. Update to the latest app version.
3. Clear the app cache.
4. Restart your device.
If it persists, reinstall the app.
General inquiry response:
Our business hours are Monday to Friday, 9 AM to 5 PM. If you need assistance outside these hours, feel free to reach out and we'll get back to you as soon as possible. Is there anything else I can help you with?
Personnaliser les handoffs
Pour un contrôle plus fin, utilisez la fonction handoff() plutôt que de passer les agents directement au paramètre handoffs :
from agents import Agent, handoff, RunContextWrapper
from datetime import datetime
# Create an agent that handles account-related questions
account_agent = Agent(
name="Account Management",
instructions="""You help customers with account-related issues such as
password resets, account settings, and profile updates.""",
)
# Custom handoff callback function
async def log_account_handoff(ctx: RunContextWrapper[None]):
print(
f"[LOG] Account handoff triggered at {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
)
# In a real app, you might log to a database or alert a human supervisor
# Create a triage agent with customized handoffs
enhanced_triage_agent = Agent(
name="Enhanced Customer Service",
instructions="""You are the initial customer service contact who directs
customers to the right specialist.
If the customer has billing or payment questions, hand off to the Billing Agent.
If the customer has technical problems, hand off to the Technical Agent.
If the customer needs to change account settings, hand off to the Account Management agent.
For general inquiries, you can answer directly.""",
handoffs=[
billing_agent, # Basic handoff
handoff( # Customized handoff
agent=account_agent,
on_handoff=log_account_handoff, # Callback function
tool_name_override="escalate_to_account_team", # Custom tool name
tool_description_override="Transfer the customer to the account management team for help with account settings, password resets, etc.",
),
technical_agent, # Basic handoff
],
)
result = await Runner.run(
enhanced_triage_agent, "I need to change my password."
)
Sortie :
[LOG] Account handoff triggered at 2025-03-16 17:45:48
La fonction handoff() permet de :
- Définir un callback personnalisé via
on_handoff - Remplacer le nom d’outil par défaut (généralement « transfer_to_[agent_name] »)
- Fournir une description d’outil personnalisée
- Configurer la gestion des entrées (voir ci‑dessous)
Transmettre des données lors d’un handoff
Il arrive que vous souhaitiez transmettre un contexte ou des métadonnées lors du transfert à un autre agent. L’Agents SDK le permet via le paramètre input_type :
from pydantic import BaseModel
from typing import Optional
from agents import Agent, handoff, RunContextWrapper
# Define the data structure to pass during handoff
class EscalationData(BaseModel):
reason: str
priority: Optional[str]
customer_tier: Optional[str]
# Handoff callback that processes the escalation data
async def process_escalation(ctx: RunContextWrapper, input_data: EscalationData):
print(f"[ESCALATION] Reason: {input_data.reason}")
print(f"[ESCALATION] Priority: {input_data.priority}")
print(f"[ESCALATION] Customer tier: {input_data.customer_tier}")
# You might use this data to prioritize responses, alert human agents, etc.
# Create an escalation agent
escalation_agent = Agent(
name="Escalation Agent",
instructions="""You handle complex or sensitive customer issues that require
special attention. Always address the customer's concerns with extra care and detail.""",
)
# Create a service agent that can escalate with context
service_agent = Agent(
name="Service Agent",
instructions="""You are a customer service agent who handles general inquiries.
For complex issues, escalate to the Escalation Agent and provide:
- The reason for escalation
- Priority level (Low, Normal, High, Urgent)
- Customer tier if mentioned (Standard, Premium, VIP)""",
handoffs=[
handoff(
agent=escalation_agent,
on_handoff=process_escalation,
input_type=EscalationData,
)
],
)
Avec cette configuration, quand l’agent de service décide d’escalader vers l’agent d’escalade, il fournit des données structurées expliquant le pourquoi du transfert. Le système valide ces données selon le modèle EscalationData avant de les transmettre au callback process_escalation.
Quand utiliser handoffs vs. agent‑comme‑outil
L’Agents SDK propose deux manières de faire collaborer des agents : les handoffs et l’utilisation d’agents comme outils (vu plus haut). Quand utiliser quelle approche ?
Utilisez des handoffs lorsque :
- Vous souhaitez transférer complètement le contrôle à un autre agent
- La conversation doit se poursuivre avec un spécialiste
- Vous concevez un workflow où chaque étape est gérée par un agent différent
Utilisez des agents‑comme‑outils lorsque :
- L’agent principal doit consulter un spécialiste tout en gardant la main
- Vous voulez intégrer la réponse du spécialiste dans une réponse plus large
- Vous construisez un système hiérarchique où un coordinateur délègue des sous‑tâches
Les deux approches peuvent se combiner dans des systèmes sophistiqués : un agent principal peut parfois consulter des spécialistes (comme outils) et parfois transférer totalement le contrôle quand c’est pertinent.
Les handoffs offrent un puissant mécanisme pour construire des systèmes d’agents où la responsabilité bascule entre spécialistes. À la conception, choisissez l’approche la plus adaptée à votre cas d’usage pour une expérience optimale.
Conclusion et prochaines étapes
Nous avons parcouru les composants clés de l’OpenAI Agents SDK, de la création d’agents basiques à l’implémentation d’outils fonctionnels et à la gestion des handoffs entre spécialistes. Nous avons vu comment les sorties structurées via des modèles Pydantic rendent les applications plus fiables et maintenables, et comment concevoir des systèmes d’agents capables de traiter des tâches complexes grâce à la délégation et à la spécialisation.
Nous n’avons toutefois fait qu’effleurer le potentiel de ce framework. Pour aller plus loin : les réponses en streaming pour des mises à jour en temps réel, la traçabilité et l’observabilité pour le débogage, l’ orchestration multi‑agents pour des workflows complexes, la gestion de contexte pour maintenir l’état de conversation, et les garde‑fous pour garantir un comportement sûr et approprié.
À mesure que les agents d’IA deviennent centraux dans les applications modernes, les compétences acquises dans ce tutoriel constituent une base solide pour créer des systèmes d’IA sophistiqués. Poursuivez votre apprentissage avec des ressources comme le guide DataCamp pour apprendre l’IA, et gardez en tête que la conception d’agents efficaces est autant un art qu’une science — elle demande itération, tests et une compréhension fine des besoins utilisateurs comme des capacités de l’IA.
Systèmes multi-agents avec LangGraph
FAQ sur l’OpenAI Agents SDK
Qu’est‑ce que l’OpenAI Agents SDK ?
L’OpenAI Agents SDK est un framework Python qui permet aux développeurs de créer des applications d’IA capables de prendre des décisions et d’agir. Il combine des modèles de langage de grande taille avec des outils et des capacités de coordination pour concevoir des systèmes qui résolvent de manière autonome des problèmes complexes, au‑delà d’une simple réponse à des requêtes.
Quels types d’outils les agents peuvent‑ils utiliser dans le SDK ?
Le SDK prend en charge trois types d’outils principaux : les outils hébergés (comme WebSearchTool, exécutés sur les serveurs d’OpenAI), les outils fonctionnels (fonctions Python personnalisées qui étendent les capacités) et les agents‑comme‑outils (utiliser des agents spécialisés comme outils pour d’autres agents). Ces mécanismes permettent de rechercher sur le web, d’accéder à des APIs ou de déléguer à des spécialistes.
Comment fonctionnent les sorties structurées dans l’Agents SDK ?
Les sorties structurées s’appuient sur des modèles Pydantic pour définir la structure exacte des données retournées par l’agent. En définissant le paramètre output_type lors de la création d’un agent, vous recevez des objets de données correctement formatés au lieu de texte libre. Vos applications gagnent ainsi en fiabilité et vous évitez toute analyse manuelle des réponses.
Quelle est la différence entre handoffs et agents‑comme‑outils ?
Les handoffs transfèrent entièrement le contrôle à un autre agent : idéals quand la conversation doit se poursuivre avec un spécialiste. Les agents‑comme‑outils permettent à l’agent principal de consulter un spécialiste tout en gardant la main, pour intégrer sa réponse dans un ensemble plus large. Privilégiez les handoffs pour les transitions de workflow, et les agents‑comme‑outils pour des architectures hiérarchiques.
Quelles fonctionnalités avancées sont disponibles dans l’OpenAI Agents SDK ?
Au‑delà des fonctionnalités de base, le SDK propose le streaming pour des mises à jour en temps réel, la traçabilité pour le débogage et l’observabilité, l’orchestration multi‑agents pour des workflows complexes, la gestion de contexte pour maintenir l’état d’une conversation, et des garde‑fous pour garantir un comportement sûr. Ces fonctionnalités aident à construire des systèmes d’agents prêts pour la production.
Je suis créateur de contenu en science des données avec plus de 2 ans d’expérience et l’une des plus grandes audiences sur Medium. J’aime écrire des articles détaillés sur l’IA et le ML avec une pointe de sarcasme, histoire de les rendre un peu moins austères. J’ai publié plus de 130 articles et un cours DataCamp, avec un autre en préparation. Mes contenus ont été vus par plus de 5 millions de personnes, dont 20 000 sont devenues abonnées sur Medium et LinkedIn.
