OpenAI Agents SDK

16 阅读11分钟

Agents SDK

学习如何使用 OpenAI 构建智能代理。

欢迎使用 OpenAI Agents SDK。本库可助您轻松构建智能代理应用——让大型语言模型(LLM)能够利用额外上下文和工具,可能将任务转交给其他专业代理,流式传输部分结果,并完整记录执行轨迹。

以下为全面概览。通过本指南,您将深入理解核心概念、最佳实践,以及如何将所有元素组织成结构化的代理工作流。

下载与安装

访问最新版 Agents SDK GitHub 仓库


快速链接

核心概念代理工具上下文输出类型任务转交流式传输执行跟踪安全护栏综合应用最佳实践后续步骤


核心概念

Agents SDK 围绕以下核心组件设计:

组件功能描述
代理配置了指令、工具、转接机制和安全护栏的 LLM
工具代理可调用的外部功能(如 API 接口、计算、文件访问)
上下文可创建并传递的可变对象,用于存储状态或共享资源
输出类型允许指定结构化最终输出(默认支持自由文本格式)
任务转交将会话委托或切换至其他代理的机制
流式传输在代理思考或调用工具时实时输出增量事件(适用于实时 UI 场景)
执行跟踪自动记录每次"代理运行"的详细轨迹,便于调试、分析或存档
安全护栏验证输入输出、检查策略或在异常时终止执行

通过组合这些组件,您可以创建强大的多步骤对话工作流,确保结果正确可验证,必要时可分解任务或通过安全护栏调用专业子代理,实现流式传输或结构化输出。


代理

代理封装了大型语言模型(LLM)及其所有配置,包括系统指令、可用工具和转接目标。还可包含输入输出验证的安全护栏及高级模型设置。

核心思想

代理本质上是具备以下功能的 LLM:

指令系统(静态提示或动态生成) • 可调用的工具集转接机制(委托其他代理) • 可选的输入输出安全护栏附加设置(如模型参数、输出类型、回调函数)

调用代理处理用户输入时,会启动代理循环

  1. 代理获取当前会话上下文(包含用户输入、历史工具结果、系统消息)
  2. LLM 决策选择: • 生成最终答案(结束循环) • 调用工具(可能连续多次) • 转接至其他代理
  3. 当代理生成最终答案(或转接)后循环终止

示例:基础代理

from agents import Agent, AgentRunner

agent = Agent(
name="basic_agent",
instructions="You are a helpful agent."
)

result = await AgentRunner.run(agent, ["What's the capital of the USA?"])
print(result.agent_output)
# The capital of the United States is Washington, D.C.

代理字段

name: 代理的简短标识符 • instructionsinstructions_function: • instructions: 描述代理行为的静态字符串 • instructions_function: 返回指令字符串的动态函数 • description: 说明代理角色(常用于展示子代理/工具信息) • tools: 代理可调用的外部函数(工具)列表 • handoffs: 可转接的目标代理列表 • model_settings: LLM 使用参数(模型类型、温度系数等) • output_type: 默认输出为字符串,可指定结构化输出 • context_type: 设置上下文对象的 Python 类型(见上下文

创建或克隆代理
from agents import Agent

# 基础创建
my_agent = Agent(
    name="my_agent",
    instructions="You are extremely friendly and helpful."
)

# 克隆并修改
new_agent = my_agent.clone(
    name="my_new_agent",
    instructions="Now you're more formal."
)

代理循环

当执行以下代码时:

final_result = await AgentRunner.run(agent, ["some user input"])

底层流程:

  1. LLM 获取当前会话(包含用户输入、系统消息、历史工具输出)
  2. LLM 可能生成最终回复、调用工具或触发转接
  3. 若调用工具,结果将反馈至会话,循环直至生成最终消息或转接
  4. 使用结构化输出时(如 Pydantic 模型),代理必须调用特殊 final_output 工具生成有效 JSON,否则触发 ModelBehaviorError
  5. 框架内置 max_turns 安全机制防止死循环

工具

工具使代理能够调用外部函数(如访问 API、运行代码、执行搜索)。通过将 Python 函数暴露为工具,LLM 可在运行时决定调用参数并获取结果。

定义工具

使用 @function_tool 装饰器(或 function_tool(...))定义工具:

创建天气查询工具

from agents.tool import function_tool

@function_tool
def get_weather(location: str, unit: str = "C") -> str:
  """
  Fetch the weather for a given location, returning a short description.
  """
  # 示例逻辑
  return f"The weather in {location} is 22 degrees {unit}."

将工具附加至代理:

agent.tools.append(get_weather)

• 工具支持同步/异步调用 • 可选将上下文类型作为首个参数(见下文) • 代理通过工具名称识别,需传入有效 JSON 参数调用

常见模式

• 数学计算、网络请求、数据查询、专业计算等工具 • 需要时可记录或存储数据至系统 • 工具较多时建议使用明确指令指导 LLM 选择


上下文

当需要跨工具调用或多步骤保持会话数据、凭证或临时状态时,可使用 context 对象传递上下文信息。

• 可创建任意 Python 类作为上下文,或使用 Agent(context_type=MyContext) 类型化方案 • 工具可访问并更新上下文数据

使用上下文管理用户会话

from agents.run_context import AgentContextWrapper
from agents.tool import function_tool

class MyContext:
  def __init__(self, user_id: str):
      self.user_id = user_id
      self.seen_messages = []

@function_tool
def greet_user(context: AgentContextWrapper[MyContext], greeting: str) -> str:
  user_id = context.agent_context.user_id
  return f"Hello {user_id}, you said: {greeting}"

agent = Agent(
  name="my_agent_with_context",
  context_type=MyContext,
  tools=[greet_user],
)

my_ctx = MyContext(user_id="alice")
result = await AgentRunner.run(
  agent,
  input=["Hi agent!"],
  context=my_ctx,
)

此例中,greet_user 工具可访问 context.agent_context.user_id。通过此模式可存储状态、计数器或共享资源,对复杂推理或多步骤工具调用至关重要。


输出类型

代理可生成自由文本(默认)或结构化输出。

默认(字符串)输出

默认情况下,代理的最终输出为未调用工具时生成的文本消息,生成后运行终止。

agent = Agent(
    name="StringOutputAgent",
    instructions="Always provide final answers as text, never a tool."
)
out = await AgentRunner.run(agent, ["Summarize thermodynamics"])
print(out.agent_output)
# "Thermodynamics is the study of heat, energy, and work..."

结构化输出

设置 output_type 可强制代理生成符合 Python(通常为 Pydantic)模式的 JSON 对象。LLM 需调用特殊 final_output 工具进行验证。

使用 Pydantic 的结构化输出

from pydantic import BaseModel
from agents import Agent, AgentRunner

class WeatherAnswer(BaseModel):
  location: str
  temperature_c: float
  summary: str

agent = Agent(
  name="StructuredWeatherAgent",
  instructions="Use the final_output tool with WeatherAnswer schema.",
  output_type=WeatherAnswer,
)

out = await AgentRunner.run(agent, ["What's the temperature in Paris?"])
print(type(out.agent_output))
# <class '__main__.WeatherAnswer'>
print(out.agent_output.temperature_c)
# e.g. 22.0

若 LLM 返回无效 JSON,运行将报错,确保最终数据合法有效。


任务转交

任务转交允许代理将会话转交给其他代理,适用于多专业代理场景(如"西班牙语专用代理"与"英语专用代理")或领域区分(技术支持 vs 账单查询)。

高层流程

  1. 主控(或"分流")代理可见多个子代理转接目标
  2. 主代理决定调用特定子代理的"转接工具"
  3. SDK 切换至子代理处理后续步骤,直至其完成或继续转交

转接示例

from agents import Agent, AgentRunner, handoff

spanish_agent = Agent(name="spanish_agent", instructions="You only speak Spanish.")
english_agent = Agent(name="english_agent", instructions="You only speak English.")

triage_agent = Agent(
  name="triage_agent",
  instructions="Handoff to the appropriate agent based on language.",
  handoffs=[spanish_agent, english_agent],
)

out = await AgentRunner.run(triage_agent, ["Hola, ¿cómo estás?"])
# 会话转交至 spanish_agent
# 最终响应为西班牙语

后台机制:

• 每个子代理被封装为 handoff(...) 对象,暴露类似 "handoff_spanish_agent" 的工具 • 主代理调用该工具时,SDK 将激活代理切换至 spanish_agent

转接输入与过滤

可定义新代理的输入参数,或过滤传递的会话历史。例如限制子代理可见的上下文量,或在回调中存储信息。


流式传输

流式传输用于需要增量输出的实时场景。使用 AgentRunner.run_streamed(...) 获取异步事件迭代器。

流式传输示例

from agents import Agent, AgentRunner

stream = AgentRunner.run_streamed(agent, ["Tell me a story"])

async for event in stream.stream_events():
  # event.delta 通常包含增量文本或函数调用信息
  print(event.delta, end="", flush=True)
print("\n--- done ---")

事件可能包含:

• 部分文本响应 • 工具调用参数增量 • 最终答案生成标识

代理在流式传输中仍可调用多个工具、生成部分消息或执行转接。


执行跟踪

执行跟踪自动记录代理运行的每个步骤:用户消息、系统提示、工具调用、函数输入输出及最终响应。这对调试、分析或保存会话记录至关重要。

• 默认调用 AgentRunner.run(...) 时执行 trace(name="agent_run") • 可通过 AgentRunConfig 或环境变量自定义/禁用跟踪: • LLM_DEBUG=trueAGENT_LIFECYCLE=trueTOOL_DEBUG=true

若需自定义处理跟踪记录,可实现 TracingProcessor 并通过 add_trace_processorset_trace_processors([...]) 注册。

配置示例:

from agents import AgentRunner, AgentRunConfig

config = AgentRunConfig(
    run_name="CustomerSupportFlow",
    tracing_disabled=False,
    trace_non_openai_generations=True,
)

result = await AgentRunner.run(my_agent, ["Hello?"], run_config=config)

安全护栏

安全护栏用于实施代理输入输出的策略,如阻止禁用内容或验证数据完整性。若触发护栏,运行将立即终止或抛出异常。

配置护栏

from agents.guardrails import CustomGuardrail

async def is_not_swearing(msgs, context) -> bool:
    content = " ".join(m["content"] for m in msgs if "content" in m)
    return "badword" not in content.lower()

my_guardrail = CustomGuardrail(
    guardrail_function=is_not_swearing,
    tripwire_config=lambda output: not output  # 若返回 'False' 则触发错误
)

agent = Agent(
    name="my_agent",
    input_guardrails=[my_guardrail]
)

out = await AgentRunner.run(agent, ["some text"])
# 若输入含 "badword" 将触发 GuardrailTripwireTriggered 异常

也可使用基于 LLM 的护栏实施 AI 驱动的策略检查。护栏可应用于输入、输出或中间步骤,根据需求灵活配置。


综合应用

以下示例演示多项功能的整合:指令系统、工具调用、任务转交、结构化输出和运行配置。可根据需要添加流式传输或执行跟踪。

多代理工作流示例

from agents import Agent, AgentRunner, AgentRunConfig, handoff
from agents.tool import function_tool
from pydantic import BaseModel

class StructuredAnswer(BaseModel):
  decision: str
  reasoning: str

@function_tool
def get_forecast(city: str) -> str:
  return f"The forecast in {city} is sunny."

spanish_agent = Agent(name="spanish_agent", instructions="You only speak Spanish.")
english_agent = Agent(name="english_agent", instructions="You only speak English.")

triage_agent = Agent(
  name="triage_agent",
  instructions="Switch to Spanish if user uses Spanish, otherwise English.",
  tools=[get_forecast],
  handoffs=[handoff(spanish_agent), handoff(english_agent)],
  output_type=StructuredAnswer,
)

config = AgentRunConfig(run_name="multilingual_weather_run")
output = await AgentRunner.run(
  triage_agent, 
  ["Hola, ¿qué tiempo hace en Madrid?"], 
  run_config=config
)

print(output.agent_output)
# => StructuredAnswer(decision='Spanish agent used', reasoning='Detected Spanish phrase')

综合代码示例


from agents import Agent, AgentRunner, handoff
from agents.tool import function_tool
from pydantic import BaseModel

class WeatherResponse(BaseModel):
    location: str
    forecast: str

@function_tool
def get_forecast(city: str) -> str:
    return f"{city} is sunny."

spanish_agent = Agent(name="spanish_agent", instructions="Respond only in Spanish.")
english_agent = Agent(name="english_agent", instructions="Respond only in English.")

triage_agent = Agent(
    name="triage_agent",
    instructions="Use language detection to hand off appropriately.",
    tools=[get_forecast],
    handoffs=[handoff(spanish_agent), handoff(english_agent)],
    output_type=WeatherResponse,
)

config = AgentRunConfig(run_name="weather_check")
output = await AgentRunner.run(
    triage_agent,
    ["Hola, clima en Madrid?"],
    run_config=config
)

print(output.agent_output)
# WeatherResponse(location='Madrid', forecast='Madrid is sunny.')

最佳实践

详细说明函数模式 以便 LLM 正确调用工具 • 使用严格模式校验(如 Pydantic 模型)避免参数错误 • 根据领域需求设置安全护栏,如内容过滤、用量配额或数据验证 • 复杂流程中启用完整执行跟踪,调试日志或自定义跟踪处理器至关重要 • 涉及多领域或多语言时考虑使用任务转交至专业子代理


后续步骤

• 参考我们的示例目录获取典型用例: • 对话代理:配备工具的标准问答助手 • 多步推理:迭代使用多个工具的代理 • 任务转交:转接至专业子代理 • 护栏应用:实施自定义策略检查 • 跟踪进阶:优化跟踪存储或禁用设置 • 查阅代码文档字符串获取深层细节

OpenAI Agents SDK 核心要点:

  1. 代理定义 LLM 特性与能力(工具、转接、护栏)
  2. 工具为 LLM 提供外部功能接口
  3. 上下文实现步骤间数据共享
  4. 输出类型确保结构化或自由格式输出
  5. 任务转交支持委托专业代理
  6. 流式传输提供增量输出事件
  7. 执行跟踪记录完整运行轨迹
  8. 安全护栏保障策略合规与使用限制

祝您使用 Agents SDK 开发愉快!