1?pom.xml,?注意版本(jdk17) ,倉庫地址,排除的依賴(日志錯誤)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.1</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>demo_mvn_test_1</artifactId><version>0.0.1-SNAPSHOT</version><name>demo_mvn_test_1</name><description>demo_mvn_test_1</description><url/><licenses><license/></licenses><developers><developer/></developers><scm><connection/><developerConnection/><tag/><url/></scm><properties><java.version>17</java.version></properties><dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2023.0.1.0</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-ai</artifactId><exclusions><exclusion><artifactId>slf4j-simple</artifactId><groupId>org.slf4j</groupId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository></repositories></project>
2?yml?文件,key申請查看幫助
如何開通DashScope并創建API-KEY_模型服務靈積(DashScope)-阿里云幫助中心
spring:cloud:ai:tongyi:api-key: xxxxxxxx
3 service類接口,抽象類,實現類編寫,你想簡單也行,自己改
import org.springframework.ai.image.ImageResponse;
import java.util.Map;public interface TongYiService {/*** 基本問答*/String completion(String message);/*** 基本問答,流式返回*/Map<String, String> streamCompletion(String message);/*** 文生圖,根據文本描述生成圖片*/ImageResponse genImg(String imgPrompt);/*** 語音合成,將文本轉成語音文件*/String genAudio(String text);
}
import com.example.demo_mvn_test_1.service.TongYiService;
import org.springframework.ai.image.ImageResponse;
import java.util.Map;public abstract class AbstractTongYiServiceImpl implements TongYiService {@Overridepublic String completion(String message) {return null;}@Overridepublic Map<String, String> streamCompletion(String message) {return null;}@Overridepublic ImageResponse genImg(String imgPrompt) {return null;}@Overridepublic String genAudio(String text) {return null;}
}
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.StreamingChatClient;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import java.util.Map;@Service
//自動注入ChatClient、StreamingChatClient,屏蔽模型調用細節
@RequiredArgsConstructor
public class TongYiSimpleServiceImpl extends AbstractTongYiServiceImpl {private final ChatClient chatClient;private final StreamingChatClient streamingChatClient;//方式1@Overridepublic String completion(String message) {Prompt prompt = new Prompt(new UserMessage(message));return chatClient.call(prompt).getResult().getOutput().getContent();}//方式2,streaming的方式@Overridepublic Map<String, String> streamCompletion(String message) {StringBuilder fullContent = new StringBuilder();streamingChatClient.stream(new Prompt(message)).flatMap(chatResponse -> Flux.fromIterable(chatResponse.getResults())).map(content -> content.getOutput().getContent()).doOnNext(fullContent::append).last().map(lastContent -> Map.of(message, fullContent.toString())).block();return Map.of(message, fullContent.toString());}
}
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.image.ImageClient;
import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
import org.springframework.stereotype.Service;@Slf4j
@Service
@RequiredArgsConstructor
public class TongYiImagesServiceImpl extends AbstractTongYiServiceImpl {private final ImageClient imageClient;@Overridepublic ImageResponse genImg(String imgPrompt) {var prompt = new ImagePrompt(imgPrompt);return imageClient.call(prompt);}
}
import com.alibaba.cloud.ai.tongyi.audio.api.SpeechClient;
import com.alibaba.dashscope.audio.tts.SpeechSynthesisAudioFormat;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;@Slf4j
@Service
@RequiredArgsConstructor
public class TongYiAudioSimpleServiceImpl extends AbstractTongYiServiceImpl {private final SpeechClient speechClient;@Overridepublic String genAudio(String text) {log.info("gen audio prompt is: {}", text);var resWAV = speechClient.call(text);// save的代碼省略,就是將音頻保存到本地而已return save(resWAV, SpeechSynthesisAudioFormat.WAV.getValue());}// 輔助方法,用于將模型的響應保存到本地.private String save(ByteBuffer audio, String type) {String currentPath = System.getProperty("user.dir");LocalDateTime now = LocalDateTime.now();DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd-HH-mm-ss");String fileName = currentPath + File.separator + now.format(formatter) + "." + type;File file = new File(fileName);try (FileOutputStream fos = new FileOutputStream(file)) {fos.write(audio.array());}catch (Exception e) {throw new RuntimeException(e);}return fileName;}}
4 controller層調用測試
import com.example.demo_mvn_test_1.service.TongYiService;
import org.springframework.ai.image.ImageResponse;
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 java.util.Map;@RestController
@RequestMapping("/ai")
public class TongYiController {@Autowired@Qualifier("tongYiSimpleServiceImpl")private TongYiService tongYiSimpleService;@Autowired@Qualifier("tongYiImagesServiceImpl")private TongYiService tongYiSimpleService_img;@Qualifier("tongYiAudioSimpleServiceImpl")@Autowiredprivate TongYiService yinpinService;//基本回答@GetMapping("/simple")public String completion(@RequestParam(value = "message", defaultValue = "荷花怎么種植") String message) {return tongYiSimpleService.completion(message);}//基本回答@GetMapping("/simple_stream")public Map<String, String> completion_stream(@RequestParam(value = "message", defaultValue = "荷花怎么種植") String message) {Map<String, String> stringStringMap = tongYiSimpleService.streamCompletion(message);return stringStringMap;}//圖片生成,返回的是圖片的地址和圖片的base64@RequestMapping("/getimg")public ImageResponse genImg(@RequestParam(value = "message", defaultValue = "荷花怎么種植") String message) {ImageResponse imageResponse = tongYiSimpleService_img.genImg(message);return imageResponse;}//語音生成//文字不要放太多了@RequestMapping("/getaudio")public String genAudio(@RequestParam(value = "message", defaultValue = "荷花怎么種植") String message) {String audio = yinpinService.genAudio(message);return audio;}}
?