全书目录

第九编 框架层

第 44 章 OpenAI Agents SDK:把运行时对象产品化

11 分钟 4,912 字 第 45 / 161 个阅读单元

OpenAI Agents SDK 的设计重点,和 LangGraph 这类图框架非常不同。

它不是从图、节点、边开始讲系统。 它是从一组运行时对象开始讲系统:

  • Agent
  • Runner
  • Tool
  • Handoff
  • Guardrail
  • RunState
  • Session
  • Trace / Span

这意味着它真正想做的事情,是把一个 Agent 系统在运行时最常见的稳定对象,整理成一套产品化 SDK。

因此,第 44 章第一条结论应该是:

text
OpenAI Agents SDK 的中心不是图,
而是“一个 agent run 过程中会稳定出现哪些对象,以及这些对象如何协同”。

这件事听上去简单,但其实非常有力量。

因为很多团队自己写 Agent 时,都会零散地遇到这些问题:

  • agent 定义放在哪里
  • tool 如何描述和审批
  • handoff 如何发生
  • structured output 如何接
  • 会话历史如何保存
  • 中断如何恢复
  • 结果如何检查
  • tracing 如何串起来

而这个 SDK 的回答是:不要把这些能力散成工具箱,而要把它们组织成统一的 runtime 对象体系。

#44.1 它真正解决的,不是“图编排”,而是“运行时对象标准化”

如果把 OpenAI Agents SDK 和 LangGraph、LangChain 放在一起看,它的差异非常鲜明。

它不是从图结构出发,也不是从高层应用入口出发。 它的出发点更接近:

text
一个 agent 系统真正运行起来之后,
哪些对象会稳定出现,应该被固定成 SDK 标准件?

这就是为什么官方首页会把原语压缩得非常少。 它希望开发者主要围绕这些对象思考:

  • Agent
  • Tool
  • Handoff
  • Guardrail
  • Runner
  • Session
  • RunResult
  • RunState
  • Tracing

这与很多框架完全不同。

有些框架的核心问题是“执行结构如何表达”。 有些框架的核心问题是“高层应用如何快速构造”。 而 OpenAI Agents SDK 的核心问题更像是:

text
如何让一次 agent run 里的关键对象具有稳定边界、稳定职责和稳定生命周期。

这正是“产品化 runtime”的典型特征。

#44.2 对象模型:Agent 不是人格壳,而是静态能力边界

理解这个 SDK,第一件事就是不要把 Agent 看成“人格化对象”。

在这里,一个 Agent 更像一个声明式配置对象。 它聚合的是:

  • instructions / prompt
  • model
  • tools
  • handoffs
  • input / output guardrails
  • output type
  • hooks
  • tool use behavior

也就是说,在 OpenAI Agents SDK 里,Agent 首先回答的不是“它像谁”,而是:

text
这个运行单元拥有哪些能力、约束和委派边界。

再看 Tool 与 Handoff,会更清楚。

Tool 不是自由文本外部函数,而是带有 schema、审批位、超时策略、guardrails 的运行接口对象。 Handoff 也不是抽象图边,而是一个显式声明“把当前控制权切给另一个 agent”的对象。

这说明 SDK 并没有把“多 agent”做成自由度极高的工作流语言。 它是在把最常见的运行时对象标准化。

#44.3 生命周期:真正的主语是 Runner.run(),不是单个 Agent

和前两章比起来,这一章最重要的主语变化是:

在 OpenAI Agents SDK 中,真正推进系统前进的,不是图,也不是某个 middleware 总线,而是 Runner.run() 所代表的 run loop。

它的核心循环非常清楚:

  1. 调当前 agent
  2. 如果得到 final_output,结束
  3. 如果触发 handoff,切换活动 agent
  4. 如果产生 tool calls,运行工具并继续
  5. 直到结束或超过 turn 限制

这套循环看起来朴素,但非常具有产品化风格。

因为它把运行中的关键分支限制在少数稳定类型上:

  • final output
  • tool call
  • handoff
  • interruption / approval

这意味着 SDK 不鼓励开发者一上来就定义无限多的自定义控制原语。 它更倾向于说:

text
大多数 agent run 可以先被组织成有限几类事件。

这正是 SDK 易用性的来源。

#44.4 输入契约:input items 才是第一性输入,不是 prompt 字符串

理解这个 SDK 的输入模型,最重要的一步,是放弃“输入就是一段字符串”的思维。

虽然它当然支持字符串输入,但那只是高层便利接口。 从更本质的角度看,它真正的一等输入是:

text
Responses API 风格的 input items 序列。

这件事非常关键。

因为一旦输入被理解成 items,而不是一整段 prompt,很多系统能力就自然出现了:

  • 可以区分用户消息、工具调用、工具结果、handoff 项、审批项
  • 可以把历史表示成可重放序列
  • 可以把一次 run 的新产出重新变回下一轮输入
  • 可以把结果对象和会话对象接到同一输入协议上

也就是说,这个 SDK 的输入契约不是“聊天文本”,而是“可序列化、可回放的运行项”。

#44.5 状态分层:RunContextWrapper、Session、RunResult、RunState 不是一回事

这一章最需要讲透的,就是状态分层。

因为 OpenAI Agents SDK 最容易被误解的一点,就是把“上下文”“会话”“结果”“恢复状态”全混成一层。 而它实际上分得很清楚。

第一层,是 RunContextWrapper。 这是本地运行上下文。 它服务于工具、guardrails、handoffs、hooks。 官方明确强调:这里面的 context 默认不会自动发给模型。

第二层,是 Session。 这是跨 run 的会话记忆层。 它的职责非常明确:

  • 取历史 items
  • 存新历史 items
  • 清理或裁剪历史

第三层,是 RunResult。 它是一次运行的结果观察面,回答的是“这次 run 发生了什么、得到了什么”。

第四层,是 RunState。 它解决的不是“以前聊了什么”,而是:

text
这次执行停在了哪里,如何从这里继续。

所以可以把这四层压缩成一句非常重要的话:

text
RunContextWrapper 是本地运行上下文,
Session 是跨轮历史,
RunResult 是观察结果,
RunState 是可恢复执行快照。

这也是为什么 Session 和 RunState 绝不能混为一谈。 前者偏“记住之前发生过什么”,后者偏“从哪里继续跑”。

#44.6 多 Agent:agents as tools 与 handoff 的本质分界

这个 SDK 的多 Agent 设计也非常值得注意。

它没有把多 Agent 做成复杂图模式集,而是主要集中在两条主线:

  1. agents as tools
  2. handoff

这两者的区别并不只是写法不同,而是控制权结构不同。

agents as tools 的本质是:

  • 上层 manager 保持最终控制权
  • 下层 specialist 被当作能力接口调用
  • specialist 的结果回到 manager 再做整合

而 handoff 的本质则是:

  • 当前 active agent 发生切换
  • specialist 接管当前对话后续
  • 本轮控制权不再由原 agent 保持

因此,本章必须把一条边界写得很清楚:

text
handoff 是活动 agent 切换,不是通用流程编排。

如果你真正需要的是复杂工作流状态机,仅靠 handoff 这个原语通常不够。

#44.7 guardrails、审批与 tracing:它没有通用 middleware,而是拆成三类治理对象

这一点是它和 LangChain 很不一样的地方。

LangChain 倾向于用 middleware 形成统一控制面。 而 OpenAI Agents SDK 并没有走这条路。

它在治理层采用的是另一种更“强类型、窄接口”的设计:

  • guardrails 负责校验与阻断
  • human in the loop 负责审批式暂停与恢复
  • tracing 负责观测、审计和链路可见性

这三个面不是一个大 middleware 总线,而是三个职责明确的治理对象族。

这恰恰反映了 SDK 的产品化姿态:

text
它宁愿把常见治理问题做成专门对象,
也不急着把一切都抽象成一个万能拦截层。

#44.8 HITL 的真实边界:它是工具审批暂停,不是通用图中断

很多人看到 SDK 支持 human-in-the-loop,就会自然联想到:

  • 那是不是等价于图框架里的通用 interrupt?

答案是否定的。

在 OpenAI Agents SDK 里,HITL 的原生语义更窄,也更明确:

text
它主要是围绕敏感工具调用的审批暂停与恢复。

也就是说,它最适合的是:

  • shell 执行
  • apply_patch
  • 外部系统写操作
  • 敏感业务动作
  • 高风险 MCP 工具

而不是:

  • 任意节点都可以随时暂停
  • 任意状态都可以人工编辑后再继续
  • 任意图结构都能靠同一 interrupt 机制控制

这就是它和 LangGraph interrupt() 的本质差异。

LangGraph interrupt() 是通用 runtime primitive。 OpenAI Agents SDK 的 HITL 是产品化审批机制。

#44.9 业务适配:它为什么更适合“run-centered agent app”

从业务适配角度看,这个 SDK 最适合的不是一切 agent 系统,而是一类特定形状的问题:

  • 一次 run 的回合语义很重要
  • session 历史很重要
  • 工具审批很重要
  • handoff 或 manager-style 协作已经足够表达业务
  • 你希望 tracing、guardrails、session 一体化

这类问题通常长得像:

  • 客服分诊与专家接管
  • 企业助理与工具执行
  • 标准多轮对话式 copilot
  • 以 Responses API 与 built-in tools 为中心的应用 agent

它不太适合的,则通常是:

  • 复杂显式状态机
  • 大量自定义控制节点
  • 以图结构为第一性对象的系统
  • 深度依赖自定义并发图编排的系统

也就是说,OpenAI Agents SDK 最适合的不是“所有 Agent”,而是:

text
那些真正以 run、session、approval、handoff、tracing 为核心对象的 agent application。

#44.10 团队价值:统一运行时语言,而不是统一图语言

从团队角度看,这个 SDK 的价值也很有特色。

如果说 LangChain 更像统一高层应用接口,那么 OpenAI Agents SDK 更像统一运行时语言。

它让团队围绕以下稳定对象协作:

  • Agent
  • Tool
  • Handoff
  • RunResult
  • RunState
  • Session
  • Trace

这件事非常重要。 因为在真实团队里,很多协作问题都不是“能力不够”,而是没有共同对象语言。

而这个 SDK 最大的产品化价值之一,就是把这些对象固定下来。

#44.11 它和 LangGraph、LangChain 的真正分界

现在可以把三者边界并列写清:

  • LangGraph 的中心是图、状态、检查点和中断
  • LangChain 的中心是高层入口、中间件和应用接口
  • OpenAI Agents SDK 的中心是 runtime objects、run loop、session、guardrails、tracing

三者都能做 agent。 但它们真正放在中心的系统对象完全不同。

所以不要用“谁功能更多”去比较。 更准确的比较方式是:

  • 你想先控制图结构,还是先控制应用入口,还是先控制运行时对象

#44.12 最常见的误用:把它期待成通用 orchestration kernel

真正理解一个框架,也要看它最容易被误用成什么。

OpenAI Agents SDK 最常见的误用,至少有六种。

第一,把它期待成图框架。 结果会在复杂流程和显式状态机需求上持续受挫。

第二,把 Session 和 RunState 混成一件事。 结果会把会话历史与执行恢复语义搅在一起。

第三,把 handoff 当成通用编排边。 结果会误以为复杂流程问题只靠 agent 切换就能解决。

第四,把 guardrails 当成统一 middleware。 结果会高估它在任意点拦截和治理复杂流程的能力。

第五,把 HITL 当成通用 interrupt。 结果会把审批暂停和任意节点暂停混为一谈。

第六,只把它看成“Agent 类 + 工具调用”封装。 这样会完全低估 RunResult / RunState / Session / Tracing 这些真正有系统含义的对象。

因此,本章最后应留下的判断是:

text
OpenAI Agents SDK 的强项,不在于把任意流程表达成图,
而在于把 agent run 中最关键的对象、状态边界和生命周期产品化。

进一步压缩成一句话就是:

text
它不是图语言,也不是高层应用壳,
而是一套以 run、session、result、state、handoff、approval、trace 为中心的 runtime object framework。