refactor(module-llm):重构聊天功能处理逻辑

-优化了知识库处理逻辑,提取为单独的字符串变量
-重构了系统提示的处理方式,支持自定义系统提示
-简化了消息历史记录的处理流程
- 删除了冗余代码,提高了代码可读性和维护性
This commit is contained in:
Liuyang 2025-03-11 16:51:30 +08:00
parent b056abf513
commit 2fcfb86f87

View File

@ -36,6 +36,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
@ -364,6 +365,38 @@ public class ConversationServiceImpl implements ConversationService {
&& Objects.equals(expectedGroupId, actualGroupId);
}
public static final String PROMPT="【系统角色】\n" +
"您是基于限定知识库的问答助手,需严格遵循以下交互规则:\n" +
"\n" +
"角色定义:您被设定为「知识库解析引擎」,仅处理与用户提供的知识库内容直接相关的问题\n" +
"【输入规范】\n" +
"2. 知识库验证:当用户提问时,必须包含用```分隔符包裹的完整知识库内容,格式示例:\n" +
"\n" +
"问题:<用户问题>\n" +
"知识库:\n" +
"<知识库内容>\n" +
"【响应规则】\n" +
"3. 内容匹配:仅当知识库中存在与问题直接相关的明确信息时,方可生成回答。需满足:\n" +
"\n" +
"引用完整性:答案必须包含知识库中的具体数据/案例\n" +
"精确映射:每个回答要点需标注对应知识库段落的引用编号\n" +
"限制处理:若出现以下情况,请回复预设语句:\n" +
"知识库未提供 → \"抱歉,我无法回答这个问题,因为相关信息不在知识库中。\"\n" +
"问题超出知识库范围 → \"该问题超出当前知识库支持范围\"\n" +
"检测到推测请求 → \"根据规则,我无法进行推测或想象\"\n" +
"【结构化输出】\n" +
"5. 响应格式要求:\n" +
"采用分点式回答,每个要点包含:\n" +
"\n" +
"知识引用:标注[^编号]对应知识库段落\n" +
"信息摘要:精确提取的知识片段\n" +
"逻辑连接:说明该信息与问题的关联性\n" +
"【安全机制】\n" +
"6. 内容过滤:自动触发以下保护机制:\n" +
"\n" +
"屏蔽知识库外的任何数据引用\n" +
"禁止添加解释性语句或背景补充\n" +
"拦截包含\"假设\"/\"如果\"等假设性词汇的问题";
/**
* 公共模型聊天流式处理方法
*
@ -428,22 +461,19 @@ public class ConversationServiceImpl implements ConversationService {
}
List<ModelCompletionsReqVO.ModelCompletionsMessage> messages = new ArrayList<>();
String systemPrompt="";
String knowledgeBaseString="";
if (chatReqVO.getKnowledge() != null) {
StringBuilder knowledgeBase = getKnowledgeBase(chatReqVO);
knowledgeBaseString = knowledgeBase.toString();
// 处理 systemPrompt
systemPrompt = StringUtils.isBlank(chatReqVO.getSystemPrompt())
? PROMPT
: chatReqVO.getSystemPrompt() + "\n" + PROMPT;
StringBuilder knowledgeBase = getKnowledgeBase(chatReqVO);
if(chatReqVO.getKnowledge()!=null){
String prompt = "你是一个只能基于给定知识库回答问题的助手。以下是你的规则:\n" +
"1. 你只能依据知识库中的内容回答问题。\n" +
"2. 如果问题的答案不在知识库中,回答:“抱歉,我无法回答这个问题,因为相关信息不在知识库中。”\n" +
"3. 不允许进行推测、想象或生成与知识库无关的内容。\n" +
"4. 请严格遵守以上规则。";
if (StringUtils.isBlank(chatReqVO.getPrompt())){
chatReqVO.setPrompt(prompt);
}else {
chatReqVO.setPrompt(chatReqVO.getPrompt()+"\n"+prompt);
}
}
String mess = chatReqVO.getSystemPrompt() + knowledgeBase.toString();
String mess = systemPrompt + knowledgeBaseString;
// 查询历史记录消息并将查询出来的知识信息放入到 role = system 的消息中
List<String> messageHistoryList = stringRedisTemplate.opsForList().range(CHAT_HIStORY_REDIS_KEY + ":" + chatReqVO.getUuid(), 0, -1);
if (messageHistoryList != null && !messageHistoryList.isEmpty()) {