原厂 SDK 01:OpenAI Agents SDK——Agent 声明、Tool 注册与原生 Handoff 机制

原厂 SDK 01:OpenAI Agents SDK——Agent 声明、Tool 注册与原生 Handoff 机制
Asaakii在过去,如果直接使用 OpenAI 的基础 SDK(openai 包)构建 Agent,开发者必须手动维护一套繁琐的外层逻辑:发起 Chat Completions 请求、判断模型是否返回了 tool_calls、根据名称分发执行本地函数、将工具执行结果构造为 tool 角色的消息追加到历史数组中,再发起下一轮模型调用,直到模型输出普通文本。
这套逻辑每个团队都要重复写一遍。OpenAI 推出的官方开源库 Agents SDK(openai-agents)正是官方针对这一模式给出的轻量运行时方案。它在基础 API 之上增加了一层面向智能体的抽象,同时又比 LangChain 这类通用框架轻巧得多。
安装与快速启动
Agents SDK 作为一个独立的包进行分发:
1 | pip install openai-agents |
运行时通过读取标准环境变量完成鉴权:
1 | export OPENAI_API_KEY="sk-..." |
核心架构三大原语
Agents SDK 的设计非常精炼,核心运行时围绕三个对象展开:
| 对象 | 运行时角色 | 职责说明 |
|---|---|---|
Agent |
静态行为配置 | 声明智能体的标识、系统指令(instructions)、基底模型、挂载工具以及允许转交的目标 Agent |
Tool |
能力单元 | 被包装的本地 Python 函数,携带自动生成的 JSON Schema |
Runner |
动态执行驱动 | 负责驱动模型交互与工具调用的完整闭环,直到达成终止状态 |
这三者的交互关系非常直观:
flowchart TD
Config["配置定义: Agent + Tools + Handoffs"] --> Runner["Runner 执行器"]
InputUser(["用户输入"]) --> Runner
subgraph ExecutionLoop ["Runner 自动维护的内部闭环"]
MCall["模型推理调用"] --> Check{"判断返回"}
Check -- "触发工具" --> LocalExec["执行本地函数"]
LocalExec --> AppendHist["自动组装并追加消息"]
AppendHist --> MCall
Check -- "触发 Handoff" --> SwitchAgent["切换活动 Agent 上下文"]
SwitchAgent --> MCall
end
Runner --> ExecutionLoop
Check -- "完成回答" --> Result(["返回 RunResult"])
最小运行示例
通过 Runner.run_sync 可以用同步方式驱动一个最基础的对话 Agent:
1 | from agents import Agent, Runner |
对于基于 FastAPI 或 Tornado 搭建的异步微服务,改用 await Runner.run(...) 即可。
工具注册与 Schema 自动推导
在基础 API 中,开发者需要手写复杂的 JSON Schema 来描述函数参数。而在 Agents SDK 中,使用 @function_tool 装饰器即可完成自动提取:
1 | from agents import Agent, Runner, function_tool |
工具声明的工程规范
SDK 在底层通过 Python 的 inspect 模块分析函数的签名和类型注解:
- 参数必须具备类型注解:如
cluster_id: str,缺少注解会导致模型无法确定参数类型; - 文档字符串(docstring)就是模型的指令输入:docstring 会被完整提取为工具描述,如果注释模糊不清,模型调用工具的参数准确率就会大幅下滑。
强类型结构化输出(Structured Outputs)
在很多自动化管线中,我们不希望 Agent 返回自由文本,而是需要符合 Schema 的结构化对象。在 Agent 中传入 output_type 并绑定 Pydantic 模型,可以保证输出类型的确定性:
1 | from pydantic import BaseModel, Field |
原生多 Agent 协作:Handoff 机制
多 Agent 协同通常有两种模式:
- 委托模式(Sub-agent Call):主 Agent 将子 Agent 当成普通工具调用,等待子 Agent 返回结果后主 Agent 继续回复;
- 转交模式(Handoff):主 Agent 判定当前任务不属于自己范畴,直接将整个控制权与对话历史移交给目标 Agent,由目标 Agent 直接对接后续处理。
Agents SDK 的核心卖点就是原生支持 Handoff。
以客服智能分诊系统为例:
flowchart TD
User(["用户请求"]) --> Triage["分诊 Agent (triage_agent)"]
Triage --> Decision{"意图分流判定"}
Decision -- "技术故障" --> TechAgent["技术支持 Agent (tech_agent)"]
Decision -- "账单与发票" --> BillingAgent["财务账单 Agent (billing_agent)"]
TechAgent --> TechOut(["技术专员完成解答并交付"])
BillingAgent --> BillOut(["财务专员完成解答并交付"])
代码实现
1 | from agents import Agent, Runner |
当模型判断需要转交时,SDK 会自动构建一个特殊的转移调用,将活动指针切换到目标 Agent,无需编写复杂的路由器代码。
流式输出与运行结果检查
在对响应时延敏感的终端界面,可以通过 Runner.run_streamed 消费异步事件流:
1 | import asyncio |
运行完成后,result 对象提供了一组检查字段用于排错审计:
1 | # result 字段清单 |
适用场景与工程局限
适用场景
- 职责清晰的客服/企业级多智能体分诊系统:Handoff 机制让工单流转逻辑非常干净;
- 轻量级单任务 Agent:免去手写 Tool 循环的代码噪音;
- 已有业务全量运行在 OpenAI 生态中。
工程局限
- 厂商强绑定:目前该 SDK 深度契合 OpenAI 消息格式与模型行为,难以原生桥接其它第三方或本地部署的模型;
- 缺乏显式状态机拓扑:对于需要复杂有向无环图(DAG)、并行分支聚合(Fan-out/Fan-in)或复杂自旋重试的场景,SDK 的配置式抽象不如 LangGraph 这类专门的状态机框架灵活;
- 中间黑盒感强:Runner 内部的重试策略和状态流转不易打断,难以插入细粒度的自定义持久化 Checkpoint。
下一篇我们将剖析 Google 全新统一的 google-genai SDK,看看它是如何用一套 API 兼顾开发者生态与企业级多模型后端的。











