ai-agent框架spring ai/alibaba源码原理分析(五) graph II 编译图 简介saa是java的ai agent框架本系列将深入剖析 Spring AI Alibaba 的源码实现与核心原理不仅可以指导agent的开发更可以改造框架增加新特性系列内容系列(一)架构完成系列(三)调用I工具完成II MCP-1 MCP MCP能力工具资源Promptssampling。。。springboot自动配置完成-2分布式 MCP-3 MCP securityIII skills完成系列(四) RAG完成I知识库文档读取分块嵌入向量storeII检索增强生成模块化混合检索融合重排系列(二)模型 model模型完成chat模型消息提示词结构化输出记忆chat clientadvisor组件系列(五) graph图结构节点和边StateGraph推理框架graph映射示例: ReActrelectionCoTPlan-And-ExecuteCompiledGraph图执行状态和存储系列(六) agent组件分析ReactAgent钩子和拦截器记忆结构化输出人工介入系列(七) MASI flow agent; handoffs模式toolcalling模式II分布式agentA2A分布式运行系列(九) agent管理平台(admin) agent发现(a2a)agent列表提示词管理会话管理skill管理MCP管理chat评估观测系列(八) I观测观测组件(micrometer-observation)观测点chatClientchat模型工具(tracing) II 模型评估本文分析graph图编译based spring ai alibaba v1.1.2.2关键词agentgraph缩写spring ai缩写saspring ai alibaba缩写saa参考资料概览 | Spring AI Alibaba spring ai alibaba官网文档https://docs.spring.io/spring-ai/reference/index.html spring ai官方文档SAA概览上图是saa原理源码分析场景视图每个包对应着saa/sa组件或特性是本文分析的目录model大模型的封装模型包括Chat嵌入audioimage等类型其中chat模型包括advisor组件提示词记忆等agent/graphsaa agent多agent与图紧密相关可以认为saa agent/多agent是一种既定的”图”形实现推理框架开发人员可以使用graph底层api直接构建graph使用agent获得既定的图形简化agent的开发外部调用(calling)工具MCPskillsRAG检索增强生成MASA2AFlowAgent子agnetagent Toolagent 集群studio简易的agent管理工具嵌入到agent带有agent面板列表agent提供chat界面用于调试agent是开发agent的便利工具admin管理台 agent的发布列表管理执行提示词工程评估和数据集观测graphsaa graph-core是saa的图组件以图的结构节点边构建处理流程节点执行动作边决定下一个节点对应的agentic是另一种模式整个流程大模型自主编排agentic省心省事但同时agentic容易失控纯粹看大模型心情因此目前比较好的方案主体使用flowable需要的时候使用agentic节点。spring ai alibabaagent的推理框架映射成graph多agent角色也映射成graph以图的节点承载执行逻辑边决定下一节点支持检查点保存执行状态实现执行的暂停和恢复外部介入本节介绍saa的中断机制中断等待外部干预例如人工验证同时生成检查点(CheckPoint)用于恢复执行上图是中断机制两种实现方式InterruptableAction实现该接口的NodeAction执行器识别Action类型中断返回提示等候外部恢复interruptsBefore/interrupteAfter设置interruptsBefore/ interrupteAfter在CompileConfig设置哪个节点的前/后中断执行时识别中断处理还有两种中断方式将在执行图中分析编译图前面分析了状态图状态图是图的结构目的是为了方便构建图编译图扁平化邻接表数据结构目的是为了高效执行上图是编译图类图编译把整个图包括子图的数据结构转换为扁平化的邻接表结构大大降低遍历复杂度并行处理使用并行节点/action节点内处理并行执行器不需处理。图中类下面详细分析可以适时返回参看类图下面分析原理和源码扁平化邻接表ProcessedNodesEdgesAndConfig负责扁平化状态图数据结构代码比较多用示例解释代码逻辑注释版的代码放到附录首先介绍一下邻接表A: [B],B: [C],C: []左连接点结构左是head节点右是数组head节点连接的节点右对应的图进一步若B是子图节点其子图 D-E, D-F,E-G,F-GProcessedNodesEdgesAndConfig处理过后A: [B-D],B-D: [B-E, B-F],B-E: [B-G],B-F: [B-G],B-G: [C],C: []主图子图扁平化合并到一个邻接表结构主图与子图节点(B)的连接重定向到子图的节点子图节点名称修改格式%s-%s最后返回子图的Node写入到nodeFactoryesid为keyaction工程为value的mapCompiledGraph.CompiledGraph()nodeFactoryes是最终的邻接表head节点集边和并行处理ProcessedNodesEdgesAndConfig处理后返回边(edges)是list图遍历按节点找边需要遍历list因此边数据需要转为map以sourceNodeId为key即ListEdge类型转为MapString, EdgeValue另外图有并行分支编译使用并行节点替代并行执行在节点action完成不需要执行器介入首先上图回顾一下图的边模型边处理分多targes和单个target处理单个target单个target又可以分为nodeId单command条件多command条件(带条件的并行)3个情况其中nodeIdEdgeValue是NodeId单command条件返回一个NodeId均可直接put到MapString, EdgeValue即可多command条件使用ConditionalParallelNode/ConditionalParallelNodeAction处理并行在其action处理不需执行器处理这也是编译的一个关键任务下面分析源码下面的代码来自CompiledGraph.CompiledGraph()方法接上节图扁平化处理返回处理单target进一步分为nodeid单command条件多command条件3种情况首先处理多command条件插入条件并行节点负责并行执行边原来的source节点连接到新增的并行节点上图展示示例图通过返回节点名称映射(mappings)找出返回节点集即示例的A1A2查找返回节点集的汇聚点上图的Bgraph组件的约束分支后需要汇聚到同一节点最后并行节点连到B即A-- edge(mappings[a1:A1, a2:A2]) --B 变成 A-- 并行节点 --B上面的isEmpty判断是错误的数量只能是1v2.0版本已经修改了最后单target的其余两种情况单comman条件和nodeId直接增加到edges多target并行分支处理与上面多command条件类似用ParallelNode/AsyncParallelNodeAction处理并行上面展示示例图A1A2A3是并行分支首先找到A1A2A3的汇聚点即B上图检验并行分支汇聚到一节点分支的边不能带条件获取并行节点的acton构建ParallelNode插入新的并行节点重新连接总结上图是示例编译后的图可以理解为是一个”降维”的处理”摆平”多层的主图子图结构”摆平”并行处理降低执行器复杂度提高执行效率编译前后对比本节对比编译前后类图编译前上图编译前类图为了清晰边部分类图放在下图图遍历需要使用状态图的数据结构遍历Node执行NodeAction若Node是子Node深度递归遍历并行包括并行分支多command边条件需要执行器处理编译后图编译后图的数据结构编译后邻接表结构节点集在nodeFactories nodeFactories的values存放ActionFatory节点连接的边放到edges注意虽然名字与原状态图一样但类型变了编译后edges是map类型状态图相当于list类型。并行处理替换为并行节点/action执行阶段并行执行与执行一般的action一样编译图与代码编译的意义是一样的减少执行的工作提高执行效率附录ProcessedNodesEdgesAndConfig的代码注释