跳至内容

Handoffs

HandoffInputFilter 模块属性

HandoffInputFilter: TypeAlias = Callable[
    [HandoffInputData], HandoffInputData
]

一个用于过滤传递给下一个代理的输入数据的函数。

HandoffInputData dataclass

Source code in src/agents/handoffs.py
@dataclass(frozen=True)
class HandoffInputData:
    input_history: str | tuple[TResponseInputItem, ...]
    """
    The input history before `Runner.run()` was called.
    """

    pre_handoff_items: tuple[RunItem, ...]
    """
    The items generated before the agent turn where the handoff was invoked.
    """

    new_items: tuple[RunItem, ...]
    """
    The new items generated during the current agent turn, including the item that triggered the
    handoff and the tool output message representing the response from the handoff output.
    """

输入历史 instance-attribute

input_history: str | tuple[TResponseInputItem, ...]

在调用Runner.run()之前的输入历史记录。

pre_handoff_items instance-attribute

pre_handoff_items: tuple[RunItem, ...]

在调用交接之前由代理生成的条目。

new_items instance-attribute

new_items: tuple[RunItem, ...]

当前代理回合期间生成的新项目,包括触发交接的项目和代表交接输出响应的工具输出消息。

交接 dataclass

基类: Generic[TContext]

交接是指一个代理将任务委托给另一个代理的过程。 例如,在客户支持场景中,您可能会有一个"分诊代理"来确定 应该由哪个代理处理用户的请求,以及专门处理不同领域 (如账单、账户管理等)的子代理。

Source code in src/agents/handoffs.py
@dataclass
class Handoff(Generic[TContext]):
    """A handoff is when an agent delegates a task to another agent.
    For example, in a customer support scenario you might have a "triage agent" that determines
    which agent should handle the user's request, and sub-agents that specialize in different
    areas like billing, account management, etc.
    """

    tool_name: str
    """The name of the tool that represents the handoff."""

    tool_description: str
    """The description of the tool that represents the handoff."""

    input_json_schema: dict[str, Any]
    """The JSON schema for the handoff input. Can be empty if the handoff does not take an input.
    """

    on_invoke_handoff: Callable[[RunContextWrapper[Any], str], Awaitable[Agent[TContext]]]
    """The function that invokes the handoff. The parameters passed are:
    1. The handoff run context
    2. The arguments from the LLM, as a JSON string. Empty string if input_json_schema is empty.

    Must return an agent.
    """

    agent_name: str
    """The name of the agent that is being handed off to."""

    input_filter: HandoffInputFilter | None = None
    """A function that filters the inputs that are passed to the next agent. By default, the new
    agent sees the entire conversation history. In some cases, you may want to filter inputs e.g.
    to remove older inputs, or remove tools from existing inputs.

    The function will receive the entire conversation history so far, including the input item
    that triggered the handoff and a tool call output item representing the handoff tool's output.

    You are free to modify the input history or new items as you see fit. The next agent that
    runs will receive `handoff_input_data.all_items`.

    IMPORTANT: in streaming mode, we will not stream anything as a result of this function. The
    items generated before will already have been streamed.
    """

    strict_json_schema: bool = True
    """Whether the input JSON schema is in strict mode. We **strongly** recommend setting this to
    True, as it increases the likelihood of correct JSON input.
    """

    def get_transfer_message(self, agent: Agent[Any]) -> str:
        base = f"{{'assistant': '{agent.name}'}}"
        return base

    @classmethod
    def default_tool_name(cls, agent: Agent[Any]) -> str:
        return _transforms.transform_string_function_style(f"transfer_to_{agent.name}")

    @classmethod
    def default_tool_description(cls, agent: Agent[Any]) -> str:
        return (
            f"Handoff to the {agent.name} agent to handle the request. "
            f"{agent.handoff_description or ''}"
        )

工具名称 instance-attribute

tool_name: str

表示交接的工具名称。

工具描述 instance-attribute

tool_description: str

表示交接的工具描述。

input_json_schema instance-attribute

input_json_schema: dict[str, Any]

交接输入的JSON模式。如果交接不需要输入,可以为空。

on_invoke_handoff instance-attribute

on_invoke_handoff: Callable[
    [RunContextWrapper[Any], str],
    Awaitable[Agent[TContext]],
]

触发交接的函数。传入的参数包括: 1. 交接运行上下文 2. 来自LLM的参数,以JSON字符串形式传递。如果input_json_schema为空则为空字符串。

必须返回一个代理。

agent_name instance-attribute

agent_name: str

正在交接的代理名称。

input_filter class-attribute instance-attribute

input_filter: HandoffInputFilter | None = None

一个用于过滤传递给下一个代理的输入的函数。默认情况下,新代理可以看到整个对话历史记录。在某些情况下,您可能希望过滤输入,例如删除较早的输入,或从现有输入中移除工具。

该函数将接收迄今为止的完整对话历史记录,包括触发转交的输入项以及代表转交工具输出的工具调用输出项。

您可以自由修改输入历史记录或新项目。下一个运行的代理将接收handoff_input_data.all_items

重要提示:在流式传输模式下,由于此函数的结果,我们将不会传输任何内容。之前生成的项应该已经被传输过了。

strict_json_schema class-attribute instance-attribute

strict_json_schema: bool = True

输入JSON模式是否处于严格模式。我们强烈建议将此设置为True,因为它会增加正确JSON输入的可能性。

交接

handoff(
    agent: Agent[TContext],
    *,
    tool_name_override: str | None = None,
    tool_description_override: str | None = None,
    input_filter: Callable[
        [HandoffInputData], HandoffInputData
    ]
    | None = None,
) -> Handoff[TContext]
handoff(
    agent: Agent[TContext],
    *,
    on_handoff: OnHandoffWithInput[THandoffInput],
    input_type: type[THandoffInput],
    tool_description_override: str | None = None,
    tool_name_override: str | None = None,
    input_filter: Callable[
        [HandoffInputData], HandoffInputData
    ]
    | None = None,
) -> Handoff[TContext]
handoff(
    agent: Agent[TContext],
    *,
    on_handoff: OnHandoffWithoutInput,
    tool_description_override: str | None = None,
    tool_name_override: str | None = None,
    input_filter: Callable[
        [HandoffInputData], HandoffInputData
    ]
    | None = None,
) -> Handoff[TContext]
handoff(
    agent: Agent[TContext],
    tool_name_override: str | None = None,
    tool_description_override: str | None = None,
    on_handoff: OnHandoffWithInput[THandoffInput]
    | OnHandoffWithoutInput
    | None = None,
    input_type: type[THandoffInput] | None = None,
    input_filter: Callable[
        [HandoffInputData], HandoffInputData
    ]
    | None = None,
) -> Handoff[TContext]

从代理创建交接。

参数:

名称 类型 描述 默认值
agent Agent[TContext]

要交接给的代理,或者返回代理的函数。

required
tool_name_override str | None

用于表示交接的工具名称的可选覆盖项。

None
tool_description_override str | None

可选覆盖,用于表示交接的工具描述。

None
on_handoff OnHandoffWithInput[THandoffInput] | OnHandoffWithoutInput | None

当交接被调用时运行的函数。

None
input_type type[THandoffInput] | None

交接输入的参数类型。如果提供此参数,输入将根据该类型进行验证。仅当您传递需要输入的函数时相关。

None
input_filter Callable[[HandoffInputData], HandoffInputData] | None

一个用于过滤传递给下一个代理的输入的函数。

None
Source code in src/agents/handoffs.py
def handoff(
    agent: Agent[TContext],
    tool_name_override: str | None = None,
    tool_description_override: str | None = None,
    on_handoff: OnHandoffWithInput[THandoffInput] | OnHandoffWithoutInput | None = None,
    input_type: type[THandoffInput] | None = None,
    input_filter: Callable[[HandoffInputData], HandoffInputData] | None = None,
) -> Handoff[TContext]:
    """Create a handoff from an agent.

    Args:
        agent: The agent to handoff to, or a function that returns an agent.
        tool_name_override: Optional override for the name of the tool that represents the handoff.
        tool_description_override: Optional override for the description of the tool that
            represents the handoff.
        on_handoff: A function that runs when the handoff is invoked.
        input_type: the type of the input to the handoff. If provided, the input will be validated
            against this type. Only relevant if you pass a function that takes an input.
        input_filter: a function that filters the inputs that are passed to the next agent.
    """
    assert (on_handoff and input_type) or not (on_handoff and input_type), (
        "You must provide either both on_input and input_type, or neither"
    )
    type_adapter: TypeAdapter[Any] | None
    if input_type is not None:
        assert callable(on_handoff), "on_handoff must be callable"
        sig = inspect.signature(on_handoff)
        if len(sig.parameters) != 2:
            raise UserError("on_handoff must take two arguments: context and input")

        type_adapter = TypeAdapter(input_type)
        input_json_schema = type_adapter.json_schema()
    else:
        type_adapter = None
        input_json_schema = {}
        if on_handoff is not None:
            sig = inspect.signature(on_handoff)
            if len(sig.parameters) != 1:
                raise UserError("on_handoff must take one argument: context")

    async def _invoke_handoff(
        ctx: RunContextWrapper[Any], input_json: str | None = None
    ) -> Agent[Any]:
        if input_type is not None and type_adapter is not None:
            if input_json is None:
                _error_tracing.attach_error_to_current_span(
                    SpanError(
                        message="Handoff function expected non-null input, but got None",
                        data={"details": "input_json is None"},
                    )
                )
                raise ModelBehaviorError("Handoff function expected non-null input, but got None")

            validated_input = _json.validate_json(
                json_str=input_json,
                type_adapter=type_adapter,
                partial=False,
            )
            input_func = cast(OnHandoffWithInput[THandoffInput], on_handoff)
            if inspect.iscoroutinefunction(input_func):
                await input_func(ctx, validated_input)
            else:
                input_func(ctx, validated_input)
        elif on_handoff is not None:
            no_input_func = cast(OnHandoffWithoutInput, on_handoff)
            if inspect.iscoroutinefunction(no_input_func):
                await no_input_func(ctx)
            else:
                no_input_func(ctx)

        return agent

    tool_name = tool_name_override or Handoff.default_tool_name(agent)
    tool_description = tool_description_override or Handoff.default_tool_description(agent)

    # Always ensure the input JSON schema is in strict mode
    # If there is a need, we can make this configurable in the future
    input_json_schema = ensure_strict_json_schema(input_json_schema)

    return Handoff(
        tool_name=tool_name,
        tool_description=tool_description,
        input_json_schema=input_json_schema,
        on_invoke_handoff=_invoke_handoff,
        input_filter=input_filter,
        agent_name=agent.name,
    )