|
|
|
@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
|
|
import cn.hutool.core.lang.Pair;
|
|
|
|
|
import cn.hutool.core.lang.UUID;
|
|
|
|
|
import cn.hutool.core.map.MapUtil;
|
|
|
|
|
import cn.hutool.core.util.NumberUtil;
|
|
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
|
@ -88,19 +89,30 @@ public class AskServiceImpl implements AskService {
|
|
|
|
|
} else {
|
|
|
|
|
sessionParamDTO = BeanUtil.toBean(cache, SessionParamDTO.class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果前端传了角色设置ID,就更新缓存
|
|
|
|
|
if (StrUtil.isNotBlank(roundTalkReqVO.getRoleSetId())) {
|
|
|
|
|
sessionParamDTO.setRoleSetId(roundTalkReqVO.getRoleSetId());
|
|
|
|
|
redisTemplate.opsForValue().set(SESSION_PARAM + sessionId, sessionParamDTO);
|
|
|
|
|
}
|
|
|
|
|
// 判断,如果已经有确定的叶子节点了,这时,就可以直接根据意图来问了,就不要要提取实体了
|
|
|
|
|
if (ObjectUtil.isNotEmpty(sessionParamDTO.getMatchItemLeaf())) {
|
|
|
|
|
sessionParamDTO.setOriginalQuestion(roundTalkReqVO.getUserTalk());
|
|
|
|
|
String intent = identifyIntentHandler.identifyIntentExample(roundTalkReqVO.getUserTalk());
|
|
|
|
|
sessionParamDTO.setIntent(intent);
|
|
|
|
|
redisTemplate.opsForValue().set(SESSION_PARAM + sessionId, sessionParamDTO);
|
|
|
|
|
return afterMatchReturnAnswer(sessionParamDTO);
|
|
|
|
|
}
|
|
|
|
|
// 判断意图是否为空,如果意图为空,进行识别意图
|
|
|
|
|
if (StrUtil.isBlank(sessionParamDTO.getIntent())) {
|
|
|
|
|
String intent = identifyIntentHandler.identifyIntentExample(roundTalkReqVO.getUserTalk());
|
|
|
|
|
sessionParamDTO.setIntent(intent);
|
|
|
|
|
log.info("对问题:{}进行意图识别,识别的意图为:{}", roundTalkReqVO.getUserTalk(), intent);
|
|
|
|
|
redisTemplate.opsForValue().set(SESSION_PARAM + sessionId, sessionParamDTO);
|
|
|
|
|
}
|
|
|
|
|
// 识别出来意图之后,再去判断是否识别过实体
|
|
|
|
|
if (CollUtil.isEmpty(sessionParamDTO.getEntityValueByExtract())) {
|
|
|
|
|
|
|
|
|
|
// 识别出来意图之后,再去判断是否识别过实体(如果最终叶子节点已经确定了,就不需要再判断实体了)
|
|
|
|
|
if (CollUtil.isEmpty(sessionParamDTO.getEntityValueByExtract()) && ObjectUtil.isEmpty(sessionParamDTO.getMatchItemLeaf())) {
|
|
|
|
|
// 识别实体(先从图中获取所有的节点名称,然后识别)
|
|
|
|
|
List<String> allItemNode = findItemNodeHandler.findAllItemNode();
|
|
|
|
|
List<String> extractValue = itemExtractHandler.itemExtractByPossibleItemWithExample(sessionParamDTO.getOriginalQuestion(), allItemNode);
|
|
|
|
@ -150,17 +162,19 @@ public class AskServiceImpl implements AskService {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 多轮问答支持设置角色,如果设置角色了,在这里应该先根据角色来排除一遍路径
|
|
|
|
|
filterUserRoleSet(sessionParamDTO);
|
|
|
|
|
if (ObjectUtil.isEmpty(sessionParamDTO.getMatchItemLeaf())) {
|
|
|
|
|
filterUserRoleSet(sessionParamDTO);
|
|
|
|
|
}
|
|
|
|
|
// 如果没有确定节点,且没有路径可供匹配,抛出异常
|
|
|
|
|
if (CollUtil.isEmpty(sessionParamDTO.getConditionPathMap())) {
|
|
|
|
|
throw new BusinessException("未找到条件判断路径");
|
|
|
|
|
}
|
|
|
|
|
// 如果判断过实体,这时就要判断是否已经确认了节点,如果没有确认,在这里进行确认
|
|
|
|
|
match:
|
|
|
|
|
if (ObjectUtil.isEmpty(sessionParamDTO.getMatchItemLeaf())) {
|
|
|
|
|
// 如果没有确定节点,且没有路径可供匹配,抛出异常
|
|
|
|
|
if (CollUtil.isEmpty(sessionParamDTO.getConditionPathMap())) {
|
|
|
|
|
throw new BusinessException("未找到条件判断路径");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 判断待匹配的节点是不是只有一个了,如果有多个,就从路径中选择一个问题问前端
|
|
|
|
|
if (sessionParamDTO.getWaitMatchItemLeafMap().size() != 1) {
|
|
|
|
|
|
|
|
|
|
if (ObjectUtil.isNotEmpty(sessionParamDTO.getCurrentEntity())) {
|
|
|
|
|
// 如果当前对话实体不为空,说明当前问答就是上一个问题的回复,这个时候,就去大模型中进行匹配并排除路径
|
|
|
|
|
filterPath(sessionParamDTO, sessionParamDTO.getCurrentEntity().getCurrentEntityType(), sessionParamDTO.getCurrentEntity().getCurrentQuestion(), roundTalkReqVO.getUserTalk());
|
|
|
|
@ -173,6 +187,10 @@ public class AskServiceImpl implements AskService {
|
|
|
|
|
}
|
|
|
|
|
// 首先获取出现次数最多的实体类型
|
|
|
|
|
Map<String, Integer> newCountMap = countCondition(sessionParamDTO);
|
|
|
|
|
if (MapUtil.isEmpty(newCountMap)) {
|
|
|
|
|
log.info("为空了");
|
|
|
|
|
}
|
|
|
|
|
// 如果计数不为空,就继续进行筛选
|
|
|
|
|
String mostFrequentType = newCountMap.entrySet().stream()
|
|
|
|
|
.filter(entry -> !sessionParamDTO.getAlreadyMatchEntitySet().contains(entry.getKey()))
|
|
|
|
|
.max(Map.Entry.comparingByValue(Integer::compareTo))
|
|
|
|
@ -232,6 +250,10 @@ public class AskServiceImpl implements AskService {
|
|
|
|
|
private void filterPath(SessionParamDTO sessionParamDTO, String currentEntityType, String currentQuestion, String userTalk) {
|
|
|
|
|
// 遍历所有的path,找到回答
|
|
|
|
|
Set<String> possibleAnswerSet = findPossibleAnswerSet(sessionParamDTO, currentEntityType);
|
|
|
|
|
// 如果可能的回答为空,就不进行过滤,直接跳过
|
|
|
|
|
if (CollUtil.isEmpty(possibleAnswerSet)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Set<String> judgeResultSet = conditionJudgeHandler.conditionJudgeAll(currentQuestion,
|
|
|
|
|
possibleAnswerSet,
|
|
|
|
|
userTalk);
|
|
|
|
@ -397,11 +419,9 @@ public class AskServiceImpl implements AskService {
|
|
|
|
|
try {
|
|
|
|
|
RetireRoleEnum retireRoleEnum = RetireRoleEnum.valueOf(roleSetNode.getItemEn());
|
|
|
|
|
if (ObjectUtils.isNotEmpty(retireRoleEnum)) {
|
|
|
|
|
|
|
|
|
|
Map<String, Integer> entityCountMap = sessionParamDTO.getEntityCountMap();
|
|
|
|
|
|
|
|
|
|
// 如果包含,就去尝试排除路径
|
|
|
|
|
if (entityCountMap.containsKey(retireRoleEnum.getZhName()) && ObjectUtil.isNotEmpty(roleSetNode.getValueNum())) {
|
|
|
|
|
if (MapUtil.isNotEmpty(entityCountMap) && entityCountMap.containsKey(retireRoleEnum.getZhName()) && ObjectUtil.isNotEmpty(roleSetNode.getValueNum())) {
|
|
|
|
|
List<Pair<Integer, String>> answerList = retireRoleEnum.getAnswerList();
|
|
|
|
|
for (Pair<Integer, String> pair : answerList) {
|
|
|
|
|
// 如果枚举的key和用户填写的value相等,就排除
|
|
|
|
|