优化返回逻辑
This commit is contained in:
parent
e6cf18fa45
commit
bf2363b7ce
@ -1,6 +1,7 @@
|
||||
package com.knowledge.base.application.service;
|
||||
|
||||
import com.knowledge.base.infrastructure.south.llm.LLMServiceFactory;
|
||||
import com.knowledge.base.infrastructure.util.http.FilteredSseOutputAdapter;
|
||||
import com.knowledge.base.infrastructure.util.http.SseOutputAdapter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -24,10 +25,11 @@ public class LLMAppServiceImpl implements LLMAppService {
|
||||
@Override
|
||||
public SseEmitter ask(String llmToken, String question, Map<String, Object> params) throws Exception {
|
||||
SseEmitter emitter = new SseEmitter(0L); // 不超时
|
||||
SseOutputAdapter writer = new SseOutputAdapter(emitter);
|
||||
|
||||
try {
|
||||
llmServiceFactory.current().streamAnswer(llmToken, question, params, writer);
|
||||
FilteredSseOutputAdapter adapter = new FilteredSseOutputAdapter(emitter);
|
||||
llmServiceFactory.current().streamAnswer(llmToken, question, params, adapter);
|
||||
adapter.flushLastChunk(); // 收尾发一次 sources
|
||||
emitter.complete();
|
||||
} catch (Exception e) {
|
||||
log.error("LLM调用异常", e);
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
package com.knowledge.base.infrastructure.util.http;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
public class FilteredSseOutputAdapter implements WriterAdapter {
|
||||
|
||||
private final SseEmitter emitter;
|
||||
private static final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
private Map<String, Object> lastChunk = new HashMap<>();
|
||||
|
||||
public FilteredSseOutputAdapter(SseEmitter emitter) {
|
||||
this.emitter = emitter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeLine(String line) throws IOException {
|
||||
if (line == null || line.isBlank()) return;
|
||||
|
||||
if (line.startsWith("data:")) {
|
||||
line = line.substring(5).trim();
|
||||
}
|
||||
|
||||
try {
|
||||
Map<String, Object> original = mapper.readValue(line, Map.class);
|
||||
Map<String, Object> filtered = new HashMap<>();
|
||||
|
||||
// 累积 textResponse
|
||||
if (original.containsKey("textResponse")) {
|
||||
filtered.put("textResponse", original.get("textResponse"));
|
||||
lastChunk.put("textResponse", original.get("textResponse"));
|
||||
}
|
||||
|
||||
// 如果含有 sources,延迟输出,合并到最后一条 textResponse 中
|
||||
if (original.containsKey("sources")) {
|
||||
lastChunk.put("sources", original.get("sources"));
|
||||
return; // 暂不发送
|
||||
}
|
||||
|
||||
if (!filtered.isEmpty()) {
|
||||
String payload = mapper.writeValueAsString(filtered);
|
||||
emitter.send("data: " + payload + "\n\n");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.warn("SSE数据解析失败:{}", line, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void flushLastChunk() {
|
||||
if (lastChunk.isEmpty()) return;
|
||||
try {
|
||||
String finalJson = mapper.writeValueAsString(lastChunk);
|
||||
emitter.send("data: " + finalJson + "\n\n");
|
||||
} catch (Exception e) {
|
||||
log.warn("flush 最后一条 SSE 失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -23,7 +23,7 @@ public class SseOutputAdapter implements WriterAdapter {
|
||||
// 如果 line 以 "data: " 开头,则去除该前缀
|
||||
if (line.startsWith("data:")) {
|
||||
log.debug("[LLM-SSE] line received: {}", line);
|
||||
line = line.substring(6).trim();
|
||||
line = line.substring(5).trim();
|
||||
}
|
||||
|
||||
// 发送单行 SSE 事件
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user