使用LangGraph构建多Agent系统架构!

0 前言

Agent是一个使用大语言模型决定应用程序控制流的系统。随着这些系统的开发,它们随时间推移变得复杂,使管理和扩展更困难。如你可能会遇到:

  • Agent拥有太多的工具可供使用,对接下来应该调用哪个工具做出糟糕决策
  • 上下文过于复杂,以至于单个Agent无法跟踪
  • 系统中需要多个专业领域(例如规划者、研究员、数学专家等)。

为解决这些问题,你可能考虑将应用程序拆分成多个更小、独立的代理,并将它们组合成一个多Agent系统。这些独立的Agent可以简单到一个提示和一个LLM调用,或者复杂到像一个ReActAgent(甚至更多!)。

1 多Agent系统的好处

  • 模块化:独立的Agent使得开发、测试和维护Agent系统更加容易。
  • 专业化:你可以创建专注于特定领域的专家Agent,这有助于提高整个系统的性能。
  • 控制:你可以明确控制Agent之间的通信(而不是依赖于函数调用)。

2 多Agent架构

多Agent系统中有几种方式连接Agent:

  • 网络:每个Agent都可与其他Agent通信。任何Agent都可以决定接下来调用哪个其他Agent
  • 监督者:每个Agent与一个监督者Agent通信。监督者Agent决定接下来应该调用哪个Agent。
  • 监督者(工具调用):这是监督者架构的一个特殊情况。个别Agent可以被表示为工具。在这种情况下,监督者Agent使用一个工具调用LLM来决定调用哪个Agent工具,以及传递哪些参数给这些Agent。
  • 层次结构:你可以定义一个有监督者的多Agent系统。这是监督者架构的概括,并允许更复杂的控制流。
  • 自定义多Agent工作流:每个Agent只与Agent子集中的其他Agent通信。流程的部分是确定性的,只有一些Agent可以决定接下来调用哪个其他Agent。

网络

这种架构中,Agent被定义为图节点。每个Agent都可以与每个其他Agent通信(多对多连接),并且可以决定接下来调用哪个Agent。虽然非常灵活,但随着Agent数量的增加,这种架构扩展性并不好:

  • 很难强制执行接下来应该调用哪个Agent
  • 很难确定应该在Agent之间传递多少信息

建议生产避免使用这架构,而是使用以下架构之一。

监督者

这种架构中,定义Agent为节点,并添加一个监督者节点(LLM),它决定接下来应该调用哪个Agent节点。使用条件边根据监督者的决策将执行路由到适当的Agent节点。这种架构也适用于并行运行多个Agent或使用map-reduce模式。

from typing import Literal
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, MessagesState, STARTmodel = ChatOpenAI()class AgentState(MessagesState):next: Literal["agent_1", "agent_2"]def supervisor(state: AgentState):response = model.invoke(...)return {"next": response["next_agent"]}def agent_1(state: AgentState):response = model.invoke(...)return {"messages": [response]}def agent_2(state: AgentState):response = model.invoke(...)return {"messages": [response]}builder = StateGraph(AgentState)
builder.add_node(supervisor)
builder.add_node(agent_1)
builder.add_node(agent_2)builder.add_edge(START, "supervisor")
# 根据监督者的决策路由到Agent之一或退出
builder.add_conditional_edges("supervisor", lambda state: state["next"])
builder.add_edge("agent_1", "supervisor")
builder.add_edge("agent_2", "supervisor")supervisor = builder.compile()

教程以获取有关监督者多Agent架构的示例。

监督者(工具调用)

在这种监督者架构的变体中,我们定义个别Agent为工具,并在监督者节点中使用一个工具调用LLM。这可以作为一个ReAct风格的Agent实现,有两个节点——一个LLM节点(监督者)和一个执行工具(在这种情况下是Agent)的工具调用节点。

from typing import Annotated
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import InjectedState, create_react_agentmodel = ChatOpenAI()def agent_1(state: Annotated[dict, InjectedState]):tool_message = ...return {"messages": [tool_message]}def agent_2(state: Annotated[dict, InjectedState]):tool_message = ...return {"messages": [tool_message]}tools = [agent_1, agent_2]
supervisor = create_react_agent(model, tools)

自定义多Agent工作流

在这种架构中,我们添加个别Agent作为图节点,并提前定义Agent被调用的顺序,以自定义工作流。在LangGraph中,工作流可以以两种方式定义:

  • 显式控制流(普通边):LangGraph允许你通过普通图边显式定义应用程序的控制流(即Agent通信的顺序)。这是上述架构中最确定性的变体——我们总是提前知道接下来将调用哪个Agent。
  • 动态控制流(条件边):在LangGraph中,你可以允许LLM决定应用程序控制流的部分。这可以通过使用条件边实现。一个特殊情况是监督者工具调用架构。在这种情况下,驱动监督者Agent的工具调用LLM将决定工具(Agent)被调用的顺序。
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, MessagesState, STARTmodel = ChatOpenAI()def agent_1(state: MessagesState):response = model.invoke(...)return {"messages": [response]}def agent_2(state: MessagesState):response = model.invoke(...)return {"messages": [response]}builder = StateGraph(MessagesState)
builder.add_node(agent_1)
builder.add_node(agent_2)
# 明确定义流程
builder.add_edge(START, "agent_1")
builder.add_edge("agent_1", "agent_2")

3 Agent之间通信

构建多Agent系统时最重要的事情是弄清楚Agent如何通信。有几个不同的考虑因素:

  • Agent是通过图状态或工具调用进行通信的吗?
  • 如果两个Agent有不同的状态模式怎么办?
  • 如何通过共享消息列表进行通信?

3.1 图状态与工具调用

Agent之间传递的“有效载荷”是什么?在上述讨论的大多数架构中,Agent通过图状态进行通信。在监督者带工具调用的情况下,有效载荷是工具调用参数。

图状态

要通过图状态进行通信,各个Agent需要被定义为图节点。这些可以作为函数或整个子图添加。在图执行的每一步中,Agent节点接收当前的图状态,执行Agent代码,然后将更新的状态传递给下一个节点。

通常,Agent节点共享一个单一的状态模式。然而,你可能想要设计具有不同状态模式的Agent节点。

3.2 不同的状态模式

一个Agent可能需要与其余Agent有不同的状态模式。例如,搜索Agent可能只需要跟踪查询和检索到的文档。在LangGraph中有两种方法可以实现这一点:

  • 定义具有单独状态模式的子图Agent。如果子图和父图之间没有共享状态键(通道),则需要添加输入/输出转换,以便父图知道如何与子图通信。
  • 定义具有私有输入状态模式的Agent节点函数,该模式与整个图的状态模式不同。这允许传递仅需要用于执行该特定Agent的信息。

3.3 共享消息列表

Agent之间通信的最常见方式是通过共享状态通道,通常是消息列表。这假设状态中至少有一个通道(键)由Agent共享。当通过共享消息列表通信时,还有一个额外的考虑因素:Agent是共享完整的历史记录还是仅共享最终结果?

共享完整历史记录

Agent可以共享他们的思维过程的完整历史记录(即“草稿垫”)与其他所有Agent。这种“草稿垫”通常看起来像一个消息列表。共享完整思维过程的好处是,它可能有助于其他Agent做出更好的决策,提高整个系统的整体推理能力。缺点是,随着Agent数量和复杂性的增长,“草稿垫”将迅速增长,可能需要额外的策略进行内存管理。

共享最终结果

Agent可以拥有自己的私有“草稿垫”,并且只与其余Agent共享最终结果。这种方法可能更适合拥有许多Agent或更复杂的Agent的系统。在这种情况下,你需要定义具有不同状态模式的Agent。

对于作为工具调用的Agent,监督者根据工具模式确定输入。此外,LangGraph允许在运行时传递状态给单个工具,以便从属Agent在需要时可以访问父状态。

关注我,紧跟本系列专栏文章,咱们下篇再续!

作者简介:魔都架构师,多家大厂后端一线研发经验,在分布式系统设计、数据平台架构和AI应用开发等领域都有丰富实践经验。

各大技术社区头部专家博主。具有丰富的引领团队经验,深厚业务架构和解决方案的积累。

负责:

  • 中央/分销预订系统性能优化

  • 活动&券等营销中台建设

  • 交易平台及数据中台等架构和开发设计

  • 车联网核心平台-物联网连接平台、大数据平台架构设计及优化

  • LLM Agent应用开发

  • 区块链应用开发

  • 大数据开发挖掘经验

  • 推荐系统项目

    目前主攻市级软件项目设计、构建服务全社会的应用系统。

参考:

  • 编程严选网

    本文由博客一文多发平台 OpenWrite 发布!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/56716.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

51单片机的超声波视力保护仪【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能 该系统由AT89C51/STC89C52单片机LCD1602显示模块温度传感器光照传感器超声波传感器按键、LED、蜂鸣器等模块构成。适用于视力保护仪、坐姿矫正器、超声波防近视等相似项目。 可实现功能: 1、LCD1602显示温度、光照、距离和学习时间 2、超声波传感器采集头部与探…

【计算机网络】HTTP报文详解,HTTPS基于HTTP做了哪些改进?(面试经典题)

HTTP协议基本报文格式 在计算机网络中,HTTP(超文本传输协议)是应用层的一种协议,用于客户端(通常是浏览器)和服务器之间的通信。HTTP报文分为请求报文和响应报文,以下是它们的基本格式。 1. H…

基于Java微信小程序的水果销售系统详细设计和实现(源码+lw+部署文档+讲解等)

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念,提供了一套默认的配置,让开发者可以更专注于业务逻辑而不…

PyTorch 介绍

什么是 PyTorch PyTorch 是一个开源的机器学习库,广泛用于计算机视觉和自然语言处理等应用。它由 Facebook 的人工智能研究团队开发,并得到了许多其他机构和个人的贡献。PyTorch 以其易用性、灵活性和动态计算图(也称为自动微分系统&#xf…

Nexpose 6.6.273 发布,新增功能概览

Nexpose 6.6.273 for Linux & Windows - 漏洞扫描 Rapid7 Vulnerability Management, released Oct 10, 2024 请访问原文链接:https://sysin.org/blog/nexpose-6/ 查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org 您的本地…

python学习-怎么在Pycharm写代码

打开Pycharm,点击文件-新建项目 2.选择pure python-点击箭头 展开 3.选择 Existing interpreter 如果 Existing interpreter 下没有相关环境 (1)点击**…** (2)选择python的安装路径 4.可修改文件名称-点击创建 …

STM32CUBEIDE的使用【三】RTC

于正点原子潘多拉开发板&#xff0c;使用stm32官方免费软件进行开发 CubeMx 配置 使用CubeMx 配置RTC 勾选RTC 设置日期和时间 配置LCD的引脚用来显示 STM32CUBEIDE 在usbd_cdc_if.c中重定向printf函数用于打印 #include <stdarg.h>void usb_printf(const char *f…

API项目5:申请签名 在线调用接口

开发申请签名 现在用户已经能看到这个接口了&#xff0c;也能看到这个接口文档&#xff0c;接下来就要在线调用 现在我们可以给每个新注册的用户自动分配一个签名和密钥&#xff0c;去修改一下注册流程&#xff1a; backend 项目&#xff0c;找到 UserServiceImpl.java 中的…

Miniconda管理虚拟环境【Python环境配置】

Miniconda管理虚拟环境【Python环境配置】 1. 下载并安装Miniconda2. 管理虚拟环境3. 管理虚拟环境中的包 1. 下载并安装Miniconda 1. 下载 从清华大学开源软件镜像站 | Tsinghua Open Source Mirror 下载Miniconda&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/anaconda…

go压缩的使用

基础&#xff1a;使用go创建一个zip func base(path string) {// 创建 zip 文件zipFile, err : os.Create("test.zip")if err ! nil {panic(err)}defer zipFile.Close()// 创建一个新的 *Writer 对象zipWriter : zip.NewWriter(zipFile)defer zipWriter.Close()// 创…

使用开源的 Vue 移动端表单设计器创建表单

FcDesigner Vant 版是一款基于 Vue3.0 的移动端低代码可视化表单设计器工具&#xff0c;通过数据驱动表单渲染。可以通过拖拽的方式快速创建表单&#xff0c;提高开发者对表单的开发效率&#xff0c;节省开发者的时间。 源码下载 | 演示地址 | 帮助文档 本项目采用 Vue3.0 和 …

HCIP open-Euler学习文档

第一期 操作系统基础&#xff0c;web基础 OpenEuler 目录 学习系统常用应用(Apache Nginx DNS MySQL)服务器集群架构(HAProxy, Nginx, LVS,keepalived)存储管理(GlusterFS,NAS,SAN)自动化基础(Ansible,SaltStack)Shell脚本基础(变量&#xff0c;语法&#xff0c;函数&…

使用fpm工具制作Vim.rpm包

背景&#xff1a;生产环境中的CentOS 7在安全扫描中被扫描出vim存在堆缓冲区溢出&#xff08;CVE-2024-45306&#xff09;等漏洞。根据漏洞说明&#xff0c;需要升级到最新版。 奈何CentOS 7已经停止维护了&#xff0c;所以&#xff0c;想在网上找一个最新版的vim.rpm相当不容易…

腾讯云宝塔面板前后端项目发版

后端发版 1. 打开“网站”页面&#xff0c;找到java项目&#xff0c;点击状态暂停服务 2.打开“文件”页面&#xff0c;进入jar包目录&#xff0c;删除原有的jar包&#xff0c;上传新jar包 3. 再回到第一步中的网站页面&#xff0c;找到jar项目&#xff0c;启动项目即可 前端发…

跨境业务收款难?Zoho Books来帮忙

外贸跨境企业应收账款管理繁琐&#xff0c;ZohoBooks财务管理软件提供自动化解决方案&#xff0c;简化开票、跟进、收款和账户更新流程&#xff0c;提升效率和准确性&#xff0c;助力企业优化现金流和财务健康。 什么是应收账款&#xff1f; 应收账款指的是企业在提供商品或服…

王爽汇编语言第三版实验1

前言 本系列的文章是对王爽老师的汇编语言中的实验的解答记录&#xff0c;原书一共有17个实验&#xff0c;由于学校的教学流程只做到了第14个实验&#xff0c;因此本文章只会有前十四个实验的解答记录,还有个比较重要的是&#xff0c;文章中会有原书实验中没有的题目&#xff…

汇总10个AI免费一键生成PPT的网站

一、前言 PPT幻灯片是现代办公和学习中的重要组成部分。它在工作、研究或培训中扮演着重要角色&#xff0c;并能够让观众更好地理解信息。随着当今人工智能技术的快速发展&#xff0c;现在有很多免费的AI PPT生成器可供选择&#xff0c;帮助用户更加便捷地制作出高效且具有较强…

rhce:列行性(at和cron)

配置 at练习 设置时间提醒 定义一分钟后显示命令&#xff0c;使用atq查看 cron练习 配置 systemctl status crond 查看文件所在位置 ll /var/spool/cron/ 主要功能 开始操作 进入界面操作每天早上9点说hello crontab -e 五个星号分别代表分时日月周&#xff0c;其次是执…

光通信——前传基本架构

一、前传基本架构 第三代移动通信技术引入了分布式射频接入网络&#xff08;Distributed Radio Access Network &#xff0c; D-RAN&#xff09;架构。在此架构中的的基带处理单元&#xff08; Baseband Unit &#xff0c; BBU&#xff09; 和 射频拉远单元&#xff08; Remot…

Kafka-初识

一、Kafka是什么&#xff1f; Kafka是一个高度可扩展、弹性、容错和安全的分布式流处理平台&#xff0c;由服务器和客户端组成&#xff0c;通过高性能TCP网络协议进行通信。它可以像消息队列一样生产和消费数据。可以部署在裸机硬件、虚拟机和容器上&#xff0c;也可以部署在本…