偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

JDK1.8也可以對接DeepSeek-R1,你知道嗎?

人工智能
AI4J 是一款 Java SDK,用于快速接入 AI 大模型應(yīng)用。它能整合多平臺大模型,如 OpenAI、Ollama、智譜 Zhipu(ChatGLM)、深度求索 DeepSeek、月之暗面 Moonshot(Kimi)、騰訊混元 Hunyuan、零一萬物(01)等,為用戶提供快速整合 AI 的能力。

什么是ai4j

首先,我們先了解一下什么是ai4j。

AI4J 是一款 Java SDK,用于快速接入 AI 大模型應(yīng)用。它能整合多平臺大模型,如 OpenAI、Ollama、智譜 Zhipu(ChatGLM)、深度求索 DeepSeek、月之暗面 Moonshot(Kimi)、騰訊混元 Hunyuan、零一萬物(01)等,為用戶提供快速整合 AI 的能力。

其特點包括提供統(tǒng)一的輸入輸出(對齊 OpenAI)以消除差異化,優(yōu)化函數(shù)調(diào)用(Tool Call)和 RAG 調(diào)用,支持向量數(shù)據(jù)庫(如 Pinecone),并且支持 JDK1.8,能滿足很多仍在使用 JDK8 版本的應(yīng)用需求。

敲重點:JDK1.8

看過上一篇使用SpringAI的都知道,SpringAI對JDK的要求非常高,那次了不起使用了JDK 17,但是Java發(fā)展了這么多年,很多項目都是基于JDK1.8來構(gòu)建的,你讓他們現(xiàn)在去升級JDK,可能AI還沒接入,項目就先起不來了。

也因此誕生了ai4j,他支持 JDK1.8,能滿足很多仍在使用 JDK8 版本的應(yīng)用需求,并且向量數(shù)據(jù)庫還能幫助很多項目做知識庫搜索。

進(jìn)入正題

我們使用目前最新版本的ai4j。

<dependency>
      <groupId>io.github.lnyo-cly</groupId>
      <artifactId>ai4j</artifactId>
      <version>0.8.1</version>
  </dependency>

現(xiàn)在網(wǎng)上很多版本的ai4j都不支持ollama調(diào)用,所以直接使用最新版本的話,就沒有問題了。

我們依舊是寫兩個接口,一個直接返回,一個流式返回。

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

通過getChatService的方式,選擇是用本地ollama還是其他平臺。

它一共支持以下平臺。

@AllArgsConstructor
@Getter
public enum PlatformType {
    OPENAI("openai"),
    ZHIPU("zhipu"),
    DEEPSEEK("deepseek"),
    MOONSHOT("moonshot"),
    HUNYUAN("hunyuan"),
    LINGYI("lingyi"),
    OLLAMA("ollama"),
    MINIMAX("minimax"),
    BAICHUAN("baichuan"),
    ;
   ....
}

由于我修改過ollama的端口,所以我沒辦法使用默認(rèn)的端口,需要單獨設(shè)置調(diào)用的url。

spring.application.name=demo
server.port=8080
ai.ollama.api-host=http://localhost:8000

創(chuàng)建請求體:

// 創(chuàng)建請求參數(shù)
  ChatCompletion chatCompletion = ChatCompletion.builder()
         .model("deepseek-r1:7b")
         .message(ChatMessage.withUser(question))
         .build();

直接返回就調(diào)用chatCompletion方法:

// 發(fā)送chat請求
ChatCompletionResponse chatCompletionResponse = chatService.chatCompletion(chatCompletion);

流式放回就調(diào)用chatCompletionStream方法:

// 發(fā)送chat請求
chatService.chatCompletionStream(chatCompletion, sseListener);

流式的話他是以SSE端點的形式去獲取數(shù)據(jù),所以需要你實現(xiàn)一個SSE監(jiān)聽器去打印和發(fā)送數(shù)據(jù)給前端。

以下是完整的后端接口:

@RestController
@CrossOrigin
public class OllamChatController {
    // 注入Ai服務(wù)
    @Autowired
    private AiService aiService;

    @GetMapping("/chat")
    public String getChatMessage(@RequestParam String question) throws Exception {
        // 獲取OLLAMA的聊天服務(wù)
        IChatService chatService = aiService.getChatService(PlatformType.OLLAMA);
        // 創(chuàng)建請求參數(shù)
        ChatCompletion chatCompletion = ChatCompletion.builder()
               .model("deepseek-r1:7b")
               .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;
    }

    @GetMapping(path = "/chat-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> chatStream(@RequestParam String question) {
        Logger logger = LoggerFactory.getLogger(getClass());
        return Flux.create(emitter -> {
            try {
                logger.info("開始進(jìn)行Chat對話: {}", question);
                // 獲取chat服務(wù)實例
                IChatService chatService = aiService.getChatService(PlatformType.OLLAMA);
                logger.info("成功創(chuàng)建服務(wù)實例");
                // 構(gòu)造請求參數(shù)
                ChatCompletion chatCompletion = ChatCompletion.builder()
                        .model("deepseek-r1:7b")
                        .messages(Arrays.asList(ChatMessage.withUser(question)))
                        .functions()
                        .build();
                logger.info("成功構(gòu)建流式請求體");
                // 構(gòu)造監(jiān)聽器
                SseListener sseListener = new SseListener() {
                    @Override
                    protected void send() {
                        try {
                            // 將消息發(fā)送到前端
                            String data = this.getCurrStr();
                            if (data != null && !data.isEmpty()) {
                                emitter.next(ServerSentEvent.<String>builder()
                                        .data(data)
                                        .build());
                            }
                        } catch (Exception e) {
                            logger.error("SSE端點報錯", e);
                            emitter.error(e);
                        }
                    }
                };
                // 顯示函數(shù)參數(shù),默認(rèn)不顯示
                sseListener.setShowToolArgs(true);
                // 發(fā)送SSE請求
                chatService.chatCompletionStream(chatCompletion, sseListener);
                logger.info("成功請求SSE端點");
            } catch (Exception e) {
                logger.error("流式輸出報錯", e);
                emitter.error(e);
            }
        });
    }


}

流式的話,我們再寫個前端來看看測試效果。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Chat Stream Frontend</title>
</head>

<body>
<input type="text" id="questionInput" placeholder="請輸入問題">
<button id="sendButton">發(fā)送</button>
<div id="responseContainer"></div>

<script>
    const questionInput = document.getElementById('questionInput');
    const sendButton = document.getElementById('sendButton');
    const responseContainer = document.getElementById('responseContainer');

    sendButton.addEventListener('click', () => {
        const question = questionInput.value;
        if (question.trim() === '') {
            alert('請輸入問題');
            return;
        }

        // 創(chuàng)建 EventSource 實例,連接到后端的 SSE 接口
        const eventSource = new EventSource(`http://localhost:8080/chat-stream?question=${encodeURIComponent(question)}`);

        // 監(jiān)聽 message 事件,當(dāng)接收到服務(wù)器發(fā)送的消息時觸發(fā)
        eventSource.onmessage = (event) => {
            const data = event.data;
            // 將接收到的數(shù)據(jù)追加到響應(yīng)容器中
            responseContainer.textContent += data;
        };

        // 監(jiān)聽 error 事件,當(dāng)連接出現(xiàn)錯誤時觸發(fā)
        eventSource.onerror = (error) => {
            console.error('EventSource failed:', error);
            // 關(guān)閉連接
            eventSource.close();
        };
    });
</script>
</body>

</html>

運行服務(wù),打開html,在輸入框輸入一個問題,點擊按鈕發(fā)送,在F12的接口請求里,你會在Response里看到服務(wù)不斷的推送文字給你。

圖片圖片

責(zé)任編輯:武曉燕 來源: Java面試教程
相關(guān)推薦

2025-02-19 08:00:00

2024-01-09 07:29:05

Argo代碼庫應(yīng)用程序

2022-05-09 07:49:47

PulsarJava問題排查

2024-06-14 08:36:57

2025-02-19 08:33:18

2023-12-20 08:23:53

NIO組件非阻塞

2023-12-12 08:41:01

2023-04-26 10:21:04

2024-04-30 09:02:48

2022-12-12 08:17:29

2023-09-04 07:54:06

2024-05-28 09:12:10

2024-04-07 00:00:00

ESlint命令變量

2019-12-12 09:23:29

Hello World操作系統(tǒng)函數(shù)庫

2017-10-16 13:45:04

2024-07-30 08:22:47

API前端網(wǎng)關(guān)

2022-05-27 08:55:15

工具自動化軟件

2022-03-10 08:25:27

JavaScrip變量作用域

2022-06-24 08:20:04

CAP網(wǎng)絡(luò)通信
點贊
收藏

51CTO技術(shù)棧公眾號