package com.iflytek.knowledge.util;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;

@Component
public class DeepSeekUtils {

    @Value("${chat-model}")
    private String model;
    
    @Value("${spring.profiles.active}")
    private String activeProfile;

    private static final String SYSTEM_MESSAGE = "You are a helpful assistant.";

    private String apiUrl;
    private String apiKey;
    
    @PostConstruct
    public void init() {
        if ("prod".equalsIgnoreCase(activeProfile)) {
            this.apiUrl = "http://10.222.2.2:8006/v1/chat/completions";
            this.apiKey = "sk-okzsnuisuoydfgvmjmcnjfalnxxyabuwoixbkabweyajnstp";
        } else {
            this.apiUrl = "https://api.deepseek.com/chat/completions";
            this.apiKey = "sk-55c2cb90d92940908c83279491da20f9";
        }
    }

    // 对外方法:非流式调用(兼容原接口)
    public String ask(String question) {
        return ask(question, false);
    }

    // 核心方法:支持流式与非流式
    public String ask(String question, boolean stream) {
        if (question == null || question.trim().isEmpty()) {
            throw new IllegalArgumentException("问题不能为空");
        }
        String requestBody = buildRequestBody(question, stream);
        if (stream) {
            return sendStreamRequest(requestBody);
        } else {
            String responseJson = sendRequest(requestBody);
            return extractContent(responseJson);
        }
    }

    private String buildRequestBody(String question, boolean stream) {
        return String.format(
                "{" +
                        "\"model\": \"%s\"," +
                        "\"messages\": [" +
                        "{\"role\": \"system\", \"content\": \"%s\"}," +
                        "{\"role\": \"user\", \"content\": \"%s\"}" +
                        "]," +
                        "\"stream\": %s" +
                        "}",
                escapeJson(model),      // 这里使用非静态字段 model
                escapeJson(SYSTEM_MESSAGE),
                escapeJson(question),
                stream
        );
    }

    private String sendRequest(String requestBody) {
        HttpURLConnection conn = null;
        try {
            URL url = new URL(apiUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Authorization", "Bearer " + apiKey);
            conn.setDoOutput(true);
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(60000);

            try (OutputStream os = conn.getOutputStream()) {
                byte[] input = requestBody.getBytes(StandardCharsets.UTF_8);
                os.write(input, 0, input.length);
            }

            int responseCode = conn.getResponseCode();
            InputStream stream = (responseCode >= 200 && responseCode < 300)
                    ? conn.getInputStream() : conn.getErrorStream();
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(stream, StandardCharsets.UTF_8))) {
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                String responseBody = response.toString();
                if (responseCode >= 200 && responseCode < 300) {
                    return responseBody;
                } else {
                    throw new RuntimeException("API请求失败,响应码: " + responseCode + ", 响应体: " + responseBody);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("调用DeepSeek API失败", e);
        } finally {
            if (conn != null) conn.disconnect();
        }
    }

    private String sendStreamRequest(String requestBody) {
        HttpURLConnection conn = null;
        try {
            URL url = new URL(apiUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Authorization", "Bearer " + apiKey);
            conn.setDoOutput(true);
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(60000);

            try (OutputStream os = conn.getOutputStream()) {
                byte[] input = requestBody.getBytes(StandardCharsets.UTF_8);
                os.write(input, 0, input.length);
            }

            int responseCode = conn.getResponseCode();
            if (responseCode != 200) {
                try (BufferedReader br = new BufferedReader(
                        new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8))) {
                    StringBuilder error = new StringBuilder();
                    String line;
                    while ((line = br.readLine()) != null) {
                        error.append(line);
                    }
                    throw new RuntimeException("流式请求失败,响应码: " + responseCode + ", 错误: " + error);
                }
            }

            StringBuilder fullAnswer = new StringBuilder();
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    if (line.startsWith("data: ")) {
                        String data = line.substring(6);
                        if ("[DONE]".equals(data)) {
                            break;
                        }
                        String delta = extractDeltaContent(data);
                        if (delta != null && !delta.isEmpty()) {
                            fullAnswer.append(delta);
                        }
                    }
                }
            }
            return fullAnswer.toString();
        } catch (Exception e) {
            throw new RuntimeException("调用DeepSeek流式API失败", e);
        } finally {
            if (conn != null) conn.disconnect();
        }
    }

    private String extractContent(String json) {
        String target = "\"content\":\"";
        int start = json.indexOf(target);
        if (start == -1) {
            throw new RuntimeException("响应JSON中未找到content字段: " + json);
        }
        start += target.length();
        StringBuilder content = new StringBuilder();
        boolean escaped = false;
        for (int i = start; i < json.length(); i++) {
            char c = json.charAt(i);
            if (escaped) {
                if (c == 'n') content.append('\n');
                else if (c == 'r') content.append('\r');
                else if (c == 't') content.append('\t');
                else if (c == '"') content.append('"');
                else if (c == '\\') content.append('\\');
                else content.append(c);
                escaped = false;
            } else if (c == '\\') {
                escaped = true;
            } else if (c == '"') {
                break;
            } else {
                content.append(c);
            }
        }
        return content.toString();
    }

    private String extractDeltaContent(String json) {
        String target = "\"delta\":{\"content\":\"";
        int start = json.indexOf(target);
        if (start == -1) return null;
        start += target.length();
        StringBuilder content = new StringBuilder();
        boolean escaped = false;
        for (int i = start; i < json.length(); i++) {
            char c = json.charAt(i);
            if (escaped) {
                if (c == 'n') content.append('\n');
                else if (c == 'r') content.append('\r');
                else if (c == 't') content.append('\t');
                else if (c == '"') content.append('"');
                else if (c == '\\') content.append('\\');
                else content.append(c);
                escaped = false;
            } else if (c == '\\') {
                escaped = true;
            } else if (c == '"') {
                break;
            } else {
                content.append(c);
            }
        }
        return content.toString();
    }

    private String escapeJson(String s) {
        if (s == null) return "";
        StringBuilder sb = new StringBuilder();
        for (char c : s.toCharArray()) {
            if (c == '\\') sb.append("\\\\");
            else if (c == '"') sb.append("\\\"");
            else if (c == '\n') sb.append("\\n");
            else if (c == '\r') sb.append("\\r");
            else if (c == '\t') sb.append("\\t");
            else sb.append(c);
        }
        return sb.toString();
    }
}
Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐