// 直接调用DeepSeek大模型
String type;
String model = DS_MODEL_V3;
if (sessionChatRecordEntityExt.getDataReturnType() != null) {
type = sessionChatRecordEntityExt.getDataReturnType();
} else {
type = "-1"; //未知
model = DS_MODEL;
if ("5".equals(type)) {
model = DS_MODEL;
}
}
com.zbIntel.integration.deepseek.dto.ChatRequest request = com.zbIntel.integration.deepseek.dto.ChatRequest.builder()
.model(model)
.temperature(0.7)
//.max_tokens(6000)
.messages(Collections.singletonList(new com.zbIntel.integration.deepseek.dto.ChatRequest.Message("user", promtContent)))
.stream(true) // 设置为流式模式
.build();
okhttp3.RequestBody body;
try {
body = okhttp3.RequestBody.create(
MediaType.get("application/json; charset=utf-8"),
new ObjectMapper().writeValueAsString(request)
);
} catch (Exception e) {
log.error("Error during parse chatBody data: ", e);
StreamingResponseBody streamingResponseBody = out -> {
try {
String errorMessage = ("{" +
" \"error_code\": 113," +
" \"error_msg\": \"parse data error\"" +
"}");
out.write(errorMessage.getBytes(StandardCharsets.UTF_8));
out.flush();
} catch (IOException et) {
// 处理解析或写入输出流时可能发生的异常
log.error(et.getMessage());
}
};
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.header("Access-Control-Allow-Origin", "*")
.contentType(org.springframework.http.MediaType.TEXT_EVENT_STREAM)
.body(streamingResponseBody);
}
Request httpRequest = new Request.Builder()
.url(DS_API_URL)
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + DS_API_KEY)
.post(body)
.build();
StringBuilder respContent = new StringBuilder();
AtomicReference<Boolean> isEndflag = new AtomicReference<>(Boolean.FALSE);
SessionChatRecordEntity finalAskRecord = askRecord
return ResponseEntity.ok()
.header("Access-Control-Allow-Origin", "*")
.contentType(org.springframework.http.MediaType.TEXT_EVENT_STREAM)
.cacheControl(org.springframework.http.CacheControl.noCache())
.body(outputStream -> {
Long n = 0L;
String idStr = org.apache.commons.lang3.StringUtils.EMPTY;
try (Response response = client.newCall(httpRequest).execute();
okhttp3.ResponseBody responseBody = response.body();
InputStream inputStream = responseBody.byteStream()) {
if (!response.isSuccessful()) {
throw new IOException("Failed to fetch streaming data, HTTP error code: " + response.code());
}
byte[] buffer = new byte[40960];
int bytesRead;
List<com.zbIntel.integration.wenxin.entity.ChatResponse> collectedResponses = new ArrayList<>();
while (!Thread.currentThread().isInterrupted() && (bytesRead = inputStream.read(buffer)) != -1) {
String data = new String(buffer, 0, bytesRead, StandardCharsets.UTF_8);
String[] lines = data.split("\n");
for (String line : lines) {
if (line.startsWith("data: ")) {
// 解析每行数据
String jsonData = line.substring(6);
// 记录流输出结果,用于后续持久化
com.zbIntel.integration.wenxin.entity.ChatResponse bean = new com.zbIntel.integration.wenxin.entity.ChatResponse();
// 如果有 流结束标志,可以提前结束
if ("[DONE]".equals(jsonData)) {
// 流结束标志
bean.setIs_end(Boolean.TRUE);
isEndflag.set(Boolean.TRUE);
bean.setId(idStr); // 或者使用其他生成ID的方法
bean.setObject("chat.completion");
ChatUsage chatUsage = new ChatUsage();
chatUsage.setTotalTokens(returnContent.length());
bean.setUsage(chatUsage); // 初始化usage对象
bean.setResult(""); // 结束标志不需要实际的结果
bean.setReasoning_content("");
bean.setSentenceId(n);
bean.setCreated(System.currentTimeMillis() / 1000);
} else {
bean.setIs_end(Boolean.FALSE);
// 将 JSON 数据反序列化为 ChatResponse 对象
com.zbIntel.integration.deepseek.dto.ChatResponse chatResponse =
JSONUtil.parseObj(jsonData.getBytes(StandardCharsets.UTF_8))
.toBean(com.zbIntel.integration.deepseek.dto.ChatResponse.class);
// deepseek
String result = chatResponse.getChoices().get(0).getDelta().getContent();
bean.setResult(result);
// deepseek
String reasoningContent = chatResponse.getChoices().get(0).getDelta().getReasoning_content();
// siliconflow
bean.setReasoning_content(reasoningContent);
ChatUsage usage = new ChatUsage();
if (chatResponse.getUsage() != null) {
usage.setPromptTokens(chatResponse.getUsage().getPrompt_tokens());
usage.setCompletionTokens(chatResponse.getUsage().getCompletion_tokens());
usage.setTotalTokens(chatResponse.getUsage().getTotal_tokens());
}
bean.setUsage(usage);
bean.setSentenceId(n);
bean.setId(chatResponse.getId());
bean.setObject("chat.completion");
bean.setCreated(Long.valueOf(chatResponse.getCreated()));
}
bean.setIsTruncated(Boolean.FALSE);
bean.setNeedClearHistory(Boolean.FALSE);
bean.setBan_round(null); // 可能需要根据实际情况设置
bean.setSessionId(req.getSessionId());
bean.setDataType(type);
bean.setKeyQuestion(keyQuestion);
bean.setClassType(classType);
if ("2".equals(type)) {
// 收集数据,直到条件满足后再统一发送
collectedResponses.add(bean);
if (bean.getIs_end()) {
// 当达到结束条件时,统一发送所有收集的数据
StringBuilder tmpStr = new StringBuilder();
for (com.zbIntel.integration.wenxin.entity.ChatResponse collectedBean : collectedResponses) {
String content = collectedBean.getResult();
// 记录流输出结果,用于后续持久化
respContent.append(content);
// 序列化bean并发送
String serializedBean = JSONUtil.toJsonStr(collectedBean);
outputStream.write(("data: " + serializedBean + "\n\n").getBytes(StandardCharsets.UTF_8));
outputStream.flush();
if (collectedBean.getResult() != null) {
tmpStr.append(collectedBean.getResult());
}
}
log.info("返回数据:{}", tmpStr.toString());
collectedResponses.clear(); // 清空已发送的数据集合
}
} else {
// 对于其他类型,继续逐条发送
if (bean.getIs_end()) {
// 更新状态
bean.setIs_end(Boolean.FALSE);
n = bean.getSentenceId();
idStr = bean.getId();
}
String content = bean.getResult();
// 记录流输出结果,用于后续持久化
respContent.append(content);
// 序列化bean并发送
String serializedBean = JSONUtil.toJsonStr(bean);
outputStream.write(("data: " + serializedBean + "\n\n").getBytes(StandardCharsets.UTF_8));
outputStream.flush();
log.info("返回数据:{}", bean);
}
n = n + 1L;
}
}
}
// 处理结束后,确保没有遗漏的数据
if ("2".equals(type) && !collectedResponses.isEmpty()) {
for (com.zbIntel.integration.wenxin.entity.ChatResponse collectedBean : collectedResponses) {
String content = collectedBean.getResult();
// 记录流输出结果,用于后续持久化
respContent.append(content);
// 序列化bean并发送
String serializedBean = JSONUtil.toJsonStr(collectedBean);
outputStream.write(("data: " + serializedBean + "\n\n").getBytes(StandardCharsets.UTF_8));
outputStream.flush();
log.info("返回数据:{}", collectedBean);
}
collectedResponses.clear(); // 清空已发送的数据集合
}
} catch (JsonProcessingException e) {
// 忽略非 JSON 数据或其他异常
System.err.println("Error parsing line: " + e);
// 异常时先返回关闭
outputStream.write(("{" +
" \"error_code\": 112," +
" \"error_msg\": \"" + e.getMessage() + "\"" +
"}").getBytes(StandardCharsets.UTF_8));
outputStream.flush();
} catch (IOException e) {} finally {
try {
// 不论是否结束都 构造回复数据对象,持久化
String respContentStr = respContent.toString();
SessionChatRecordEntity replyRecord = new SessionChatRecordEntity(
finalAskRecord.getSessionId(), Role.ASSISTANT.name,
respContentStr, ChatGPTApi.getMessageTokenNum(respContentStr), type);
sessionChatRecordService.saveBatch(ImmutableList.of(finalAskRecord, replyRecord));
chatService.refreshWindowRecordCache(finalAskRecord.getSessionId());
SessionChatRecordEntity sessionChatLastOne = sessionChatRecordService.getSessionLastRecord(finalAskRecord.getSessionId());
com.zbIntel.integration.wenxin.entity.ChatResponse endResponse = new ChatResponse();
endResponse.setId(idStr); // 或者使用其他生成ID的方法
endResponse.setObject("chat.completion");
endResponse.setIsTruncated(false);
endResponse.setNeedClearHistory(false);
endResponse.setBan_round(null); // 可能需要根据实际情况设置
ChatUsage chatUsage = new ChatUsage();
chatUsage.setTotalTokens(returnContent.length());
endResponse.setUsage(chatUsage); // 初始化usage对象
endResponse.setResult(""); // 结束标志不需要实际的结果
endResponse.setSentenceId(n + 1L);
endResponse.setCreated(System.currentTimeMillis() / 1000);
endResponse.setIs_end(Boolean.TRUE);
isEndflag.set(Boolean.TRUE);
endResponse.setSessionId(req.getSessionId());
endResponse.setDataType(type);
endResponse.setKeyQuestion(keyQuestion);
endResponse.setClassType(classType);
if (sessionChatLastOne != null) {
// 最后一条返回聊天SessionChatId
endResponse.setSessionChatId(sessionChatLastOne.getSessionChatId());
}
String serializedBean = JSONUtil.toJsonStr(endResponse);
outputStream.write(("data: " + serializedBean + "\n\n").getBytes(StandardCharsets.UTF_8));
outputStream.flush();
if (!isEndflag.get()) {
// 如果未结束 则发送最终事件,指示流结束
com.zbIntel.integration.wenxin.entity.ChatResponse beanCheck = new ChatResponse();
beanCheck.setIs_end(Boolean.TRUE);
beanCheck.setSessionId(req.getSessionId());
if (sessionChatLastOne != null) {
// 最后一条返回聊天SessionChatId
beanCheck.setSessionChatId(sessionChatLastOne.getSessionChatId());
}
String serializedBeanCheck = JSONUtil.toJsonStr(beanCheck);
outputStream.write(("data: " + serializedBeanCheck + "\n\n").getBytes(StandardCharsets.UTF_8));
outputStream.flush();
}
} catch (IOException e) {
log.error("Failed to write final end event: ", e);
} finally {
// 确保outputStream关闭
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
log.error("Failed to close output stream: ", e);
}
}
}
}
}
);
重点是这段对数据的处理:
if (line.startsWith("data: ")) {
// 解析每行数据
String jsonData = line.substring(6);
// 记录流输出结果,用于后续持久化
com.zbIntel.integration.wenxin.entity.ChatResponse bean = new com.zbIntel.integration.wenxin.entity.ChatResponse();
// 如果有 流结束标志,可以提前结束
if ("[DONE]".equals(jsonData)) {
// 流结束标志
bean.setIs_end(Boolean.TRUE);
isEndflag.set(Boolean.TRUE);
bean.setId(idStr); // 或者使用其他生成ID的方法
bean.setObject("chat.completion");
ChatUsage chatUsage = new ChatUsage();
chatUsage.setTotalTokens(returnContent.length());
bean.setUsage(chatUsage); // 初始化usage对象
bean.setResult(""); // 结束标志不需要实际的结果
bean.setReasoning_content("");
bean.setSentenceId(n);
bean.setCreated(System.currentTimeMillis() / 1000);
} else {
bean.setIs_end(Boolean.FALSE);
// 将 JSON 数据反序列化为 ChatResponse 对象
com.zbIntel.integration.deepseek.dto.ChatResponse chatResponse =
JSONUtil.parseObj(jsonData.getBytes(StandardCharsets.UTF_8))
.toBean(com.zbIntel.integration.deepseek.dto.ChatResponse.class);
// deepseek
String result = chatResponse.getChoices().get(0).getDelta().getContent();
bean.setResult(result);
// deepseek
String reasoningContent = chatResponse.getChoices().get(0).getDelta().getReasoning_content();
// siliconflow
bean.setReasoning_content(reasoningContent);
ChatUsage usage = new ChatUsage();
if (chatResponse.getUsage() != null) {
usage.setPromptTokens(chatResponse.getUsage().getPrompt_tokens());
usage.setCompletionTokens(chatResponse.getUsage().getCompletion_tokens());
usage.setTotalTokens(chatResponse.getUsage().getTotal_tokens());
}
bean.setUsage(usage);
bean.setSentenceId(n);
bean.setId(chatResponse.getId());
bean.setObject("chat.completion");
bean.setCreated(Long.valueOf(chatResponse.getCreated()));
}
bean.setIsTruncated(Boolean.FALSE);
bean.setNeedClearHistory(Boolean.FALSE);
bean.setBan_round(null); // 可能需要根据实际情况设置
bean.setSessionId(req.getSessionId());
bean.setDataType(type);
bean.setKeyQuestion(keyQuestion);
bean.setClassType(classType);
if ("2".equals(type)) {
// 收集数据,直到条件满足后再统一发送
collectedResponses.add(bean);
if (bean.getIs_end()) {
// 当达到结束条件时,统一发送所有收集的数据
StringBuilder tmpStr = new StringBuilder();
for (com.zbIntel.integration.wenxin.entity.ChatResponse collectedBean : collectedResponses) {
String content = collectedBean.getResult();
// 记录流输出结果,用于后续持久化
respContent.append(content);
// 序列化bean并发送
String serializedBean = JSONUtil.toJsonStr(collectedBean);
outputStream.write(("data: " + serializedBean + "\n\n").getBytes(StandardCharsets.UTF_8));
outputStream.flush();
if (collectedBean.getResult() != null) {
tmpStr.append(collectedBean.getResult());
}
}
log.info("返回数据:{}", tmpStr.toString());
collectedResponses.clear(); // 清空已发送的数据集合
}
} else {
// 对于其他类型,继续逐条发送
if (bean.getIs_end()) {
// 更新状态
bean.setIs_end(Boolean.FALSE);
n = bean.getSentenceId();
idStr = bean.getId();
}
String content = bean.getResult();
// 记录流输出结果,用于后续持久化
respContent.append(content);
// 序列化bean并发送
String serializedBean = JSONUtil.toJsonStr(bean);
outputStream.write(("data: " + serializedBean + "\n\n").getBytes(StandardCharsets.UTF_8));
outputStream.flush();
log.info("返回数据:{}", bean);
}
n = n + 1L;
}
}
}
其他:
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class ChatResponse {
private String id;
private String object;
private Integer created;
private String model;
private List<Choices> choices;
private Usage usage;
private String system_fingerprint;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Choices {
private Integer index;
/**
* deepseek 的字段
*/
private Message delta;
private String logprobs;
private String finish_reason;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Message {
private String role;
private String content;
private String reasoning_content;
}
}
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Usage {
private Integer prompt_tokens;
private Integer completion_tokens;
private Integer total_tokens;
private Prompt_tokens_details prompt_tokens_details;
private Integer prompt_cache_hit_tokens;
private Integer prompt_cache_miss_tokens;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Prompt_tokens_details {
private Integer cached_tokens;
}
}
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ChatRequest {
private String model;
private List<Message> messages;
private Double temperature;
private Integer max_tokens;
@Builder.Default
private Boolean stream = false;
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Message {
private String role;
private String content;
}
}