交接
交接让一个智能体可以将对话的一部分委派给另一个智能体。当不同智能体专注于特定领域时,这很有用。例如,在客户支持应用中,您可能会有分别处理预订、退款或常见问题的智能体。
交接会以工具的形式呈现给 LLM。如果您交接给名为 Refund Agent 的智能体,工具名称会是 transfer_to_refund_agent。
当您确定应由专家接管对话后,请在阅读智能体之后阅读本页。如果专家应留在原始智能体背后,请改用 agents as tools。
每个智能体都接受一个 handoffs 选项。它可以包含其他 Agent 实例,或由 handoff() 辅助函数返回的 Handoff 对象。
如果您传入普通的 Agent 实例,它们的 handoffDescription(如果提供)会追加到默认工具描述中。使用它来说明模型应在何时选择该交接。
import { Agent, handoff } from '@openai/agents';
const billingAgent = new Agent({ name: 'Billing agent' });const refundAgent = new Agent({ name: 'Refund agent' });
// Use Agent.create method to ensure the finalOutput type considers handoffsconst triageAgent = Agent.create({ name: 'Triage agent', handoffs: [billingAgent, handoff(refundAgent)],});通过 handoff() 自定义交接
Section titled “通过 handoff() 自定义交接”handoff() 函数可让您调整生成的工具。
agent– 要交接给的智能体。toolNameOverride– 覆盖默认的transfer_to_<agent_name>工具名称。toolDescriptionOverride– 覆盖默认的工具描述。onHandoff– 交接发生时的回调。接收一个RunContext;当配置了inputType时,还会接收解析后的交接负载。inputType– 交接工具调用参数的 schema。inputFilter– 过滤传递给下一个智能体的历史记录。isEnabled– 布尔值或谓词,仅在匹配的运行中暴露该交接。
handoff() 辅助函数始终会将控制权转移给您传入的特定 agent。如果您有多个可能的目标,请为每个目标注册一个交接,并让模型在它们之间选择。当您自己的交接代码必须在调用时决定返回哪个智能体时,请使用自定义 Handoff。
import { z } from 'zod';import { Agent, handoff, RunContext } from '@openai/agents';
const FooSchema = z.object({ foo: z.string() });
function onHandoff(ctx: RunContext, input?: { foo: string }) { console.log('Handoff called with:', input?.foo);}
const agent = new Agent({ name: 'My agent' });
const handoffObj = handoff(agent, { onHandoff, inputType: FooSchema, toolNameOverride: 'custom_handoff_tool', toolDescriptionOverride: 'Custom description',});有时,您希望模型在选择交接时附带一小段结构化负载。对于这种情况,请同时定义 inputType 和 onHandoff。
import { z } from 'zod';import { Agent, handoff, RunContext } from '@openai/agents';
const EscalationData = z.object({ reason: z.string() });type EscalationData = z.infer<typeof EscalationData>;
async function onHandoff( ctx: RunContext<EscalationData>, input: EscalationData | undefined,) { console.log(`Escalation agent called with reason: ${input?.reason}`);}
const agent = new Agent<EscalationData>({ name: 'Escalation agent' });
const handoffObj = handoff(agent, { onHandoff, inputType: EscalationData,});inputType 描述交接工具调用本身的参数。SDK 会将该 schema 作为交接工具的 parameters 暴露给模型,在本地解析返回的参数,并将解析后的值传递给 onHandoff。
它不会替换下一个智能体的主输入,也不会选择不同的目标。handoff() 辅助函数仍会转移到您封装的特定智能体,接收方智能体仍会看到对话历史,除非您使用 inputFilter 对其进行更改。
inputType 也与 RunContext 分离。它用于模型在交接时决定的元数据,而不是用于您已经在本地拥有的应用状态或依赖项。
inputType 的使用时机
Section titled “inputType 的使用时机”当交接需要一小段由模型生成的路由元数据时,请使用 inputType,例如 reason、language、priority 或 summary。例如,分诊智能体可以通过 { reason: 'duplicate_charge', priority: 'high' } 交接给退款智能体,而 onHandoff 可以在退款智能体接管之前记录或持久化这些元数据。
当目标不同时,请选择其他机制:
- 将现有应用状态放入
RunContext。 - 如果您想更改接收方智能体看到的历史记录,请使用
inputFilter。 - 如果有多个可能的专家,请为每个目标注册一个交接。
inputType可以向选中的交接添加元数据,但它不会在多个目标之间分发。 - 如果您希望 SDK 在
onHandoff运行之前验证解析后的负载,请优先使用 Zod schema;原始 JSON Schema 只定义发送给模型的工具契约。
默认情况下,交接会接收完整的对话历史。若要修改传递给下一个智能体的内容,请提供 inputFilter。常用辅助函数位于 @openai/agents-core/extensions 中。
import { Agent, handoff } from '@openai/agents';import { removeAllTools } from '@openai/agents-core/extensions';
const agent = new Agent({ name: 'FAQ agent' });
const handoffObj = handoff(agent, { inputFilter: removeAllTools,});inputFilter 接收并返回一个 HandoffInputData 对象:
inputHistory– 运行开始前的输入历史。preHandoffItems– 发生交接的轮次之前生成的项目。newItems– 当前轮次中生成的项目,包括交接调用/输出项目。runContext– 活跃的运行上下文。
如果您还在 Runner 上配置了 handoffInputFilter,则该特定交接的每个交接级 inputFilter 优先。
当您的提示中提到交接时,LLM 的响应会更可靠。SDK 通过 RECOMMENDED_PROMPT_PREFIX 暴露了推荐前缀。
import { Agent } from '@openai/agents';import { RECOMMENDED_PROMPT_PREFIX } from '@openai/agents-core/extensions';
const billingAgent = new Agent({ name: 'Billing agent', instructions: `${RECOMMENDED_PROMPT_PREFIX}Fill in the rest of your prompt here.`,});