下面我帮你写一个Java完整示范项目骨架,实现了:

  • DeepSeek API调用(包含带上下文的多轮问答)
  • 知识库参数传入
  • 流式响应的异步处理示例(基于OkHttp)
  • JSON解析(用Jackson)
  • 简单的上下文管理示范

Java调用DeepSeek示范代码

1. 依赖(Maven示例)

<dependencies>
  <!-- OkHttp: HTTP客户端,支持异步流式 -->
  <dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.11.0</version>
  </dependency>
  <!-- Jackson: JSON解析 -->
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version>
  </dependency>
</dependencies>

2. DeepSeekClient.java

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.CountDownLatch;

public class DeepSeekClient {

    private static final String API_KEY = "YOUR_DEEPSEEK_API_KEY";
    private static final String BASE_URL = "https://api.deepseek.ai/v1/chat/completions";

    private final OkHttpClient client;
    private final ObjectMapper mapper;

    public DeepSeekClient() {
        this.client = new OkHttpClient.Builder().build();
        this.mapper = new ObjectMapper();
    }

    /**
     * 多轮对话消息格式
     */
    public static class Message {
        public String role;
        public String content;

        public Message(String role, String content) {
            this.role = role;
            this.content = content;
        }
    }

    /**
     * 发送非流式请求,获取完整回答
     */
    public String askSync(List<Message> messages, List<Map<String, String>> knowledgeBase) throws IOException {
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", "deepseek-gpt");
        requestBody.put("messages", messages);
        if (knowledgeBase != null && !knowledgeBase.isEmpty()) {
            requestBody.put("knowledge_base", knowledgeBase);
        }
        requestBody.put("enable_retrieval", true);
        requestBody.put("stream", false);

        Request request = new Request.Builder()
                .url(BASE_URL)
                .header("Authorization", "Bearer " + API_KEY)
                .header("Content-Type", "application/json")
                .post(RequestBody.create(
                        mapper.writeValueAsString(requestBody),
                        MediaType.parse("application/json")))
                .build();

        try (Response response = client.newCall(request).execute()) {
            String body = response.body().string();
            JsonNode root = mapper.readTree(body);
            // 解析回答文本:choices[0].message.content
            return root.path("choices").get(0).path("message").path("content").asText();
        }
    }

    /**
     * 流式响应,异步接收并实时处理
     */
    public void askStream(List<Message> messages, List<Map<String, String>> knowledgeBase, StreamListener listener) throws IOException, InterruptedException {
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", "deepseek-gpt");
        requestBody.put("messages", messages);
        if (knowledgeBase != null && !knowledgeBase.isEmpty()) {
            requestBody.put("knowledge_base", knowledgeBase);
        }
        requestBody.put("enable_retrieval", true);
        requestBody.put("stream", true);

        Request request = new Request.Builder()
                .url(BASE_URL)
                .header("Authorization", "Bearer " + API_KEY)
                .header("Content-Type", "application/json")
                .post(RequestBody.create(
                        mapper.writeValueAsString(requestBody),
                        MediaType.parse("application/json")))
                .build();

        CountDownLatch latch = new CountDownLatch(1);

        client.newCall(request).enqueue(new Callback() {
            StringBuilder partialAnswer = new StringBuilder();

            @Override
            public void onFailure(Call call, IOException e) {
                listener.onError(e);
                latch.countDown();
            }

            @Override
            public void onResponse(Call call, Response response) {
                try (ResponseBody body = response.body()) {
                    if (body == null) {
                        listener.onError(new IOException("响应体为空"));
                        latch.countDown();
                        return;
                    }

                    // 读取流式数据
                    var source = body.source();
                    while (!source.exhausted()) {
                        String line = source.readUtf8LineStrict();
                        // DeepSeek流式返回通常是 SSE 格式,包含data:字段
                        if (line.startsWith("data: ")) {
                            String jsonPart = line.substring(6).trim();
                            if ("[DONE]".equals(jsonPart)) {
                                break;
                            }
                            JsonNode node = mapper.readTree(jsonPart);
                            JsonNode contentNode = node.path("choices").get(0).path("delta").path("content");
                            if (!contentNode.isMissingNode()) {
                                String content = contentNode.asText();
                                partialAnswer.append(content);
                                listener.onPartialResponse(content);
                            }
                        }
                    }
                    listener.onComplete(partialAnswer.toString());
                } catch (Exception e) {
                    listener.onError(e);
                } finally {
                    latch.countDown();
                }
            }
        });

        latch.await(); // 等待响应结束
    }

    /**
     * 流式监听器接口
     */
    public interface StreamListener {
        void onPartialResponse(String partial);

        void onComplete(String fullResponse);

        void onError(Exception e);
    }
}

3. 使用示例

import java.io.IOException;
import java.util.*;

public class DeepSeekDemo {

    public static void main(String[] args) throws IOException, InterruptedException {
        DeepSeekClient client = new DeepSeekClient();

        // 维护多轮对话上下文
        List<DeepSeekClient.Message> messages = new ArrayList<>();
        messages.add(new DeepSeekClient.Message("system", "你是一个专业Java助手。"));
        messages.add(new DeepSeekClient.Message("user", "什么是Java内存模型?"));

        // 简单知识库示例
        List<Map<String, String>> knowledgeBase = new ArrayList<>();
        knowledgeBase.add(Map.of(
                "title", "Java内存模型简介",
                "content", "Java内存模型描述了线程之间如何通过主内存和工作内存交互..."
        ));

        // 同步调用示范
        String answer = client.askSync(messages, knowledgeBase);
        System.out.println("同步回答:\n" + answer);

        // 添加用户第二轮提问
        messages.add(new DeepSeekClient.Message("assistant", answer));
        messages.add(new DeepSeekClient.Message("user", "它对多线程有什么影响?"));

        // 流式调用示范
        client.askStream(messages, knowledgeBase, new DeepSeekClient.StreamListener() {
            @Override
            public void onPartialResponse(String partial) {
                System.out.print(partial);  // 实时打印流式回答
            }

            @Override
            public void onComplete(String fullResponse) {
                System.out.println("\n=== 回答结束 ===");
            }

            @Override
            public void onError(Exception e) {
                System.err.println("请求出错:" + e.getMessage());
            }
        });
    }
}

四、项目运行说明

  1. 替换代码中YOUR_DEEPSEEK_API_KEY为你真实的DeepSeek API密钥。
  2. 使用mvn clean compile exec:java或你喜欢的IDE运行。
  3. 程序演示先同步请求,再用流式输出实时显示多轮对话结果。

五、总结

  • 使用OkHttp和Jackson实现HTTP请求和JSON解析,代码简洁且高效。
  • 通过维护messages列表,实现多轮上下文传递。
  • knowledge_base参数可以灵活传入,支持自定义知识库补充回答内容。
  • 流式接口支持实时数据处理,用户体验更好。
  • 可以根据需要扩展缓存、异常重试、并发控制等功能。

如果你需要,我还可以帮你扩展:

  • 基于Spring Boot的DeepSeek服务封装
  • 集成数据库的知识库动态管理
  • 多线程并发调用示例
  • 流式结果UI实时展示方案

随时告诉我!