Vai al contenuto principale

Tutorial sull'SDK OpenAI Agents: crea sistemi di IA che agiscono

Impara a creare applicazioni di IA intelligenti con l'SDK OpenAI Agents. Questa guida completa copre la creazione di agenti, l'implementazione di tool, output strutturati e il coordinamento di più agenti.
Aggiornato 29 set 2026  · 12 min leggi

Scopri con l'IA

ChatGPTClaudePerplexity

Il campo dell’intelligenza artificiale sta passando da sistemi che si limitano a rispondere a domande a sistemi in grado di agire in autonomia. Il nuovo Agents SDK di OpenAI è all’avanguardia in questa tendenza, offrendo agli sviluppatori un framework pratico per creare applicazioni di IA che prendono decisioni ed eseguono azioni da sole. Questo toolkit rappresenta la prossima evoluzione nello sviluppo IA, in cui i sistemi non si limitano a rispondere, ma risolvono attivamente i problemi.

L’Agents SDK combina i large language model con la capacità di usare strumenti e coordinarsi tra agenti specializzati. Sviluppato in Python, offre un equilibrio tra semplicità e potenza — con pochi concetti chiave come agenti, strumenti, handoff e guardrail. Questo approccio lo rende accessibile a chi vuole creare sistemi di IA sofisticati senza gestire le complesse meccaniche sottostanti del comportamento degli agenti.

In questo tutorial esploreremo come costruire applicazioni pratiche con l’OpenAI Agents SDK. Partendo dalla creazione di un agente di base, passeremo all’implementazione di strumenti, al coordinamento di più agenti e alla garanzia di sicurezza tramite guardrail. Le competenze acquisite ti permetteranno di sviluppare sistemi di IA in grado di gestire vari compiti, fornendoti abilità in linea con gli approcci attuali allo sviluppo di IA.

Se è la tua prima volta con OpenAI, dai un’occhiata alla nostra skill track OpenAI Fundamentals per metterti in pari. Puoi anche guardare qui sotto il nostro video tutorial sull’OpenAI Agents SDK.

Prerequisiti per lavorare con l'OpenAI Agents SDK

Prima di immergerti nell’OpenAI Agents SDK, è importante capire alcuni concetti fondamentali e configurare correttamente l’ambiente. Questa sezione copre tutto ciò che ti serve sapere prima di scrivere il tuo primo agente.

Conoscenze richieste

Per ottenere il massimo da questo tutorial, dovresti sentirti a tuo agio con:

  • Programmazione Python intermedia: dovresti comprendere funzioni, classi, pattern async/await e type hint
  • Uso base dell’API OpenAI: familiarità con l’invio di richieste ai modelli OpenAI e la gestione delle risposte
  • Large language model (LLM): comprensione concettuale del funzionamento degli LLM e delle loro capacità/limitazioni
  • Pydantic: una conoscenza base dell’uso di Pydantic per la validazione dei dati sarà utile, dato che l’Agents SDK lo utilizza ampiamente
  • Programmazione asincrona: familiarità con i pattern async/await in Python, poiché l’Agents SDK è basato sull’esecuzione asincrona

Se hai bisogno di rafforzare alcune di queste aree, DataCamp offre diverse ottime risorse:

Concetti chiave per gli agenti

Prima di iniziare a scrivere codice, chiaramo alcuni concetti chiave centrali per l’Agents SDK:

  1. Agenti: sistemi di IA che possono usare strumenti e prendere decisioni per portare a termine compiti
  2. Strumenti: funzioni che gli agenti possono chiamare per eseguire azioni come cercare sul web o accedere a database
  3. Handoff: meccanismi per trasferire il controllo tra agenti specializzati
  4. Guardrail: misure di sicurezza che convalidano input e output per garantire un comportamento appropriato

Capire questi concetti e le loro relazioni ti aiuterà a costruire applicazioni basate su agenti più efficaci. Puoi saperne di più nella nostra guida per capire gli agenti di IA. 

Configurazione dell'ambiente OpenAI Agents

Impostiamo l’ambiente di sviluppo con tutto il necessario per lavorare con l’OpenAI Agents SDK:

Installazione dei pacchetti richiesti

Per prima cosa, crea e attiva un ambiente virtuale:

# 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

Poi installa l’OpenAI Agents SDK e python-dotenv:

pip install openai-agents python-dotenv

Usare python-dotenv per la gestione delle chiavi API

Quando lavori con chiavi API, è buona pratica tenerle fuori dal codice. Il pacchetto python-dotenv fornisce un modo sicuro per gestire le variabili d’ambiente:

  1. Crea un file chiamato .env nella directory del progetto
  2. Aggiungi la tua chiave API OpenAI in questo file:

OPENAI_API_KEY=your-api-key-here

3. Carica e usa le variabili d’ambiente nel tuo codice:

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")

Questo approccio mantiene le informazioni sensibili fuori dal codice, cosa particolarmente importante se condividi o pubblichi il tuo lavoro.

Lavorare con funzioni async

L’OpenAI Agents SDK utilizza ampiamente la programmazione asincrona. Ecco come lavorare con funzioni async in diversi ambienti:

In script Python (file .py)

Negli script Python tradizionali, dovrai usare asyncio.run() per eseguire funzioni 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

Nei notebook Jupyter

I notebook Jupyter hanno già un event loop in esecuzione, quindi NON dovresti usare asyncio.run(). Invece, puoi attendere direttamente le funzioni 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)

Se provi a usare asyncio.run() in un notebook, incontrerai errori del tipo:

RuntimeError: asyncio.run() cannot be called from a running event loop

Questa è una delle regolazioni più comuni da fare quando copi codice tra script e notebook. In tutto il tutorial userò principalmente la sintassi adatta ai notebook, dato che la maggior parte dei lettori userà Jupyter.

Test dell’installazione

Verifichiamo che tutto sia configurato correttamente:

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?

Con questa configurazione completata, sei pronto per iniziare a costruire applicazioni con l’OpenAI Agents SDK.

Primi passi con l'OpenAI Agents SDK

Al cuore dell’OpenAI Agents SDK c’è la classe Agent, la tua interfaccia principale per creare sistemi di IA che comprendono ed eseguono istruzioni. Vediamo come creare e configurare agenti per scenari diversi.

Un agente in questo SDK rappresenta un sistema di IA in grado di seguire istruzioni e, opzionalmente, usare strumenti per portare a termine i compiti. Creare un agente di base richiede solo pochi parametri essenziali:

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
)

I tre componenti principali di un agente sono:

  1. Nome: un identificatore per il tuo agente che aiuta con logging e debugging
  2. Istruzioni: il “prompt di sistema” che definisce il comportamento e lo scopo dell’agente
  3. Modello: il modello linguistico sottostante che alimenta l’agente (predefinito GPT-4o)

Sebbene questa configurazione di base sia sufficiente per iniziare, la classe Agent offre diverse opzioni aggiuntive di configurazione del modello che ti danno più controllo sul comportamento dell’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
)

Istruzioni e configurazione

Il parametro delle istruzioni è forse l’aspetto più importante del design di un agente. Funziona come un “prompt di sistema” che guida comportamento, tono e capacità dell’agente. Scrivere istruzioni efficaci è sia un’arte che una scienza:

Buone pratiche per scrivere istruzioni

  1. Sii specifico: definisci chiaramente ruolo, personalità e limitazioni dell’agente
  2. Imposta confini: indica esplicitamente argomenti o azioni da evitare
  3. Definisci pattern di interazione: spiega come l’agente dovrebbe gestire vari tipi di input
  4. Stabilisci i limiti di conoscenza: chiarisci cosa l’agente dovrebbe sapere e quando dovrebbe riconoscere l’incertezza

L’Agent include anche un parametro description, una descrizione leggibile dall’uomo dell’agente, usata quando l’agente è impiegato all’interno di strumenti/handoff.

Opzioni di configurazione

Oltre alle istruzioni, puoi perfezionare il comportamento dell’agente usando diversi parametri di configurazione:

  • temperature: controlla la casualità nelle risposte (0,0–2,0)
    • Valori bassi (0,1–0,4) producono risposte più deterministiche e focalizzate
    • Valori alti (0,7–1,0) generano output più creativi e vari
  • max_tokens: limita la lunghezza delle risposte dell’agente
    • Utile per garantire output concisi o controllare i costi
    • Il valore predefinito varia per modello ma è in genere sufficiente per la maggior parte dei casi d’uso
  • model: seleziona l’LLM sottostante
    • “gpt-4o” offre le migliori prestazioni per la maggior parte dei casi d’uso
    • “gpt-4o-mini” offre un buon equilibrio tra prestazioni e costi
    • “gpt-3.5-turbo” è disponibile per compiti meno complessi dove velocità e costo sono prioritari

Queste opzioni di configurazione forniscono un potente framework per personalizzare il comportamento degli agenti in base alle applicazioni. Ti incoraggiamo a sperimentare impostazioni diverse per scoprire come influenzano le risposte e trovare la configurazione ottimale per il tuo caso d’uso.

Esempio Open AI Agents SKD: creare un assistente meteo specializzato

Ora mettiamo insieme questi concetti costruendo un esempio pratico: un assistente specializzato in informazioni meteo. Questo esempio mostra come creare un agente con competenze, capacità e limitazioni ben definite:

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
   )
)

Eseguire il tuo primo agente

Una volta creato un agente, puoi eseguirlo con la classe Runner. Questa classe gestisce l’esecuzione dei compiti dell’agente e il flusso della conversazione:

# 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

Per gli script Python, dovresti usare l’approccio 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())

In questa sezione abbiamo visto i fondamenti per creare ed eseguire agenti con l’OpenAI Agents SDK. Nella prossima, amplieremo questi concetti aggiungendo strumenti ai nostri agenti, migliorandone notevolmente le capacità.

Lavorare con i tool

Il vero potere dell’OpenAI Agents SDK emerge quando doti i tuoi agenti di strumenti. I tool consentono agli agenti di interagire con sistemi esterni, accedere a dati ed eseguire azioni che vanno oltre la semplice generazione di testo. L’Agents SDK supporta tre tipi principali di tool: hosted tool, function tool e agenti come tool.

Hosted tool

Gli hosted tool vengono eseguiti sui server di OpenAI insieme ai modelli linguistici. Offrono funzionalità integrate senza richiedere di implementare logiche complesse.

WebSearchTool: costruire un assistente alla ricerca

Il WebSearchTool dà al tuo agente la possibilità di cercare sul web informazioni aggiornate. È particolarmente utile per compiti che richiedono conoscenze attuali oltre i dati di training del modello.

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

In questo esempio, abbiamo creato un assistente alla ricerca che sa cercare sul web e sintetizzare informazioni in un riepilogo coerente. Il WebSearchTool non richiede parametri per funzionare, ma puoi personalizzarne il comportamento secondo necessità:

# 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
)

Il parametro user_location è particolarmente utile per query che beneficiano del contesto geografico, come servizi locali o informazioni regionali. Il parametro search_context_size aiuta a controllare quanti risultati di ricerca il modello considera quando formula la risposta.

Function tool

I function tool ti permettono di estendere il tuo agente con qualsiasi funzione Python. Qui risiede la vera flessibilità dell’Agents SDK, che consente l’integrazione con qualsiasi API, database o servizio locale.

Tool per le previsioni meteo

Creiamo un esempio pratico che si integra con un’API meteo di terze parti:

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)}"

Questo function tool per l’API meteo funge da ponte tra l’OpenWeatherMap API e il nostro agente. Recupera dati meteo in tempo reale per coordinate geografiche e li formatta in un report leggibile. 

Il codice definisce una data class WeatherInfo per strutturare i dati con campi tipizzati (temperatura, umidità, ecc.), rendendoli ordinati e manutenibili. Il decorator @function_tool trasforma la nostra funzione Python in un tool utilizzabile dall’agente, creando automaticamente uno schema dalla firma e dalla docstring della funzione.

Quando chiamata, la funzione recupera in modo sicuro una chiave API dalle variabili d’ambiente, effettua una richiesta HTTP a OpenWeatherMap ed elabora la risposta JSON. 

Gestisce in sicurezza campi opzionali come le precipitazioni e formatta tutto in un report meteo chiaro, includendo la gestione degli errori se la richiesta API fallisce. Questo consente al nostro agente di fornire informazioni meteo attuali in un formato coerente e comprensibile senza dover conoscere i dettagli dell’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]
)

Per eseguire l’assistente meteo:

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 risposta dimostra che l’agente ha usato correttamente il tool meteo. Ha isolato dal prompt il nome della città, ha usato la propria base di conoscenza per ottenerne le coordinate e le ha fornite come lat e lon al tool.

Agenti come tool

L’Agents SDK ti permette di usare gli stessi agenti come tool, abilitando una struttura gerarchica in cui agenti specialisti lavorano sotto un coordinatore. È un pattern potente per workflow complessi.

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"
       )
   ]
)

In questo esempio:

  1. Creiamo due agenti specialisti, ciascuno con un dominio di competenza focalizzato.
  2. Creiamo poi un agente coordinatore che può delegare a questi specialisti.
  3. Convertiamo ogni agente specialista in un tool usando il metodo .as_tool(), specificando:
  • Un tool_name che il coordinatore userà per fare riferimento al tool.
  • Una tool_description che aiuta il coordinatore a capire quando usare quel tool.

Questo pattern ti consente di creare sistemi di agenti complessi mantenendo la separazione delle responsabilità. Ogni agente specialista può avere il proprio set di strumenti e competenze, mentre il coordinatore gestisce l’interazione con l’utente e delega allo specialista appropriato.

Per usare il productivity assistant:

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()

I tool trasformano gli agenti da semplici assistenti conversazionali in sistemi potenti capaci di compiere azioni significative nel mondo reale. Anche se abbiamo coperto le basi di creazione e uso dei tool, questo è solo l’inizio di ciò che è possibile. Per un uso più avanzato, inclusa la gestione degli errori nei function tool, fai riferimento alla documentazione ufficiale.

Ora che sappiamo equipaggiare i nostri agenti con tool, la prossima sfida è gestire e strutturare i loro output. Nella sezione successiva esploreremo tecniche per processare le risposte degli agenti, dagli output testuali di base a dati strutturati complessi, assicurandoci di ottenere esattamente il formato informativo di cui le nostre applicazioni hanno bisogno.

Capire gli output degli OpenAI Agent

Quando lavori con agenti, ottenere informazioni strutturate anziché testo libero può rendere le applicazioni più affidabili. L’OpenAI Agents SDK offre un modo pulito e integrato per ricevere direttamente output strutturati dagli agenti.

Output strutturati con modelli Pydantic

L’SDK ti consente di definire esattamente quale struttura dati vuoi che il tuo agente restituisca specificando un parametro output_type quando crei un agente:

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]

Questi modelli definiscono la struttura che vogliamo per i dati estratti. Ogni classe rappresenta un tipo specifico di informazione che vogliamo ricavare da un’email.

Ora creiamo un agente che produrrà dati nel nostro formato strutturato impostando il parametro 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
)

Quando specifichi l’output_type, l’agente produrrà automaticamente dati strutturati invece di risposte in testo libero. Questo elimina la necessità di parsing manuale di JSON o di usare regex.

Usiamo questo estrattore con un’email di esempio:

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
"""

Ora l’elaborazione dell’email diventa molto più semplice perché l’SDK gestisce la conversione:

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

Questo codice è molto più pulito rispetto all’approccio precedente perché:

  1. Non dobbiamo estrarre e analizzare manualmente JSON dalla risposta.
  2. L’SDK gestisce la conversione dall’output dell’agente al nostro modello Pydantic.
  3. Possiamo accedere direttamente alle proprietà dei dati strutturati (come result.final_output.subject).
  4. La validazione dei tipi avviene automaticamente, quindi sappiamo che i dati corrispondono al modello.

Lavorare con tipi di output diversi

Il parametro output_type funziona con qualsiasi tipo incapsulabile in un TypeAdapter di 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
)

Vantaggi degli output strutturati

Usare il parametro output_type offre diversi vantaggi:

  1. Integrazione diretta: gli output dell’agente sono disponibili automaticamente come oggetti Python.
  2. Sicurezza dei tipi: l’SDK garantisce che gli output corrispondano alla struttura definita.
  3. Codice più semplice: niente parsing manuale di JSON o gestione errori.
  4. Migliori prestazioni: l’SDK gestisce la conversione in modo efficiente.
  5. Supporto dell’IDE: il tuo IDE può fornire autocompletamento per le proprietà dell’output strutturato.

Definendo modelli dati chiari e usando il parametro output_type, i tuoi agenti possono produrre esattamente le strutture dati di cui la tua applicazione ha bisogno, rendendo l’integrazione fluida e riducendo la complessità del codice.

Nella prossima sezione esploreremo gli handoff tra agenti, che ti consentono di creare agenti specializzati in grado di lavorare insieme su compiti complessi. Questi handoff possono usare output strutturati per passare informazioni tra agenti in modo coerente e type-safe.

Handoff: delegare tra agenti

Nelle applicazioni complesse, compiti diversi richiedono spesso aree di competenza differenti. L’OpenAI Agents SDK supporta gli “handoff”, che consentono a un agente di delegare il controllo a un altro agente specializzato. Questa funzione è particolarmente utile per sistemi che gestiscono richieste eterogenee, come nel supporto clienti dove agenti diversi possono occuparsi di fatturazione, supporto tecnico o gestione account.

Creare handoff di base

Nella forma più semplice, gli handoff ti permettono di collegare più agenti affinché possano trasferire il controllo quando opportuno. Creiamo un semplice sistema di assistenza clienti con un agente di triage che può passare la mano agli specialisti:

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
)

In questo esempio, abbiamo creato un sistema con tre agenti:

  • Due agenti specialisti con competenze focalizzate
  • Un agente di triage che può delegare agli specialisti

Nota come includiamo semplicemente gli agenti specialisti nel parametro handoffs dell’agente di triage. L’Agents SDK crea automaticamente gli strumenti di handoff appropriati che l’agente di triage può usare quando necessario.

Vediamo il sistema in azione:

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}")

Quando l’agente di triage riceve una domanda di fatturazione, riconosce che il Billing Agent è più adatto a gestirla e avvia un handoff. Le domande tecniche vengono passate all’agente tecnico. Le domande generali vengono gestite direttamente entro le sue capacità. Ecco l’output:

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?

Personalizzare gli handoff

Per avere più controllo sugli handoff, puoi usare la funzione handoff() invece di passare gli agenti direttamente al parametro 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."
)

Output:

[LOG] Account handoff triggered at 2025-03-16 17:45:48

La funzione handoff() ti consente di:

  • Specificare una callback personalizzata con on_handoff
  • Sovrascrivere il nome predefinito del tool (normalmente “transfer_to_[agent_name]”)
  • Fornire una descrizione personalizzata del tool
  • Configurare la gestione dell’input (vedi sotto)

Passare dati durante gli handoff

Talvolta vuoi che il primo agente fornisca contesto aggiuntivo o metadati quando passa la mano a un altro agente. L’Agents SDK lo supporta tramite il parametro 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,
       )
   ],
)

Con questa configurazione, quando l’agente di servizio decide di passare la mano all’agente di escalation, fornirà dati strutturati sul motivo dell’escalation. Il sistema convaliderà questi dati rispetto al modello EscalationData prima di passarli alla callback process_escalation.

Quando usare handoff vs. agente-come-tool

L’Agents SDK offre due modi per far collaborare gli agenti: handoff e uso degli agenti come tool (come visto nella sezione precedente). Ecco quando usare ciascun approccio:

Usa gli handoff quando:

  • Vuoi trasferire completamente il controllo a un altro agente
  • La conversazione deve proseguire con uno specialista
  • Stai costruendo un workflow in cui agenti diversi gestiscono fasi differenti

Usa gli agenti-come-tool quando:

  • L’agente principale deve consultare uno specialista ma mantenere il controllo
  • Vuoi incorporare la risposta dello specialista come parte di una risposta più ampia
  • Stai costruendo un sistema gerarchico in cui un coordinatore delega sotto-compiti

Entrambi gli approcci possono essere combinati in sistemi sofisticati, con un agente principale che talvolta consulta specialisti (usandoli come tool) e talvolta passa completamente il controllo quando opportuno.

Gli handoff offrono un meccanismo potente per costruire sistemi di agenti complessi in cui la responsabilità passa tra specialisti diversi. Quando progetti l’architettura dei tuoi agenti, valuta quale approccio si adatta meglio al tuo caso d’uso per creare l’esperienza utente più efficace.

Conclusioni e prossimi passi

Abbiamo esplorato i componenti principali dell’OpenAI Agents SDK, dalla creazione di agenti di base all’implementazione di function tool e alla gestione degli handoff tra agenti specialisti. Abbiamo visto come gli output strutturati con modelli Pydantic possano rendere le applicazioni più affidabili e manutenibili, e come progettare sistemi di agenti in grado di gestire compiti complessi tramite delega e specializzazione.

Tuttavia, abbiamo solo scalfito la superficie di ciò che è possibile con questo potente framework. Per gli sviluppatori pronti a portare i propri sistemi di agenti al livello successivo, ci sono diversi temi avanzati da esplorare: streaming delle risposte per aggiornamenti in tempo reale, tracing e osservabilità per il debug, orchestrazione multi-agente per workflow complessi, gestione del contesto per mantenere lo stato della conversazione, e guardrail per garantire un comportamento sicuro e appropriato degli agenti.

Man mano che gli agenti di IA diventano sempre più centrali nelle applicazioni moderne, le competenze che hai sviluppato con questo tutorial forniscono basi solide per creare sistemi di IA sofisticati. Continua il tuo percorso con risorse come la guida di DataCamp per imparare l’IA, e ricorda che il design efficace degli agenti è tanto arte quanto scienza — richiede iterazione, test e una profonda comprensione sia dei bisogni degli utenti sia delle capacità dell’IA.

OpenAI Agents SDK: domande frequenti

What is the OpenAI Agents SDK?

L’OpenAI Agents SDK è un framework Python che consente agli sviluppatori di creare applicazioni di IA capaci di prendere decisioni ed eseguire azioni. Combina large language model con strumenti e funzionalità di coordinamento, permettendoti di creare sistemi che risolvono problemi complessi in autonomia invece di limitarsi a rispondere a domande.

What types of tools can agents use in the SDK?

L’SDK supporta tre tipi principali di tool: hosted tool (come WebSearchTool che girano sui server di OpenAI), function tool (funzioni Python personalizzate che estendono le capacità dell’agente) e agenti-come-tool (uso di agenti specializzati come strumenti per altri agenti). Questi permettono agli agenti di eseguire azioni come cercare sul web, accedere ad API o delegare a specialisti.

How do structured outputs work in the Agents SDK?

Gli output strutturati usano modelli Pydantic per definire esattamente quale struttura dati vuoi che il tuo agente restituisca. Impostando il parametro output_type quando crei un agente, ricevi oggetti dati formattati correttamente invece di testo libero. Questo rende le applicazioni più affidabili ed elimina la necessità di effettuare parsing manuale delle risposte.

What's the difference between handoffs and agents-as-tools?

Gli handoff trasferiscono completamente il controllo a un altro agente, rendendoli ideali quando la conversazione deve continuare con uno specialista. Gli agenti-come-tool consentono a un agente principale di consultare uno specialista mantenendo il controllo, incorporando la risposta dello specialista in un output più ampio. Gli handoff sono migliori per le transizioni di workflow, mentre gli agenti-come-tool sono più adatti a sistemi gerarchici.

What advanced features are available in the OpenAI Agents SDK?

Oltre alle funzionalità di base, l’SDK offre streaming per aggiornamenti in tempo reale, tracing per il debug e l’osservabilità, orchestrazione multi-agente per workflow complessi, gestione del contesto per mantenere lo stato della conversazione e guardrail per garantire un comportamento sicuro degli agenti. Queste funzionalità aiutano a creare sistemi di agenti sofisticati, pronti per la produzione.


Bexruz (Bex) Tuychiev's photo
Author
Bexruz (Bex) Tuychiev
LinkedIn

Sono un creator di contenuti sulla data science con oltre 2 anni di esperienza e uno dei più seguiti su Medium. Mi piace scrivere articoli dettagliati su AI e ML con un pizzico di sarcasmo, perché bisogna pur fare qualcosa per renderli un po’ meno noiosi. Ho pubblicato oltre 130 articoli e un corso su DataCamp, con un altro in arrivo. I miei contenuti sono stati visti da oltre 5 milioni di persone, 20.000 delle quali sono diventate follower sia su Medium che su LinkedIn. 

Argomenti
AI Agents
OpenAI
Intelligenza artificiale

I migliori corsi DataCamp

Corso

Lavorare con l'API di OpenAI

3 ore
178.4K
Inizia a sviluppare applicazioni AI con l’API OpenAI. Scopri le funzionalità alla base di applicazioni AI popolari come ChatGPT.
Vedi i dettagliRight Arrow
Inizia Il Corso
Mostra altroRight Arrow
Correlato

blog

I 15 migliori server MCP remoti che ogni AI builder dovrebbe conoscere nel 2026

Scopri i 15 migliori server MCP remoti che stanno trasformando lo sviluppo AI nel 2026. Scopri come migliorano automazione, ragionamento, sicurezza e velocità dei workflow.
Abid Ali Awan's photo

Abid Ali Awan

15 min

blog

Tokenizzazione nel NLP: come funziona, sfide e casi d'uso

Guida al preprocessing NLP nel machine learning. Copriamo spaCy, i transformer di Hugging Face e come funziona la tokenizzazione in casi d'uso reali.
Abid Ali Awan's photo

Abid Ali Awan

10 min

blog

Che cos'è Snowflake? Guida per principianti alla piattaforma dati cloud

Esplora le basi di Snowflake, la piattaforma dati cloud. Scopri la sua architettura, le sue funzionalità e come integrarla nelle tue pipeline di dati.
Tim Lu's photo

Tim Lu

12 min

Mostra AltroMostra Altro