Bili-Docs
技术工具AI 应用

🦜🕸️ LangGraph Supervisor 200 行代码复刻 CrewAI 😨

视频介绍了如何利用 LangGraph Supervisor 库,通过极简代码复刻 CrewAI 的多智能体协作功能,并对比了两者的实现逻辑。

UP主: 沧海九粟 · 时长: 19:34 · 🔗 B站原视频

发布: 2025-02-18 · 收录: 2025-02-19

标签: LangGraph · CrewAI · 多智能体 · AI编程 · LangChain

开场与主题

小朋友们大家好,欢迎来到 Lin Action。今天给大家介绍 LangChain 团队最新推出的一个上层类库,叫做 LangGraph Multi-Agent Supervisor。简单来讲,它用 200 行左右的代码复刻了 CrewAI 的基础功能,也就是 CrewAI 刚出来时候的经典功能。

今天给大家介绍一下如何使用这个类库,以及它背后的实现。因为它代码确实比较短小精悍。

先看 CrewAI 的经典用法(用于对比)

在介绍这个类库之前,我们先看一下 CrewAI 的经典实现和用法。我们来到 CrewAI 的页面,可以看到它经典的用法大概可以分成三步,确实非常简单,这也是它的立足之本。

第一步,创建一些 crew,也就是创建一些“工作人员”。创建方式也比较简单:需要一个 agent,然后给它 role、goal、backstory、tools,再绑定大语言模型。也就是定义它的身份、目标、个人背景,给它足够的工具,然后使用大模型来驱动,这样 agent 就定义好了。

第二步,定义任务。任务会包括任务描述、期待的输出,以及这个任务所绑定的 agent。你可以指定 agent,也可以不指定。一般还是根据实际场景需求来绑定。

第三步,kick off。把前面准备好的工作人员、准备好的任务(可以多个任务、多个工作人员),再指定一个流转方式,比如顺序流转,然后开始执行。最终等待输出返回就好了。目标也可以通过外部传入,比如任务里带一个参数 topic,再传进去。

这就是最基本、最经典的使用方式。

LangGraph Supervisor 的用法:同样是“三步走”

回过头来看 LangGraph Supervisor 这个库的使用方式。我们先不看结构图,先看用法。

首先定义一系列工具,比如加法、乘法、web 搜索。

然后创建 agent,绑定模型、添加工具。这里有两个 agent:

  • 第一个是数学 agent,绑定 add 和 multiply,告诉它你是谁、你是干什么的,也就是指定身份和背景。
  • 第二个是研究 agent,绑定 web search,告诉它你是全球顶级研究者,可以做 web search,但不要去碰数学相关的事情,做一定隔离。

两个 agent 就这样定义好了。

接着定义 workflow。在 workflow 里给它团队任务背景:你现在是一个团队,有数学专家和研究专家,什么情况下该找谁做什么。你也可以不写,但写了会更明确,类似前面 CrewAI 的 task 绑定 agent,只不过这里是通过提示词去完成。

最后就是生成 workflow,把任务扔进去运行。它本质写法还是和 LangGraph 比较接近,但你会发现定义 agent、团队背景、最终任务,然后运行任务,也是三步走,和前面的方式本质很接近:提示词驱动 + 工具绑定 + 内置的流程预设,就可以把一个多 agent 系统初步构建起来。

核心代码其实就这么几句,和 CrewAI 很接近。这也印证了我们之前常说的:LangGraph 这种底层框架要实现上层封装、结构化的 high level,其实相对容易。随着 LangGraph 不断成熟,这件事变得越来越容易,所以你会看到 200 行代码就能把这事情做出来,因为很多能力都预埋在 LangGraph 框架里。

Supervisor 架构:中心化调度 + Everything are tools

再来看实现逻辑,也就是架构流程。这是一个典型的 multi-agent system。在 LangGraph 体系里也有对 multi-agent system 的基础梳理,其中最重要的架构之一就是 supervisor 架构。

supervisor(监督者)模式的核心是:有一个中心节点作为驱动、组织、规划者,去驱动其他节点。换个角度看,如果你用单个 agent 的视角,也可以把其他 worker agent 当成 tools。核心思想就是 Everything are tools:外部函数、工具 API,甚至 agent 本身都可以当作工具来调用。这样就能组织成 supervisor 的中心化模式,用来组织、串联、协调。

运行时流程:handoff 交接与回到 supervisor 再规划

回到这个库的执行流程:先添加 agent,把它们加到一个组里。具体执行时通过 handoff,把任务传递给某个 agent。agent 通常是一个典型的 ReAct agent,负责具体处理。执行完把结果返回给 supervisor,再由 supervisor 做下一步规划,继续指派给特定 agent 执行。

这就是典型的 supervisor 结构。在这里它特指多 agent 体系结构。不过它并不是只有 multi-agent system 才能用;单 agent system 也可以用类似方式,只是把“别的能力”当成工具来用。对于 multi-agent system 来说,本质上也还是把 agent 作为工具,所以本质不变。

安装与附加能力:仍然没跳出 LangGraph 体系

安装方式很简单:安装 langgraph-supervisor 就可以。

它还呈现了一些附加功能(不是高级功能),但整体能力没有跳出 LangGraph 体系,这点要记住。

附加功能 1:消息历史管理(Full history vs Last message)

第一个附加功能是 message history management。多 agent 之间通讯、业务交流需要信息传递:supervisor handoff 上下文给 agent,agent 做完把结果返回给 supervisor,然后再 handoff 给下一个 agent。

关键问题是:handoff 时传递什么?

有两种选择:

  1. Full history:把所有消息原封不动传递给下一个 agent。因为在 LangGraph 里消息队列多数维护在 message state 里,所以直接全量传就行。
  2. Last message:只传递上一个 agent 最终输出的内容。

Last message 的好处是减少干扰:不会把前一个 agent 的思考过程、执行过程带给后面的 agent。类似推理模型的做法:会把上一轮输入输出作为下一轮输入,但中间思考过程产生的 token 不会传递。一方面思考过程很长会占上下文窗口,另一方面在多 agent 场景里各 agent 分管领域不同,传太多过程容易造成混乱和幻觉。所以这种情况下更常用 last message,把最终结果传递就好,可以减轻多 agent 之间干扰。

附加功能 2:多层级层次结构(Multi-level hierarchies)

第二个特性是 multilevel hierarchies,用来组织层级化的多 agent 系统。

既然可以把几个 agent 变成一个组,同样也可以把这一组再变成更高阶的组,就像组织架构一样。比如有 researching team 和 writing team 两个小组,再创建一个更高层 supervisor,这个 supervisor 里包含的不是单个 agent,而是两个 supervisor 组。后面的用法一模一样。

本质原因还是 Everything are tools:任何东西都可以当工具调用执行,所以自然可以一层层嵌套。

附加功能 3:长短期 Memory 的注入(Checkpoint + Store)

再往下是 LangGraph 本身就具备的特性:长短期 memory。这里主要演示怎么注入 memory,方式和传统注入方式一样。

比如还是两个 agent 创建一个组,在创建 workflow 的地方注入短期 memory checkpoint,以及长期 memory store 就可以。注入更多是在最顶层做就行,整体使用方式很简单直接。

这种 high-level 封装的优缺点

这种方式的缺点也有:它是 high level 的实现,是黑盒,不能精细控制当中的过程。

优点也很明显:写起来简单很多。特别适合一些简单逻辑、不需要精细流程控制的场景,可以试试。

代码结构:两个文件加起来约 200 行

下面介绍一下它的代码实现。代码就在一个目录下,只有两个文件:一个 140 多行,一个 60 多行,加起来约 200 行。两个文件都很重要:一个是 supervisor,管理整个体系;一个是 handoff,专门处理交接信息。

supervisor 文件:图的构建与状态(AgentState)

在 supervisor 文件里主要看图的构建。

它创建图时的 state 默认来自 AgentState。AgentState 来自 LangGraph 新加的一个 prebuilt 工具类 chat agent executor。官方文档里目前还没有它的 API 介绍,但从代码基本可以推测,它是带了 messages 列表的一种状态。

也就是说外层默认不需要自己定义 state。当然你也可以在创建 supervisor 时传入自己的 state。默认就用这个带 message 列表的 state 作为整个系统的 state。

然后添加 supervisor 工作节点。supervisor 节点也很巧妙:它利用了另一个 prebuilt 工具类 create_react_agent。通过一行代码就能创建一个最基础的 ReAct agent,绑定 tools、prompt、schema。

中心节点有了之后,外层工作节点由外部传入。把这些节点一个个添加进来,再做一层封装,最后把这些节点连回中心 supervisor,就完成整个图的构建。

外层对每个传入 agent 的封装里,最重要的就是消息传递机制:full history 就不做处理;last message 就截取最后消息再传递。

handoff 文件:通过 Command.goto 做动态跳转

在具体流转里有个重要执行过程:handoff。handoff 文件里有一个 handoff_to 工具,帮助进行节点之间的流转。

这个工具参数是 agent 名称。它会把 agent 当成工具来描述,所以 agent 的名字最好简单清晰,后续会生成类似 transfer to XXX agent 这种语义化名称,增强可调用性。

这里有个很重要的技巧:利用新的 Command 机制做节点跳转。通过 Command 的 goto 能力,从工具里直接跳转到某一个特定 agent 节点。这样就少了很多条件边和实体边,代码简化很多。

调用这个工具发生在 supervisor 节点中,所以最终是从 supervisor 跳转到下一个动态绑定的 agent 节点。

agent 作为工具绑定到 supervisor:Everything are tools 的落地

创建完 handoff 工具后,在 create_supervisor 里会把每个外部 agent 都变成一个 handoff_to 工具,再把这些工具注入给 supervisor 节点进行绑定。supervisor 负责判断该由哪个 agent 执行,执行完后结果再回到 supervisor,再继续规划下一步。

这就是 Everything are tools 的典型落地:工具是工具,agent 也是工具。这样就能快速构建一个层级化、中心式,并且能在节点之间动态跳转的框架体系。

工具/agent 最终执行在哪:ReAct 体系里的 ToolNode

最后可能有人会问:工具的最后执行在哪里,或者 agent 的最后执行在哪里?

这里调用的是 prebuilt 的 create_react_agent。绑定的 tools 里已经包含了这些 agent(以工具形式注入)。最终执行是在标准 ReAct 体系里,通过 ToolNode 去执行。流程是:supervisor 选定要执行哪个 agent,通过 command 指定跳转到哪个节点;每个 agent 已经是图上的节点,所以图就会正常流转,执行对应节点就可以了。

结尾:建议动手试与交流

差不多整个库的介绍就到这里。大家可以简单动手试一下,因为现在构建方式已经非常简单,直接复制案例代码,安装、配置模型,就能运行做实验。

对源代码有兴趣的话也可以参考前面分享的内容进行探索。有相关问题也欢迎在评论区交流互动。今天分享就到这里,谢谢大家。

On this page