Spring AI
学习目标:通过SpringAI对接各种主流大模型,包括聊天问答,语音,图像等操作
开发环境和版本要求:
- jdk版本:17.x及以上。
- SpringBoot版本要求3.x。
- 学习前提条件:有java基础,并且能熟练使用SpringBoot。
- 熟悉OpenAI,有OpenAI的API key(淘宝自己买), 也可以使用国内中转(直连)的账号(有的中转地址处理参数有问题),最好支持gpt4.0
- 如果使用官方的OpenAI,需要自己会使用魔法(不懂的私聊)
SpringAI理解(理解)
-
官网地址 https://spring.io/projects/spring-ai#overview
-
SpringAI介绍:下图是SpringAI官网对SpringAI的描述
上图是官网对SpringAI的描述,翻译中文:Spring AI是一个人工智能工程的应用框架。它的目标是将Spring生态系统的设计原则(如可移植性和模块化设计)应用于人工智能领域,并推广使用POJO作为人工智能领域应用程序的构建块。
人话理解:通过SpringAI模块,可以使用面向对象的思想帮助我们快速对接主流大模型,也就是调用各种主流大模型api去满足自己的业务需求。
-
SpringAI版本
解释:PRE: 即将发布的版本,M2: 里程碑版本,一般在即将发布版本之前,都会有几个里程碑版本。
SpringAI案例(掌握)
环境搭建
-
创建springboot项目,如下图:
-
下一步,选择对应的依赖,如下图:
-
点击create创建项目
代码实现
-
pom.xml文件
<?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.3</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.cjc</groupId> <artifactId>spring-ai-study</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-ai-study</name> <description>spring-ai-study</description> <url/> <properties> <java.version>17</java.version> <spring-ai.version>1.0.0-M2</spring-ai.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-openai-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-bom</artifactId> <version>${spring-ai.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <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>
-
application.yml文件
spring: ai: openai: api-key: 自己的API key base-url: url地址 chat: options: temperature: 0.4f model: gpt-4-turbo #可配置自己支持的model,默认是4.0
-
controller层实现
@RestController @RequestMapping("/ai") public class HelloController { /** * */ private final ChatClient chatClient; /** * 通过构造方法对chatClient赋值 * @param chatClientBuilder */ public HelloController(ChatClient.Builder chatClientBuilder) { this.chatClient = chatClientBuilder.build(); } /** * @param userInput :请求参数 * @return */ @GetMapping("/chat") public String hello1(String msg) { return this.chatClient.prompt() .user(userInput) .call() .content(); } }
-
展示结果 浏览器发送请求:http://localhost:8080/ai?userInput=二哈咬人不?
流式输出
- 代码如下:
/**
* 流式输出,会乱码 produces = "text/html;charset=utf-8"
* @param msg
* @return
*/
@GetMapping(value = "/stream",produces = "text/html;charset=utf-8")
public Flux<String> hello2(@RequestParam(value = "msg") String msg) {
Flux<String> content = this.chatClient.prompt()
.user(msg)
.stream()
.content();
return content;
}
设定角色
-
代码: 方式一:
// 可以在构造方法中设置 public HelloController(ChatClient.Builder chatClientBuilder) { chatClientBuilder.defaultSystem("现在你的角色是一个科学家,狗是一种海底动物,吃鱼虾长大,不需要呼吸"); this.chatClient = chatClientBuilder.build(); } // 也可以单独写一个bean,然后设置
代码: 方式二:
@Configuration class OpenAiConfig { /** * 通过@Bean管理ChatClient * @param builder * @return */ @Bean public ChatClient chatClient(ChatClient.Builder builder) { return builder.defaultSystem("现在你的角色是一个科学家,狗是一种海底动物,吃鱼虾长大,不需要呼吸") .build(); } }
/** * 通过注解直接注入 */ @Autowired private ChatClient chatClient; // 不需要构造方法赋值了。 /*public HelloController(ChatClient.Builder chatClientBuilder) { chatClientBuilder.defaultSystem("现在你的角色是一个科学家,狗是一种海底动物,吃鱼虾长大,不需要呼吸"); this.chatClient = chatClientBuilder.build(); }*/
ChatModel使用
- ChatClient和ChatModel的区别:ChatClient代表的通用的模型客户端,ChatModel代表的是具体的某个类型的模型客户端
- 代码:
@Autowired
private ChatModel chatModel;
/**
* 简单使用
* @param msg
* @return
*/
@GetMapping("/h4")
public String hello4(@RequestParam(value = "msg") String msg) {
return chatModel.call(msg);
}
/**
* 流式输出
* @param msg
* @return
*/
@GetMapping(value = "/h5",produces = "text/html;charset=utf-8")
public Flux<String> hello5(@RequestParam(value = "msg") String msg) {
Prompt prompt = new Prompt(new UserMessage(msg));
Flux<ChatResponse> stream = chatModel.stream(prompt);
Flux<String> flux = stream.mapNotNull(chatResponse -> chatResponse.getResult().getOutput().getContent());
return flux;
}
/**
* 通过chatModel对话,设置多个参数
* 一般在yml中设置一次就可以了。
*/
@GetMapping("/chatModel")
public String hello3(@RequestParam(value = "msg") String msg){
ChatResponse response = chatModel.call(
new Prompt(
msg,
OpenAiChatOptions.builder()
// .withModel("gpt-4-turbo") // 自己指定模型
// .withTemperature(0.4f) // 温度 0-1,值越大,回答的越发散,
.build()
));
return response.getResult().getOutput().getContent();
}
文生图
@Autowired
private OpenAiImageModel openaiImageModel;
/**
* 文生图:
* 注意: 一定要跟商家确认,买的key是否支持文生图。
*/
@GetMapping("/tti")
public String textToImage(@RequestParam(value = "msg",defaultValue = "狗") String msg){
ImageResponse response = openaiImageModel.call(
new ImagePrompt(msg,
OpenAiImageOptions.builder()
.withQuality("hd") // 清晰懂
.withN(1) // 生成图片数量
.withHeight(1024)
.withWidth(1024).build()
)
);
return response.getResult().getOutput().getUrl();
}
音频转文本
@Autowired
private OpenAiAudioTranscriptionModel openAiAudioTranscriptionModel;
/**
* 语音转文本
*/
@GetMapping("/transTest")
public String transTest(){
var transcriptionOptions = OpenAiAudioTranscriptionOptions.builder()
.withResponseFormat(OpenAiAudioApi.TranscriptResponseFormat.TEXT)
.withTemperature(0f) // 温度,直接语音转文本,不瞎吹
.build();
var audioFile = new ClassPathResource("长歌行.mp3"); // 类路径下的文件
AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(audioFile, transcriptionOptions);
AudioTranscriptionResponse response = openAiAudioTranscriptionModel.call(transcriptionRequest);
String str = response.getResult().getOutput();
return str;
}
文本转语音
@Autowired
private OpenAiAudioSpeechModel openAiAudioSpeechModel;
/**
* 文本转语音
*/
@GetMapping("/textToAudio")
public String textToAudio(@RequestParam(value = "msg")String msg){
var speechOptions = OpenAiAudioSpeechOptions.builder()
.withResponseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3) // 输出格式
.withSpeed(1.0f) // 声音合成语速
.withVoice(OpenAiAudioApi.SpeechRequest.Voice.ECHO) // 声音的种类,比如老人,年轻人等
.withModel(OpenAiAudioApi.TtsModel.TTS_1.value) // 模型
.build();
var speechPrompt = new SpeechPrompt(msg, speechOptions);
SpeechResponse response = openAiAudioSpeechModel.call(speechPrompt);
OpenAiAudioSpeechResponseMetadata metadata = response.getMetadata();
byte[] responseAsBytes = response.getResult().getOutput();
fileToBytes(responseAsBytes,"D:\\WorkSpace\\spring-ai-study\\","xx.mp3");
return "success";
}
/**
* 百度搜的工具类,只要byte[]可以转文件就行
* 将Byte数组转换成文件
* @param bytes byte数组
* @param filePath 文件路径 如 D://test/ 最后“/”结尾
* @param fileName 文件名
*/
public static void fileToBytes(byte[] bytes, String filePath, String fileName) {
BufferedOutputStream bos = null;
FileOutputStream fos = null;
File file = null;
try {
file = new File(filePath + fileName);
if (!file.getParentFile().exists()){
//文件夹不存在 生成
file.getParentFile().mkdirs();
}
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(bytes);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
标签:return,String,AI,Spring,ai,openAI,spring,msg,public
From: https://blog.csdn.net/QQ903275718/article/details/142874197