1.简介

graph模块是spring-ai-alibaba模仿langgraph引入的一个模块,graph本身是图的意思,官方解释graph模块为编排框架,我个人理解为类似工作流的一种框架,让智能体按照设置好的流程图来一步步执行。

1.1困难

spring-ai-alibaba本身是一个比较新的项目,处于急速发展中,比不上spring等框架经过多年发展,比较成熟。学习过程中可能会遇到以下问题:

1. 概念不熟悉:graph并不是spring-ai里的原生概念,刚从spring-ai过来的同学可能有些懵,这是借鉴langgraph的一个模块,也可以参考一些langgraph的学习文档

2. 文档不完整:spring-ai-alibaba官方网站上对于graph的介绍零零碎碎,不太完整,没有一个循序渐进的教程,期待官方对相关文档进行补充

3. 代码不清晰:graph没有像spring-ai那样,给每一个职责抽象一个对应的接口,并以这些接口为基础给出整体的框架流程图,所以在理解上可能会困难一点,不过graph中本身概念并不多,可以结合示例逐个研究

4. 层次不分明:源码中很多包都平铺在第一层,缺少一个清晰的层次和归纳,无法根据代码结构建立一个清晰的第一印象

以上就是我在学习过程中感觉可以改进优化的地方,不过还是那句话,在项目急速发展期这种情况也是正常的,相信项目组后面会持续进行优化。

2.概念

graph中涉及到的概念不太多,主要以图、点、边、状态四类为主:

2.1图:这里的图不是图片的图,是大学中离散数学课程中的一个章节,是由节点和边构成的一种图形,有点类似地图,起点、终点,路线这样。 graph中用到的图主要是有向状态图。

2.2节点:在spring-ai-alibaba中负责执行某种操作的一个环节,例如大模型节点、知识库检索节点、人工介入节点等,节点也可以是一个子图。

2.3边:负责连接两个节点,有方向,代表流程执行方向。

2.4状态:各个节点间的全局共享变量。

3.简单样例

大概有了个模糊的概念,看一个简单的样例

3.1 定义流程图

KeyStrategyFactory keyStrategyFactory = ...

StateGraph stateGraph = new StateGraph(keyStrategyFactory)                
.addNode("expander", node_async(new ExpanderNode(chatClientBuilder)))                
.addEdge(StateGraph.START, "expander")                
.addEdge("expander", StateGraph.END);

graph的核心类就是StateGraph状态图,学习graph模块可以从StateGraph类开始向外整理

上述代码创建了一个 START -> expander -> END 的最简单的流程图

代码中初始化StateGraph后,添加了一个expander节点,然后添加了一个START到expander的边,然后又添加了一个expander到END的边

3.2 使用流程图

前面是定义流程图,然后看一下使用流程图(ExpanderNode是自定义节点,暂时忽略)

RunnableConfig runnableConfig = ...;        
Map<String, Object> objectMap = ...;        

Optional<OverAllState> invoke = stateGraph.compile().invoke(objectMap, runnableConfig);        
Map<String, Object> result = invoke.map(OverAllState::data).orElse(new HashMap<>());

上述代码首先调用StateGraph的compile方法进行编译,然后调用invode方法执行,最终得到结果

业务实现都放在自定义节点ExpanderNode中,要自定义节点,实现NodeAction接口即可

4.相关接口及实现类

然后看一下样例中提到的各个概念下的接口和类

StateGraph 类:状态图,核心类

提供 compile 方法,将 StateGraph 编译为 CompiledGraph

提供 addEdge 方法,用法为addEdge(起点id,终点id)

提供 addNode 方法,用法为addNode(节点id,节点)

CompiledGraph 类:编译后的图

提供一个 invoke 方法来执行图的逻辑

NodeAction接口:自定义节点需要实现的接口

OverAllState类:全局状态,即全局共享参数

核心类 核心类常用方法 其他相关类或接口
StateGraph

addEdge

addNode

compile

CompiledGraph
Edge 构造函数Edge(String sourceId)

EdgeValue

EdgeCondition

EdgeAction

AsyncEdgeAction

节点 NodeAction apply

Node

ActionFactory

AsyncNodeActionWithConfig

NodeActionWithConfig

AsyncNodeAction

状态 OverAllState data

KeyStrategy

HumanFeedback

其中边和节点的部分接口有异步封装

业务接口 异步封装
节点 NodeAction AsyncNodeAction
带配置的节点 NodeActionWithConfig AsyncNodeActionWithConfig
EdgeAction AsyncEdgeAction

Async* : AsyncXXX 接口一般是为了将 XXX 接口封装为异步,AsyncXXX 接口会继承 Function 或 BiFunction 接口,提供一个 apply 方法,apply 方法的入参与 XXX 接口相同,返回则是将 XXX 的返回类型套上了 CompletableFuture。

5.衍生类说明

5.1图(状态图)

首先是图,图中主要是 StateGraph 和调用 StateGraph.compile 后返回的 CompiledGraph。

5.1.1 StateGraph 类:包含节点集合 Nodes、边集合 Edges、全局状态 OverAllState、OverAllStateFactory(新版本已弃用)等。

提供 compile 方法,将 StateGraph 编译为 CompiledGraph,接收 CompileConfig 类型的参数或无参,返回 CompiledGraph 类型的结果。

提供 addEdge 和 addNode 方法用来添加边和节点。

5.1.2 CompiledGraph 类:包含 StateGraph、OverAllState、Map<String, AsyncNodeActionWithConfig> 类型的 nodes、Map<String,EdgeValue> 类型的 edges、CompileConfig、ProcessedNodesEdgesAndConfig 等。

提供一个 invoke 方法来执行图的逻辑。

5.2 边

5.2.1 Edge 记录:这里的Edge记录是指同一个节点出发的若干条边,包含一个起点 id 和若干个终点对象 EdgeValue

5.2.2 EdgeValue 记录:包含终点 id 和 EdgeCondition,EdgeCondition 可以为空

5.2.3 EdgeCondition 记录:边的条件,包含 AsyncEdgeAction 和一个 Map

5.2.4 AsyncEdgeAction 接口:继承了 Function 接口,定义了一个 apply 方法,接收OverAllState 类型参数,返回 CompletableFuture<String>。

以 lambda 表达式表示该接口:OverAllState -> CompletableFuture<String>

同时提供一个 edge_async 静态方法,将 EdgeAction 封装为异步 AsyncEdgeAction。

5.2.5 EdgeAction 接口:边相关的操作可以实现该接口,定义了一个 apply 方法,接收OverAllState 类型参数,返回 String。 

以 lambda 表达式表示该接口 OverAllState -> String

5.3节点 

概述:节点中最核心的是 NodeAction 接口,要自定义节点,实现该接口即可

可以通过 AsyncNodeAction 的 node_async 方法将 NodeAction 封装为异步的 AsyncNodeAction

当使用 StateGraph 的 addNode 方法时,addNode 内部会使用 AsyncNodeActionWithConfig 的 of 方法将 AsyncNodeAction 再封装为 AsyncNodeActionWithConfig

即 NodeAction -> AsyncNodeAction -> AsyncNodeActionWithConfig

NodeAction 接口:定义了一个 apply 方法,接收 OverAllState 类型的参数,返回 Map<String, Object> 类型的结果。

以lambda 表示该接口:OverAllState -> Map<String, Object>

AsyncNodeAction 接口:继承了 Function 接口,定义了一个 apply 方法,接收 OverAllState 类型的参数,返回 CompletableFuture<Map<String, Object>> 类型的结果。

以 lambda 表示该接口:OverAllState -> CompletableFuture<Map<String, Object>>

同时提供了一个 node_async 方法,接收 NodeAction 类型的参数,返回 AsyncNodeAction 类型的结果。

NodeActionWithConfig 接口:附带 config 的 NodeAction,定义了一个 apply 方法,接收 OverAllState 和 RunnableConfig 类型的参数,返回 Map<String, Object> 类型的结果。

以lambda表示该接口:(OverAllState,RunnableConfig)-> Map<String, Object>

AsyncNodeActionWithConfig 接口:附带 config 的 AsyncNodeAction,继承了 BiFunction 接口,定义了一个 apply 方法,接收 OverAllState 和 RunnableConfig 类型的参数,返回 CompletableFuture<Map<String, Object>> 类型的结果。

以 lambda 表示该接口:(OverAllState,RunnableConfig)-> CompletableFuture<Map<String, Object>>

同时提供了一个 node_async 静态方法,接收 NodeActionWithConfig 类型的参数,返回 AsyncNodeActionWithConfig 结果。

同时提供了一个 of 静态方法,接收 AsyncNodeAction 类型的参数,返回 AsyncNodeActionWithConfig 结果。

Node 类:包含一个 id 与 ActionFactory。ActionFactory 的作用是延迟创建,在调用 StateGraph 的 compile 时才创建真正的 AsyncNodeActionWithConfig。

ActionFactory 接口:定义了一个 apply 方法,接收 CompileConfig 类型的参数,返回 AsyncNodeActionWithConfig 类型的结果。

以lambda表示该接口:CompileConfig -> AsyncNodeActionWithConfig

5.4状态

OverAllState类:包含一个Map<String, Object>类型的data,负责保存执行结果;一个Map<String, KeyStrategy>类型的keyStrategies,一个HumanFeedback类型的humanFeedback。

KeyStrategy接口:继承了BiFunction接口

HumanFeedback类:包含一个Map<String, Object>类型的data,当前节点id,下一节点id

5.5 其他

Nodes:StateGraph中Node的容器类,内部含有一个Set<Node>

Edges:StateGraph中Edge的容器类,内部含有一个List<Edge>

OverAllStateFactory:OverAllState的工厂类

KeyStrategyFactory:KeyStrategy的工厂类

CompileConfig:编译参数

RunnableConfig:运行参数

ProcessedNodesEdgesAndConfig类:负责处理子图 

GraphRepresentation记录:可视化相关,负责打印输出图信息

5.6方法

StateGraph.compile:

使用ProcessedNodesEdgesAndConfig处理子图,使用ActionFactory创建各节点,处理并行边(将a->b,a->c,b->d,c->d这种分支的,其中b、c合并为一个ParallelNode)

以上简单介绍了下graph中的核心类和衍生类,graph中的其他功能及各种高级节点见下篇

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐