spring-ai-alibaba 1.0.0.2 学习(十七)——初识graph
本文介绍了Spring-AI-Alibaba中的Graph模块,这是一个基于有向状态图的工作流编排框架。主要内容包括:1)Graph模块的核心概念(图、节点、边、状态);2)开发中遇到的文档不完整、代码层次不清等困难;3)通过简单示例演示了StateGraph的创建和使用流程;4)详细解析了核心类StateGraph、CompiledGraph及节点、边相关接口的设计。该模块借鉴了LangGrap
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中的其他功能及各种高级节点见下篇
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐

所有评论(0)