欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot快速接入OpenAI大模型的方法(JDK8)

 更新時間:2025年02月28日 10:48:38   作者:呱 太  
本文介紹了如何使用AI4J快速接入OpenAI大模型,并展示了如何實現(xiàn)流式與非流式的輸出,以及對函數(shù)調(diào)用的使用,AI4J支持JDK8,適用于多種應(yīng)用場景,包括Spring Boot項目,感興趣的朋友一起看看吧

使用AI4J快速接入OpenAI大模型

本博文給大家介紹一下如何使用AI4J快速接入OpenAI大模型,并且如何實現(xiàn)流式與非流式的輸出,以及對函數(shù)調(diào)用的使用。

介紹

由于SpringAI需要使用JDK17和Spring Boot3,但是目前很多應(yīng)用依舊使用的JDK8版本,所以使用可以支持JDK8的AI4J來接入OpenAI大模型。

AI4J是一款JavaSDK用于快速接入AI大模型應(yīng)用,整合多平臺大模型,如OpenAi、智譜Zhipu(ChatGLM)、深度求索DeepSeek、月之暗面Moonshot(Kimi)、騰訊混元Hunyuan、零一萬物(01)等等,提供統(tǒng)一的輸入輸出(對齊OpenAi)消除差異化,優(yōu)化函數(shù)調(diào)用(Tool Call),優(yōu)化RAG調(diào)用、支持向量數(shù)據(jù)庫(Pinecone),并且支持JDK1.8,為用戶提供快速整合AI的能力。

AI4J-GitHub

快速使用

目前較多的應(yīng)用場景為Spring應(yīng)用,而AI4J接入SpringBoot應(yīng)用也是非常簡單的,本篇博文先帶著大家為SpringBoot應(yīng)用集成OpenAI服務(wù),后續(xù)會介紹如何再非Spring項目中搭建。

創(chuàng)建SpringBoot項目

這里以JDK1.8為例創(chuàng)建SpringBoot2項目,當(dāng)然你也可以創(chuàng)建JDK17、SpringBoot3。

引入AI4J依賴

<!-- Spring應(yīng)用 -->
<dependency>
    <groupId>io.github.lnyo-cly</groupId>
    <artifactId>ai4j-spring-boot-stater</artifactId>
    <version>0.5.2</version>
</dependency>

如果你使用阿里源無法引入,可能是阿里云鏡像還沒有同步。

配置application.yml

給大家兩種配置方法

第一種:使用官網(wǎng)的url,自己有代理

第二種:使用中轉(zhuǎn)代理地址(或第三方中轉(zhuǎn)平臺)

如:https://api.openai-proxy.com

上面任意配置一種即可。

搭建聊天服務(wù)Controller

下面是一個小的demo演示:

@RestController
public class OpenAiController {
    // 注入Ai服務(wù)
    @Autowired
    private AiService aiService;
    @GetMapping("/chat")
    public String getChatMessage(@RequestParam String question) throws Exception {
        // 獲取OpenAi的聊天服務(wù)
        IChatService chatService = aiService.getChatService(PlatformType.OPENAI);
        // 創(chuàng)建請求參數(shù)
        ChatCompletion chatCompletion = ChatCompletion.builder()
                .model("gpt-4o-mini")
                .message(ChatMessage.withUser(question))
                .build();
        System.out.println(chatCompletion);
        // 發(fā)送chat請求
        ChatCompletionResponse chatCompletionResponse = chatService.chatCompletion(chatCompletion);
        // 獲取聊天內(nèi)容和token消耗
        String content = chatCompletionResponse.getChoices().get(0).getMessage().getContent();
        long totalTokens = chatCompletionResponse.getUsage().getTotalTokens();
        System.out.println("總token消耗: " + totalTokens);
        return content;
    }
}

實現(xiàn)stream流式輸出(打字機效果)

編寫stream.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Stream Example</title>
</head>
<body>
<input id="question" type="text" placeholder="輸入需要提問的問題"/>
<button id="startButton">開始</button>
<div id="output"></div>
<script>
    const input = document.getElementById("question");
    const outputDiv = document.getElementById('output');
    const startButton = document.getElementById('startButton');
    async function getResponse(){
        const question = input.value;
        const resp = await fetch("/chatStream" + "?question=" + question,{
            method: 'GET'
        })
        const reader = resp.body.getReader();
        const textDecoder = new TextDecoder();
        while (1){
            const { done , value } = await reader.read()
            if(done) break;
            const str = textDecoder.decode(value);
            outputDiv.innerText += str;
            console.log(str)
        }
    }
    startButton.addEventListener("click", getResponse)
</script>
</body>
</html>

向controller中添加stream接口:

    @GetMapping("/chatStream")
    public void getChatMessageStream(@RequestParam String question, HttpServletResponse response) throws Exception {
        // 中文亂碼問題
        response.setCharacterEncoding("UTF-8");
        // 獲取OpenAi的聊天服務(wù)
        IChatService chatService = aiService.getChatService(PlatformType.OPENAI);
        // 創(chuàng)建請求參數(shù)
        ChatCompletion chatCompletion = ChatCompletion.builder()
                .model("gpt-4o-mini")
                .message(ChatMessage.withUser(question))
                .build();
        PrintWriter writer = response.getWriter();
        // 發(fā)送chat請求
        SseListener sseListener = new SseListener() {
            @Override
            protected void send() {
                writer.write(this.getCurrStr());
                writer.flush();
                System.out.println(this.getCurrStr());
            }
        };
        chatService.chatCompletionStream(chatCompletion, sseListener);
        writer.close();
        System.out.println(sseListener.getOutput());
    }

注意:上面只是一個簡單的示例,你也可以使用其它方法,比如:

    @GetMapping("/chatStream")
    public ResponseBodyEmitter getChatMessageStream(@RequestParam String question) {
        ResponseBodyEmitter emitter = new ResponseBodyEmitter();
        // 獲取OpenAi的聊天服務(wù)
        IChatService chatService = aiService.getChatService(PlatformType.OPENAI);
        // 創(chuàng)建請求參數(shù)
        ChatCompletion chatCompletion = ChatCompletion.builder()
                .model("gpt-4o-mini")
                .message(ChatMessage.withUser(question))
                .build();
        Executors.newSingleThreadExecutor().submit(() -> {
            try {
                SseListener sseListener = new SseListener() {
                    @Override
                    protected void send() {
                        try {
                            emitter.send(this.getCurrStr());
                            System.out.println(this.getCurrStr());  // 打印當(dāng)前發(fā)送的內(nèi)容
                        } catch (IOException e) {
                            emitter.completeWithError(e);
                        }
                    }
                };
                // 發(fā)送流式數(shù)據(jù)
                chatService.chatCompletionStream(chatCompletion, sseListener);
                // 完成后關(guān)閉連接
                emitter.complete();
            } catch (Exception e) {
                emitter.completeWithError(e);
            }
        });
        return emitter;
    }

實現(xiàn)函數(shù)調(diào)用

首先我們需要編寫一個函數(shù),以天氣預(yù)報為例子:

@FunctionCall(name = "queryWeather", description = "查詢目標(biāo)地點的天氣預(yù)報")
public class QueryWeatherFunction implements Function<QueryWeatherFunction.Request, String> {
    @Override
    public String apply(Request request) {
        final String key = "abcdefg";
        // https://api.seniverse.com/v3/weather/hourly.json?key=your_api_key&location=beijing&start=0&hours=24
        // https://api.seniverse.com/v3/weather/daily.json?key=your_api_key&location=beijing&start=0&days=5
        String url = String.format("https://api.seniverse.com/v3/weather/%s.json?key=%s&location=%s&days=%d",
                request.type.name(),
                key,
                request.location,
                request.days);
        OkHttpClient client = new OkHttpClient();
        okhttp3.Request http = new okhttp3.Request.Builder()
                .url(url)
                .get()
                .build();
        try (Response response = client.newCall(http).execute()) {
            if (response.isSuccessful()) {
                // 解析響應(yīng)體
                return response.body() != null ? response.body().string() : "";
            } else {
                return "獲取天氣失敗 當(dāng)前天氣未知";
            }
        } catch (Exception e) {
            // 處理異常
            e.printStackTrace();
            return "獲取天氣失敗 當(dāng)前天氣未知";
        }
    }
    @Data
    @FunctionRequest
    public static class Request{
        @FunctionParameter(description = "需要查詢天氣的目標(biāo)位置, 可以是城市中文名、城市拼音/英文名、省市名稱組合、IP 地址、經(jīng)緯度")
        private String location;
        @FunctionParameter(description = "需要查詢未來天氣的天數(shù), 最多15日")
        private int days = 15;
        @FunctionParameter(description = "預(yù)報的天氣類型,daily表示預(yù)報多天天氣、hourly表示預(yù)測當(dāng)天24天氣、now為當(dāng)前天氣實況")
        private Type type;
    }
    public enum Type{
        daily,
        hourly,
        now
    }
}

其中有三個核心注解:

  • @FunctionCall:標(biāo)識這個類為一個函數(shù)
  • @FunctionRequest:標(biāo)識為該類為函數(shù)的請求類
  • @FunctionParameter:標(biāo)識為函數(shù)的具體參數(shù)

接下來稍微修改下剛剛編寫的Stream實現(xiàn)函數(shù):

    @GetMapping("/chatStream")
    public void getChatMessageStream(@RequestParam String question, HttpServletResponse response) throws Exception {
        // ......
        // 創(chuàng)建請求參數(shù)
        ChatCompletion chatCompletion = ChatCompletion.builder()
                .model("gpt-4o-mini")
                .message(ChatMessage.withUser(question))
                .functions("queryWeather") // 這里傳入剛剛我們定義的函數(shù)名稱即可
                .build();
        // ......
    }

如果想要知道函數(shù)調(diào)用的參數(shù),只需要在剛剛的代碼中,添加下面這一行即可:

sseListener.setShowToolArgs(true);

更換其它平臺

細心的你可能已經(jīng)發(fā)現(xiàn),我們在創(chuàng)建chatService的時候傳入了PlatformType.OPENAI,如果我們想要更換其它平臺,只需要更換PlatformType即可。如果你不懂,那下篇博文再詳細的說說

IChatService chatService = aiService.getChatService(PlatformType.OPENAI);

其它功能

篇幅有限,其它功能使用,下篇再講

到此這篇關(guān)于SpringBoot快速接入OpenAI大模型(JDK8)的文章就介紹到這了,更多相關(guān)SpringBoot接入OpenAI大模型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中間的接口用法詳解

    Java中間的接口用法詳解

    Java 程序員都知道要面向接口編程,那 Java? 中的接口除了定義接口方法之外還能怎么用你知道嗎,今天小編就來帶大家看一下 Java 中間的接口還可以有哪些用法,需要的朋友可以參考下
    2023-07-07
  • Java匿名內(nèi)部類和Lambda(->) 的多種寫法總結(jié)

    Java匿名內(nèi)部類和Lambda(->) 的多種寫法總結(jié)

    這篇文章主要和大家分享一下Java匿名內(nèi)部類和Lambda(->) 的多種寫法,文中的示例代碼講解詳細,對我們學(xué)習(xí)Java有一定幫助,需要的可以先看一下
    2022-07-07
  • springboot過濾器和攔截器的實例代碼

    springboot過濾器和攔截器的實例代碼

    這篇文章主要介紹了springboot過濾器和攔截器的實例代碼,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-07-07
  • 深入理解Java 線程通信

    深入理解Java 線程通信

    這篇文章主要介紹了Java 線程通信的的相關(guān)資料,文中講解非常細致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • java實現(xiàn)表格tr拖動的實例(分享)

    java實現(xiàn)表格tr拖動的實例(分享)

    下面小編就為大家分享一篇java實現(xiàn)表格tr拖動的實例。具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • JSON--List集合轉(zhuǎn)換成JSON對象詳解

    JSON--List集合轉(zhuǎn)換成JSON對象詳解

    這篇文章主要介紹了List集合轉(zhuǎn)換成JSON對象,小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。
    2017-01-01
  • 解讀前后端分離項目的跨域問題

    解讀前后端分離項目的跨域問題

    文章介紹了跨域問題的原因——瀏覽器的同源策略限制,以及CORS(跨域資源共享)的概念,CORS通過服務(wù)器設(shè)置特定的響應(yīng)頭來允許跨域請求,文章還概述了后端解決跨域問題的幾種方式,并簡要介紹了前端處理跨域請求的方法
    2024-11-11
  • 在java上使用亞馬遜云儲存方法

    在java上使用亞馬遜云儲存方法

    這篇文章主要介紹了在java上使用亞馬遜云儲存方法,首先寫一個配置類,寫一個controller接口調(diào)用方法存儲文件,本文結(jié)合示例代碼給大家介紹的非常詳細,需要的朋友參考下吧
    2024-01-01
  • idea 修改項目名和module名稱的操作

    idea 修改項目名和module名稱的操作

    這篇文章主要介紹了idea 修改項目名和module名稱的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • MyBatis動態(tài)<if>標(biāo)簽的使用

    MyBatis動態(tài)<if>標(biāo)簽的使用

    本文主要介紹了MyBatis動態(tài)<if>標(biāo)簽的使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05

最新評論