JAVA接入DeepSeek滿血版的詳細指南(問答接入、流式接入雙模式)
前言
硅基流動推出了功能完備的DeepSeek滿血版,然而眾多用戶在嘗試接入大型模型時仍面臨諸多挑戰(zhàn),特別是在流式接入方面。今天,我將引領大家通過Java實現雙模式接入DeepSeek滿血版,這涵蓋了利用HTTP協議實現的問答模式,以及借助WSS協議實現的流式問答功能。話不多說,我們直接開始。
一、必要信息準備

接入滿血版DeepSeek,肯定要有個硅基流動賬號和秘鑰啦,搜索一下硅基流動官網,打開硅基流動首頁,注冊賬號,別忘了填邀請碼wkzJFskh,注冊后可以獲取14元的贈送額度,嫌麻煩的同學可以直接復制https://cloud.siliconflow.cn/i/wkzJFskh,可以直接跳轉到官網。

注冊完成后,左側菜單欄點擊API秘鑰,然后選擇右上角的創(chuàng)建秘鑰,輸入必要信息后,秘鑰創(chuàng)建完成,鼠標點擊剛剛創(chuàng)建的秘鑰,單擊復制,這一步可以先把秘鑰用個記事本記錄一下,等會代碼里會用到。

點擊左側模型廣場,選取DeepSeekR1滿血版模型,可以看到,廣場里面有很多小模型是免費的,大家有空可以都嘗試玩一下。

復制一下模型名稱,寫在記事本里,等會會用到。點擊API文檔,進入官方接入指南。

記住這邊的路徑,請求以及響應,下面要開始代碼部分啦。
二、HTTP問答接入
我們先進行HTTP問答接入,這種接入方式需要等大模型完全回答完問題,將答案生成好之后,全部返回,這種方式的優(yōu)點是前后端交互方便,缺點是在用戶看來等待好長時間才返回答案。下面開始上代碼
1.配置文件
代碼如下(示例):
sili: apiKey: sk-xxxxxxxxx-your-api-key baseUrl: https://api.siliconflow.cn/v1/
2.創(chuàng)建實例類
會看第一節(jié)的官方API指南,根據官方的請求體和響應,構造實體類,我這邊不展開篇幅
3.創(chuàng)建調用外部API接口
這里將普通調用和流模式均展示在了下面,流式調用需要用@Streaming注解。這里不使用openFeign是因為openFeign不支持流式響應的接收。
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 請求體,包含聊天完成所需的參數。
* @param headers HTTP 請求頭,包括授權信息等。
* @return 返回一個 {@link Call} 對象,用于執(zhí)行HTTP請求并獲取 {@link ChatCompletionRes} 響應。
*/
@POST("/chat/completions")
Call<ChatCompletionRes> getChatCompletions(
@Body ChatCompletionReq chatCompletionReq,
@HeaderMap Map<String, String> headers
);
/**
* 發(fā)起流式的聊天完成請求。
*
* @param chatCompletionReq 請求體,包含聊天完成所需的參數。
* @param headers HTTP 請求頭,包括授權信息等。
* @return 返回一個 {@link Call} 對象,用于執(zhí)行HTTP請求并獲取 {@link ResponseBody} 流式響應。
* @see Streaming 表示該請求是流式的,不會將整個響應體加載到內存中。
*/
@POST("/chat/completions")
@Streaming
Call<ResponseBody> getChatCompletionsStream(
@Body ChatCompletionReq chatCompletionReq,
@HeaderMap Map<String, String> headers
);
}
4.創(chuàng)建調用服務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;
/**
* 實現與 SiliconFlow API 交互的服務類。
*/
@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 服務。
*/
@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ā)起同步的聊天完成請求,返回非流式的響應。
*
* @param req 請求體,包含聊天完成所需的參數。
* @return 返回 {@link ChatCompletionRes} 對象,表示API的響應結果。
*/
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請求并獲取響應
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è)務層service選擇模型,并調用剛剛的服務
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 交互的服務類。
*/
@Service
@Slf4j
public class SiliconFlowService {
@Resource
private SiliconFlowApiServiceImpl siliconFlowApiServiceImpl;
/**
* 發(fā)起同步的聊天完成請求,返回用戶的回答內容。
*
* @param question 用戶提出的聊天問題。
* @return 返回用戶的回答內容。
* @throws RuntimeException 如果請求過程中發(fā)生異常,拋出運行時異常。
*/
public String getChatCompletions(String question) {
// 創(chuàng)建 ChatCompletionReq 對象
ChatCompletionReq req = new ChatCompletionReq();
// 設置模型名稱
req.setModel("deepseek-ai/DeepSeek-R1");
// 創(chuàng)建消息列表
List<Message> messages = new ArrayList<>();
// 添加用戶消息
messages.add(Message.builder().role("user").content(question).build());
// 設置請求的消息列表
req.setMessages(messages);
try {
// 發(fā)起同步請求并獲取響應
ChatCompletionRes chatCompletions = siliconFlowApiServiceImpl.getChatCompletions(req);
// 返回第一個選擇的回答內容
return chatCompletions.getChoices().get(0).getMessage().getContent();
} catch (Exception e) {
// 記錄錯誤日志并拋出運行時異常
log.error("siliconflow answer error: {}", e.getMessage(), e);
throw new RuntimeException("網絡異常請重試", e);
}
}
}
三、WSS流式調用
1.先寫一個處理流式響應的方法
在官方指南中可以看到,流式調用需要將入參的stream設置為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;
/**
* 實現與 SiliconFlow API 交互的服務類。
*/
@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 服務。
*/
@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> 轉換為 Flowable<T>,并進行數據映射。
*
* @param apiCall API 調用對象。
* @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> 轉換為 Flowable<SSE>,并處理響應。
*
* @param apiCall API 調用對象。
* @param emitDone 是否在流結束時發(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> 轉換為 Flowable<SSE>,默認不發(fā)送完成信號。
*
* @param apiCall API 調用對象。
* @return Flowable<SSE> 對象。
*/
public static Flowable<SSE> stream(Call<ResponseBody> apiCall) {
return stream(apiCall, false);
}
/**
* 發(fā)起流式的聊天完成請求,返回流式的響應。
*
* @param request 請求體,包含聊天完成所需的參數。
* @return 返回 {@link Flowable<ChatCompletionResult>} 對象,表示流式的API響應結果。
*/
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è)務層service調用
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 交互的服務類。
*/
@Service
@Slf4j
public class SiliconFlowService {
@Resource
private SiliconFlowApiServiceImpl siliconFlowApiServiceImpl;
/**
* 發(fā)起流式的聊天完成請求,并將結果通過 WebSocket 會話發(fā)送給客戶端。
*
* @param question 用戶提出的聊天問題。
* @param session WebSocket 會話對象。
* @throws RuntimeException 如果請求過程中發(fā)生異常,拋出運行時異常。
*/
public void getChatCompletionsStream(String question, Session session) {
// 創(chuàng)建 ChatCompletionReq 對象
ChatCompletionReq req = new ChatCompletionReq();
// 設置模型名稱
req.setModel("deepseek-ai/DeepSeek-R1");
// 創(chuàng)建消息列表
List<Message> messages = new ArrayList<>();
// 添加用戶消息
messages.add(Message.builder().role("user").content(question).build());
// 設置請求的消息列表
req.setMessages(messages);
try {
// 發(fā)起流式請求并處理響應
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;
}
// 如果消息內容為空,則跳過
if (ObjectUtil.isEmpty(choice.getMessage().getContent())) {
return;
}
// 同步發(fā)送消息內容
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("網絡異常請重試", e);
}
}
}
3.WebSocket調用
在onMessage方法中,在session中寫入流式調用的響應,即可實現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 服務器端點,處理與客戶端的 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 接收到的消息內容。
* @param session 當前 WebSocket 會話。
*/
@OnMessage
public void onMessage(String message, Session session) {
// 調用 SiliconFlowService 處理流式聊天完成請求
siliconFlowService.getChatCompletionsStream(message, session);
}
/**
* 處理 WebSocket 連接關閉事件。
*
* @param session 當前 WebSocket 會話。
*/
@OnClose
public void onClose(Session session) {
log.info("連接關閉: {}", 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);
}
}
總結
到此這篇關于JAVA接入DeepSeek滿血版的詳細指南(問答接入、流式接入雙模式)的文章就介紹到這了,更多相關JAVA接入DeepSeek滿血版內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java?8中讀取文件內容?Files.lines()方法使用示例
這篇文章主要介紹了Java?8中讀取文件內容Files.lines()方法如何使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07

