Skip to main content
交接架构中,行为会根据状态动态变化。其核心机制是:工具更新一个跨轮次持久化的状态变量(例如 current_stepactive_agent),系统读取该变量以调整行为——要么应用不同的配置(系统提示、工具),要么路由到不同的代理。此模式既支持不同代理之间的交接,也支持单个代理内的动态配置更改。
术语交接OpenAI 提出,指使用工具调用(例如 transfer_to_sales_agent)在代理或状态之间转移控制权。

关键特性

  • 状态驱动行为:行为根据状态变量(例如 current_stepactive_agent)而变化
  • 基于工具的转换:工具更新状态变量以在状态间移动
  • 直接用户交互:每个状态的配置直接处理用户消息
  • 持久化状态:状态在对话轮次间保持

何时使用

当您需要强制执行顺序约束(仅在满足前置条件后解锁功能)、代理需要在不同状态下直接与用户对话,或者您正在构建多阶段对话流程时,请使用交接模式。此模式对于需要按特定顺序收集信息的客户支持场景特别有价值——例如,在处理退款之前收集保修 ID。

基本实现

核心机制是一个工具,它返回一个用于更新状态的 Command,从而触发向新步骤或代理的转换:
为什么需要包含 ToolMessage 当 LLM 调用工具时,它期望得到一个响应。带有匹配 tool_call_idToolMessage 完成了这个请求-响应循环——没有它,对话历史记录就会格式错误。每当您的交接工具更新消息时,这都是必需的。
有关完整实现,请参阅下面的教程。

教程:使用交接构建客户支持

了解如何使用交接模式构建客户支持代理,其中单个代理在不同配置之间转换。

实现方法

有两种实现交接的方式:带中间件的单代理(一个具有动态配置的代理)或**多代理子图**(作为图节点的不同代理)。

带中间件的单代理

单个代理根据状态改变其行为。中间件拦截每个模型调用,并动态调整系统提示和可用工具。工具更新状态变量以触发转换:

多代理子图

多个不同的代理作为图中的独立节点存在。交接工具使用 Command.PARENT 在代理节点之间导航,以指定接下来要执行哪个节点。
子图交接需要仔细的**上下文工程**。与单代理中间件(消息历史自然流动)不同,您必须明确决定哪些消息在代理之间传递。如果处理不当,代理会收到格式错误的对话历史或臃肿的上下文。请参阅下面的上下文工程
此示例展示了一个具有独立销售和支持代理的多代理系统。每个代理是一个独立的图节点,交接工具允许代理之间相互转移对话。
对于大多数交接用例,请使用带中间件的单代理——它更简单。仅当您需要定制代理实现(例如,节点本身是一个具有反思或检索步骤的复杂图)时,才使用多代理子图

上下文工程

通过子图交接,您可以精确控制哪些消息在代理之间流动。这种精确性对于维护有效的对话历史和避免可能使下游代理混淆的上下文膨胀至关重要。有关此主题的更多信息,请参阅上下文工程 在交接期间处理上下文 在代理之间交接时,您需要确保对话历史保持有效。LLM 期望工具调用与其响应配对,因此当使用 Command.PARENT 交接给另一个代理时,您必须包含两者:
  1. 包含工具调用的 AIMessage(触发交接的消息)
  2. 确认交接的 ToolMessage(对该工具调用的人工响应)
没有这种配对,接收代理将看到不完整的对话,并可能产生错误或意外行为。 以下示例假设仅调用了交接工具(没有并行工具调用):
为什么不传递所有子代理消息? 虽然您可以在交接中包含完整的子代理对话,但这通常会产生问题。接收代理可能会被无关的内部推理搞混,并且令牌成本会不必要地增加。通过仅传递交接配对,您可以保持父图的上下文专注于高层协调。如果接收代理需要额外的上下文,请考虑在 ToolMessage 内容中总结子代理的工作,而不是传递原始消息历史。
将控制权返回给用户 当将控制权返回给用户(结束代理的轮次)时,请确保最终消息是 AIMessage。这可以维护有效的对话历史,并向用户界面发出代理已完成工作的信号。

实现注意事项

在设计多代理系统时,请考虑:
  • 上下文过滤策略:每个代理是接收完整的对话历史、过滤后的部分还是摘要?不同的代理可能需要不同的上下文,具体取决于其角色。
  • 工具语义:明确交接工具是仅更新路由状态还是也执行副作用。例如,transfer_to_sales() 是否还应创建支持工单,或者这应该是一个单独的操作?
  • 令牌效率:在上下文完整性和令牌成本之间取得平衡。随着对话变长,摘要和选择性上下文传递变得更加重要。