跳至内容

多智能体系统

多智能体系统是一个由多个独立的、由大型语言模型驱动的参与者组成的系统,这些参与者以特定方式连接在一起。这些参与者可以像提示和大型语言模型调用一样简单,也可以像 ReAct 智能体一样复杂。

这种架构的主要优势是

  • 模块化:独立的智能体可以更容易地开发、测试和维护智能体系统。
  • 专业化:您可以创建专注于特定领域的专家智能体,并将它们组合成更复杂的应用程序。
  • 控制:您可以明确控制智能体之间的通信方式(而不是依赖于函数调用)。

LangGraph 中的多智能体系统

智能体作为节点

智能体可以定义为 LangGraph 中的节点。与 LangGraph 中的任何其他节点一样,这些智能体节点接收图状态作为输入,并返回对状态的更新作为它们的输出。

  • 简单的 大型语言模型节点:具有自定义提示的单个大型语言模型。
  • 子图节点:在编排图节点内部调用的复杂图。

智能体作为工具

智能体也可以定义为工具。在这种情况下,编排智能体(例如 ReAct 智能体)将使用工具调用大型语言模型来决定调用哪个智能体工具,以及传递给这些智能体的参数。

您也可以采用“巨型图”方法——将下属智能体的节点直接合并到父级编排图中。但是,对于复杂的下属智能体,不建议这样做,因为它会使整个系统更难扩展、维护和调试——在这种情况下,您应该使用子图或工具。

多智能体系统中的通信

多智能体系统中的一个重要问题是智能体如何相互通信以及与编排智能体通信。这涉及它们如何通信的模式,以及它们通信的顺序。LangGraph 非常适合编排这些类型的系统,并允许您定义两者。

模式

LangGraph 为多智能体架构中的通信方式提供了很大的灵活性。

  • LangGraph 中的节点可以具有一个 私有输入状态模式,该模式与图状态模式不同。这允许在图执行过程中传递额外的信息,这些信息仅用于执行特定节点。
  • 子图节点智能体可以具有独立的 输入/输出状态模式。在这种情况下,重要的是要 添加输入/输出转换,以便父图知道如何与子图通信。
  • 对于基于工具的下属智能体,编排器根据工具模式确定输入。此外,LangGraph 允许在运行时将状态传递给单个工具,以便下属智能体可以访问父状态(如果需要)。

序列

LangGraph 提供多种方法来控制智能体通信顺序

  • 显式控制流(图边):LangGraph 允许您通过 图边 显式定义应用程序的控制流(即智能体通信的顺序)。
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage
from langgraph.graph import StateGraph, MessagesState, START, END

model = ChatOpenAI(model="gpt-4o-mini")

def research_agent(state: MessagesState):
    """Call research agent"""
    messages = [SystemMessage(content="You are a research assistant. Given a topic, provide key facts and information.")] + state["messages"]
    response = model.invoke(messages)
    return {"messages": [response]}

def summarize_agent(state: MessagesState):
    """Call summarization agent"""
    messages = [SystemMessage(content="You are a summarization expert. Condense the given information into a brief summary.")] + state["messages"]
    response = model.invoke(messages)
    return {"messages": [response]}

graph = StateGraph(MessagesState)
graph.add_node("research", research_agent)
graph.add_node("summarize", summarize_agent)

# define the flow explicitly
graph.add_edge(START, "research")
graph.add_edge("research", "summarize")
graph.add_edge("summarize", END)
  • 动态控制流(条件边):LangGraph 还允许您定义 条件边,其中控制流取决于满足给定条件。在这种情况下,您可以使用大型语言模型来决定接下来调用哪个下属智能体。

  • 隐式控制流(工具调用):如果编排智能体将下属智能体视为工具,那么为编排器提供动力的工具调用大型语言模型将对调用工具(智能体)的顺序做出决策。

from typing import Annotated
from langchain_core.messages import SystemMessage, ToolMessage
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import ToolNode, InjectedState, create_react_agent

model = ChatOpenAI(model="gpt-4o-mini")

def research_agent(state: Annotated[dict, InjectedState]):
    """Call research agent"""
    messages = [SystemMessage(content="You are a research assistant. Given a topic, provide key facts and information.")] + state["messages"][:-1]
    response = model.invoke(messages)
    tool_call = state["messages"][-1].tool_calls[0]
    return {"messages": [ToolMessage(response.content, tool_call_id=tool_call["id"])]}

def summarize_agent(state: Annotated[dict, InjectedState]):
    """Call summarization agent"""
    messages = [SystemMessage(content="You are a summarization expert. Condense the given information into a brief summary.")] + state["messages"][:-1]
    response = model.invoke(messages)
    tool_call = state["messages"][-1].tool_calls[0]
    return {"messages": [ToolMessage(response.content, tool_call_id=tool_call["id"])]}

tool_node = ToolNode([research_agent, summarize_agent])
graph = create_react_agent(model, [research_agent, summarize_agent], state_modifier="First research and then summarize information on a given topic.")

示例架构

以下是可以在 LangGraph 中实现的几种复杂多智能体架构的示例。

多智能体协作

在这个例子中,不同的智能体在一个 共享的 消息备忘录(即共享的图状态)上协作。这意味着它们中的任何一个所做的任何工作都是其他智能体可见的。好处是其他智能体可以看到它们完成的所有单个步骤。缺点是,有时将所有这些信息传递下去过于冗长且没有必要,有时只需要智能体的最终答案。我们将其称为 协作,因为备忘录的共享性质。

在这种情况下,独立的智能体实际上只是具有自定义系统消息的单个大型语言模型调用。

以下是这些智能体如何连接的示意图

请参阅此 教程 中的完整代码示例。

智能体主管

在这个例子中,多个智能体连接在一起,但与上面不同的是,它们不共享一个共享的备忘录。相反,它们有自己的独立备忘录(即它们自己的状态),然后它们的最终响应被附加到一个全局备忘录中。

在这种情况下,独立的智能体是一个 LangGraph ReAct 智能体(图)。这意味着它们有自己的单独提示、大型语言模型和工具。调用时,它不仅仅是一个单个大型语言模型调用,而是对为 ReAct 智能体提供动力的图的调用。

请参阅此 教程 中的完整代码示例。

层次化智能体团队

如果智能体主管示例中的单个工作者工作过于复杂怎么办?如果工作者的数量变得太大怎么办?对于某些应用程序,如果工作以层次化的方式进行分配,系统可能更有效。您可以通过创建额外的子图层级并创建顶级主管以及中级主管来做到这一点。

请参阅此 教程 中的完整代码示例。

评论