You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

180 lines
6.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.dsideal.base.Tools.Util;
import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import java.io.File;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;
public class CallDeepSeek {
private static final String API_KEY = "sk-44ae895eeb614aa1a9c6460579e322f1"; // 请替换为您的API KEY
private static final String API_URL = "https://api.deepseek.com/v1/chat/completions";
/**
* 通用的DeepSeek API调用方法流式响应
*
* @param prompt 用户提示词
* @param listener 响应监听器
*/
public static void callDeepSeekStream(String prompt, SSEListener listener) {
callDeepSeekStream(prompt, listener, null, false);
}
/**
* 通用的DeepSeek API调用方法流式响应
*
* @param prompt 用户提示词
* @param listener 响应监听器
* @param outputPath 输出文件路径(可选)
* @param saveToFile 是否保存到文件
*/
public static void callDeepSeekStream(String prompt, SSEListener listener, String outputPath, boolean saveToFile) {
new Thread(() -> {
StringBuilder fullResponse = new StringBuilder();
try {
JSONObject jsonPayload = createRequestPayload(prompt);
HttpClient client = createHttpClient();
java.net.http.HttpRequest request = createHttpRequest(jsonPayload);
CompletableFuture<Void> future = client.sendAsync(request, HttpResponse.BodyHandlers.ofLines())
.thenAccept(response -> {
handleStreamResponse(response, fullResponse, listener, outputPath, saveToFile);
}).exceptionally(e -> {
listener.onError("请求或处理异常: " + e.getMessage());
e.printStackTrace();
return null;
});
future.join();
} catch (Exception e) {
listener.onError("发生意外错误: " + e.getMessage());
e.printStackTrace();
}
}).start();
}
/**
* 创建HTTP请求载荷
*/
private static JSONObject createRequestPayload(String prompt) {
JSONObject jsonPayload = new JSONObject();
jsonPayload.set("model", "deepseek-chat");
JSONObject message = new JSONObject();
message.set("role", "user");
message.set("content", prompt);
JSONArray messages = new JSONArray();
messages.add(message);
jsonPayload.set("messages", messages);
jsonPayload.set("stream", true);
return jsonPayload;
}
/**
* 创建HTTP客户端
*/
private static HttpClient createHttpClient() {
return HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.build();
}
/**
* 创建HTTP请求
*/
private static java.net.http.HttpRequest createHttpRequest(JSONObject jsonPayload) {
return java.net.http.HttpRequest.newBuilder()
.uri(URI.create(API_URL))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + API_KEY)
.header("Accept", "text/event-stream")
.POST(java.net.http.HttpRequest.BodyPublishers.ofString(jsonPayload.toString(), StandardCharsets.UTF_8))
.build();
}
/**
* 处理流式响应
*/
private static void handleStreamResponse(HttpResponse<Stream<String>> response,
StringBuilder fullResponse,
SSEListener listener,
String outputPath,
boolean saveToFile) {
if (response.statusCode() == 200) {
response.body().forEach(line -> {
if (line.startsWith("data:")) {
String data = line.substring(5).trim();
if (!data.equals("[DONE]")) {
try {
JSONObject jsonData = JSONUtil.parseObj(data);
if (jsonData.containsKey("choices")) {
String content = jsonData.getJSONArray("choices")
.getJSONObject(0)
.getJSONObject("delta")
.getStr("content", "");
if (content != null && !content.isEmpty()) {
fullResponse.append(content);
listener.onData(content);
}
}
} catch (Exception e) {
System.err.println("解析SSE JSON数据错误: " + data + " \nError: " + e.getMessage());
}
}
}
});
// 流结束后的处理
String responseContent = fullResponse.toString();
if (saveToFile && outputPath != null) {
FileUtil.writeString(responseContent, new File(outputPath), "UTF-8");
listener.onComplete("内容已成功保存到" + outputPath);
} else {
listener.onComplete(responseContent);
}
} else {
listener.onError("API请求失败: " + response.statusCode() + " Body: " + response.body().toString());
}
}
public static void main(String[] args) {
String prompt = "你好,你是谁?";
// 使用通用方法
callDeepSeekStream(prompt, new SSEListener() {
@Override
public void onData(String data) {
System.out.print(data);
System.out.flush();
}
@Override
public void onComplete(String fullResponse) {
System.out.println("\n\n完整回复: " + fullResponse);
}
@Override
public void onError(String error) {
System.err.println("错误: " + error);
}
});
}
public interface SSEListener {
void onData(String data);
void onComplete(String fullResponse);
void onError(String error);
}
}