Agents SDK
学习如何使用 OpenAI 构建智能代理。
欢迎使用 OpenAI Agents SDK。本库可助您轻松构建智能代理应用——让大型语言模型(LLM)能够利用额外上下文和工具,可能将任务转交给其他专业代理,流式传输部分结果,并完整记录执行轨迹。
以下为全面概览。通过本指南,您将深入理解核心概念、最佳实践,以及如何将所有元素组织成结构化的代理工作流。
下载与安装
访问最新版 Agents SDK GitHub 仓库。
快速链接
• 核心概念 • 代理 • 工具 • 上下文 • 输出类型 • 任务转交 • 流式传输 • 执行跟踪 • 安全护栏 • 综合应用 • 最佳实践 • 后续步骤
核心概念
Agents SDK 围绕以下核心组件设计:
组件 | 功能描述 |
---|---|
代理 | 配置了指令、工具、转接机制和安全护栏的 LLM |
工具 | 代理可调用的外部功能(如 API 接口、计算、文件访问) |
上下文 | 可创建并传递的可变对象,用于存储状态或共享资源 |
输出类型 | 允许指定结构化最终输出(默认支持自由文本格式) |
任务转交 | 将会话委托或切换至其他代理的机制 |
流式传输 | 在代理思考或调用工具时实时输出增量事件(适用于实时 UI 场景) |
执行跟踪 | 自动记录每次"代理运行"的详细轨迹,便于调试、分析或存档 |
安全护栏 | 验证输入输出、检查策略或在异常时终止执行 |
通过组合这些组件,您可以创建强大的多步骤对话工作流,确保结果正确可验证,必要时可分解任务或通过安全护栏调用专业子代理,实现流式传输或结构化输出。
代理
代理封装了大型语言模型(LLM)及其所有配置,包括系统指令、可用工具和转接目标。还可包含输入输出验证的安全护栏及高级模型设置。
核心思想
代理本质上是具备以下功能的 LLM:
• 指令系统(静态提示或动态生成) • 可调用的工具集 • 转接机制(委托其他代理) • 可选的输入输出安全护栏 • 附加设置(如模型参数、输出类型、回调函数)
调用代理处理用户输入时,会启动代理循环:
- 代理获取当前会话上下文(包含用户输入、历史工具结果、系统消息)
- LLM 决策选择: • 生成最终答案(结束循环) • 调用工具(可能连续多次) • 转接至其他代理
- 当代理生成最终答案(或转接)后循环终止
示例:基础代理
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
: 代理的简短标识符
• instructions
或 instructions_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"])
底层流程:
- LLM 获取当前会话(包含用户输入、系统消息、历史工具输出)
- LLM 可能生成最终回复、调用工具或触发转接
- 若调用工具,结果将反馈至会话,循环直至生成最终消息或转接
- 使用结构化输出时(如 Pydantic 模型),代理必须调用特殊
final_output
工具生成有效 JSON,否则触发ModelBehaviorError
- 框架内置
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 账单查询)。
高层流程
- 主控(或"分流")代理可见多个子代理转接目标
- 主代理决定调用特定子代理的"转接工具"
- 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=true
• AGENT_LIFECYCLE=true
• TOOL_DEBUG=true
若需自定义处理跟踪记录,可实现 TracingProcessor
并通过 add_trace_processor
或 set_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 核心要点:
- 代理定义 LLM 特性与能力(工具、转接、护栏)
- 工具为 LLM 提供外部功能接口
- 上下文实现步骤间数据共享
- 输出类型确保结构化或自由格式输出
- 任务转交支持委托专业代理
- 流式传输提供增量输出事件
- 执行跟踪记录完整运行轨迹
- 安全护栏保障策略合规与使用限制
祝您使用 Agents SDK 开发愉快!