Преглед на файлове

feat:实现自定义的CallAdvisor和自定义的StreamAdvisor;验证AdvisorChain的执行流程;

yangyi преди 7 месеца
родител
ревизия
711c1fd722

+ 47 - 0
src/main/java/space/anyi/springAiAlibabaLearn/advisor/MyCallAdvisor.java

@@ -0,0 +1,47 @@
+package space.anyi.springAiAlibabaLearn.advisor;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.ai.chat.client.ChatClientRequest;
+import org.springframework.ai.chat.client.ChatClientResponse;
+import org.springframework.ai.chat.client.advisor.api.CallAdvisor;
+import org.springframework.ai.chat.client.advisor.api.CallAdvisorChain;
+
+/**
+ * Advisor类似Web中的Filter和SpringMVC中Interceptor
+ * 也可以组成Advisor Chain
+ * 实现CallAdvisor接口自定义自己的advisor
+ * CallAdvisor使用用在同步调用LLM的场景
+ * StreamAdvisor使用在异步流式调用LLM的场景
+ */
+//CallAdvisor使用用在同步调用LLM的场景
+public class MyCallAdvisor implements CallAdvisor {
+    private final Logger log = LoggerFactory.getLogger(MyCallAdvisor.class);
+    @Override
+    public ChatClientResponse adviseCall(ChatClientRequest chatClientRequest, CallAdvisorChain callAdvisorChain) {
+        log.info("{}的前置处理",getName());
+        //转到下一个advisor进行处理
+        ChatClientResponse chatClientResponse = callAdvisorChain.nextCall(chatClientRequest);
+        log.debug("{}中得到的结果chatClientResponse:{}",getName(),chatClientResponse);
+        log.info("{}的后置处理",getName());
+        return chatClientResponse;
+    }
+
+    /**
+     * Advisor的名称
+     * @return String
+     */
+    @Override
+    public String getName() {
+        return "MyAdvisor1";
+    }
+
+    /**
+     * Advisor的优先级,数字越小优先级越高
+     * @return int
+     */
+    @Override
+    public int getOrder() {
+        return 0;
+    }
+}

+ 47 - 0
src/main/java/space/anyi/springAiAlibabaLearn/advisor/MyCallAdvisor2.java

@@ -0,0 +1,47 @@
+package space.anyi.springAiAlibabaLearn.advisor;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.ai.chat.client.ChatClientRequest;
+import org.springframework.ai.chat.client.ChatClientResponse;
+import org.springframework.ai.chat.client.advisor.api.CallAdvisor;
+import org.springframework.ai.chat.client.advisor.api.CallAdvisorChain;
+
+/**
+ * Advisor类似Web中的Filter和SpringMVC中Interceptor
+ * 也可以组成Advisor Chain
+ * 实现CallAdvisor接口自定义自己的advisor
+ * CallAdvisor使用用在同步调用LLM的场景
+ * StreamAdvisor使用在异步流式调用LLM的场景
+ */
+//CallAdvisor使用用在同步调用LLM的场景
+public class MyCallAdvisor2 implements CallAdvisor {
+    private final Logger log = LoggerFactory.getLogger(MyCallAdvisor2.class);
+    @Override
+    public ChatClientResponse adviseCall(ChatClientRequest chatClientRequest, CallAdvisorChain callAdvisorChain) {
+        log.info("{}的前置处理",getName());
+        //转到下一个advisor进行处理
+        ChatClientResponse chatClientResponse = callAdvisorChain.nextCall(chatClientRequest);
+        log.debug("{}中得到的结果chatClientResponse:{}",getName(),chatClientResponse);
+        log.info("{}的后置处理",getName());
+        return chatClientResponse;
+    }
+
+    /**
+     * Advisor的名称
+     * @return String
+     */
+    @Override
+    public String getName() {
+        return "MyAdvisor2";
+    }
+
+    /**
+     * Advisor的优先级,数字越小优先级越高
+     * @return int
+     */
+    @Override
+    public int getOrder() {
+        return 1;
+    }
+}

+ 32 - 0
src/main/java/space/anyi/springAiAlibabaLearn/advisor/MySteamAdvisor.java

@@ -0,0 +1,32 @@
+package space.anyi.springAiAlibabaLearn.advisor;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.ai.chat.client.ChatClientRequest;
+import org.springframework.ai.chat.client.ChatClientResponse;
+import org.springframework.ai.chat.client.advisor.api.StreamAdvisor;
+import org.springframework.ai.chat.client.advisor.api.StreamAdvisorChain;
+import reactor.core.publisher.Flux;
+//StreamAdvisor使用在异步流式调用LLM的场景
+public class MySteamAdvisor implements StreamAdvisor {
+    private final Logger log = LoggerFactory.getLogger(MySteamAdvisor.class);
+    @Override
+    public Flux<ChatClientResponse> adviseStream(ChatClientRequest chatClientRequest, StreamAdvisorChain streamAdvisorChain) {
+        log.info("{}的前置处理",getName());
+        //转到下一个advisor进行处理
+        Flux<ChatClientResponse> chatClientResponseFlux = streamAdvisorChain.nextStream(chatClientRequest);
+        log.debug("{}中得到的结果chatClientResponseFlux:{}",getName(),chatClientResponseFlux);
+        log.info("{}的后置处理",getName());
+        return chatClientResponseFlux;
+    }
+
+    @Override
+    public String getName() {
+        return "MySteamAdvisor";
+    }
+
+    @Override
+    public int getOrder() {
+        return 0;
+    }
+}

+ 68 - 0
src/main/java/space/anyi/springAiAlibabaLearn/controller/AdvisorController.java

@@ -0,0 +1,68 @@
+package space.anyi.springAiAlibabaLearn.controller;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.ai.chat.client.ChatClient;
+import org.springframework.ai.chat.client.advisor.api.Advisor;
+import org.springframework.ai.chat.client.advisor.api.CallAdvisor;
+import org.springframework.ai.chat.model.ChatModel;
+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 space.anyi.springAiAlibabaLearn.advisor.MyCallAdvisor;
+import space.anyi.springAiAlibabaLearn.advisor.MyCallAdvisor2;
+import space.anyi.springAiAlibabaLearn.advisor.MySteamAdvisor;
+
+import java.util.Collections;
+import java.util.List;
+
+@RestController
+@RequestMapping("/advisor")
+public class AdvisorController {
+    private final Logger log = LoggerFactory.getLogger(AdvisorController.class);
+    private final ChatClient chatClient;
+
+    public AdvisorController(ChatModel chatModel) {
+        this.chatClient = ChatClient.create(chatModel);
+    }
+    @GetMapping("/testCallAdvisor")
+    public String callAdvisorTest(){
+        //测试一个advisor的场景
+        return chatClient
+                .prompt("who are you?")
+                //添加一个advisor
+                .advisors(new MyCallAdvisor())
+                .call()
+                .content();
+    }
+    @GetMapping("/testChain")
+    public String advisorChainTest(){
+        //测试advisorChain的场景
+        List<Advisor> advisorList = List.of(new MyCallAdvisor(), new MyCallAdvisor2());
+        /**
+         * 链的处理流程与FilterChain和InterceptorChain的处理流程是一致的(有调用栈的存在)
+         * 1.advisor1前置处理
+         * 2.advisor2前置处理
+         * 3.实际调用LLM...
+         * 4.advisor2后置处理
+         * 5.advisor1后置处理
+         */
+        return chatClient
+                .prompt("Java是世界上最好的语言?")
+                //添加一个advisorList
+                .advisors(advisorList)
+                .call()
+                .content();
+    }
+    @GetMapping("/testStreamAdvisor")
+    public Flux<String> streamAdvisorTest(){
+        //测试一个advisor的场景
+        return chatClient
+                .prompt("who are you?")
+                //添加一个advisor
+                .advisors(new MySteamAdvisor())
+                .stream()
+                .content();
+    }
+}