[控场AI]
· 7 分钟阅读· 3,599 字

AI Agent交接机制:Handoff与Agent-as-Tool的本质区别

AI Agent交接机制:Handoff与Agent-as-Tool的本质区别

Handoff转移对话所有权,Agent-as-Tool保留调用方控制权,两者对模型都是工具调用。

文章通过客服场景类比和具体消息计数,对比了多智能体系统中 Handoff(交接)与 Agent-as-Tool(智能体即工具)两种协作模式。两者对模型而言都表现为一次工具调用,真正的区别在于代码在调用后的处理逻辑:Handoff 以 stop reason handoff 结束,接收方继承完整对话上下文并用自己的系统提示词撰写回复,每次恰好增加 2 条消息;Agent-as-Tool 则让专家以独立运行启动,仅返回任务字符串,由调用方汇总多个答案后统一回复。选择依据在于“谁应该拥有答案”:单一专家接管用 Handoff,多专家合成连贯回复用 Agent-as-Tool。OpenAI Agents SDK 分别通过 handoffs 列表和 tools 列表实现这两种模式。

在构建多智能体系统时,一个看似微小的设计选择——是让第一个智能体把客户“转接”给专家,还是“询问”专家后自己回复——会彻底改变消息流向、上下文继承和最终的回复归属。这段来自课程代码演示的内容,用两个客服场景清晰展示了AI Agent中 Handoff(交接)与 Agent-as-Tool(智能体即工具)的两种协作模式。

triage调用transfer to refunds后,工具结果返回给调用方模型

两种协作模式:转接电话还是询问同事

视频用两个电话场景做类比。第一个场景中,前台把电话转给同事,之后由同事直接与客户沟通,前台退出通话——这就是 Handoff。第二个场景中,经理让客户稍等,分别询问两位同事,然后汇总成一个答案回复客户——这就是 Agent-as-Tool。

关键洞察在于:对模型而言,这两种方式看起来完全一样,都是一次工具调用。真正的区别在于代码在调用之后做了什么。在 Handoff 模式下,triage 智能体调用 transfer to refunds,运行以 stop reason handoff 结束,输出为空,triage 不写任何回复。控制权完全移交给接收方 refunds。而在 Agent-as-Tool 模式下,经理智能体调用 ask refunds,每个专家以独立运行启动,只接收一个任务字符串,最终答案以字符串形式返回给经理,由经理撰写统一回复。

工具调用(Tool Call)与停止原因(Stop Reason)
在基于大语言模型的智能体框架中,工具调用是模型输出的一种结构化指令,表示模型希望执行某个外部函数(如查询订单、转接对话)。模型不会直接执行函数,而是返回一个包含函数名和参数的调用请求,由运行时环境执行后将结果作为新消息追加到对话中,再交还模型继续推理。停止原因则标识一次模型运行结束的缘由:常见值包括 end_turn(模型自然结束回复)、tool_use(模型请求调用工具)以及本文提到的 handoff(模型请求将控制权移交)。在 Handoff 模式下,运行时识别到 stop reason handoff 后不再把控制权交还原智能体,而是启动接收方智能体并继承对话历史,因此原智能体的输出为空。理解停止原因是区分两种协作模式的关键——它决定了代码在工具调用之后走哪条分支。

消息数与上下文继承的差异

演示中 Priya 的退款案例提供了可量化的对比。单个智能体处理退款需要 9 条消息。采用 Handoff 后,refunds 的运行包含 11 条消息——多出的 2 条是 triage 的转接请求和“transferred to refunds”结果。注意演示中的 handoff 运行省略了 triage 的系统提示词,若保留则总数为 12 条。

refunds 接管后看到的内容包括:自己的系统提示词(而非 triage 的)、Priya 的原始消息、triage 的转接请求及其结果,然后才开始自己的 get order 工作。这说明 Handoff 传递的是完整对话上下文,但接收方使用自己的指令体系。

经理智能体的规则是询问shipping和refunds,对模型而言与普通工具无异

在双问题工单场景中,A1002 未到货且 A1001 不合脚。经理智能体分别调用 shipping 和 refunds。shipping 工作运行 5 条消息,refunds 运行 9 条消息,但经理只看到每个专家的一条最终答案字符串。经理的完整消息列表仅包含指令、工单、一个同时询问两位专家的回合、两条专家回复,以及最后自己撰写的合并回复。

系统提示词(System Prompt)与上下文继承
系统提示词是对话开始时注入的、优先级最高的指令消息,用于定义智能体的角色、可用工具和行为边界。在多智能体协作中,每个智能体通常拥有独立的系统提示词。Handoff 发生时,接收方智能体会以自己的系统提示词开始新运行,同时继承此前的用户消息和交接记录,但不会继承原智能体的系统提示词(除非显式传递)。这就是为什么演示中 handoff 运行省略 triage 系统提示词时总数为 11 条,若保留则为 12 条。Agent-as-Tool 模式则不同:专家智能体只收到一个任务字符串作为用户消息,其上下文被刻意隔离,父运行的完整对话状态不会自动传入。这种隔离降低了 token 消耗和上下文污染,但也意味着专家无法看到任务字符串之外的任何细节,调用方必须在字符串中提供充分信息。

谁拥有对话:设计决策的核心

视频反复强调的核心问题是“谁撰写回复、谁拥有下一轮对话”。答案取决于模式选择:

  • Handoff:接收方拥有所有权,接收方撰写回复并处理后续交互。适合单一专家接管场景,如 Priya 的单纯退款需求。
  • Agent-as-Tool:调用方保留所有权,调用方汇总多个专家的答案后统一回复。适合需要多专家意见合成一个连贯回复的场景,如双问题工单。

两种模式对比:工具调用返回字符串,调用方保留控制权

两种模式各有代价。Handoff 让专家获得完整上下文,但 triage 无法合并多个答案。Agent-as-Tool 能产生连贯回复且上下文精简,但专家只知道任务字符串里的内容——如果字符串遗漏了细节,专家就无从得知。

在OpenAI Agents SDK中的实现

演示展示了两种模式在 OpenAI Agents SDK 中的对应写法。triage 获得 handoffs 列表(shipping 和 refunds),可以直接传智能体对象,也可以用 handoff() 包装以自定义交接行为。无论哪种方式,SDK 都会把每个 handoff 作为工具呈现给模型,命名为 transfer to refunds 这样的形式。

经理则获得 tools 列表,即 ask refunds 这类工具。按文档说法,这允许一个智能体调用另一个智能体而无需交接,且父运行不会自动继承对话状态。对于交接后的下一轮,SDK 提供 result.last_agent,通常是最适合复用的智能体。

Rahul的工单:handoff后shipping运行包含7条消息,由shipping撰写回复

最后的测验用 Rahul 的订单查询验证理解:triage 转接给 shipping 后,shipping 的运行包含 7 条消息(自己的 5 条加转接请求和结果 2 条),由 shipping 撰写回复而非 triage。这再次印证了 11-9=2、7-5=2 的固定规律——每次 handoff 恰好增加 2 条消息。

OpenAI Agents SDK 中的 Handoff 与 Agent-as-Tool
OpenAI Agents SDK 是一个用于构建多智能体工作流的轻量级框架,核心抽象包括 Agent(智能体)、Runner(运行器)和 Handoff(交接)。在 SDK 中,handoffs 列表中的每个元素会被自动包装成一个工具暴露给模型,工具名默认为 transfer_to_<agent_name>,模型调用它即触发控制权转移。handoff() 函数允许自定义交接行为,例如覆盖工具名、描述或添加回调。而 tools 列表中的智能体则通过 agent.as_tool() 方法转换成一个普通工具,调用时启动一个独立的子运行,只把最终输出字符串返回给父智能体,父运行的对话状态不会被继承。运行结束后,result.last_agent 指向最后实际处理请求的智能体,便于在交接后继续对话时复用正确的智能体实例。这两种机制在 API 层面都表现为工具调用,因此模型侧的行为完全一致,差异全部由 SDK 运行时的后处理逻辑决定。

设计启示

选择 Handoff 还是 Agent-as-Tool,本质上是在回答“谁应该拥有答案”。这个决策直接影响上下文传递的完整性、回复的一致性以及系统的可组合性。视频结尾预告下一课将讨论编排、最小权限和协议——即每个专家可以做什么、可以看什么,这同样是多智能体系统设计的关键维度。

分享:

相关推荐