前面了解了基础的概念及流程,以及一些参数类
下面了解一些特殊的边和节点
条件边
常见的流程图可能长这个样子:
其中菱形的为条件节点(或者叫判定节点),但是在spring-ai-alibaba-graph中,并没有条件节点
在spring-ai-alibaba-graph中,条件是加在边上的
直觉添加条件边的方法可能是这个样子:addEdge(sourceNodeId, targetNodeId, condition)
但实际是这个样子:addConditionalEdges(sourceNodeId, condition, mappings)
sourceNodeId 是边的起始节点,condition 是判断条件,输出结果中包含一个 String 类型的结果,mappings 是一个Map<String, String>,key 是 condition 返回的结果中的 String, value 是 targetNodeId,目标节点id
也就是说,addConditionalEdges 方法添加了一个Edge对象,这个Edge对象包含了传统流程图中判定节点的逻辑,和后续从该判定节点延伸出的所有边
说实话这种设计给人的感觉不够直观,不清楚是为了与langgraph保持一致,还是有其他考量
并行节点
条件边是多边n选1,那如果多边n选n,也就是并行执行,类似下图,该如何操作
其实根据图形来设置节点和边即可
StateGraph stateGraph = new StateGraph(keyStrategyFactory)
.addNode("a", nodeasync(new ...))
.addNode("b", nodeasync(new ...))
.addNode("c", nodeasync(new ...))
.addNode("d", nodeasync(new ...)).addEdge(StateGraph.START, "a")
.addEdge("a", "b")
.addEdge("a", "c")
.addEdge("b", "d")
.addEdge("c", "d")
.addEdge("d", StateGraph.END)
在编译图时,会将b节点和c节点组合成为一个并行节点 ParallelNode,并行节点的id为“__PARALLEL__”+前序节点的id
ParallelNode:继承Node类,内部含id和ActionFactory,构造函数参数为【id,多个异步节点 List<AsyncNodeActionWithConfig> actions,状态中各字段的更新策略Map<String, KeyStrategy> keyStrategyMap】
ActionFactory 对应 lambda 表达式为:(config) -> new AsyncParallelNodeAction(actions, keyStrategyMap)
AsyncParallelNodeAction:实现了AsyncNodeActionWithConfig接口,提供 CompletableFuture<Map<String, Object>> apply(OverAllState state, RunnableConfig config) 方法,内部包含前面提到的多个异步节点 List<AsyncNodeActionWithConfig> actions,状态中各字段的更新策略Map<String, KeyStrategy> keyStrategyMap
AsyncParallelNodeAction执行时会同时执行内部的多个异步节点 List<AsyncNodeActionWithConfig> actions,并等待全部执行完成后进入下一节点
ps:并行节点的原节点,也就是b和c,后续的边不能是条件边,而且必须有同一个targetNode,也就是d,不支持配置下图的流程
子图节点
StateGraph child = ...StateGraph parent = ...parent.addNode("nodeId", child);...
所谓子图,就是图中图,以节点的形式将一个图嵌入到另一个图中
使用方法很简单,StateGraph 提供了一个重载方法 addNode(String id, StateGraph subGraph)
addNode 方法会将子图封装为 SubStateGraphNode ,该类内部包含id和一个StateGraph
编译时,ProcessedNodesEdgesAndConfig 会将子图中的START节点替换为子图外部的前序节点,将子图中的END节点替换为子图外部的后续节点,子图中的节点的id会替换为【子图节点id+节点id】
子图不支持内部以并行节点开始,也不支持子图外部后续节点为并行节点
ps:由于编译时是先处理子图,然后再处理并行节点,所以前一节的多步骤并行的流程也无法通过将b和b2做成子图节点来实现