Parcourir la source

feat:实现graph的demo;
### 实现了一个单词造句并翻译的工作流
- node1负责造句;
- node2负责翻译;

yangyi il y a 7 mois
Parent
commit
bebd2be1cd

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

@@ -6,6 +6,10 @@ 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.ai.chat.messages.SystemMessage;
+import org.springframework.ai.chat.messages.UserMessage;
+import org.springframework.ai.chat.model.ChatModel;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
@@ -16,12 +20,19 @@ import java.util.Optional;
 @Configuration
 public class GraphConfig {
     private static final Logger log = LoggerFactory.getLogger(GraphConfig.class);
+    public final ChatModel chatModel;
+
+    public GraphConfig(ChatModel chatModel) {
+        this.chatModel = chatModel;
+    }
+
     /**
      * <a href='https://java2ai.com/docs/frameworks/graph-core/quick-start'>参考文档</>
      * @return
      * @throws GraphStateException
      */
     @Bean
+    @Qualifier("compiledGraph")
     public CompiledGraph compiledGraph() throws GraphStateException {
         //key策略工厂,作用是指明stateGraph中变量的更新策略
         KeyStrategyFactory keyStrategyFactory = new KeyStrategyFactory(){
@@ -87,4 +98,56 @@ public class GraphConfig {
         log.debug("input2:{}", input2.orElse(Map.of("key","input2没有值")));
         log.debug("input3:{}", input3.orElse(List.of("input3没有值")));
     }
+
+    /**
+     * 输出一个单词,输出句子和翻译的工作流
+     * 1.输出单词
+     * 2.造句
+     * 3.翻译
+     * @return
+     */
+    @Bean
+    @Qualifier("createStanceGraph")
+    public CompiledGraph createStanceGraph() throws GraphStateException {
+        KeyStrategyFactory keyStrategyFactory = new KeyStrategyFactory(){
+            @Override
+            public Map<String, KeyStrategy> apply() {
+                return Map.of(
+                        "word",KeyStrategy.REPLACE,
+                        "stance",KeyStrategy.REPLACE,
+                        "translation",KeyStrategy.REPLACE
+                );
+            }
+        };
+        //1.创建状态图,用于存储工作流中的数据
+        StateGraph stateGraph = new StateGraph(keyStrategyFactory);
+        //创建节点,每个节点表示特定的处理流程
+        AsyncNodeAction asyncNodeAction1 = AsyncNodeAction.node_async(state -> {
+            //数据处理,造句
+            Optional<String> word = state.value("word", String.class);
+            SystemMessage systemMessage = SystemMessage.builder().text("你是一个造句小助手.根据用户输入的英文单词,输出一个英文句子.如果用户输入的是:unknow,则直接输出:unknow word!").build();
+            UserMessage userMessage = UserMessage.builder().text(word.orElse("unknow")).build();
+            String stance = chatModel.call(systemMessage,userMessage);
+            //更新数据
+            return Map.of("stance", stance);
+        });
+        AsyncNodeAction asyncNodeAction2 = AsyncNodeAction.node_async(state -> {
+            //翻译
+            Optional<String> stance = state.value("stance", String.class);
+            SystemMessage systemMessage = SystemMessage.builder().text("你是一个英语翻译小助手.根据用户输入的英文句子,输出对应的中文.如果用户输入的是:unknow,则直接输出:unknow stance!").build();
+            UserMessage userMessage = UserMessage.builder().text(stance.orElse("unknow")).build();
+            String translation = chatModel.call(systemMessage,userMessage);
+            return Map.of("translation", translation);
+        });
+
+        //2.向工作流添加节点
+        stateGraph.addNode("node1", asyncNodeAction1);
+        stateGraph.addNode("node2", asyncNodeAction2);
+        //3.定义图中的边,边的作用是指明节点间的流转关系
+        stateGraph.addEdge(StateGraph.START,"node1");
+        stateGraph.addEdge("node1","node2");
+        stateGraph.addEdge("node2",StateGraph.END);
+        //4.编译图,最终使用的graph
+        return  stateGraph.compile();
+    }
 }

+ 11 - 1
spring-ai-learn/src/main/java/space/anyi/springAiAlibabaLearn/controller/GraphController.java

@@ -2,10 +2,14 @@ package space.anyi.springAiAlibabaLearn.controller;
 
 import com.alibaba.cloud.ai.graph.CompiledGraph;
 import com.alibaba.cloud.ai.graph.NodeOutput;
+import jakarta.annotation.Resource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import reactor.core.publisher.Flux;
 
@@ -17,9 +21,11 @@ import java.util.function.Consumer;
 public class GraphController {
     private static final Logger log = LoggerFactory.getLogger(GraphController.class);
     private final CompiledGraph compiledGraph;
+    private final CompiledGraph createStanceGraph;
 
-    public GraphController(CompiledGraph compiledGraph) {
+    public GraphController(@Autowired @Qualifier("compiledGraph")CompiledGraph compiledGraph, @Autowired @Qualifier("createStanceGraph")CompiledGraph createStanceGraph) {
         this.compiledGraph = compiledGraph;
+        this.createStanceGraph = createStanceGraph;
     }
 
     @GetMapping("/quickStart")
@@ -34,4 +40,8 @@ public class GraphController {
             }
         });
     }
+    @GetMapping("/createStance")
+    public Map<String, Object> createStance(@RequestParam("word")String word){
+        return createStanceGraph.stream(Map.of("word", word)).log().last().block().state().data();
+    }
 }