跳至内容

OpenAI Agents SDK 教程:构建会行动的 AI 系统

学习如何使用 OpenAI 的 Agents SDK 构建智能 AI 应用。本综合指南涵盖创建智能体、实现工具、结构化输出,以及协同多个智能体。
已更新 2026年10月6日  · 12分钟 阅读

使用 AI 探索

ChatGPTClaudePerplexity

人工智能领域正从仅对查询作出响应的系统,转向能够自主行动的系统。OpenAI 最新的 Agents SDK 走在这一趋势前沿,为开发者提供了一个实用框架,用于构建能自主决策并执行操作的 AI 应用。这套工具标志着 AI 开发的下一步演进:系统不再只是回答问题,而是主动解决问题。

Agents SDK 将大型语言模型与工具使用以及多个专业智能体之间的协作能力相结合。它基于 Python 构建,在简洁与强大之间取得平衡——仅通过少数核心概念(如智能体、工具、交接与护栏)即可上手。这种方法让开发者无需管理智能体行为背后的复杂机制,也能创建复杂 AI 系统。

在本教程中,我们将探索如何使用 OpenAI Agents SDK 构建实用应用。从基础的智能体创建开始,我们将逐步实现工具、协调多个智能体,并通过护栏确保安全。通过这些知识,您将能够开发可处理多种任务的 AI 系统,掌握贴合当前 AI 开发方法的实用技能。

如果您刚开始接触 OpenAI,欢迎查看我们的 OpenAI Fundamentals 技能路径快速上手。您也可以观看下方的 OpenAI Agents SDK 视频教程。

使用 OpenAI Agents SDK 的先决条件

在深入 OpenAI Agents SDK 之前,理解若干基础概念并正确配置环境非常重要。本节涵盖在编写第一个智能体前,您需要了解的所有内容。

必备知识

为最大化学习效果,建议您熟悉:

  • 中级 Python 编程:理解函数、类、async/await 模式与类型提示
  • 基础 OpenAI API 用法:熟悉向 OpenAI 模型发送请求并处理响应
  • 大型语言模型(LLM):理解 LLM 的基本原理及其能力/局限
  • Pydantic:了解使用 Pydantic 进行数据校验的基础知识将很有帮助,因为 Agents SDK 广泛使用它
  • 异步编程:熟悉 Python 中的 async/await 模式,因为 Agents SDK 围绕异步执行构建

如果您需要在上述某些方面补课,DataCamp 提供了多项优质资源:

智能体关键概念

在开始编码之前,让我们澄清几个对 Agents SDK 至关重要的核心概念:

  1. Agents(智能体):能够使用工具并做出决策以完成任务的 AI 系统
  2. Tools(工具):智能体可调用的函数,用于执行如网页搜索或访问数据库等操作
  3. Handoffs(交接):在专业智能体之间转移控制权的机制
  4. Guardrails(护栏):用于验证输入与输出、确保行为得当的安全措施

理解这些概念及其关系,将帮助您构建更高效的基于智能体的应用。您可以在我们的指南中进一步了解AI 智能体入门。

OpenAI Agents 环境搭建

让我们为 OpenAI Agents SDK 配置好开发环境:

安装所需包

首先,创建并激活虚拟环境:

# 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

接着,安装 OpenAI Agents SDK 与 python-dotenv:

pip install openai-agents python-dotenv

使用 python-dotenv 管理 API 密钥

处理 API 密钥时,最佳实践是不要将其写入代码中。python-dotenv 提供了一种安全的方式来管理环境变量:

  1. 在项目目录下创建一个名为 .env 的文件
  2. 将您的 OpenAI API 密钥添加到该文件:

OPENAI_API_KEY=your-api-key-here

3. 在代码中加载并使用环境变量:

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

这种方法可以让敏感信息不出现在代码中,尤其是在您需要共享或发布作品时格外重要。

使用异步函数

OpenAI Agents SDK 广泛使用异步编程。以下是在不同环境中使用异步函数的方法:

在 Python 脚本(.py 文件)中

在常规 Python 脚本中,您需要使用 asyncio.run() 来执行异步函数:

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

在 Jupyter 笔记本中

Jupyter 笔记本已运行事件循环,因此不应使用 asyncio.run()。您可以直接 await 异步函数:

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)

如果您在笔记本中尝试使用 asyncio.run(),将会遇到如下错误:

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

这是在脚本与笔记本之间拷贝代码时最常见的调整之一。整个教程中,我将主要采用适用于笔记本的语法,因为大多数读者会使用 Jupyter。

测试安装

让我们确认一切就绪:

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?

完成以上设置后,您就可以开始使用 OpenAI Agents SDK 构建应用了。

OpenAI Agents SDK 快速上手

OpenAI Agents SDK 的核心是 Agent 类,它是创建能够理解并执行指令的 AI 系统的主要接口。下面我们来探索如何为不同场景创建与配置智能体。

在该 SDK 中,一个智能体代表一个能够遵循指令,并可选地使用工具完成任务的 AI 系统。创建一个基础智能体只需几个关键参数:

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
)

智能体的三个主要组成部分是:

  1. 名称(Name):用于标识智能体,便于日志与调试
  2. 指令(Instructions):定义智能体行为与目标的核心“系统提示”
  3. 模型(Model):支撑智能体的底层语言模型(默认为 GPT-4o)

虽然这一基础配置已足以开始,但 Agent 类还提供了若干模型配置项,可让您更好地控制 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 参数或许是智能体设计中最重要的部分。它相当于引导智能体行为、语气与能力的“系统提示”。撰写高效的指令既是艺术,也是科学:

撰写指令的最佳实践

  1. 具体明确:清晰定义智能体的角色、风格与限制
  2. 设定边界:明确说明智能体应避免的话题或行为
  3. 定义交互模式:解释智能体应如何处理不同类型的输入
  4. 建立知识边界:阐明智能体应了解的范围,以及何时应承认不确定性

Agent 还包含一个 description 参数,即面向人的可读描述,用于当智能体在工具/交接中被调用时。

配置选项

除了指令之外,您还可通过多项配置参数细化智能体行为:

  • temperature:控制响应随机性(0.0–2.0)
    • 较低数值(0.1–0.4)产生更确定、聚焦的响应
    • 较高数值(0.7–1.0)带来更有创意、更多样的输出
  • max_tokens:限制智能体响应长度
    • 有助于确保输出简洁或控制成本
    • 默认值因模型而异,但通常足以覆盖大多数用例
  • model:选择底层 LLM
    • “gpt-4o”在大多数用例下提供最佳性能
    • “gpt-4o-mini”在性能与成本间取得良好平衡
    • “gpt-3.5-turbo”适用于以速度与成本为优先的较简单任务

这些配置选项为根据不同应用自定义智能体行为提供了强大框架。我们鼓励您尝试不同设置,观察其对响应的影响,并为您的特定用例找到最优配置。

Open AI Agents SKD 示例:构建专业的天气助理

现在,让我们把这些概念结合起来,构建一个实用示例:一个专业的天气信息助理。该示例展示如何创建具备清晰专业领域、能力与限制的智能体:

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

运行您的第一个智能体

创建好智能体后,您可以使用 Runner 类来运行。该类负责执行智能体任务并管理会话流程:

# 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

对于 Python 脚本,您需要使用 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())

本节我们介绍了使用 OpenAI Agents SDK 创建与运行智能体的基础。下一节,我们将通过为智能体添加工具来扩展这些概念,以显著增强其能力。

使用工具

当您为智能体配备工具时,OpenAI Agents SDK 的真正威力便展现出来。工具让智能体可以与外部系统交互、访问数据,并执行超越简单文本生成的操作。Agents SDK 支持三类主要工具:托管工具、函数工具以及“智能体即工具”。

托管工具

托管工具运行在 OpenAI 的服务器上,与语言模型并行。这些工具无需您实现复杂功能,便提供了内建能力。

WebSearchTool:构建研究助理

WebSearchTool 让您的智能体具备搜索网络以获取最新信息的能力。对于需要超出模型训练数据、涉及当前知识的任务,这尤其有价值。

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

在此示例中,我们创建了一个可以搜索网络并将信息综合成连贯摘要的研究助理。WebSearchTool 无需任何参数即可运行,但您可以按需自定义其行为:

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

user_location 参数对需要地理上下文的查询(如本地服务或区域信息)特别有用。search_context_size 参数有助于控制生成响应时参考的搜索结果数量。

函数工具

函数工具允许您用任意 Python 函数扩展智能体。这正是 Agents SDK 灵活性的体现,使其能够与任何 API、数据库或本地服务集成。

天气预报工具

让我们构建一个集成第三方天气 API 的实用示例:

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

该天气 API 函数工具在 OpenWeatherMap API 与我们的智能体之间搭起桥梁。它通过地理坐标获取实时天气数据,并将其格式化为可读报告。

代码定义了一个 WeatherInfo 数据类,用类型化字段(温度、湿度等)来组织数据,使其结构化且易于维护。@function_tool 装饰器将我们的 Python 函数转换为智能体可用的工具,并根据函数签名与文档字符串自动创建模式。

调用时,该函数会安全地从环境变量中读取 API 密钥,向 OpenWeatherMap 发起 HTTP 请求,并处理 JSON 响应。

它能安全处理如降雨量等可选字段,并将所有信息格式化为清晰的天气报告;若 API 请求失败,也会进行错误处理。这样,智能体无需理解 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]
)

运行该天气助理:

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!

该响应表明智能体已成功使用天气工具。它从提示中抽取城市名称,利用自身知识获取坐标,并将其作为 lat 与 lon 参数传给工具。

智能体即工具

Agents SDK 允许将智能体本身作为工具使用,从而构建一个由协调者管理、专家智能体协同工作的层级结构。这是在复杂工作流中非常有用的模式。

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

在这个示例中:

  1. 我们创建了两个专业智能体,各自专注于一个领域。
  2. 然后创建一个协调者智能体,可将任务委派给这些专家。
  3. 通过 .as_tool() 方法将每个专家智能体转换为工具,并指定:
  • tool_name:协调者用于引用该工具的名称。
  • tool_description:帮助协调者理解何时应使用该工具的描述。

这种模式使您能够在保持关注点分离的同时构建复杂的智能体系统。每个专家智能体都可拥有自己的工具与专业领域,而协调者负责与用户交互并将问题委派给合适的专家。

使用该效率助理:

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

工具让智能体从简单的会话助理,进化为能够在真实世界中采取有意义行动的强大系统。尽管我们已涵盖创建与使用工具的基础,但这仅是开始。有关更高级用法(包括函数工具的错误处理),请参阅官方文档。

现在我们已经了解如何为智能体配备工具,下一个挑战是处理与结构化其输出。下一节将探索处理智能体响应的技巧——从基础文本输出到复杂的结构化数据——以确保我们的应用获得所需的精确信息格式。

理解 OpenAI 智能体的输出

在使用智能体时,相较于自由文本,获取结构化信息能让应用更可靠。OpenAI Agents SDK 提供了一种简洁、内建的方式,直接从智能体获得结构化输出。

结合 Pydantic 模型的结构化输出

通过在创建智能体时指定 output_type 参数,SDK 允许您精确定义希望智能体返回的数据结构:

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]

这些模型定义了我们想要提取数据所遵循的结构。每个类代表我们希望从邮件中提取的特定信息类型。

现在,通过设置 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
)

当您指定 output_type 后,智能体将自动产生结构化数据,而非纯文本响应。这免除了手动 JSON 解析或正则提取的需要。

让我们用一封示例邮件来试试:

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

现在,处理该邮件变得更加简单,因为 SDK 负责了转换:

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

这段代码相比早先方法更加简洁,因为:

  1. 我们无需手动从响应中提取并解析 JSON。
  2. SDK 负责将智能体输出转换为我们的 Pydantic 模型。
  3. 我们可以直接访问结构化数据属性(如 result.final_output.subject)。
  4. 类型校验自动进行,确保数据符合模型。

使用不同的输出类型

output_type 参数适用于任何可被 Pydantic TypeAdapter 包装的类型:

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

结构化输出的优势

使用 output_type 参数具有多项优势:

  1. 直接集成:智能体输出可自动作为 Python 对象使用。
  2. 类型安全:SDK 确保输出符合您定义的结构。
  3. 代码更简洁:无需手动解析 JSON 或处理错误。
  4. 更佳性能:SDK 高效完成转换。
  5. IDE 友好:IDE 可为结构化输出属性提供自动补全。

通过定义清晰的数据模型并使用 output_type 参数,您的智能体可以生成应用所需的精确数据结构,从而实现无缝集成并降低代码复杂度。

下一节我们将探索智能体之间的交接,使您能够创建能协作处理复杂任务的专业智能体。这些交接可使用结构化输出,在智能体间以一致、类型安全的方式传递信息。

交接:在智能体之间委派

在复杂应用中,不同任务往往需要不同的专业领域。OpenAI Agents SDK 支持“交接”,允许一个智能体将控制权移交给另一个专业智能体。此功能在构建处理多样化用户请求的系统时尤为有用,例如客服应用中,不同智能体分别处理账单咨询、技术支持或账户管理。

创建基础交接

最简单的情况下,交接允许您连接多个智能体,使其在合适时移交控制。让我们创建一个简单的客服系统,其中分诊智能体可交接给专家:

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
)

在此示例中,我们创建了三个智能体的系统:

  • 两个拥有聚焦专业能力的专家智能体
  • 一个可将任务委派给专家的分诊智能体

注意,我们只需将专家智能体包含在分诊智能体的 handoffs 参数中。Agents SDK 会自动创建合适的交接工具,供分诊智能体在需要时调用。

来看系统的实际效果:

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

当分诊智能体收到账单问题时,它会识别出由账单智能体更适合处理,并触发交接。技术问题将交由技术智能体处理。一般问题则在其能力范围内直接回答。输出如下:

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?

自定义交接

若需对交接进行更精细控制,可使用 handoff() 函数,而不是将智能体直接传入 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."
)

输出:

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

handoff() 函数允许您:

  • 通过 on_handoff 指定自定义回调
  • 覆盖默认工具名(通常为“transfer_to_[agent_name]”)
  • 提供自定义工具描述
  • 配置输入处理(详见下文)

在交接中传递数据

有时,您希望第一个智能体在交接给另一个智能体时提供额外上下文或元数据。Agents SDK 通过 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,
       )
   ],
)

通过此设置,当客服智能体决定交接给升级处理智能体时,它会提供有关为何升级的结构化数据。系统会在将数据传递给 process_escalation 回调之前,依据 EscalationData 模型对其进行校验。

何时使用交接 vs. 智能体即工具

Agents SDK 提供了两种让智能体协作的方式:交接与“智能体即工具”(上一节已展示)。何时使用各自方式:

在以下情况下使用交接:

  • 您希望将控制权完全移交给另一个智能体
  • 需要由专家继续对话
  • 您在构建不同阶段由不同智能体处理的工作流

在以下情况下使用“智能体即工具”:

  • 主智能体需要咨询专家但保持控制权
  • 您希望将专家的回复纳入更大的答案中
  • 您在构建由协调者分配子任务的层级系统

在复杂系统中,两种方式也可结合:主智能体有时咨询专家(将其作为工具使用),而在合适情况下则完全交接控制权。

交接为构建由不同专家分工协作、职责可平滑转移的复杂智能体系统提供了强大机制。在设计您的智能体架构时,请权衡哪种方式更契合您的具体用例,以打造最佳的用户体验。

结语与后续学习

我们探索了 OpenAI Agents SDK 的核心组件:从创建基础智能体,到实现函数工具,再到在专业智能体间进行交接。我们看到借助 Pydantic 模型的结构化输出如何让应用更可靠、更易维护,以及如何通过委派与专业化设计出能够处理复杂任务的智能体系统。

然而,这只是这个强大框架的冰山一角。若您准备将智能体系统提升到新水平,还有多个高级主题等待探索: 流式响应用于实时更新, 跟踪与可观测性用于调试, 多智能体编排用于复杂工作流, 上下文管理用于维持会话状态,以及 护栏用于确保智能体行为安全且恰当。

随着 AI 智能体日益成为现代应用的核心,您通过本教程所培养的技能为构建复杂 AI 系统奠定了坚实基础。继续您的学习旅程,参考诸如 DataCamp 的 AI 学习指南等资源。请记住,有效的智能体设计既是科学,也是艺术——需要不断迭代、测试,并深入理解用户需求与 AI 能力。

OpenAI Agents SDK 常见问答

什么是 OpenAI Agents SDK?

OpenAI Agents SDK 是一个 Python 框架,帮助开发者构建能够做出决策并采取行动的 AI 应用。它将大型语言模型与工具和协作能力相结合,使您能够创建能够自主解决复杂问题的系统,而不仅仅是对查询做出回应。

SDK 中智能体可以使用哪些类型的工具?

该 SDK 支持三类主要工具:托管工具(如在 OpenAI 服务器上运行的 WebSearchTool)、函数工具(扩展智能体能力的自定义 Python 函数),以及智能体即工具(将专业智能体作为其他智能体的工具)。这些工具使智能体能够执行如网页搜索、访问 API 或委派给专业智能体等操作。

Agents SDK 中的结构化输出如何工作?

结构化输出使用 Pydantic 模型来精确定义您希望智能体返回的数据结构。通过在创建智能体时设置 output_type 参数,您将收到格式规范的数据对象,而非自由文本。这让应用更可靠,并免除了手动解析智能体响应的需求。

交接与“智能体即工具”有何区别?

交接会将控制权完全移交给另一位智能体,适用于需要由专家继续对话的场景。智能体即工具允许主智能体在保持控制权的同时咨询专家,并将专家的回复整合为更大的答案。交接更适合工作流的阶段性转换,而智能体即工具更适用于层级系统。

OpenAI Agents SDK 还提供了哪些高级功能?

除核心功能外,SDK 还提供流式传输以实现实时更新、用于调试与可观测性的跟踪、多智能体编排以支持复杂工作流、用于维护会话状态的上下文管理,以及用于确保智能体行为安全的护栏。这些功能帮助开发者构建复杂、可用于生产的智能体系统。


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

我是一名数据科学内容创作者,拥有超过 2 年的经验,并在 Medium 上拥有较大的读者群。我喜欢用略带讽刺的笔调撰写有关 AI 和机器学习的深度文章——毕竟总得想点办法让这些内容不那么枯燥。我已发表 130 多篇文章,并制作了一门 DataCamp 课程,另有一门正在筹备中。我的内容已被超过 500 万人次阅读,其中有 2 万人在 Medium 和 LinkedIn 上成为关注者。 

主题
AI 代理
OpenAI
人工智能

DataCamp 热门课程

课程

使用 OpenAI API

3 小时
179.8K
用 OpenAI API 开始开发 AI 驱动的应用。 了解支撑 ChatGPT 等热门 AI 应用的功能。
查看详情Right Arrow
开始课程
查看更多Right Arrow