DeepSeek java 流式接口开发

// 直接调用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;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值