新鲜速递:OpenAI-Agents-Python:构建智能代理系统的轻量级框架
图片来自于官方README.md
一、什么是OpenAI Agents SDK?
OpenAI Agents SDK是一个轻量级但功能强大的框架,专为构建多智能体工作流而设计。作为OpenAI之前实验项目Swarm的生产级升级版本,该SDK提供了极少但高效的抽象概念,使开发者能够快速搭建复杂的智能应用。
该SDK的核心理念是:足够简单易学,同时又足够强大实用。它内置了智能体循环、交接机制、安全护栏和全面的追踪功能,让开发者可以专注于应用逻辑而非底层实现。
二、核心概念
OpenAI Agents SDK主要包含四个核心概念:
- 智能体(Agents):配备了指令、工具、护栏和交接功能的大语言模型(LLM)
- 交接(Handoffs):允许智能体将控制权转移给其他智能体处理特定任务
- 护栏(Guardrails):用于输入和输出验证的可配置安全检查
- 追踪(Tracing):内置的智能体运行跟踪功能,便于查看、调试和优化工作流
值得注意的是,这个SDK与任何支持OpenAI聊天补全API格式的模型提供商兼容,不仅限于OpenAI自己的模型。
三、应用场景
OpenAI Agents SDK适用于多种场景,包括但不限于:
- 客户服务自动化:创建能够理解查询并提供准确回答的智能客服系统
- 多步骤任务处理:处理需要多个步骤或专业知识的复杂任务
- 信息检索与分析:结合搜索工具和分析能力,提供基于事实的回答
- 专业领域咨询:构建在特定领域(如法律、医疗、财务等)具有专业知识的顾问系统
- 内容创建与编辑:自动化创建和编辑文本、代码或其他内容
四、基础示例解析
1. Hello World示例
from agents import Agent, Runner
agent = Agent(name="Assistant", instructions="You are a helpful assistant")
result = Runner.run_sync(agent, "Write a haiku about recursion in programming.")
print(result.final_output)
# 输出示例:
# Code within the code,
# Functions calling themselves,
# Infinite loop's dance.
这个简单示例展示了如何创建一个基本智能体并运行它。通过指定名称和指令,我们告诉智能体它的角色和行为方式。然后使用Runner.run_sync()
方法同步运行智能体并获取结果。
2. 交接(Handoffs)示例
from agents import Agent, Runner
import asyncio
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 the language of the request.",
handoffs=[spanish_agent, english_agent],
)
async def main():
result = await Runner.run(triage_agent, input="Hola, ¿cómo estás?")
print(result.final_output)
# 预期输出:¡Hola! Estoy bien, gracias por preguntar. ¿Y tú, cómo estás?
if __name__ == "__main__":
asyncio.run(main())
这个示例展示了智能体之间的交接功能。分流智能体(triage_agent)根据输入的语言决定将请求交给西班牙语或英语智能体处理。当收到西班牙语输入时,分流智能体会将请求交给西班牙语智能体处理。
3. 函数工具示例
import asyncio
from agents import Agent, Runner, function_tool
@function_tool
def get_weather(city: str) -> str:
return f"The weather in {city} is sunny."
agent = Agent(
name="Hello world",
instructions="You are a helpful agent.",
tools=[get_weather],
)
async def main():
result = await Runner.run(agent, input="What's the weather in Tokyo?")
print(result.final_output)
# 预期输出:The weather in Tokyo is sunny.
if __name__ == "__main__":
asyncio.run(main())
这个示例展示了如何为智能体添加工具函数。通过使用@function_tool
装饰器,我们可以轻松地将普通Python函数转换为智能体可调用的工具。当用户询问特定城市的天气时,智能体会自动调用相应的工具函数获取信息。
五、智能体循环机制
当调用Runner.run()
方法时,SDK会运行一个循环直到获得最终输出:
- 调用LLM,使用智能体上的模型、设置和消息历史
- LLM返回响应,可能包含工具调用
- 如果响应包含最终输出,返回并结束循环
- 如果响应包含交接,将智能体切换为新智能体并返回步骤1
- 处理工具调用(如果有)并添加工具响应消息,然后返回步骤1
可以使用max_turns
参数限制循环执行的次数。
最终输出的确定方式
最终输出是智能体在循环中产生的最后一个结果:
- 如果在智能体上设置了
output_type
,最终输出是LLM返回该类型数据时的结果(使用结构化输出) - 如果没有设置
output_type
(即纯文本响应),则第一个没有工具调用或交接的LLM响应被视为最终输出
六、高级功能
1. 护栏(Guardrails)
护栏允许你在用户输入上运行检查和验证,与智能体并行运行。例如,你可以筛选用户输入的相关性或安全性。
from pydantic import BaseModel
from agents import (
Agent,
GuardrailFunctionOutput,
InputGuardrailTripwireTriggered,
RunContextWrapper,
Runner,
TResponseInputItem,
input_guardrail,
)
class MathHomeworkOutput(BaseModel):
is_math_homework: bool
reasoning: str
guardrail_agent = Agent(
name="Guardrail check",
instructions="Check if the user is asking you to do their math homework.",
output_type=MathHomeworkOutput,
)
@input_guardrail
async def math_guardrail(
ctx: RunContextWrapper[None], agent: Agent, input: str | list[TResponseInputItem]
) -> GuardrailFunctionOutput:
result = await Runner.run(guardrail_agent, input, context=ctx.context)
return GuardrailFunctionOutput(
output_info=result.final_output,
tripwire_triggered=result.final_output.is_math_homework,
)
agent = Agent(
name="Customer support agent",
instructions="You are a customer support agent. You help customers with their questions.",
input_guardrails=[math_guardrail],
)
这个示例创建了一个数学作业检测护栏,如果用户请求解决数学作业,护栏将触发并阻止请求被处理。
2. 上下文管理
SDK支持两类上下文:
- 本地代码上下文:在工具函数运行、回调等过程中可用的数据和依赖项
- LLM上下文:LLM在生成响应时可见的数据
使用RunContextWrapper
类和其中的context
属性可以方便地管理本地上下文:
import asyncio
from dataclasses import dataclass
from agents import Agent, RunContextWrapper, Runner, function_tool
@dataclass
class UserInfo:
name: str
uid: int
@function_tool
async def fetch_user_age(wrapper: RunContextWrapper[UserInfo]) -> str:
return f"User {wrapper.context.name} is 47 years old"
async def main():
user_info = UserInfo(name="John", uid=123)
agent = Agent[UserInfo](
name="Assistant",
tools=[fetch_user_age],
)
result = await Runner.run(
starting_agent=agent,
input="What is the age of the user?",
context=user_info,
)
print(result.final_output)
# 预期输出:The user John is 47 years old.
if __name__ == "__main__":
asyncio.run(main())
3. 多智能体协调
可以通过两种主要方式协调多个智能体:
- 通过LLM决策:利用LLM的智能进行规划、推理和决策
- 通过代码协调:通过代码确定智能体的流程
常见的代码协调模式包括:
- 使用结构化输出生成格式良好的数据
- 将一个智能体的输出转换为下一个智能体的输入
- 在评估循环中运行智能体
- 并行运行多个智能体
七、实战案例:构建智能客服系统
下面是一个完整的智能客服系统示例,包含分流、专业回答和内容安全检查:
from agents import Agent, InputGuardrail, GuardrailFunctionOutput, Runner
from pydantic import BaseModel
import asyncio
class SafetyCheckOutput(BaseModel):
is_safe: bool
reasoning: str
guardrail_agent = Agent(
name="Safety check",
instructions="检查用户输入是否包含不适当内容。如果包含侮辱、威胁或其他不适当内容,请标记为不安全。",
output_type=SafetyCheckOutput,
)
billing_agent = Agent(
name="账单专家",
handoff_description="处理账单、付款和退款相关问题的专家",
instructions="你是一位账单和支付专家。帮助用户解决账单查询、支付问题和退款请求。提供清晰明确的步骤指导。",
)
technical_agent = Agent(
name="技术支持",
handoff_description="处理技术问题和故障排除的专家",
instructions="你是一位技术支持专家。帮助用户解决产品使用过程中遇到的技术问题。提供详细的故障排除步骤。",
)
async def safety_guardrail(ctx, agent, input_data):
result = await Runner.run(guardrail_agent, input_data, context=ctx.context)
final_output = result.final_output_as(SafetyCheckOutput)
return GuardrailFunctionOutput(
output_info=final_output,
tripwire_triggered=not final_output.is_safe,
)
triage_agent = Agent(
name="客服分流",
instructions="""
你是一位客服分流专家。根据用户的问题,将其转接到适当的专家:
- 如果是关于账单、付款或退款的问题,转接到账单专家
- 如果是关于产品使用或技术问题的,转接到技术支持
- 如果是简单的一般问题,直接回答
始终保持专业和友好的态度。
""",
handoffs=[billing_agent, technical_agent],
input_guardrails=[
InputGuardrail(guardrail_function=safety_guardrail),
],
)
async def main():
print("=== 场景一:账单问题 ===")
result = await Runner.run(triage_agent, "我上个月被多收费了,如何申请退款?")
print(result.final_output)
print("\n=== 场景二:技术问题 ===")
result = await Runner.run(triage_agent, "我的账户登录不了,一直显示密码错误")
print(result.final_output)
print("\n=== 场景三:一般问题 ===")
result = await Runner.run(triage_agent, "你们的客服热线是多少?")
print(result.final_output)
if __name__ == "__main__":
asyncio.run(main())
这个示例构建了一个智能客服系统,包含分流智能体、账单专家和技术支持。系统还包含内容安全检查护栏,确保用户输入不包含不适当内容。分流智能体根据用户的问题性质将请求转发给适当的专家智能体处理。
八、总结与展望
OpenAI Agents SDK提供了构建复杂智能体系统所需的基础组件,同时保持了简单易用的设计理念。通过智能体、交接、护栏和追踪这四个核心概念,开发者可以轻松构建从简单到复杂的智能应用。
该SDK的主要优势在于:
- 简单清晰的API:少量抽象概念,易于学习和掌握
- 强大的扩展性:可以自定义各个组件和行为
- 内置追踪:自动记录智能体运行情况,便于调试和优化
- 模型兼容性:支持任何遵循OpenAI API格式的模型提供商
- 生产就绪:设计用于生产环境,不仅限于原型开发
随着人工智能技术的不断发展,智能体框架将在未来发挥越来越重要的作用。OpenAI Agents SDK作为一个轻量级但功能强大的框架,为开发者提供了构建下一代智能应用的工具。
无论是构建客户服务系统、智能助手还是复杂的决策系统,OpenAI Agents SDK都能提供所需的工具和抽象,帮助开发者更快地将想法转化为现实。
参考资源
- OpenAI Agents SDK 官方文档
- GitHub 仓库
- 示例目录
要开始使用,只需通过pip安装SDK并设置OpenAI API密钥即可开始构建您的第一个智能体系统。
pip install openai-agents
export OPENAI_API_KEY=sk-... # 替换为您的API密钥