JAVA接入DeepSeek滿血版的詳細指南(問答接入、流式接入雙模式)
前言
硅基流動推出了功能完備的DeepSeek滿血版,然而眾多用戶在嘗試接入大型模型時仍面臨諸多挑戰(zhàn),特別是在流式接入方面。今天,我將引領(lǐng)大家通過Java實現(xiàn)雙模式接入DeepSeek滿血版,這涵蓋了利用HTTP協(xié)議實現(xiàn)的問答模式,以及借助WSS協(xié)議實現(xiàn)的流式問答功能。話不多說,我們直接開始。
一、必要信息準備
接入滿血版DeepSeek,肯定要有個硅基流動賬號和秘鑰啦,搜索一下硅基流動官網(wǎng),打開硅基流動首頁,注冊賬號,別忘了填邀請碼wkzJFskh,注冊后可以獲取14元的贈送額度,嫌麻煩的同學可以直接復制https://cloud.siliconflow.cn/i/wkzJFskh,可以直接跳轉(zhuǎn)到官網(wǎng)。
注冊完成后,左側(cè)菜單欄點擊API秘鑰,然后選擇右上角的創(chuàng)建秘鑰,輸入必要信息后,秘鑰創(chuàng)建完成,鼠標點擊剛剛創(chuàng)建的秘鑰,單擊復制,這一步可以先把秘鑰用個記事本記錄一下,等會代碼里會用到。
點擊左側(cè)模型廣場,選取DeepSeekR1滿血版模型,可以看到,廣場里面有很多小模型是免費的,大家有空可以都嘗試玩一下。
復制一下模型名稱,寫在記事本里,等會會用到。點擊API文檔,進入官方接入指南。
記住這邊的路徑,請求以及響應(yīng),下面要開始代碼部分啦。
二、HTTP問答接入
我們先進行HTTP問答接入,這種接入方式需要等大模型完全回答完問題,將答案生成好之后,全部返回,這種方式的優(yōu)點是前后端交互方便,缺點是在用戶看來等待好長時間才返回答案。下面開始上代碼
1.配置文件
代碼如下(示例):
sili: apiKey: sk-xxxxxxxxx-your-api-key baseUrl: https://api.siliconflow.cn/v1/
2.創(chuàng)建實例類
會看第一節(jié)的官方API指南,根據(jù)官方的請求體和響應(yīng),構(gòu)造實體類,我這邊不展開篇幅
3.創(chuàng)建調(diào)用外部API接口
這里將普通調(diào)用和流模式均展示在了下面,流式調(diào)用需要用@Streaming注解。這里不使用openFeign是因為openFeign不支持流式響應(yīng)的接收。
package com.example.awesome.feign.siliconflow; import com.example.awesome.feign.siliconflow.req.ChatCompletionReq; import com.example.awesome.feign.siliconflow.res.ChatCompletionRes; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.http.Body; import retrofit2.http.HeaderMap; import retrofit2.http.POST; import retrofit2.http.Streaming; import java.util.Map; /** * 定義與 SiliconFlow API 交互的 Retrofit 接口。 */ public interface SiliconFlowApiService { /** * 發(fā)起同步的聊天完成請求。 * * @param chatCompletionReq 請求體,包含聊天完成所需的參數(shù)。 * @param headers HTTP 請求頭,包括授權(quán)信息等。 * @return 返回一個 {@link Call} 對象,用于執(zhí)行HTTP請求并獲取 {@link ChatCompletionRes} 響應(yīng)。 */ @POST("/chat/completions") Call<ChatCompletionRes> getChatCompletions( @Body ChatCompletionReq chatCompletionReq, @HeaderMap Map<String, String> headers ); /** * 發(fā)起流式的聊天完成請求。 * * @param chatCompletionReq 請求體,包含聊天完成所需的參數(shù)。 * @param headers HTTP 請求頭,包括授權(quán)信息等。 * @return 返回一個 {@link Call} 對象,用于執(zhí)行HTTP請求并獲取 {@link ResponseBody} 流式響應(yīng)。 * @see Streaming 表示該請求是流式的,不會將整個響應(yīng)體加載到內(nèi)存中。 */ @POST("/chat/completions") @Streaming Call<ResponseBody> getChatCompletionsStream( @Body ChatCompletionReq chatCompletionReq, @HeaderMap Map<String, String> headers ); }
4.創(chuàng)建調(diào)用服務(wù)service
package com.example.awesome.feign.siliconflow; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.example.awesome.feign.siliconflow.req.ChatCompletionReq; import com.example.awesome.feign.siliconflow.res.ChatCompletionRes; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.volcengine.ark.runtime.model.completion.chat.ChatCompletionResult; import com.volcengine.ark.runtime.utils.ResponseBodyCallback; import com.volcengine.ark.runtime.utils.SSE; import io.reactivex.BackpressureStrategy; import io.reactivex.Flowable; import lombok.extern.slf4j.Slf4j; import okhttp3.OkHttpClient; import okhttp3.ResponseBody; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import retrofit2.Call; import retrofit2.Retrofit; import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; /** * 實現(xiàn)與 SiliconFlow API 交互的服務(wù)類。 */ @Service @Slf4j public class SiliconFlowApiServiceImpl { @Value("${sili.baseUrl}") private String SILI_API_URL; @Value("${sili.apiKey}") private String apiKey; private Retrofit retrofit; private SiliconFlowApiService apiService; /** * 初始化 Retrofit 客戶端和 API 服務(wù)。 */ @PostConstruct public void init() { log.info("SiLiApiService init"); retrofit = new Retrofit.Builder() .baseUrl(SILI_API_URL) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .build(); this.apiService = retrofit.create(SiliconFlowApiService.class); } /** * 發(fā)起同步的聊天完成請求,返回非流式的響應(yīng)。 * * @param req 請求體,包含聊天完成所需的參數(shù)。 * @return 返回 {@link ChatCompletionRes} 對象,表示API的響應(yīng)結(jié)果。 */ public ChatCompletionRes getChatCompletions(ChatCompletionReq req) { Map<String, String> headers = new HashMap<>(); headers.put("Authorization", "Bearer " + apiKey); headers.put("Content-Type", "application/json"); try { // 執(zhí)行HTTP請求并獲取響應(yīng) Call<ChatCompletionRes> call = this.apiService.getChatCompletions(req, headers); return call.execute().body(); } catch (Exception e) { // 記錄錯誤日志并拋出運行時異常 log.error("SiLiApiService error: {}", e.getMessage(), e); throw new RuntimeException("SiLiApiService error: " + e.getMessage(), e); } } }
5.業(yè)務(wù)層service選擇模型,并調(diào)用剛剛的服務(wù)
package com.example.awesome.service; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.example.awesome.feign.siliconflow.SiliconFlowApiServiceImpl; import com.example.awesome.feign.siliconflow.req.ChatCompletionReq; import com.example.awesome.feign.siliconflow.req.Message; import com.example.awesome.feign.siliconflow.res.ChatCompletionRes; import com.volcengine.ark.runtime.model.completion.chat.ChatCompletionResult; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.websocket.Session; import java.util.ArrayList; import java.util.List; /** * 提供與 SiliconFlow API 交互的服務(wù)類。 */ @Service @Slf4j public class SiliconFlowService { @Resource private SiliconFlowApiServiceImpl siliconFlowApiServiceImpl; /** * 發(fā)起同步的聊天完成請求,返回用戶的回答內(nèi)容。 * * @param question 用戶提出的聊天問題。 * @return 返回用戶的回答內(nèi)容。 * @throws RuntimeException 如果請求過程中發(fā)生異常,拋出運行時異常。 */ public String getChatCompletions(String question) { // 創(chuàng)建 ChatCompletionReq 對象 ChatCompletionReq req = new ChatCompletionReq(); // 設(shè)置模型名稱 req.setModel("deepseek-ai/DeepSeek-R1"); // 創(chuàng)建消息列表 List<Message> messages = new ArrayList<>(); // 添加用戶消息 messages.add(Message.builder().role("user").content(question).build()); // 設(shè)置請求的消息列表 req.setMessages(messages); try { // 發(fā)起同步請求并獲取響應(yīng) ChatCompletionRes chatCompletions = siliconFlowApiServiceImpl.getChatCompletions(req); // 返回第一個選擇的回答內(nèi)容 return chatCompletions.getChoices().get(0).getMessage().getContent(); } catch (Exception e) { // 記錄錯誤日志并拋出運行時異常 log.error("siliconflow answer error: {}", e.getMessage(), e); throw new RuntimeException("網(wǎng)絡(luò)異常請重試", e); } } }
三、WSS流式調(diào)用
1.先寫一個處理流式響應(yīng)的方法
在官方指南中可以看到,流式調(diào)用需要將入?yún)⒌?strong>stream設(shè)置為true
package com.example.awesome.feign.siliconflow; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.example.awesome.feign.siliconflow.req.ChatCompletionReq; import com.example.awesome.feign.siliconflow.res.ChatCompletionRes; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.volcengine.ark.runtime.model.completion.chat.ChatCompletionResult; import com.volcengine.ark.runtime.utils.ResponseBodyCallback; import com.volcengine.ark.runtime.utils.SSE; import io.reactivex.BackpressureStrategy; import io.reactivex.Flowable; import lombok.extern.slf4j.Slf4j; import okhttp3.OkHttpClient; import okhttp3.ResponseBody; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import retrofit2.Call; import retrofit2.Retrofit; import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; /** * 實現(xiàn)與 SiliconFlow API 交互的服務(wù)類。 */ @Service @Slf4j public class SiliconFlowApiServiceImpl { @Value("${sili.baseUrl}") private String SILI_API_URL; @Value("${sili.apiKey}") private String apiKey; private Retrofit retrofit; private SiliconFlowApiService apiService; private static final ObjectMapper mapper = defaultObjectMapper(); /** * 創(chuàng)建并配置 ObjectMapper 實例。 * * @return 配置好的 ObjectMapper 實例。 */ public static ObjectMapper defaultObjectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); return mapper; } /** * 初始化 Retrofit 客戶端和 API 服務(wù)。 */ @PostConstruct public void init() { log.info("SiLiApiService init"); retrofit = new Retrofit.Builder() .baseUrl(SILI_API_URL) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .build(); this.apiService = retrofit.create(SiliconFlowApiService.class); } /** * 將 Call<ResponseBody> 轉(zhuǎn)換為 Flowable<T>,并進行數(shù)據(jù)映射。 * * @param apiCall API 調(diào)用對象。 * @param cl 目標類類型。 * @param <T> 泛型類型。 * @return Flowable<T> 對象。 */ public static <T> Flowable<T> stream(Call<ResponseBody> apiCall, Class<T> cl) { return stream(apiCall).map((sse) -> { // log.info("SiLiApiService stream: {}", sse.getData()); return mapper.readValue(sse.getData(), cl); }); } /** * 將 Call<ResponseBody> 轉(zhuǎn)換為 Flowable<SSE>,并處理響應(yīng)。 * * @param apiCall API 調(diào)用對象。 * @param emitDone 是否在流結(jié)束時發(fā)送完成信號。 * @return Flowable<SSE> 對象。 */ public static Flowable<SSE> stream(Call<ResponseBody> apiCall, boolean emitDone) { return Flowable.create((emitter) -> { apiCall.enqueue(new ResponseBodyCallback(emitter, emitDone)); }, BackpressureStrategy.BUFFER); } /** * 將 Call<ResponseBody> 轉(zhuǎn)換為 Flowable<SSE>,默認不發(fā)送完成信號。 * * @param apiCall API 調(diào)用對象。 * @return Flowable<SSE> 對象。 */ public static Flowable<SSE> stream(Call<ResponseBody> apiCall) { return stream(apiCall, false); } /** * 發(fā)起流式的聊天完成請求,返回流式的響應(yīng)。 * * @param request 請求體,包含聊天完成所需的參數(shù)。 * @return 返回 {@link Flowable<ChatCompletionResult>} 對象,表示流式的API響應(yīng)結(jié)果。 */ public Flowable<ChatCompletionResult> streamChatCompletion(ChatCompletionReq request) { Map<String, String> headers = new HashMap<>(); headers.put("Authorization", "Bearer " + apiKey); headers.put("Content-Type", "application/json"); request.setStream(Boolean.TRUE); return stream(this.apiService.getChatCompletionsStream(request, headers), ChatCompletionResult.class); } }
2.業(yè)務(wù)層service調(diào)用
package com.example.awesome.service; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.example.awesome.feign.siliconflow.SiliconFlowApiServiceImpl; import com.example.awesome.feign.siliconflow.req.ChatCompletionReq; import com.example.awesome.feign.siliconflow.req.Message; import com.example.awesome.feign.siliconflow.res.ChatCompletionRes; import com.volcengine.ark.runtime.model.completion.chat.ChatCompletionResult; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.websocket.Session; import java.util.ArrayList; import java.util.List; /** * 提供與 SiliconFlow API 交互的服務(wù)類。 */ @Service @Slf4j public class SiliconFlowService { @Resource private SiliconFlowApiServiceImpl siliconFlowApiServiceImpl; /** * 發(fā)起流式的聊天完成請求,并將結(jié)果通過 WebSocket 會話發(fā)送給客戶端。 * * @param question 用戶提出的聊天問題。 * @param session WebSocket 會話對象。 * @throws RuntimeException 如果請求過程中發(fā)生異常,拋出運行時異常。 */ public void getChatCompletionsStream(String question, Session session) { // 創(chuàng)建 ChatCompletionReq 對象 ChatCompletionReq req = new ChatCompletionReq(); // 設(shè)置模型名稱 req.setModel("deepseek-ai/DeepSeek-R1"); // 創(chuàng)建消息列表 List<Message> messages = new ArrayList<>(); // 添加用戶消息 messages.add(Message.builder().role("user").content(question).build()); // 設(shè)置請求的消息列表 req.setMessages(messages); try { // 發(fā)起流式請求并處理響應(yīng) siliconFlowApiServiceImpl.streamChatCompletion(req) .doOnError(e -> log.error("Error in streamChatCompletion: ", e)) .blockingForEach(chunk -> { if (!chunk.getChoices().isEmpty()) { chunk.getChoices().forEach(choice -> { // 如果完成原因為空或不是 "stop",則繼續(xù)處理 if (StrUtil.isNotEmpty(choice.getFinishReason()) && StrUtil.equals(choice.getFinishReason(), "stop")) { // 發(fā)送 "answer-stop" 信號 session.getAsyncRemote().sendText("answer-stop"); return; } // 如果消息內(nèi)容為空,則跳過 if (ObjectUtil.isEmpty(choice.getMessage().getContent())) { return; } // 同步發(fā)送消息內(nèi)容 synchronized (session) { try { session.getBasicRemote().sendText(choice.getMessage().getContent()); } catch (Exception e) { // 記錄錯誤日志并拋出運行時異常 log.error("answerByStream error: {}", e.getMessage(), e); throw new RuntimeException(e); } } }); } }); } catch (Exception e) { // 記錄錯誤日志并拋出運行時異常 log.error("siliconflow answer error: {}", e.getMessage(), e); throw new RuntimeException("網(wǎng)絡(luò)異常請重試", e); } } }
3.WebSocket調(diào)用
在onMessage方法中,在session中寫入流式調(diào)用的響應(yīng),即可實現(xiàn)wss流式接入,輸出就類似于官方的一字一字輸出。在用戶看來減少了等待時間,十分友好。
package com.example.awesome.controller.webSocket; import cn.hutool.core.util.ObjectUtil; import com.example.awesome.service.SiliconFlowService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; /** * WebSocket 服務(wù)器端點,處理與客戶端的 WebSocket 連接。 */ @Slf4j @ServerEndpoint(value = "/websocket/test") @Component public class TestSocketServer { private static SiliconFlowService siliconFlowService; /** * 注入 SiliconFlowService 實例。 * * @param siliconFlowService SiliconFlowService 實例。 */ @Autowired public void setSiliconFlowService(SiliconFlowService siliconFlowService) { this.siliconFlowService = siliconFlowService; } /** * 處理 WebSocket 連接打開事件。 * * @param session 當前 WebSocket 會話。 */ @OnOpen public void onOpen(Session session) { log.info("新連接: {}", session.getId()); } /** * 處理接收到的 WebSocket 消息。 * * @param message 接收到的消息內(nèi)容。 * @param session 當前 WebSocket 會話。 */ @OnMessage public void onMessage(String message, Session session) { // 調(diào)用 SiliconFlowService 處理流式聊天完成請求 siliconFlowService.getChatCompletionsStream(message, session); } /** * 處理 WebSocket 連接關(guān)閉事件。 * * @param session 當前 WebSocket 會話。 */ @OnClose public void onClose(Session session) { log.info("連接關(guān)閉: {}", session.getId()); } /** * 處理 WebSocket 連接中的錯誤事件。 * * @param session 當前 WebSocket 會話。 * @param throwable 發(fā)生的異常。 */ @OnError public void onError(Session session, Throwable throwable) { log.error("Error on session: {}", session.getId(), throwable); } }
總結(jié)
到此這篇關(guān)于JAVA接入DeepSeek滿血版的詳細指南(問答接入、流式接入雙模式)的文章就介紹到這了,更多相關(guān)JAVA接入DeepSeek滿血版內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Java去除json數(shù)據(jù)中的null空值問題
這篇文章主要介紹了詳解Java去除json數(shù)據(jù)中的null空值問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-08-08SpringBoot實現(xiàn)嵌入式 Servlet容器
傳統(tǒng)的Spring MVC工程部署時需要將WAR文件放置在servlet容器的文檔目錄內(nèi),而Spring Boot工程使用嵌入式servlet容器省去了這一步驟,本文就來設(shè)置一下相關(guān)配置,感興趣的可以了解一下2023-12-12SpringBoot+Email發(fā)送郵件的實現(xiàn)示例
Spring?Boot提供了簡單而強大的郵件發(fā)送功能,本文主要介紹了SpringBoot+Email發(fā)送郵件的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下2024-03-03Java?8中讀取文件內(nèi)容?Files.lines()方法使用示例
這篇文章主要介紹了Java?8中讀取文件內(nèi)容Files.lines()方法如何使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07SpringBoot項目Jar包如何瘦身部署的實現(xiàn)
這篇文章主要介紹了SpringBoot項目Jar包如何瘦身部署的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09SpringBoot實現(xiàn)數(shù)據(jù)加密脫敏的示例代碼
這篇文章主要為大家學習介紹了SpringBoot如何利用注解+反射+AOP實現(xiàn)數(shù)據(jù)加密脫敏的功能,文中的示例代碼講解詳細,需要的可以參考一下2023-08-08