|
@@ -0,0 +1,90 @@
|
|
|
|
|
+package space.anyi.springAiAlibabaLearn.config;
|
|
|
|
|
+
|
|
|
|
|
+import com.alibaba.cloud.ai.graph.*;
|
|
|
|
|
+import com.alibaba.cloud.ai.graph.action.AsyncNodeAction;
|
|
|
|
|
+import com.alibaba.cloud.ai.graph.action.NodeAction;
|
|
|
|
|
+import com.alibaba.cloud.ai.graph.exception.GraphStateException;
|
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
|
+import org.springframework.context.annotation.Bean;
|
|
|
|
|
+import org.springframework.context.annotation.Configuration;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+import java.util.Optional;
|
|
|
|
|
+
|
|
|
|
|
+@Configuration
|
|
|
|
|
+public class GraphConfig {
|
|
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(GraphConfig.class);
|
|
|
|
|
+ /**
|
|
|
|
|
+ * <a href='https://java2ai.com/docs/frameworks/graph-core/quick-start'>参考文档</>
|
|
|
|
|
+ * @return
|
|
|
|
|
+ * @throws GraphStateException
|
|
|
|
|
+ */
|
|
|
|
|
+ @Bean
|
|
|
|
|
+ public CompiledGraph compiledGraph() throws GraphStateException {
|
|
|
|
|
+ //key策略工厂,作用是指明stateGraph中变量的更新策略
|
|
|
|
|
+ KeyStrategyFactory keyStrategyFactory = new KeyStrategyFactory(){
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Map<String, KeyStrategy> apply() {
|
|
|
|
|
+ return Map.of(
|
|
|
|
|
+ //替换策略,简单的替换,所有类型都适用
|
|
|
|
|
+ "input1",KeyStrategy.REPLACE,
|
|
|
|
|
+ //合并策略,一般用于map类型的数据
|
|
|
|
|
+ "input2",KeyStrategy.MERGE,
|
|
|
|
|
+ //追加策略,一般用于列表类型的数据
|
|
|
|
|
+ "input3",KeyStrategy.APPEND
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ //1.创建状态图,用于存储工作流中的数据
|
|
|
|
|
+ StateGraph stateGraph = new StateGraph(keyStrategyFactory);
|
|
|
|
|
+ //创建节点,每个节点表示特定的处理流程
|
|
|
|
|
+ AsyncNodeAction asyncNodeAction1 = AsyncNodeAction.node_async(new NodeAction() {
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Map<String, Object> apply(OverAllState state) throws Exception {
|
|
|
|
|
+ //OverAllState表示图中的所有信息上下文,可以从中获取前面节点存储的信息
|
|
|
|
|
+ Optional<String> input1 = state.value("input1", String.class);
|
|
|
|
|
+ var input2 = state.value("input2", Map.class);
|
|
|
|
|
+ var input3 = state.value("input3", List.class);
|
|
|
|
|
+ log.debug("input1:{}", input1.orElse("input1没有值"));
|
|
|
|
|
+ log.debug("input2:{}", input2.orElse(Map.of("key","input2没有值")));
|
|
|
|
|
+ log.debug("input3:{}", input3.orElse(List.of("input3没有值")));
|
|
|
|
|
+ //返回表示对OverAllState数据的更新
|
|
|
|
|
+ return Map.of("input1", "修改后的input1");
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ AsyncNodeAction asyncNodeAction2 = AsyncNodeAction.node_async(state -> {
|
|
|
|
|
+ printLog(state);
|
|
|
|
|
+ return Map.of("input2", "修改后的input2");
|
|
|
|
|
+ });
|
|
|
|
|
+ AsyncNodeAction asyncNodeAction3 = AsyncNodeAction.node_async(state -> {
|
|
|
|
|
+ printLog(state);
|
|
|
|
|
+ return Map.of("input3", "修改后的input3");
|
|
|
|
|
+ });
|
|
|
|
|
+ //2.向工作流添加节点
|
|
|
|
|
+ stateGraph.addNode("node1", asyncNodeAction1);
|
|
|
|
|
+ stateGraph.addNode("node2", asyncNodeAction2);
|
|
|
|
|
+ stateGraph.addNode("node3", asyncNodeAction3);
|
|
|
|
|
+ //3.定义图中的边,边的作用是指明节点间的流转关系
|
|
|
|
|
+ stateGraph.addEdge(StateGraph.START,"node1");
|
|
|
|
|
+ stateGraph.addEdge("node1","node2");
|
|
|
|
|
+ stateGraph.addEdge("node2","node3");
|
|
|
|
|
+ stateGraph.addEdge("node3",StateGraph.END);
|
|
|
|
|
+ //4.编译图,最终使用的graph
|
|
|
|
|
+ return stateGraph.compile();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 打印日志
|
|
|
|
|
+ * @param state
|
|
|
|
|
+ */
|
|
|
|
|
+ private void printLog(OverAllState state) {
|
|
|
|
|
+ Optional<String> input1 = state.value("input1", String.class);
|
|
|
|
|
+ var input2 = state.value("input2", Map.class);
|
|
|
|
|
+ var input3 = state.value("input3", List.class);
|
|
|
|
|
+ log.debug("input1:{}", input1.orElse("input1没有值"));
|
|
|
|
|
+ log.debug("input2:{}", input2.orElse(Map.of("key","input2没有值")));
|
|
|
|
|
+ log.debug("input3:{}", input3.orElse(List.of("input3没有值")));
|
|
|
|
|
+ }
|
|
|
|
|
+}
|