OpenAI 官方 Agents SDK:Agent、Runner、handoffs、guardrails 与内置 tracing。
OpenAI Agents SDK 是轻量的多 Agent 工作流框架,核心对象是 Agent 和 Runner。Agent 声明 instructions、tools、handoffs、output_type;Runner 负责循环调用模型、执行工具、处理 handoff,直到得到最终输出。它支持 function tools、hosted tools、MCP、sessions 和 structured outputs。
Handoff 与“Agent 作为工具”不同:handoff 把控制权转给另一个 Agent,仍在同一次 run 内;agents-as-tools 让主 Agent 调用子 Agent 并拿回结果。Guardrails 分输入和输出:输入 guardrail 只在首个 Agent 上运行,输出 guardrail 只在最终产出上运行,触发 tripwire 会抛异常。Tracing 默认开启,会把运行数据发送到 OpenAI 平台,隐私场景必须关闭或脱敏。
它适合以 OpenAI 模型为主、需要 handoff/guardrail/tracing 的多 Agent 应用。Pydantic AI 更强调 provider 无关和 Pydantic 类型;LangGraph 更偏底层图编排和持久化;smolagents 更轻量,CodeAgent 直接执行代码。模型和 API 细节以当前版本文档为准。
安装 SDK 并配置 key:
pip install -U openai-agents
export OPENAI_API_KEY="sk-..."
最小 Agent 用 Runner.run_sync 执行,final_output 是最终文本:
from agents import Agent, Runner
agent = Agent(name="assistant", instructions="用一句话回答,不要寒暄。")
result = Runner.run_sync(agent, "什么是 OOMKilled?")
print(result.final_output)
用 @function_tool 定义工具,参数注解和 docstring 会生成 schema:
from agents import Agent, Runner, function_tool
@function_tool
def disk_free(path: str) -> int:
"""返回指定路径的可用字节数。
Args:
path: 要检查的目录路径。
"""
import shutil
return shutil.disk_usage(path).free
agent = Agent(name="ops", instructions="需要时调用工具", tools=[disk_free])
print(Runner.run_sync(agent, "根分区还剩多少空间?").final_output)
用 handoff 把控制权转给专门 Agent;接收方会看到对话历史:
from agents import Agent, Runner
billing = Agent(name="billing", instructions="只处理账单和退款问题。")
triage = Agent(name="triage", instructions="无法处理时转给 billing。", handoffs=[billing])
result = Runner.run_sync(triage, "我要申请退款")
print(result.final_output)
输入 guardrail 在首个 Agent 上检查,触发时抛 tripwire 异常:
from agents import Agent, GuardrailFunctionOutput, RunContextWrapper, input_guardrail
@input_guardrail
async def no_secrets(ctx: RunContextWrapper[None], agent: Agent, user_input):
text = str(user_input)
return GuardrailFunctionOutput(output_info=None, tripwire_triggered="sk-" in text)
agent = Agent(name="safe", instructions="正常回答", input_guardrails=[no_secrets])
捕获 tripwire,把它转换成业务错误而不是 500:
from agents import InputGuardrailTripwireTriggered, Runner
try:
Runner.run_sync(agent, "我的 key 是 sk-123")
except InputGuardrailTripwireTriggered:
print("请求包含敏感凭据,已拒绝")
用 trace() 给一次业务流程加名字,便于在追踪平台里检索:
from agents import Runner, trace
with trace("checkout-flow"):
result = Runner.run_sync(agent, "帮我查订单状态")
print(result.final_output)
不需要平台追踪时用环境变量彻底关闭,避免数据外发:
export OPENAI_AGENTS_DISABLE_TRACING=1
run_in_parallel=False。InputGuardrailTripwireTriggered 和 OutputGuardrailTripwireTriggered。OPENAI_AGENTS_DISABLE_TRACING=1、set_tracing_disabled(True) 或 RunConfig(tracing_disabled=True) 关闭,并检查敏感字段。OpenAIChatCompletionsModel 和 set_default_openai_api("chat_completions")。failure_error_function=None。run_sync 会阻塞事件循环;用 await Runner.run(...),并给工具和模型调用设置超时。max_turns 限制并记录每个 Agent 的调用。OPENAI_AGENTS_DISABLE_TRACING=1、调用 set_tracing_disabled(True),或在单次 run 上传 RunConfig(tracing_disabled=True);还需避免在日志和工具参数中写入敏感数据。