Pārlūkot izejas kodu

feat:实现graph的demo;
搭建一个简单的graph(工作流),并成功运行;

yangyi 7 mēneši atpakaļ
vecāks
revīzija
1480eb6a0b

+ 90 - 0
spring-ai-learn/src/main/java/space/anyi/springAiAlibabaLearn/config/GraphConfig.java

@@ -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没有值")));
+    }
+}

+ 37 - 0
spring-ai-learn/src/main/java/space/anyi/springAiAlibabaLearn/controller/GraphController.java

@@ -0,0 +1,37 @@
+package space.anyi.springAiAlibabaLearn.controller;
+
+import com.alibaba.cloud.ai.graph.CompiledGraph;
+import com.alibaba.cloud.ai.graph.NodeOutput;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Flux;
+
+import java.util.Map;
+import java.util.function.Consumer;
+
+@RestController
+@RequestMapping("/graph")
+public class GraphController {
+    private static final Logger log = LoggerFactory.getLogger(GraphController.class);
+    private final CompiledGraph compiledGraph;
+
+    public GraphController(CompiledGraph compiledGraph) {
+        this.compiledGraph = compiledGraph;
+    }
+
+    @GetMapping("/quickStart")
+    public Flux<NodeOutput> quickStart(){
+        return compiledGraph.stream().log().doOnNext(new Consumer<NodeOutput>() {
+            @Override
+            public void accept(NodeOutput nodeOutput) {
+                log.debug("nodeOutput:{}",nodeOutput);
+                //获取工作流中存储的数据
+                Map<String, Object> data = nodeOutput.state().data();
+                log.debug("data:{}",data);
+            }
+        });
+    }
+}