公司搭建了deepSeek服务,让项目对接使用。
这里有两种对接方案,使用okhttp去调用,但过程代码比较多,不够简洁。
这里推荐使用webflux。直接上代码。
maven座标,引入webflux
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
springboot项目,写个controller
package space.goldchen.ai;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import javax.servlet.http.HttpServletResponse;
/**
* deepseek控制层
*
* @author 2021
* @create 2025-02-14 16:41
*/
@RestController
@Slf4j
public class DeepSeekController {
// deepSeek服务的url
private final static String BASE_URL ="http://192.16.21.190:8060/";
// deepSeek的uri
private final static String URI = "/v1/chat/completions";
// 向deepSeek发送请求的webclient
private final WebClient WEB_CLIENT = WebClient.create(BASE_URL);
/**
* 请求deepseek
*
* @return
*/
@GetMapping(path = "/chat/completions",produces="text/event-stream")
public Flux<ServerSentEvent<String>> handleStream4(HttpServletResponse response ) {
response.setContentType("text/event-stream");
response.setCharacterEncoding("UTF-8");
// response.setHeader("Cache-Control", "no-cache");
// response.setHeader("Connection", "keep-alive");
response.setHeader("proxy_buffering", "off");
response.setHeader("proxy_cache", "off");
// response.setHeader("X-Accel-Buffering", "no");
// 向DeepSeek提问的内容
String content = "你好";
// 是否流式返回
boolean stream = true;
// 假设请求体是一个简单的 JSON 对象,参数是content和stream
String requestBody = "{\n" +
" \"model\": \"deepseek_R1\",\n" +
" \"strategy\": \"Default\",\n" +
" \"messages\": [\n" +
" {\n" +
" \"role\": \"user\",\n" +
" \"content\": \"" + content + "\"\n" +
" }\n" +
" ],\n" +
" \"stream\": " + stream + "\n" +
"}";
log.info("请求deepseek{}", requestBody);
Flux<String> sseFlux = WEB_CLIENT.post()
.uri(URI)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(requestBody)
.retrieve()
.bodyToFlux(String.class);
// 用answer来接回复的内容,方便回答完成后入库
StringBuffer answer = new StringBuffer();
sseFlux.subscribe(eventData -> {
// log.info("Received Event: " + eventData);
if (eventData.contains("content")) {
JSONObject jsonObject = JSONObject.parseObject(eventData);
JSONArray jsonArray = jsonObject.getJSONArray("choices");
JSONObject jsonObject1 = jsonArray.getJSONObject(0);
JSONObject delta = jsonObject1.getJSONObject("delta");
if (delta.containsKey("content")) {
answer.append(delta.getString("content"));
}
}
}
, error -> {
// 处理错误
log.error(JSONObject.toJSONString(error));
log.error("Error occurred: " + error.getMessage());
}, () -> {
// 处理完成,完成后,将回答的结果入库了
log.info("answer{}", answer);
log.info("Completed");
}
);
return sseFlux.map(data -> ServerSentEvent.builder(data).build());
}
}