OpenAI Agents SDK 的设计重点,和 LangGraph 这类图框架非常不同。
它不是从图、节点、边开始讲系统。 它是从一组运行时对象开始讲系统:
AgentRunnerToolHandoffGuardrailRunStateSessionTrace/Span
这意味着它真正想做的事情,是把一个 Agent 系统在运行时最常见的稳定对象,整理成一套产品化 SDK。
因此,第 44 章第一条结论应该是:
OpenAI Agents SDK 的中心不是图,
而是“一个 agent run 过程中会稳定出现哪些对象,以及这些对象如何协同”。这件事听上去简单,但其实非常有力量。
因为很多团队自己写 Agent 时,都会零散地遇到这些问题:
- agent 定义放在哪里
- tool 如何描述和审批
- handoff 如何发生
- structured output 如何接
- 会话历史如何保存
- 中断如何恢复
- 结果如何检查
- tracing 如何串起来
而这个 SDK 的回答是:不要把这些能力散成工具箱,而要把它们组织成统一的 runtime 对象体系。
#44.1 它真正解决的,不是“图编排”,而是“运行时对象标准化”
如果把 OpenAI Agents SDK 和 LangGraph、LangChain 放在一起看,它的差异非常鲜明。
它不是从图结构出发,也不是从高层应用入口出发。 它的出发点更接近:
一个 agent 系统真正运行起来之后,
哪些对象会稳定出现,应该被固定成 SDK 标准件?这就是为什么官方首页会把原语压缩得非常少。 它希望开发者主要围绕这些对象思考:
AgentToolHandoffGuardrailRunnerSessionRunResultRunStateTracing
这与很多框架完全不同。
有些框架的核心问题是“执行结构如何表达”。
有些框架的核心问题是“高层应用如何快速构造”。
而 OpenAI Agents SDK 的核心问题更像是:
如何让一次 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 首先回答的不是“它像谁”,而是:
这个运行单元拥有哪些能力、约束和委派边界。再看 Tool 与 Handoff,会更清楚。
Tool 不是自由文本外部函数,而是带有 schema、审批位、超时策略、guardrails 的运行接口对象。
Handoff 也不是抽象图边,而是一个显式声明“把当前控制权切给另一个 agent”的对象。
这说明 SDK 并没有把“多 agent”做成自由度极高的工作流语言。 它是在把最常见的运行时对象标准化。
#44.3 生命周期:真正的主语是 Runner.run(),不是单个 Agent
和前两章比起来,这一章最重要的主语变化是:
在 OpenAI Agents SDK 中,真正推进系统前进的,不是图,也不是某个 middleware 总线,而是 Runner.run() 所代表的 run loop。
它的核心循环非常清楚:
- 调当前 agent
- 如果得到
final_output,结束 - 如果触发 handoff,切换活动 agent
- 如果产生 tool calls,运行工具并继续
- 直到结束或超过 turn 限制
这套循环看起来朴素,但非常具有产品化风格。
因为它把运行中的关键分支限制在少数稳定类型上:
- final output
- tool call
- handoff
- interruption / approval
这意味着 SDK 不鼓励开发者一上来就定义无限多的自定义控制原语。 它更倾向于说:
大多数 agent run 可以先被组织成有限几类事件。这正是 SDK 易用性的来源。
#44.4 输入契约:input items 才是第一性输入,不是 prompt 字符串
理解这个 SDK 的输入模型,最重要的一步,是放弃“输入就是一段字符串”的思维。
虽然它当然支持字符串输入,但那只是高层便利接口。 从更本质的角度看,它真正的一等输入是:
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。
它解决的不是“以前聊了什么”,而是:
这次执行停在了哪里,如何从这里继续。所以可以把这四层压缩成一句非常重要的话:
RunContextWrapper 是本地运行上下文,
Session 是跨轮历史,
RunResult 是观察结果,
RunState 是可恢复执行快照。这也是为什么 Session 和 RunState 绝不能混为一谈。
前者偏“记住之前发生过什么”,后者偏“从哪里继续跑”。
#44.6 多 Agent:agents as tools 与 handoff 的本质分界
这个 SDK 的多 Agent 设计也非常值得注意。
它没有把多 Agent 做成复杂图模式集,而是主要集中在两条主线:
agents as toolshandoff
这两者的区别并不只是写法不同,而是控制权结构不同。
agents as tools 的本质是:
- 上层 manager 保持最终控制权
- 下层 specialist 被当作能力接口调用
- specialist 的结果回到 manager 再做整合
而 handoff 的本质则是:
- 当前 active agent 发生切换
- specialist 接管当前对话后续
- 本轮控制权不再由原 agent 保持
因此,本章必须把一条边界写得很清楚:
handoff 是活动 agent 切换,不是通用流程编排。如果你真正需要的是复杂工作流状态机,仅靠 handoff 这个原语通常不够。
#44.7 guardrails、审批与 tracing:它没有通用 middleware,而是拆成三类治理对象
这一点是它和 LangChain 很不一样的地方。
LangChain 倾向于用 middleware 形成统一控制面。
而 OpenAI Agents SDK 并没有走这条路。
它在治理层采用的是另一种更“强类型、窄接口”的设计:
guardrails负责校验与阻断human in the loop负责审批式暂停与恢复tracing负责观测、审计和链路可见性
这三个面不是一个大 middleware 总线,而是三个职责明确的治理对象族。
这恰恰反映了 SDK 的产品化姿态:
它宁愿把常见治理问题做成专门对象,
也不急着把一切都抽象成一个万能拦截层。#44.8 HITL 的真实边界:它是工具审批暂停,不是通用图中断
很多人看到 SDK 支持 human-in-the-loop,就会自然联想到:
- 那是不是等价于图框架里的通用 interrupt?
答案是否定的。
在 OpenAI Agents SDK 里,HITL 的原生语义更窄,也更明确:
它主要是围绕敏感工具调用的审批暂停与恢复。也就是说,它最适合的是:
- 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”,而是:
那些真正以 run、session、approval、handoff、tracing 为核心对象的 agent application。#44.10 团队价值:统一运行时语言,而不是统一图语言
从团队角度看,这个 SDK 的价值也很有特色。
如果说 LangChain 更像统一高层应用接口,那么 OpenAI Agents SDK 更像统一运行时语言。
它让团队围绕以下稳定对象协作:
AgentToolHandoffRunResultRunStateSessionTrace
这件事非常重要。 因为在真实团队里,很多协作问题都不是“能力不够”,而是没有共同对象语言。
而这个 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 这些真正有系统含义的对象。
因此,本章最后应留下的判断是:
OpenAI Agents SDK 的强项,不在于把任意流程表达成图,
而在于把 agent run 中最关键的对象、状态边界和生命周期产品化。进一步压缩成一句话就是:
它不是图语言,也不是高层应用壳,
而是一套以 run、session、result、state、handoff、approval、trace 为中心的 runtime object framework。