• Spring AI 初学


    Spring AI 初学

    Spring AI 官方地址

    ”spring 不生产 AI,只是 AI 工具的搬运工“

    项目可以查看gitee

    Open AI

    前期准备

    Open AI官方地址,需要使用魔法才能打开,同时购买很麻烦,建议淘宝进行购买,只需要购买 open ai 的 apikey 即可。

    apikey 形如 sk-xxxxxxxxxxxxxxxxx

    项目创建

    Idea 创建 SpringBoot Maven 项目(Spring AI基于1.0-SNAPSHOT版本,SpringBoot 3.2.6),依赖选择Spring Web、 OpenAI。其他可以自行选择

    修改项目仓库地址,中央仓库暂时还没 Spring AI 相关 jar 包。仓库地址改成快照仓库地址,官方说明

        <repository>
            <id>spring-snapshotsid>
            <name>Spring Snapshotsname>
            <url>https://repo.spring.io/snapshoturl>
            <releases>
                <enabled>falseenabled>
            releases>
        repository>
    

    项目中找到 pom.xml 文件,将 0.8.1 改为 1.0.0-SNAPSHOT

    yaml 配置文件中添加,openai 更多配置可以查看 org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration。

    spring:
      ai:
        openai:
          # 购买的 api-key
          api-key: sk-xxxx
          # 如果是官方地址,则可以不填,默认为 https://api.openai.com
          base-url: 
    

    聊天

    基础使用

    主要类 org.springframework.ai.openai.OpenAiChatModel,快照版本不同,可能名字不一样,可以查看 org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration 中的聊天类是哪个。

    import jakarta.annotation.Resource;
    import org.junit.jupiter.api.Test;
    import org.springframework.ai.openai.OpenAiChatModel;
    import org.springframework.boot.test.context.SpringBootTest;
    
    @SpringBootTest
    public class ChatTest {
    
        @Resource
        private OpenAiChatModel chatModel;
    
        @Test
        public void chat1(){
            String msg = "你好";
            //返回string数据
            String res = chatModel.call(msg);
            System.out.println(res);
        }
        
        @Test
        public void chat2(){
            String msg = "你好";
            //返回对象
            ChatResponse res = chatModel.call(new Prompt(msg));
            System.out.println(res);
            //获取对话返回结果
            System.out.println(res.getResult().getOutput().getContent());
        }
    
        /**
        * 流式返回数据,类似打字效果,一个词一个json数据,整句话多个json数据
        */
        @Test
        public void chat3(){
            String msg = "你好";
            Prompt prompt = new Prompt(msg);
            Flux flux = chatModel.stream(prompt);
            flux.toStream().forEach(res -> {
                System.out.println(res.getResult().getOutput().getContent());
            });
        }
        
    }
    

    配置属性

        @Test
        public void test3(){
            String msg = "你是谁";
            //采用 gpt-4-turbo 模型,配置属性创建可以参考 OpenAiChatModel 构造函数
            OpenAiChatOptions options = OpenAiChatOptions.builder()
                    .withModel("gpt-4-turbo")
                    .build();
            ChatResponse res = chatModel.call(new Prompt(msg, options));
            System.out.println(res);
            //获取对话返回结果
            System.out.println(res.getResult().getOutput().getContent());
        }
    

    聊天模型配置属性可以查看 org.springframework.ai.autoconfigure.openai.OpenAiChatProperties,也可以在官网查看更详细的信息。配置属性也可以放在 yml 配置文件中,如 OpenAiChatProperties 的注解,需要以 spring.ai.openai.chat 开头,例如将 gpt-4-turbo 配置在配置文件中,就是 OpenAiChatProperties 中 options 中的属性。

    spring:
      ai:
        openai:
          chat:
            options:
              model: gpt-4-turbo
    

    多模型

    可以配合图片等让聊天模型进行回答。

        //给图片来进行聊天
        @Test
        public void test4() {
            //获取图片资源
            ClassPathResource resource = new ClassPathResource("2024052701.png");
            UserMessage userMessage = new UserMessage("说说你看到了什么", 
                    List.of(new Media(MimeTypeUtils.IMAGE_PNG, resource)));
            ChatResponse res = chatModel.call(new Prompt(userMessage, OpenAiChatOptions.builder()
                    .withModel("gpt-4-turbo")
                    .build()));
            System.out.println(res);
            //获取回答
            System.out.println(res.getResult().getOutput().getContent());
        }
    

    图像

    基础使用

    主要类 org.springframework.ai.openai.OpenAiImageModel,快照版本不同,可能类不一样。可以查看 org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration 中具体的图像类是哪个。

    import jakarta.annotation.Resource;
    import org.junit.jupiter.api.Test;
    import org.springframework.ai.image.ImagePrompt;
    import org.springframework.ai.image.ImageResponse;
    import org.springframework.ai.openai.OpenAiImageModel;
    import org.springframework.boot.test.context.SpringBootTest;
    
    @SpringBootTest
    public class ImageTest {
    
        @Resource
        private OpenAiImageModel imageModel;
    
        @Test
        public void test(){
            //调用 image 模型的 call 方法获取图片
            ImageResponse res = imageModel.call(new ImagePrompt("山水画"));
            //AI 绘制的图片路径
            String url = res.getResult().getOutput().getUrl();
            System.out.println(url);
        }
    
    }
    

    配置属性

        @Test
        public void test2(){
            //使用 dall-e-2 绘画,配置属性模型创建可以参考 OpenAiImageModel 构造函数
            OpenAiImageOptions options = OpenAiImageOptions.builder()
                .withModel(OpenAiImageApi.ImageModel.DALL_E_2.getValue())
                .build();
            ImageResponse res = imageModel.call(new ImagePrompt("山水画", options));
            //获取 AI 绘画路径
            String url = res.getResult().getOutput().getUrl();
            System.out.println(url);
        }
    

    图像模型属性配置可以查看 org.springframework.ai.autoconfigure.openai.OpenAiImageProperties,也可以查看官网获取更详细的信息。当然配置属性也可以在 yml 中定义,如 OpenAiImageProperties 上的注解,需要以 spring.ai.openai.image 开头,例如使用 dall-e-2 模型进行绘画

     spring:
      ai:
        openai:
          image:
            options:
              model: dall-e-2
    

    语音

    语音转文字

    基础使用

    主要类 org.springframework.ai.openai.OpenAiAudioTranscriptionModel,快照版本不同,可能名字不一样,可以查看 org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration 中的语音转文字翻译类是哪个。

    import jakarta.annotation.Resource;
    import org.junit.jupiter.api.Test;
    import org.springframework.ai.openai.OpenAiAudioTranscriptionModel;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.core.io.ClassPathResource;
    
    @SpringBootTest
    public class AudioTest {
    
        //语音转文字
        @Resource
        private OpenAiAudioTranscriptionModel transcriptionModel;
    
        @Test
        public void testTranscription1(){
            String res = transcriptionModel.call(new ClassPathResource("2024052702.mp3"));
            System.out.println(res);
        }
    
    }
    
    配置属性
        @Test
        public void testTranscription2(){
            //创建模型属性,采用 whisper-1 语音模型,配置属性创建可以参考 OpenAiAudioTranscriptionModel 构造函数
            OpenAiAudioTranscriptionOptions options = new OpenAiAudioTranscriptionOptions().builder()
                    .withModel(OpenAiAudioApi.WhisperModel.WHISPER_1.getValue())
                    .build();
            AudioTranscriptionResponse res = transcriptionModel.call(
                new AudioTranscriptionPrompt(new ClassPathResource("2024052702.mp3"), options));
            //获取翻译内容
            String output = res.getResult().getOutput();
            System.out.println(output);
        }
    

    语音转文字模型属性可以查看 org.springframework.ai.autoconfigure.openai.OpenAiAudioTranscriptionProperties,也可以在官网查看更详细信息。当然可以在 yml 配置中配置属性,如 OpenAiAudioTranscriptionProperties 上的注解,以 spring.ai.openai.audio.transcription 开头,例如采用 whisper-1 模型

    spring:
      ai:
        openai:
          audio:
            transcription:
              options:
                model: whisper-1
    

    文字转语音

    基础使用

    主要类 org.springframework.ai.openai.OpenAiAudioSpeechModel,快照版本不同,可能名字不一样,可以查看 org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration 中的文字转语音类是哪个。

    import jakarta.annotation.Resource;
    import org.junit.jupiter.api.Test;
    import org.springframework.ai.openai.OpenAiAudioSpeechModel;
    import org.springframework.boot.test.context.SpringBootTest;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    @SpringBootTest
    public class AudioTest2 {
    
        @Resource
        private OpenAiAudioSpeechModel speechModel;
    
        //byte数组转文件
        private void byteArrayToFile(byte[] byteArray, String filePath) throws IOException {
            FileOutputStream fos = new FileOutputStream(filePath);
            fos.write(byteArray);
            fos.close();
        }
    
        @Test
        public void testSpeech() throws IOException {
            byte[] res = speechModel.call("我爱北京");
            byteArrayToFile(res,"D:\\project\\AI\\openai\\speech\\1.mp3");
        }
    
    }
    
    
    属性配置
        @Test
        public void testSpeech2() throws IOException {
            //采用 tts-1-hd 模型,配置属性创建可以参考 OpenAiAudioSpeechModel 构造函数
            OpenAiAudioSpeechOptions options = new OpenAiAudioSpeechOptions().builder()
                    .withModel(OpenAiAudioApi.TtsModel.TTS_1_HD.getValue())
                    .build();
            SpeechPrompt prompt = new SpeechPrompt("我爱北京", options);
            SpeechResponse res = speechModel.call(prompt);
            byte[] bytes = res.getResult().getOutput();
            byteArrayToFile(bytes,"D:\\project\\AI\\openai\\speech\\1-hd.mp3");
        }
    

    文字转语音模型属性可以查看 org.springframework.ai.autoconfigure.openai.OpenAiAudioSpeechProperties,也可以在官网查看更详细信息。当然可以在 yml 配置中配置属性,如 OpenAiAudioSpeechProperties 上的注解,以 spring.ai.openai.audio.speech 开头,例如采用 tts-1-hd 模型

    spring:
      ai:
        openai:
          audio:
            speech:
              options:
                model: tts-1-hd
    

    ollama

    安装 ollama

    ollama 官网提供了下载地址,可以自己选择版本安装。ollama 主要提供了一些语言模型可以让用户在本地运行模型。

    安装运行模型

    在 ollama 官网右上角提供下载模型。在模型中选择想本地安装使用的模型,如 谷歌语言模型 gemma,搜索查询。选择要下载的数据集,右边选择复制。

    image-20240528193858877

    image-20240528194029654

    image-20240528194117623

    window 端打开 cmd 命令窗口,粘贴刚才复制的命令,回车下载安装。

    image-20240528194307337

    安装完之后,使用刚才复制的命令,运行 gemma 模型,可以向模型提问。

    1

    java 集成 ollama

    Idea 创建 SpringBoot Maven 项目(Spring AI基于1.0-SNAPSHOT版本,SpringBoot 3.2.6),依赖选择Spring Web、 Ollama。其他可以自行选择

    修改项目仓库地址,中央仓库暂时还没 Spring AI 相关 jar 包。仓库地址改成快照仓库地址,官方说明

        <repository>
            <id>spring-snapshotsid>
            <name>Spring Snapshotsname>
            <url>https://repo.spring.io/snapshoturl>
            <releases>
                <enabled>falseenabled>
            releases>
        repository>
    

    项目中找到 pom.xml 文件,将 0.8.1 改为 1.0.0-SNAPSHOT

    简单用法

    SpringBoot 测试类

    import jakarta.annotation.Resource;
    import org.junit.jupiter.api.Test;
    import org.springframework.ai.chat.model.ChatResponse;
    import org.springframework.ai.chat.prompt.Prompt;
    import org.springframework.ai.ollama.OllamaChatModel;
    import org.springframework.ai.ollama.api.OllamaOptions;
    import org.springframework.boot.test.context.SpringBootTest;
    
    @SpringBootTest
    public class SimpleTest {
    
        @Resource
        private OllamaChatModel chatModel;
    
        @Test
        public void test(){
            //使用下载的 gemma:7b 配置模型属性,模型属性创建可以参考 OllamaChatModel 构造函数
            OllamaOptions options = OllamaOptions.create().withModel("gemma:7b");
            Prompt prompt = new Prompt("你好", options);
            //调用聊天模型,获取返回值对象
            ChatResponse res = chatModel.call(prompt);
            //获取 AI 回答字符串
            System.out.println(res.getResult().getOutput().getContent());
        }
        
        /**
         * 流式返回数据,类似打字效果,一个词一个json数据,整句话多个json数据
         */
        @Test
        public void test2(){
            //使用下载的 gemma:7b 配置模型属性,模型属性配置可以参考 OllamaChatModel 构造函数
            OllamaOptions options = OllamaOptions.create().withModel("gemma:7b");
            Prompt prompt = new Prompt("你好", options);
            Flux flux = chatModel.stream(prompt);
            flux.toStream().forEach(res -> {
                System.out.println(res.getResult().getOutput().getContent());
            });
        }
    
    }
    

    模型属性可以查看 org.springframework.ai.autoconfigure.ollama.OllamaChatProperties,也可以在官网查看具体的属性。属性配置也可以在 yml 文件上定义,如 OllamaChatProperties 上的注解,需要以 spring.ai.ollama.chat 开头,如配置 gemma:7b、访问其他服务器的 ollama(安装ollama的服务器环境变量配置增加 OLLAMA_HOST=0.0.0.0:11434):

    spring:
      ai:
        ollama:
          base-url: http://192.168.8.16:11434
          chat:
            model: gemma:7b
    

    调用 ollama API

    ollama 具体 API 方法可以查看官网

    import org.apache.http.HttpEntity;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    import org.json.JSONObject;
    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import java.nio.charset.Charset;
    import java.util.HashMap;
    import java.util.Map;
    
    
    @SpringBootTest
    public class OllamaApiTest {
    
        @Test
        public void test() throws Exception{
            CloseableHttpClient client = HttpClients.createDefault();
            //ollama 默认端口是 11434
            HttpPost post = new HttpPost("http://127.0.0.1:11434/api/generate");
            post.addHeader("Content-type","application/json; charset=utf-8");
            //参数
            Map map = new HashMap<>();
            map.put("model","gemma:7b");
            map.put("prompt","你好");
            //不以流式返回
            map.put("stream",false);
    
            StringEntity stringEntity = new StringEntity(JSONObject.valueToString(map),Charset.forName("UTF-8"));
            post.setEntity(stringEntity);
            CloseableHttpResponse response = client.execute(post);
            HttpEntity entity = response.getEntity();
            System.out.println(EntityUtils.toString(entity));
        }
    
    }
    
  • 相关阅读:
    【Java学习挑战】
    新手学PCB画板选什么软件
    高防ip能不能扛住ddos和CC攻击
    ZZNUOJ_用C语言编写程序实现1342:支配值数目(附完整源码)
    Python关于 *args 和 **kwargs 参数的详解(全)
    【Java 进阶篇】JDBC ResultSet 遍历结果集详解
    你知道不同U盘在ARM+Linux下的读写速率吗?
    CUDA + Visual Studio 环境搭建
    py.test --pep8 vsearch.py报错解决办法
    有没有一种可能,我可以学好Java的多线程——知识点汇总
  • 原文地址:https://www.cnblogs.com/ytryhard/p/18216456