首先我们要在SpirngBoot项目中集成SpirngAI的话,对我们SpringBoot的版本有一定的要求,我们一般选择较新SpringBoot(3.0及以上)的版本才支持SpringAI。
这是SpringAI集成大模型的架构图
RAG 是检索增强生成(Retrieval Augmented Generation )的简称,它为大语言模型 (LLMs) 提供了从数据源检索信息的能力,并以此为基础生成回答。
Fine-tuning(微调):通过特定领域数据对预训练模型进行针对性优化,以提升其在特定任务上的性能。
函数调用(Function Calling):函数调用使您能够更可靠地从模型中获取结构化数据。
首先我们先自动创建一个SpringBoot的项目
接下来我们选择需要导入的依赖信息,导入Web依赖和OpenAI的依赖既可
项目创建完成之后我们需要配置项目application.yml文件
这里我有一个售卖中转key的网站,不是广告,大家按需要购买
GPT4.0 API KEY By OPENAI HK 中转ChatGPT (openai-hk.com)https://openai-hk.com/open/index
如果使用的是OpenAI官方的key,使用官方的调用地址既可,如果中转的key,调用地址需要改为中转的调用地址
我们来编写第一个文生文的请求示例
配置类(这里可以通过代码内容可以给ChatGpt进行微调,这里微调后,他就会按照一个客服来跟你进行对话)跟OpenAI官方发布的GPTS的功能类似
@Configuration public class AIConfig { @Bean ChatClient chatClient(ChatClient.Builder builder) { //设置系统默认 return builder.defaultSystem("你现在不是chatgpt了,我希望你是一个客服") .build(); } }
@RestController @RequestMapping("/ai") public class AIController { //ChatClient提供所有大语言模型通用的功能 @Autowired private ChatClient chatClient; public AIController(ChatClient.Builder chatClientBuilder) { this.chatClient = chatClientBuilder.build(); } @GetMapping("/chat") public String generation(@RequestParam(value = "message" ,defaultValue = "诸葛亮是谁?") String message) { //prompt : 提示词 return this.chatClient.prompt() //用户信息 .user(message) //远程请求大模型 .call() //返回文本 .content(); } }
@SpringBootApplication public class SpringAiDemo20240508Application { public static void main(String[] args) { //访问OpenAI官方的API,需要设置代理 /*String proxy="127.0.0.1"; //开启代理的端口 int port = 7890; System.setProperty("proxyType","4"); System.setProperty("proxyPort",Integer.toString(port)); System.setProperty("proxyHost",proxy); System.setProperty("proxySet","true");*/ SpringApplication.run(SpringAiDemo20240508Application.class, args); } }
启动SpringBoot,我们在浏览器中输入路径进行访问localhost:8080/ai/chat?message=你是一名客服吗?
我们让他使用流的方式进行回复(要指定字符集和格式不然结果会产生乱码)
@GetMapping(value = "/stream",produces = "text/html;charset=UTF-8") public Flux<String> stream(@RequestParam(value = "message" ,defaultValue = "诸葛亮是谁?") String message) { //prompt : 提示词 Flux<String> output = chatClient.prompt() //用户信息 .user(message) //流方式请求 .stream() .content(); return output; }
我们在浏览器中输入路径进行访问localhost:8080/ai/stream?message=你作为一名客服能为我做什么?
我们接着使用ChatModel的方式对OpenAI官方的接口进行访问,ChatClient是所有大语言模型通用的,如果切换大语言模型,ChatClient的代码不用改动,但我们如果需要一些大语言模型的特有的功能的话,我们就要使用ChatModel来进行调用
下面我们来使用ChatModel方式来调用OpenAI
//利用chatModel调用不同大模型的特有的功能 @Autowired private ChatModel chatModel; @GetMapping("/chat/model") public String chatModel(@RequestParam(value = "message" ,defaultValue = "诸葛亮是谁?") String message) { //prompt : 提示词 ChatResponse response = chatModel.call( new Prompt( message, // = new UserMessage(message) OpenAiChatOptions.builder() .withModel("gpt-4-o") .withTemperature(0.8F) .build() )); return response.getResult().getOutput().getContent(); }
在请求时我们可以自定义一些参数,我们选择调用的模型,温度(这是生成内容的想象力的参数),有一系列的参数,SpringAI官网地址:OpenAI Chat :: Spring AI Referencehttps://docs.spring.io/spring-ai/reference/api/chat/openai-chat.html
我们在浏览器中输入路径进行访问,访问路径:localhost:8080/ai/chat/model
接下来我们调用OpenAI提供文生图功能
//文生图 @Autowired private OpenAiImageModel openaiImageModel; //文生图 @GetMapping("/images") public String images(@RequestParam(value = "message" ,defaultValue = "画一个猫?") String message) { //prompt : 提示词 ImageResponse response = openaiImageModel.call( //图片的提示词 new ImagePrompt( //提示词信息 message, OpenAiImageOptions.builder() //让图片更加的清晰 .withQuality("hd") .withModel(OpenAiImageApi.DEFAULT_IMAGE_MODEL)//默认文生图模型为Dalle3 //生成张数 .withN(1) //高 .withHeight(1024) //宽 .withWidth(1024).build()) ); return response.getResult().getOutput().getUrl(); }
同样也可自定义访问请求的参数,SpringAI官网:OpenAI Image Generation :: Spring AI Referencehttps://docs.spring.io/spring-ai/reference/api/image/openai-image.html
我们在浏览器中输入路径进行访问,localhost:8080/ai/images
我们接着使用SpringAI调用OpenAI的文生语音的功能
//文生语音 @Autowired private OpenAiAudioSpeechModel openAiAudioSpeechModel; //文生语音 @GetMapping("/audio") public String audio(@RequestParam(value = "message" ,defaultValue = "画一个猫?") String message) { //文生语音配置项 OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder() .withModel("tts-1") .withVoice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY) .withResponseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3) .withSpeed(1.0f) .build(); //prompt : 提示词 SpeechPrompt speechPrompt = new SpeechPrompt("战斗爽,战斗爽", speechOptions); SpeechResponse response = openAiAudioSpeechModel.call(speechPrompt); byte[] body = response.getResult().getOutput(); //将byte[]存为mp3文件 try { writeByteArrayToMP3(body,System.getProperty("user.dir")); } catch (Exception e) { throw new RuntimeException(e); } return "ok"; } public static void writeByteArrayToMP3(byte[] audioBytes,String outputFilePath) throws IOException { //创建FileOutputStream实例 FileOutputStream fileOutputStream = new FileOutputStream(outputFilePath + "/nb.mp3"); //将字节数组写入文件 fileOutputStream.write(audioBytes); //关闭文件输出流 fileOutputStream.close(); }
文生语音自定义参数官方文档地址:OpenAI Text-to-Speech (TTS) Integration :: Spring AI Referencehttps://docs.spring.io/spring-ai/reference/api/audio/speech/openai-speech.html
我们在浏览器中输入路径进行访问,localhost:8080/ai/audio
我们接着使用SpringAI调用OpenAI的语音转文字的功能
//语音转文本 @Autowired private OpenAiAudioTranscriptionModel openAiTranscriptionModel; //语音转换文本 @GetMapping("/audio2text") public String audio2text(@RequestParam(value = "message" ,defaultValue = "画一个猫?") String message) { //语音翻译的可选配置 var transcriptionOptions = OpenAiAudioTranscriptionOptions.builder() .withResponseFormat(OpenAiAudioApi.TranscriptResponseFormat.TEXT) .withTemperature(0f) .build(); var audioFile = new ClassPathResource("/丁真青藏高原之旅2.wav"); AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(audioFile, transcriptionOptions); AudioTranscriptionResponse response = openAiTranscriptionModel.call(transcriptionRequest); return response.getResult().getOutput(); }
将生成的一段音频文件放入resource文件下让它解析,这个音频是用丁真声音的训练AI的音频内容
这个是开源的地址,大家想玩可以直接在线登录,输入内容就可生成丁真音频内容
AI丁真2.0 · 创空间 (modelscope.cn)https://modelscope.cn/studios/xzjosh/DZ-Bert-VITS2-2.3/summary/
我们在浏览器中输入路径进行访问,localhost:8080/ai/audio2text
我们继续使用SpringAI调用OpenAI的多模态功能,我们可以上传视屏内容或音频内容等,我们就把刚才那个生成的猫咪图片传给大模型
//多模态 @GetMapping("/mutil") public String mutil(@RequestParam(value = "message" ,defaultValue = "你从这个图片中看出了什么?") String message) throws IOException { //图片的二进流 byte[] imageData = new ClassPathResource("/cat1.png").getContentAsByteArray(); //用户信息 var userMessage = new UserMessage( message, // content List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))); // media ChatResponse response = chatModel.call(new Prompt(userMessage, OpenAiChatOptions.builder() .withModel(OpenAiApi.ChatModel.GPT_4_O.getValue()) .build())); return response.getResult().getOutput().getContent(); }
我们在浏览器中输入路径进行访问,localhost:8080/ai/mutil
大模型还可以支持function-call的功能,function-call的功能主要是针对大模型所不知道的实时的问题或者我们系统一些私有性的问题,这类问题调用OpenAI官方的大模型正常无法解决,所以OpenAI采用了function-call来解决这个无法回答即时性的问题和我们系统中一些私有性的一些问题。
这是function-call官方文档说明:Function Calling API :: Spring AI Referencehttps://docs.spring.io/spring-ai/reference/api/functions.html
以上是我个人学习的SpringAI的收获的内容,这是个人学习SpringAI的个人总结,大家如果有问题可以在评论区多多讨论。