Selaa lähdekoodia

0814 文本、绘图和音频模型

Qing 8 kuukautta sitten
vanhempi
commit
096c1e3824
18 muutettua tiedostoa jossa 452 lisäystä ja 2 poistoa
  1. 0 0
      consumer-service-demo/admin-demo/sql/sfcc_bak_2024-08-13.sql
  2. BIN
      consumer-service-demo/output.mp3
  3. 8 0
      consumer-service-demo/pom.xml
  4. 11 0
      consumer-service-demo/spring-ai-demo/pom.xml
  5. 3 2
      consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/controller/chat/ChatController.java
  6. 56 0
      consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/controller/chat/ContextController.java
  7. 41 0
      consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/controller/image/ImageController.java
  8. 25 0
      consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/controller/multi/MultiController.java
  9. 56 0
      consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/controller/prompt/PromptController.java
  10. 95 0
      consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/controller/prompt/TemplateController.java
  11. 37 0
      consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/controller/video/TTSController.java
  12. 14 0
      consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/dto/Book.java
  13. 11 0
      consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/service/MultiService.java
  14. 65 0
      consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/service/impl/MultiServiceImpl.java
  15. 5 0
      consumer-service-demo/spring-ai-demo/src/main/resources/st/code.st
  16. 1 0
      consumer-service-demo/spring-ai-demo/src/main/resources/st/judge.st
  17. 1 0
      consumer-service-demo/spring-ai-demo/src/main/resources/st/prompt.st
  18. 23 0
      consumer-service-demo/spring-ai-demo/src/test/java/com/sf/ai/ListTests.java

+ 0 - 0
consumer-service-demo/sql/sfcc_bak_2024-08-13.sql → consumer-service-demo/admin-demo/sql/sfcc_bak_2024-08-13.sql


BIN
consumer-service-demo/output.mp3


+ 8 - 0
consumer-service-demo/pom.xml

@@ -31,6 +31,7 @@
 
         <!-- ai相关版本 -->
         <spring-ai.version>1.0.0-M1</spring-ai.version>
+        <baidu-ai.version>4.16.19</baidu-ai.version>
     </properties>
 
     <dependencyManagement>
@@ -102,6 +103,13 @@
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
+
+            <!-- 百度智能云 -->
+            <dependency>
+                <groupId>com.baidu.aip</groupId>
+                <artifactId>java-sdk</artifactId>
+                <version>${baidu-ai.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 

+ 11 - 0
consumer-service-demo/spring-ai-demo/pom.xml

@@ -27,11 +27,22 @@
 			<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
 		</dependency>
 
+<!--		<dependency>-->
+<!--			<groupId>org.springframework.ai</groupId>-->
+<!--			<artifactId>spring-ai-stability-ai-spring-boot-starter</artifactId>-->
+<!--		</dependency>-->
+
 		<dependency>
 			<groupId>org.projectlombok</groupId>
 			<artifactId>lombok</artifactId>
 		</dependency>
 
+		<!-- 百度智能云 -->
+		<dependency>
+			<groupId>com.baidu.aip</groupId>
+			<artifactId>java-sdk</artifactId>
+		</dependency>
+
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-test</artifactId>

+ 3 - 2
consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/controller/ChatController.java → consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/controller/chat/ChatController.java

@@ -1,4 +1,4 @@
-package com.sf.ai.controller;
+package com.sf.ai.controller.chat;
 
 import lombok.RequiredArgsConstructor;
 import org.springframework.ai.openai.OpenAiChatModel;
@@ -31,9 +31,10 @@ public class ChatController {
         return stream;
     }
 
-    // http://localhost:8090/ai/generate1?message=write%20a%20bubble%20sort%20with%20java
+
     // 设置响应头中的内容类型 content-type
     // http://localhost:8090/ai/generate1
+    // http://localhost:8090/ai/generate1?message=write%20a%20bubble%20sort%20with%20java
     @GetMapping( "/ai/generate1")
     public Flux<String> generate1(@RequestParam(value = "message",defaultValue = "take a joke") String message) {
         Flux<String> stream = openAiChatModel.stream(message);

+ 56 - 0
consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/controller/chat/ContextController.java

@@ -0,0 +1,56 @@
+package com.sf.ai.controller.chat;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.ai.chat.messages.AssistantMessage;
+import org.springframework.ai.chat.messages.Message;
+import org.springframework.ai.chat.messages.UserMessage;
+import org.springframework.ai.chat.model.ChatResponse;
+import org.springframework.ai.chat.prompt.Prompt;
+import org.springframework.ai.openai.OpenAiChatModel;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+// 支持上下的对话
+@RestController
+@RequiredArgsConstructor
+public class ContextController {
+
+    private final OpenAiChatModel openAiChatModel;
+
+    // 记录历史消息
+    static List<Message> historyMessages = new ArrayList<>();
+    // 设定消息列表的最大长度
+    static int maxLen = 10;
+
+    // http://localhost:8090/context?message=
+    @GetMapping("/context")
+    public String context(@RequestParam("message") String message) {
+        // 发送给 open ai的消息分为几部分
+        // UserMessage 用户消息
+        // SystemMessage 系统消息 给open ai一些设定
+        // AssistantMessage AI回复消息
+        UserMessage userMessage = new UserMessage(message);
+        historyMessages.add(userMessage);
+
+        // 对消息列表的长度进行检查
+        if(historyMessages.size() > maxLen) {
+            // 截取最近的10条
+            historyMessages = historyMessages.subList(historyMessages.size() - maxLen,
+                    historyMessages.size());
+        }
+
+        // 将历史消息的列表 封装成prompt
+        Prompt prompt = new Prompt(historyMessages);
+        ChatResponse response = openAiChatModel.call(prompt);
+        AssistantMessage assistantMessage = response.getResult().getOutput();
+        historyMessages.add(assistantMessage);
+
+        // 将本次问题的答案返回
+        return assistantMessage.getContent();
+    }
+
+}

+ 41 - 0
consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/controller/image/ImageController.java

@@ -0,0 +1,41 @@
+package com.sf.ai.controller.image;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.ai.image.Image;
+import org.springframework.ai.image.ImageGeneration;
+import org.springframework.ai.image.ImagePrompt;
+import org.springframework.ai.image.ImageResponse;
+import org.springframework.ai.openai.OpenAiImageModel;
+import org.springframework.ai.openai.OpenAiImageOptions;
+import org.springframework.ai.openai.api.OpenAiImageApi;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequiredArgsConstructor
+public class ImageController {
+
+    private final OpenAiImageModel openAiImageModel;
+
+    // http://localhost:8090/image?prompt=cat
+    @GetMapping("/image")
+    public String image(@RequestParam("prompt") String prompt) {
+        // 构造绘图参数
+        OpenAiImageOptions imageOptions = OpenAiImageOptions.builder()
+                .withModel(OpenAiImageApi.ImageModel.DALL_E_3.getValue()) //设置使用模型
+                .withHeight(1024) //设置图片宽高
+                .withWidth(1024)
+                .withResponseFormat("url") //设置返回格式
+                .build();
+        // 构造画图提示词
+        ImagePrompt imagePrompt = new ImagePrompt(prompt, imageOptions);
+        ImageResponse imageResponse = openAiImageModel.call(imagePrompt);
+        List<ImageGeneration> results = imageResponse.getResults();
+        Image image = results.get(0).getOutput();
+        String url = image.getUrl();
+        return String.format("<img src='%s' alt='%s'>", url, prompt);
+    }
+}

+ 25 - 0
consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/controller/multi/MultiController.java

@@ -0,0 +1,25 @@
+package com.sf.ai.controller.multi;
+
+import com.sf.ai.service.MultiService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequiredArgsConstructor
+public class MultiController {
+
+    private final MultiService multiService;
+
+    // http://localhost:8090/multi?prompt=介绍一下自己
+    // http://localhost:8090/multi?prompt=需要一张英短猫的图片
+    @GetMapping("/multi")
+    public String multi(@RequestParam("prompt") String prompt) {
+        Boolean judge = multiService.judge(prompt);
+        if (judge) {
+            return multiService.image(prompt);
+        }
+        return multiService.chat(prompt);
+    }
+}

+ 56 - 0
consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/controller/prompt/PromptController.java

@@ -0,0 +1,56 @@
+package com.sf.ai.controller.prompt;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.ai.chat.messages.AssistantMessage;
+import org.springframework.ai.chat.messages.Message;
+import org.springframework.ai.chat.messages.SystemMessage;
+import org.springframework.ai.chat.messages.UserMessage;
+import org.springframework.ai.chat.model.ChatResponse;
+import org.springframework.ai.chat.prompt.Prompt;
+import org.springframework.ai.openai.OpenAiChatModel;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+// 提示词
+@RestController
+@RequiredArgsConstructor
+public class PromptController {
+
+    private final OpenAiChatModel openAiChatModel;
+
+    // 提示词(角色设定)
+    private static final String systemPrompt = "你是一个语言学习助手,不论发送什么问题,都以中英双语来回复";
+
+    // 历史消息列表
+//    static List<Message> historyMessages = new ArrayList<>(List.of(new SystemMessage(systemPrompt)));
+    static List<Message> historyMessages = new ArrayList<>();
+
+    static {
+        SystemMessage systemMessage = new SystemMessage(systemPrompt);
+        historyMessages.add(systemMessage);
+    }
+
+    static int maxLength = 10;
+
+    // http://localhost:8090/prompt?message=
+    @GetMapping("/prompt")
+    public String prompt(@RequestParam("message") String message) {
+        historyMessages.add(new UserMessage(message));
+        if (historyMessages.size() > maxLength) {
+            // 截取最近的10条
+            historyMessages = historyMessages.subList(historyMessages.size() - maxLength,
+                    historyMessages.size());
+            // 确保是第一个
+            historyMessages.add(0,new SystemMessage(systemPrompt));
+        }
+        ChatResponse response = openAiChatModel.call(new Prompt(historyMessages));
+        AssistantMessage assistantMessage = response.getResult().getOutput();
+        historyMessages.add(assistantMessage);
+        return assistantMessage.getContent();
+    }
+
+}

+ 95 - 0
consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/controller/prompt/TemplateController.java

@@ -0,0 +1,95 @@
+package com.sf.ai.controller.prompt;
+
+import com.sf.ai.dto.Book;
+import lombok.RequiredArgsConstructor;
+import org.springframework.ai.chat.messages.AssistantMessage;
+import org.springframework.ai.chat.model.ChatResponse;
+import org.springframework.ai.chat.prompt.Prompt;
+import org.springframework.ai.chat.prompt.PromptTemplate;
+import org.springframework.ai.openai.OpenAiChatModel;
+import org.springframework.ai.parser.BeanOutputParser;
+import org.springframework.ai.parser.OutputParser;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.Resource;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+// 模板语法
+@RestController
+@RequiredArgsConstructor
+public class TemplateController {
+
+    private final OpenAiChatModel openAiChatModel;
+
+    // http://localhost:8090/template?author=
+    @GetMapping("/template")
+    public String template(@RequestParam("author") String author) {
+        // 构造提示词模板
+        String template = "请问{author}最受欢迎的书是哪本?什么时候发布?书的内容是什么?";
+        PromptTemplate promptTemplate = new PromptTemplate(template);
+        // 动态的将参数传进去
+        Map<String, Object> map = Map.of("author", author);
+        Prompt prompt = promptTemplate.create(map);
+
+        ChatResponse response = openAiChatModel.call(prompt);
+        AssistantMessage assistantMessage = response.getResult().getOutput();
+        return assistantMessage.getContent();
+    }
+
+    @Value("classpath:st/prompt.st")
+    private Resource resource;
+
+    // http://localhost:8090/template1?author=
+    @GetMapping("/template1")
+    public String template1(@RequestParam("author") String author) {
+        // 加载资源来构造模板
+        PromptTemplate promptTemplate = new PromptTemplate(resource);
+        Map<String, Object> map = Map.of("author", author);
+        Prompt prompt = promptTemplate.create(map);
+        ChatResponse response = openAiChatModel.call(prompt);
+        AssistantMessage assistantMessage = response.getResult().getOutput();
+        return assistantMessage.getContent();
+    }
+
+    @Value("classpath:st/code.st")
+    private Resource codeResource;
+
+    // http://localhost:8090/code?description=quicksort&language=java&method=sort
+    @GetMapping("/code")
+    public String code(@RequestParam("description") String description,
+                       @RequestParam("language") String language,
+                       @RequestParam("method") String method) {
+        PromptTemplate promptTemplate = new PromptTemplate(codeResource);
+        Map<String, Object> map = Map.of("description", description,
+                "language", language, "method", method);
+        Prompt prompt = promptTemplate.create(map);
+        ChatResponse response = openAiChatModel.call(prompt);
+        return response.getResult().getOutput().getContent();
+    }
+
+
+    // http://localhost:8090/bean?author=
+    @GetMapping("/bean")
+    public Book bean(@RequestParam("author") String author) {
+        String template = """
+                请问{author}最受欢迎的书是哪本?什么时候发布?书的内容是什么?
+                {format}
+                """;
+        // 定义输出解释器
+        OutputParser<Book> bookOutputParser = new BeanOutputParser<>(Book.class);
+        PromptTemplate promptTemplate = new PromptTemplate(template);
+        // 构建提示词时 传入解析器的格式
+        Prompt prompt = promptTemplate.create(
+                Map.of("author", author,"format",bookOutputParser.getFormat()));
+        ChatResponse response = openAiChatModel.call(prompt);
+        AssistantMessage assistantMessage = response.getResult().getOutput();
+
+        // 使用解析器解析返回结果
+        Book book = bookOutputParser.parse(assistantMessage.getContent());
+        return book;
+    }
+
+}

+ 37 - 0
consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/controller/video/TTSController.java

@@ -0,0 +1,37 @@
+package com.sf.ai.controller.video;
+
+import com.baidu.aip.util.Util;
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import org.springframework.ai.openai.OpenAiAudioSpeechModel;
+import org.springframework.ai.openai.OpenAiAudioSpeechOptions;
+import org.springframework.ai.openai.api.OpenAiAudioApi;
+import org.springframework.ai.openai.audio.speech.SpeechPrompt;
+import org.springframework.ai.openai.audio.speech.SpeechResponse;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequiredArgsConstructor
+public class TTSController {
+
+    private final OpenAiAudioSpeechModel audioSpeechModel;
+
+    // http://localhost:8090/tts?message=
+    @SneakyThrows
+    @GetMapping("/tts")
+    public String tts(@RequestParam("message") String message) {
+        OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder()
+                .withModel("tts-1")
+                .withVoice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY) //设置声音
+                .withResponseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
+                .withSpeed(1.0f)
+                .build();
+        SpeechPrompt speechPrompt = new SpeechPrompt(message, speechOptions);
+        SpeechResponse response = audioSpeechModel.call(speechPrompt);
+        byte[] output = response.getResult().getOutput();
+        Util.writeBytesToFileSystem(output,"output.mp3");
+        return "success";
+    }
+}

+ 14 - 0
consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/dto/Book.java

@@ -0,0 +1,14 @@
+package com.sf.ai.dto;
+
+import lombok.Data;
+
+@Data
+public class Book {
+
+    private String author;
+    private String bookName;
+    // 出版日期
+    private String publishedDate;
+    // 描述信息
+    private String description;
+}

+ 11 - 0
consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/service/MultiService.java

@@ -0,0 +1,11 @@
+package com.sf.ai.service;
+
+public interface MultiService {
+
+    // 判断提示词是需要文本处理还是图片处理
+    Boolean judge(String prompt);
+
+    String chat(String prompt);
+
+    String image(String prompt);
+}

+ 65 - 0
consumer-service-demo/spring-ai-demo/src/main/java/com/sf/ai/service/impl/MultiServiceImpl.java

@@ -0,0 +1,65 @@
+package com.sf.ai.service.impl;
+
+import com.sf.ai.service.MultiService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.ai.chat.model.ChatResponse;
+import org.springframework.ai.chat.prompt.Prompt;
+import org.springframework.ai.chat.prompt.PromptTemplate;
+import org.springframework.ai.image.ImagePrompt;
+import org.springframework.ai.image.ImageResponse;
+import org.springframework.ai.openai.OpenAiChatModel;
+import org.springframework.ai.openai.OpenAiImageModel;
+import org.springframework.ai.openai.OpenAiImageOptions;
+import org.springframework.ai.openai.api.OpenAiImageApi;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.Resource;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+@Service
+@RequiredArgsConstructor
+public class MultiServiceImpl implements MultiService {
+
+    @Value("classpath:st/judge.st")
+    private Resource judgeResource;
+
+    private final OpenAiChatModel chatModel;
+    private final OpenAiImageModel imageModel;
+
+
+    @Override
+    public Boolean judge(String message) {
+        PromptTemplate promptTemplate = new PromptTemplate(judgeResource);
+        Prompt prompt = promptTemplate.create(Map.of("prompt", message));
+        ChatResponse response = chatModel.call(prompt);
+        String content = response.getResult().getOutput().getContent();
+        // 统一为小写
+        if(content.toLowerCase().equals("yes") || content.toLowerCase().contains("yes")){
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public String chat(String prompt) {
+        ChatResponse response = chatModel.call(new Prompt(prompt));
+        return response.getResult().getOutput().getContent();
+    }
+
+    @Override
+    public String image(String prompt) {
+        // 构造绘图参数
+        OpenAiImageOptions imageOptions = OpenAiImageOptions.builder()
+                .withModel(OpenAiImageApi.ImageModel.DALL_E_3.getValue()) //设置使用模型
+                .withHeight(1024) //设置图片宽高
+                .withWidth(1024)
+                .withResponseFormat("url") //设置返回格式
+                .build();
+        // 构造画图提示词
+        ImagePrompt imagePrompt = new ImagePrompt(prompt, imageOptions);
+        ImageResponse imageResponse = imageModel.call(imagePrompt);
+        String url = imageResponse.getResult().getOutput().getUrl();
+        return String.format("<img src='%s' alt='%s'>", url, prompt);
+    }
+}

+ 5 - 0
consumer-service-demo/spring-ai-demo/src/main/resources/st/code.st

@@ -0,0 +1,5 @@
+/**
+  * @language {language}
+  * @method {method}
+  * @description {description}
+  */

+ 1 - 0
consumer-service-demo/spring-ai-demo/src/main/resources/st/judge.st

@@ -0,0 +1 @@
+Does this message want to generate an AI picture, image, art or anything similar? {prompt} . Simply answer with a yes or no.

+ 1 - 0
consumer-service-demo/spring-ai-demo/src/main/resources/st/prompt.st

@@ -0,0 +1 @@
+请问{author}最受欢迎的书是哪本?什么时候发布?书的内容是什么?

+ 23 - 0
consumer-service-demo/spring-ai-demo/src/test/java/com/sf/ai/ListTests.java

@@ -0,0 +1,23 @@
+package com.sf.ai;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ListTests {
+
+    @Test
+    public void test() {
+        List list = new ArrayList();
+        list.add(1);
+        list.add(1);
+        list.add(1);
+        list.add(1);
+        list.add(1);
+        list.add(1);
+
+        List subList = list.subList(2, 6);
+        System.out.println(subList);
+    }
+}