OpenAI Agents SDK:Handoffs、Guardrails、Tracing
OpenAI Agents SDK 是建在 Responses API 之上的轻量多 agent 框架。五个原语:Agent、Handoff、Guardrail、Session、Tracing。Handoff 是名为
transfer_to_<agent>的工具。Guardrail 在输入或输出上触发。Tracing 默认开启。
类型: Learn + Build 语言: Python(标准库) 前置要求: 阶段 14 · 01(Agent 循环)、阶段 14 · 06(工具使用) 预计时间: ~75 分钟
学习目标
- 说出 OpenAI Agents SDK 的五个原语。
- 解释 handoff:为什么把它建模成工具、模型看到什么样的名称形态、上下文如何传递。
- 区分输入 guardrail、输出 guardrail 和工具 guardrail;解释
run_in_parallelvs 阻塞模式。 - 用标准库实现一个运行时,带 handoff + guardrail + span 式 tracing。
问题背景
不能干净委派的 agent 最后会把一切都塞进一个 prompt。没有 guardrail 的 agent 会泄露 PII、产出违反策略的内容,或者永远循环下去。OpenAI 的 SDK 把让多 agent 工作变得可控的三个原语固化下来。
核心概念
五个原语
- Agent。 LLM + 指令 + 工具 + handoff。
- Handoff。 委派给另一个 agent。对模型表现为一个名为
transfer_to_<agent_name>的工具。 - Guardrail。 在输入(仅第一个 agent)、输出(仅最后一个 agent)或工具调用(每个函数工具)上做校验。
- Session。 跨轮次的自动对话历史。
- Tracing。 为 LLM 生成、工具调用、handoff、guardrail 内置的 span。
把 handoff 当工具
模型在它的工具列表里看到 transfer_to_billing_agent。调用它向运行时发出信号去:
- 复制对话上下文(或通过
nest_handoff_historybeta 把它折叠)。 - 用目标 agent 的指令初始化它。
- 用目标 agent 继续这次运行。
这就是 supervisor 模式(第 13 课 / 第 28 课)的产品化。
Guardrail
三种口味:
- 输入 guardrail。 跑在第一个 agent 的输入上。在任何 LLM 调用之前拒绝不安全或超范围的请求。
- 输出 guardrail。 跑在最后一个 agent 的输出上。抓 PII 泄露、策略违规、格式错误的响应。
- 工具 guardrail。 按函数工具跑。校验参数、检查权限、审计执行。
模式:
- 并行(默认)。guardrail LLM 与主 LLM 并排跑。尾延迟更低。若被触发,主 LLM 的工作被丢弃(浪费 token)。
- 阻塞(
run_in_parallel=False)。guardrail LLM 先跑。若被触发,不在主调用上浪费 token。
触发线抛出 InputGuardrailTripwireTriggered / OutputGuardrailTripwireTriggered。
Tracing
默认开启。每次 LLM 生成、工具调用、handoff 和 guardrail 都发出一个 span。OPENAI_AGENTS_DISABLE_TRACING=1 退出。add_trace_processor(processor) 把 span 在 OpenAI 之外也扇出到你自己的后端。
Session
Session 把对话历史存在一个后端里(SQLite、Redis、自定义)。Runner.run(agent, input, session=session) 自动加载并追加。
这个模式在哪里会出错
- handoff 漂移。 Agent A 交给 Agent B,B 又交回给 A。加一个跳数计数器。
- guardrail 绕过。 工具 guardrail 只在函数工具上触发;内置工具(文件读取器、网页抓取)需要单独的策略。
- 过度 tracing。 span 里有敏感内容。配 OTel GenAI 的内容捕获规则(第 23 课)—— 外部存储,按 ID 引用。
ae-agent-handoff动手构建
code/main.py 用标准库实现 SDK 的形态:
Agent、FunctionTool、Handoff(作为带转移语义的函数工具)。- 带输入/输出/工具 guardrail、handoff 分派和跳数计数器的
Runner。 - 一个简单的 span 发射器,用来展示轨迹形态。
- 一个分流 agent,基于用户查询交给 billing 或 support;guardrail 在一个输入上触发。
运行它:
python3 code/main.py轨迹展示两次成功的 handoff、一次输入 guardrail 触发,以及一棵镜像真实 SDK 所发出内容的 span 树。
实际使用
- OpenAI Agents SDK 用于 OpenAI 优先的产品。
- Claude Agent SDK(第 17 课)用于 Claude 优先的产品。
- LangGraph(第 13 课)当你想要显式状态和持久恢复时。
- 自定义 当你需要精确控制时(语音、多厂商、联邦部署)。
拿去用
outputs/skill-agents-sdk-scaffold.md 脚手架出一个 Agents SDK 应用,带分流 agent、handoff、输入/输出/工具 guardrail、session 存储和一个 trace processor。
练习
- 加一个 handoff 跳数计数器:N 次转移后拒绝。追踪行为。
- 把
nest_handoff_history实现为一个选项 —— 转移前把先前消息折叠成一段摘要。 - 写一个阻塞的输出 guardrail。对比会触发它的 prompt 与能通过的 prompt 的延迟。
- 把
add_trace_processor接到一个 JSON logger。它每个 span 发出什么形态? - 读 SDK 文档。把你的标准库玩具移植到
openai-agents-python。你哪里建模错了?
关键术语
| 术语 | 大家怎么说 | 它实际是什么 |
|---|---|---|
| Agent | 「LLM + 指令」 | SDK 里的 Agent 类型;掌管工具和 handoff |
| Handoff | 「转移」 | 模型调用来委派给另一个 agent 的工具 |
| Guardrail | 「策略检查」 | 在输入 / 输出 / 工具调用上的校验 |
| Tripwire | 「guardrail 触发」 | guardrail 拒绝时抛出的异常 |
| Session | 「历史存储」 | 在运行之间持久化的对话记忆 |
| Tracing | 「span」 | 覆盖 LLM + 工具 + handoff + guardrail 的内置可观测性 |
| Blocking guardrail | 「顺序检查」 | guardrail 先跑;触发时不浪费 token |
| Parallel guardrail | 「并发检查」 | guardrail 并排跑;延迟更低,触发时浪费 token |
延伸阅读
- OpenAI Agents SDK docs —— 原语、handoff、guardrail、tracing
- Claude Agent SDK overview —— Claude 风味的对应物
- Anthropic, Building Effective Agents —— 究竟何时该上 handoff
- OpenTelemetry GenAI semantic conventions —— Agents SDK span 映射到的标准