Commit 56bd131e authored by alex yao's avatar alex yao

refactor(chat): 重构Dify聊天服务实现

- 将think标签常量改为大写命名规范
- 为blockingChat和streamChat方法添加完整的JavaDoc注释
- 移除冗余的注释代码
- 重命名内部解析方法提高可读性
- 优化流式聊天中的异常处理逻辑
- 为SSEUtil构造函数添加异常捕获机制
- 统一使用StringUtils.EMPTY替代空字符串
- 改进代码结构和错误处理流程
parent 8ef4f9e1
......@@ -45,15 +45,21 @@ public class DifyChatServiceImpl implements DifyChatService {
private final Logger logger = LoggerFactory.getLogger(DifyChatServiceImpl.class);
private final String thinkStartTag = "<think>";
private final String THINK_START_TAG = "<think>";
private final String thinkEndTag = "</think>";
private final String THINK_END_TAG = "</think>";
@Autowired
private DifyConfigProperties difyConfigProperties;
/**
* 阻塞式聊天请求
*
* @param fileUrls 文件地址
* @param question 问题
* @param data 拓展参数
* @param user 用户
* @param apiKey API密钥
*/
public AgentResultEntity blockingChat(List<String> fileUrls,
String question,
......@@ -61,7 +67,6 @@ public class DifyChatServiceImpl implements DifyChatService {
String user,
String apiKey) {
// 从配置中获取API密钥,如果传入的apiKey为null或空,则从配置中查找
String actualApiKey = apiKey;
if (StringUtils.isEmpty(actualApiKey)) {
actualApiKey = difyConfigProperties.getApiKeys().get(user);
......@@ -100,16 +105,16 @@ public class DifyChatServiceImpl implements DifyChatService {
AgentResultEntity agentResultEntity = new AgentResultEntity();
String answer = chatMessageResponse.getAnswer();
int startIndex = answer.indexOf(thinkStartTag);
int endIndex = answer.indexOf(thinkEndTag);
int startIndex = answer.indexOf(THINK_START_TAG);
int endIndex = answer.indexOf(THINK_END_TAG);
if (startIndex != -1 && endIndex != -1 && endIndex > startIndex) {
// 提取<think>标签内的内容
String reasoningContent = answer.substring(startIndex + thinkStartTag.length(), endIndex);
String reasoningContent = answer.substring(startIndex + THINK_START_TAG.length(), endIndex);
agentResultEntity.setReasoningContent(reasoningContent.trim());
// 提取其余内容(去除<think>标签部分)
String message = answer.substring(0, startIndex) + answer.substring(endIndex + thinkEndTag.length());
String message = answer.substring(0, startIndex) + answer.substring(endIndex + THINK_END_TAG.length());
agentResultEntity.setMessage(message);
} else {
// 如果没有找到<think>标签,将整个answer作为message
......@@ -126,12 +131,18 @@ public class DifyChatServiceImpl implements DifyChatService {
/**
* 流式聊天请求
*
* @param fileUrls 文件地址
* @param question 问题
* @param data 拓展参数
* @param user 用户
* @param apiKey API密钥
*/
public AgentResultEntity streamChat(List<String> fileUrls,
String question,
Map<String, Object> data,
String user,
String apiKey) throws IOException, DifyApiException, InterruptedException {
String apiKey) {
AgentResultEntity agentResultEntity = new AgentResultEntity();
StringBuilder messageBuilder = new StringBuilder();
......@@ -170,34 +181,40 @@ public class DifyChatServiceImpl implements DifyChatService {
ServletRequestAttributes servletRequestAttributes =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletResponse response = servletRequestAttributes.getResponse();
// 发送消息并获取响应
try {
chatClient.sendChatMessageStream(message, new ChatStreamCallback() {
SSEUtil sseUtil = new SSEUtil(response);
boolean isThink = false;
private String think(String content) {
/**
* 解析深度思考文本内容
* 处理思考标记的开始和结束标签,提取纯文本内容
*
* @param content 原始内容
* @return 解析后的文本内容,如果内容不完整则返回空字符串
*/
String parseDeepThinkingContent(String content) {
if (!isThink) {
if (content.contains(thinkStartTag)) {
if (content.contains(THINK_START_TAG)) {
isThink = true;
return content.replaceFirst(thinkStartTag, "");
return content.replaceFirst(THINK_START_TAG, StringUtils.EMPTY);
}
return content;
} else {
if (content.contains(thinkEndTag)) {
if (content.contains(THINK_END_TAG)) {
isThink = false;
return content.replaceFirst(thinkEndTag, "");
return content.replaceFirst(THINK_END_TAG, StringUtils.EMPTY);
}
return null;
return StringUtils.EMPTY;
}
}
@Override
public void onMessage(MessageEvent event) {
try {
void responseMess(MessageEvent event) throws IOException {
if (StringUtils.isNotEmpty(event.getAnswer())) {
String think = think(event.getAnswer());
String think = parseDeepThinkingContent(event.getAnswer());
LargeModelDemandResult largeModelDemandResult = new LargeModelDemandResult();
if (isThink || StringUtils.isNotBlank(think)) {
largeModelDemandResult.setReasoningContent(think);
......@@ -212,6 +229,12 @@ public class DifyChatServiceImpl implements DifyChatService {
largeModelDemandResult.setCode("0");
sseUtil.send(JsonUtils.serialize(largeModelDemandResult));
}
}
@Override
public void onMessage(MessageEvent event) {
try {
responseMess(event);
} catch (Exception e) {
logger.error("发送SSE消息时出错: {}", e.getMessage(), e);
sseUtil.completeByError(e.getMessage());
......@@ -234,8 +257,16 @@ public class DifyChatServiceImpl implements DifyChatService {
}
countDownLatch.countDown();
}
});
countDownLatch.await(120, TimeUnit.SECONDS);
return agentResultEntity;
} catch (Exception e) {
countDownLatch.notify();
SSEUtil sseUtil = new SSEUtil(response);
sseUtil.completeByError(e.getMessage());
throw new BusinessException(e.getMessage());
}
}
}
\ No newline at end of file
......@@ -35,9 +35,13 @@ public class SSEUtil implements AutoCloseable {
outputStream = response.getOutputStream();
}
public SSEUtil(HttpServletResponse response) throws IOException {
public SSEUtil(HttpServletResponse response) {
try {
response.setContentType("text/event-stream;charset=UTF-8");
outputStream = response.getOutputStream();
} catch (IOException e) {
throw new RuntimeException("无法获取HttpServletResponse");
}
}
public void send(String data) throws IOException {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment