引入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.42</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.6.0</version>
</dependency>
代码
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
/**
* deepseek工具类
*/
@Component
public class DeepSeekUtil {
private final Logger log = LoggerFactory.getLogger(DeepSeekUtil.class);
private static OkHttpClient client;
private final static String CHAT_URL = "/v1/chat/completions";
private static String deepseekHost;
@Value("${deepseekHost}")
public void setDeepseekHost(String deepseekHost) {
DeepSeekUtil.deepseekHost = deepseekHost;
}
private static String deepseekChatUrl;
@Value("${deepseekChatUrl}")
public void setDeepseekChatUrl(String deepseekChatUrl) {
DeepSeekUtil.deepseekChatUrl = deepseekChatUrl;
}
private static String deepseekApiKey;
@Value("${deepseekApiKey}")
public void setDeepseekApiKey(String deepseekApiKey) {
DeepSeekUtil.deepseekApiKey = deepseekApiKey;
}
private static String deepseekModel;
@Value("${deepseekModel}")
public void setDeepseekModel(String deepseekModel) {
DeepSeekUtil.deepseekModel = deepseekModel;
}
DeepSeekUtil(){
client = new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS) // 连接超时 60s
.readTimeout(120, TimeUnit.SECONDS) // 读取超时 120s
.writeTimeout(60, TimeUnit.SECONDS) // 写入超时 60s
.build();
}
/**
* deepseek会话回复接口
*/
@FunctionalInterface
public interface ReplyFunction {
void apply(String reasoningContent, String content);
}
/**
* deepseek会话
* @param question 问题
* @param maxTokens 最大回复量
* @param preMessage 之前的消息,用于多轮会话
* @return
* @throws IOException
*/
public void chat(ReplyFunction replyFunction, String question, int maxTokens, JSONArray preMessage) throws IOException {
JSONArray messages = new JSONArray();
if (preMessage != null) {
messages.addAll(preMessage);
}
JSONObject message = new JSONObject();
message.put("role", "user");
message.put("content", question);
messages.add(message);
JSONObject json = new JSONObject();
json.put("model", deepseekModel);
json.put("messages", messages);
json.put("max_tokens", maxTokens);
json.put("stream", true);
RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json.toString());
Request request = new Request.Builder()
.url(deepseekHost + CHAT_URL)
.addHeader("Authorization", "Bearer " + deepseekApiKey)
.post(body).build();
Response response = client.newCall(request).execute();
if (response.code() == 401 || response.code() == 403) {
throw new BadRequestAlertException("Unauthorized", "认证失败", "");
}
// 获取响应流
InputStream inputStream = response.body().byteStream();
// 包装为BufferedReader,指定编码方式
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
String line;
try {
// 逐行读取数据
while ((line = reader.readLine()) != null) {
String str = line.replace("data:", "");
if (!StringUtils.hasText(str) || "[DONE]".equals(str.trim())) continue;
try {
JSONObject responseJson = JSONObject.parseObject(str);
if (responseJson.containsKey("choices") && !responseJson.getJSONArray("choices").isEmpty()) {
JSONObject delta = responseJson.getJSONArray("choices")
.getJSONObject(0)
.getJSONObject("delta");
// 有些模型思考内容会在reasoning_content中单独返回
String reasoningContent = delta.getString("reasoning_content");
String content = delta.getString("content");
boolean isFinish = "stop".equals(responseJson.getJSONArray("choices").getJSONObject(0).get("finish_reason"));
replyFunction.apply(reasoningContent, content);
}
} catch (Exception e) {
log.error(line);
}
}
} catch (IOException e) {
log.error("unreadable response", e);
} finally {
// 确保关闭所有流和资源
try {
reader.close();
} catch (IOException e) {
log.error("close BufferedReader error", e);
}
}
}
}