多智能体

单个智能体可能难以应对需要专门处理多个领域或管理多种工具的情况。为了解决这个问题,您可以将智能体分解为更小、独立的智能体,并将它们组合成一个多智能体系统

在多智能体系统中,智能体之间需要进行通信。它们通过移交来实现这一点——这是一种描述将控制权移交给哪个智能体以及发送给该智能体的数据负载的原始操作。

两种最受欢迎的多智能体架构是:

  • 主管——单个智能体由一个中央主管智能体协调。主管控制所有通信流和任务委派,根据当前上下文和任务要求决定调用哪个智能体。
  • 群组——智能体根据其专业性动态地相互移交控制权。系统会记住哪个智能体上次处于活动状态,确保在后续交互中,对话会与该智能体恢复。

主管

Supervisor

使用 langgraph-supervisor 库来创建主管多智能体系统

<span id="__span-0-1">pip install langgraph-supervisor

API 参考: ChatOpenAI | create_react_agent | create_supervisor

<code tabindex="0"><span id="__span-1-1">from langchain_openai import ChatOpenAI
<span id="__span-1-2">from langgraph.prebuilt import create_react_agent
<span id="__span-1-3">from langgraph_supervisor import create_supervisor
<span id="__span-1-4">
<span id="__span-1-5">def book_hotel(hotel_name: str):
<span id="__span-1-6">    """Book a hotel"""
<span id="__span-1-7">    return f"Successfully booked a stay at {hotel_name}."
<span id="__span-1-8">
<span id="__span-1-9">def book_flight(from_airport: str, to_airport: str):
<span id="__span-1-10">    """Book a flight"""
<span id="__span-1-11">    return f"Successfully booked a flight from {from_airport} to {to_airport}."
<span id="__span-1-12">
<span id="__span-1-13">flight_assistant = create_react_agent(
<span id="__span-1-14">    model="openai:gpt-4o",
<span id="__span-1-15">    tools=[book_flight],
<span id="__span-1-16">    prompt="You are a flight booking assistant",
<span id="__span-1-17">    name="flight_assistant"
<span id="__span-1-18">)
<span id="__span-1-19">
<span id="__span-1-20">hotel_assistant = create_react_agent(
<span id="__span-1-21">    model="openai:gpt-4o",
<span id="__span-1-22">    tools=[book_hotel],
<span id="__span-1-23">    prompt="You are a hotel booking assistant",
<span id="__span-1-24">    name="hotel_assistant"
<span id="__span-1-25">)
<span id="__span-1-26">
<span id="__span-1-27">supervisor = create_supervisor(
<span id="__span-1-28">    agents=[flight_assistant, hotel_assistant],
<span id="__span-1-29">    model=ChatOpenAI(model="gpt-4o"),
<span id="__span-1-30">    prompt=(
<span id="__span-1-31">        "You manage a hotel booking assistant and a"
<span id="__span-1-32">        "flight booking assistant. Assign work to them."
<span id="__span-1-33">    )
<span id="__span-1-34">).compile()
<span id="__span-1-35">
<span id="__span-1-36">for chunk in supervisor.stream(
<span id="__span-1-37">    {
<span id="__span-1-38">        "messages": [
<span id="__span-1-39">            {
<span id="__span-1-40">                "role": "user",
<span id="__span-1-41">                "content": "book a flight from BOS to JFK and a stay at McKittrick Hotel"
<span id="__span-1-42">            }
<span id="__span-1-43">        ]
<span id="__span-1-44">    }
<span id="__span-1-45">):
<span id="__span-1-46">    print(chunk)
<span id="__span-1-47">    print("\n")

群组

Swarm

使用 langgraph-swarm 库来创建群组多智能体系统

<span id="__span-2-1">pip install langgraph-swarm

API 参考: create_react_agent | create_swarm | create_handoff_tool

<code tabindex="0"><span id="__span-3-1">from langgraph.prebuilt import create_react_agent
<span id="__span-3-2">from langgraph_swarm import create_swarm, create_handoff_tool
<span id="__span-3-3">
<span id="__span-3-4">transfer_to_hotel_assistant = create_handoff_tool(
<span id="__span-3-5">    agent_name="hotel_assistant",
<span id="__span-3-6">    description="Transfer user to the hotel-booking assistant.",
<span id="__span-3-7">)
<span id="__span-3-8">transfer_to_flight_assistant = create_handoff_tool(
<span id="__span-3-9">    agent_name="flight_assistant",
<span id="__span-3-10">    description="Transfer user to the flight-booking assistant.",
<span id="__span-3-11">)
<span id="__span-3-12">
<span id="__span-3-13">flight_assistant = create_react_agent(
<span id="__span-3-14">    model="anthropic:claude-3-5-sonnet-latest",
<span id="__span-3-15">    tools=[book_flight, transfer_to_hotel_assistant],
<span id="__span-3-16">    prompt="You are a flight booking assistant",
<span id="__span-3-17">    name="flight_assistant"
<span id="__span-3-18">)
<span id="__span-3-19">hotel_assistant = create_react_agent(
<span id="__span-3-20">    model="anthropic:claude-3-5-sonnet-latest",
<span id="__span-3-21">    tools=[book_hotel, transfer_to_flight_assistant],
<span id="__span-3-22">    prompt="You are a hotel booking assistant",
<span id="__span-3-23">    name="hotel_assistant"
<span id="__span-3-24">)
<span id="__span-3-25">
<span id="__span-3-26">swarm = create_swarm(
<span id="__span-3-27">    agents=[flight_assistant, hotel_assistant],
<span id="__span-3-28">    default_active_agent="flight_assistant"
<span id="__span-3-29">).compile()
<span id="__span-3-30">
<span id="__span-3-31">for chunk in swarm.stream(
<span id="__span-3-32">    {
<span id="__span-3-33">        "messages": [
<span id="__span-3-34">            {
<span id="__span-3-35">                "role": "user",
<span id="__span-3-36">                "content": "book a flight from BOS to JFK and a stay at McKittrick Hotel"
<span id="__span-3-37">            }
<span id="__span-3-38">        ]
<span id="__span-3-39">    }
<span id="__span-3-40">):
<span id="__span-3-41">    print(chunk)
<span id="__span-3-42">    print("\n")

移交

多智能体交互中一个常见的模式是**移交(handoffs)**,即一个智能体将控制权*移交*给另一个智能体。移交允许您指定:

  • 目的地:要导航到的目标智能体
  • 负载:要传递给该智能体的信息

这在 langgraph-supervisor(主管移交给单个智能体)和 langgraph-swarm(单个智能体可以移交给其他智能体)中都有使用。

要使用 create_react_agent 实现移交,您需要:

  1. 创建一个可以转移控制权给不同智能体的特殊工具

    <span id="__span-4-1">def transfer_to_bob():
    <span id="__span-4-2">    """Transfer to bob."""
    <span id="__span-4-3">    return Command(
    <span id="__span-4-4">        # name of the agent (node) to go to
    <span id="__span-4-5">        goto="bob",
    <span id="__span-4-6">        # data to send to the agent
    <span id="__span-4-7">        update={"messages": [...]},
    <span id="__span-4-8">        # indicate to LangGraph that we need to navigate to
    <span id="__span-4-9">        # agent node in a parent graph
    <span id="__span-4-10">        graph=Command.PARENT,
    <span id="__span-4-11">    )
    
  2. 创建可以访问移交工具的单个智能体

    <span id="__span-5-1">flight_assistant = create_react_agent(
    <span id="__span-5-2">    ..., tools=[book_flight, transfer_to_hotel_assistant]
    <span id="__span-5-3">)
    <span id="__span-5-4">hotel_assistant = create_react_agent(
    <span id="__span-5-5">    ..., tools=[book_hotel, transfer_to_flight_assistant]
    <span id="__span-5-6">)
    
  3. 定义一个包含单个智能体作为节点的父图

    <span id="__span-6-1">from langgraph.graph import StateGraph, MessagesState
    <span id="__span-6-2">multi_agent_graph = (
    <span id="__span-6-3">    StateGraph(MessagesState)
    <span id="__span-6-4">    .add_node(flight_assistant)
    <span id="__span-6-5">    .add_node(hotel_assistant)
    <span id="__span-6-6">    ...
    <span id="__span-6-7">)
    

综合以上,以下是您如何实现一个简单的多智能体系统,其中包含两个智能体——一个航班预订助手和一个酒店预订助手:

API 参考: tool | InjectedToolCallId | create_react_agent | InjectedState | StateGraph | START | Command

<code tabindex="0"><span id="__span-7-1">from typing import Annotated
<span id="__span-7-2">from langchain_core.tools import tool, InjectedToolCallId
<span id="__span-7-3">from langgraph.prebuilt import create_react_agent, InjectedState
<span id="__span-7-4">from langgraph.graph import StateGraph, START, MessagesState
<span id="__span-7-5">from langgraph.types import Command
<span id="__span-7-6">
<span id="__span-7-7">def create_handoff_tool(*, agent_name: str, description: str | None = None):
<span id="__span-7-8">    name = f"transfer_to_{agent_name}"
<span id="__span-7-9">    description = description or f"Transfer to {agent_name}"
<span id="__span-7-10">
<span id="__span-7-11">    @tool(name, description=description)
<span id="__span-7-12">    def handoff_tool(
<span id="__span-7-13">        state: Annotated[MessagesState, InjectedState], 
<span id="__span-7-14">        tool_call_id: Annotated[str, InjectedToolCallId],
<span id="__span-7-15">    ) -&gt; Command:
<span id="__span-7-16">        tool_message = {
<span id="__span-7-17">            "role": "tool",
<span id="__span-7-18">            "content": f"Successfully transferred to {agent_name}",
<span id="__span-7-19">            "name": name,
<span id="__span-7-20">            "tool_call_id": tool_call_id,
<span id="__span-7-21">        }
<span id="__span-7-22">        return Command(  
<span id="__span-7-23">            goto=agent_name,  
<span id="__span-7-24">            update={"messages": state["messages"] + [tool_message]},  
<span id="__span-7-25">            graph=Command.PARENT,  
<span id="__span-7-26">        )
<span id="__span-7-27">    return handoff_tool
<span id="__span-7-28">
<span id="__span-7-29"># Handoffs
<span id="__span-7-30">transfer_to_hotel_assistant = create_handoff_tool(
<span id="__span-7-31">    agent_name="hotel_assistant",
<span id="__span-7-32">    description="Transfer user to the hotel-booking assistant.",
<span id="__span-7-33">)
<span id="__span-7-34">transfer_to_flight_assistant = create_handoff_tool(
<span id="__span-7-35">    agent_name="flight_assistant",
<span id="__span-7-36">    description="Transfer user to the flight-booking assistant.",
<span id="__span-7-37">)
<span id="__span-7-38">
<span id="__span-7-39"># Simple agent tools
<span id="__span-7-40">def book_hotel(hotel_name: str):
<span id="__span-7-41">    """Book a hotel"""
<span id="__span-7-42">    return f"Successfully booked a stay at {hotel_name}."
<span id="__span-7-43">
<span id="__span-7-44">def book_flight(from_airport: str, to_airport: str):
<span id="__span-7-45">    """Book a flight"""
<span id="__span-7-46">    return f"Successfully booked a flight from {from_airport} to {to_airport}."
<span id="__span-7-47">
<span id="__span-7-48"># Define agents
<span id="__span-7-49">flight_assistant = create_react_agent(
<span id="__span-7-50">    model="anthropic:claude-3-5-sonnet-latest",
<span id="__span-7-51">    tools=[book_flight, transfer_to_hotel_assistant],
<span id="__span-7-52">    prompt="You are a flight booking assistant",
<span id="__span-7-53">    name="flight_assistant"
<span id="__span-7-54">)
<span id="__span-7-55">hotel_assistant = create_react_agent(
<span id="__span-7-56">    model="anthropic:claude-3-5-sonnet-latest",
<span id="__span-7-57">    tools=[book_hotel, transfer_to_flight_assistant],
<span id="__span-7-58">    prompt="You are a hotel booking assistant",
<span id="__span-7-59">    name="hotel_assistant"
<span id="__span-7-60">)
<span id="__span-7-61">
<span id="__span-7-62"># Define multi-agent graph
<span id="__span-7-63">multi_agent_graph = (
<span id="__span-7-64">    StateGraph(MessagesState)
<span id="__span-7-65">    .add_node(flight_assistant)
<span id="__span-7-66">    .add_node(hotel_assistant)
<span id="__span-7-67">    .add_edge(START, "flight_assistant")
<span id="__span-7-68">    .compile()
<span id="__span-7-69">)
<span id="__span-7-70">
<span id="__span-7-71"># Run the multi-agent graph
<span id="__span-7-72">for chunk in multi_agent_graph.stream(
<span id="__span-7-73">    {
<span id="__span-7-74">        "messages": [
<span id="__span-7-75">            {
<span id="__span-7-76">                "role": "user",
<span id="__span-7-77">                "content": "book a flight from BOS to JFK and a stay at McKittrick Hotel"
<span id="__span-7-78">            }
<span id="__span-7-79">        ]
<span id="__span-7-80">    }
<span id="__span-7-81">):
<span id="__span-7-82">    print(chunk)
<span id="__span-7-83">    print("\n")

注意

此移交实现假设:

  • 多智能体系统中的每个智能体都将整体消息历史(所有智能体的)作为其输入接收
  • 每个智能体将其内部消息历史输出到多智能体系统的整体消息历史中

查看 LangGraph 主管群组文档,了解如何自定义移交。