feat(llm): 实现异步处理和流式响应的聊天接口

- 新增 ChatReqVO 类作为聊天请求的参数对象
- 在 ConversationController 中实现异步处理聊天请求的逻辑
- 在 ModelService 中添加流式响应相关的代码
- 优化了错误处理和资源释放的逻辑
This commit is contained in:
Liuyang 2025-03-02 12:45:23 +08:00
parent d9da4c0bfa
commit 8b4b896fa0
3 changed files with 43 additions and 4 deletions

View File

@ -25,6 +25,8 @@ import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@ -109,8 +111,17 @@ public class ConversationController {
public SseEmitter streamChat (@Valid @RequestBody ChatReqVO chatReqVO, HttpServletResponse response) {
log.info("收到对话推理请求,请求参数: {}", chatReqVO);
SseEmitter emitter = new SseEmitter(60_000L);
ExecutorService executor = Executors.newSingleThreadExecutor();
try {
conversationService.chatStream(chatReqVO, emitter, response);
executor.execute(() -> {
try {
conversationService.chatStream(chatReqVO, emitter, response);
} catch (Exception e) {
emitter.completeWithError(e);
} finally {
executor.shutdown();
}
});
} catch (Exception e) {
log.error("处理对话推理请求时发生异常", e);
try {
@ -120,10 +131,11 @@ public class ConversationController {
}
}
log.info("返回 SseEmitter 对象,准备进行流式响应");
emitter.onCompletion(executor::shutdown);
emitter.onTimeout(executor::shutdown);
return emitter;
}
@PostMapping("/text-to-image")
@Operation(summary = "文字转图片接口")
public CommonResult<JSONArray> textToImage (@Valid @RequestBody TextToImageReqVo req) {

View File

@ -284,9 +284,12 @@ public class ModelService {
line = line.replaceAll("\n", " ");
String content = parseStreamLine(line, uuid);
if (content != null) {
emitter.send(SseEmitter.event()
.data(content, MediaType.TEXT_EVENT_STREAM)
emitter.send(
SseEmitter.event()
.data(content, MediaType.TEXT_EVENT_STREAM)
.reconnectTime(5000)
);
log.info("已发送数据:{}", content);
}
ChatReqVO chatReqVO = JSONObject.parseObject(content, ChatReqVO.class);
if (content!=null){

View File

@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.llm.service.http.vo;
import lombok.Data;
/**
* @Description
*/
@Data
public class ChatReqVO {
/**
* 对话内容
*/
private String content;
/**
* 对话的uuid
*/
private String uuid;
/**
* 是否结束对话
*/
private boolean finish_reason;
}