| | |
| | |
|
| | | public SMTJavaAIError executeUnknowQuestionAgent(String rawKeyword, SMTAIServerRequest tranReq) throws Exception
|
| | | {
|
| | | int maxQuestion = 5;
|
| | | List<String> listKeyword = new ArrayList<>();
|
| | | |
| | | // 如果关键字太长,意味着需要做二次切分
|
| | | if(rawKeyword.length() > 1)
|
| | | if(!"知识库".equals(tranReq.getCurGroupType()))
|
| | | {
|
| | | tranReq.sendChunkedBlock("begin", "无法找到匹配的执行器,对问题中关键字进行切分");
|
| | | SMTLLMConnect llm = SMTAIServerApp.getApp().allocLLMConnect(null);
|
| | | String sJsonKeywords = llm.callWithMessage(new String[] {"请将输入的内容切分成独立的单词,并以json数组形式表示。例如:流量和压力,返回[\"流量\",\"和\",\"压力\"]"}, rawKeyword, tranReq);
|
| | | Json jsonKeywors = SMTStatic.convLLMAnswerToJson(sJsonKeywords, false);
|
| | | if(jsonKeywors != null && jsonKeywors.isArray())
|
| | | |
| | | int maxQuestion = 5;
|
| | | List<String> listKeyword = new ArrayList<>();
|
| | | |
| | | // 如果关键字太长,意味着需要做二次切分
|
| | | if(rawKeyword.length() > 1)
|
| | | {
|
| | | for(Json jsonKeyword : jsonKeywors.asJsonList())
|
| | | tranReq.sendChunkedBlock("begin", "无法找到匹配的执行器,对问题中关键字进行切分");
|
| | | SMTLLMConnect llm = SMTAIServerApp.getApp().allocLLMConnect(null);
|
| | | String sJsonKeywords = llm.callWithMessage(new String[] {"请将输入的内容切分成独立的单词,并以json数组形式表示。例如:流量和压力,返回[\"流量\",\"和\",\"压力\"]"}, rawKeyword, tranReq);
|
| | | Json jsonKeywors = SMTStatic.convLLMAnswerToJson(sJsonKeywords, false);
|
| | | if(jsonKeywors != null && jsonKeywors.isArray())
|
| | | {
|
| | | listKeyword.add(jsonKeyword.asString());
|
| | | for(Json jsonKeyword : jsonKeywors.asJsonList())
|
| | | {
|
| | | listKeyword.add(jsonKeyword.asString());
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | |
| | | // 如果关键字存在,则直接使用
|
| | | if(listKeyword.size() == 0)
|
| | | {
|
| | | tranReq.sendChunkedBlock("begin", "关键字切分失败, 直接用原始问题进行匹配");
|
| | | listKeyword.add(rawKeyword);
|
| | | }
|
| | | |
| | | // 首先尝试从agent中找到相关问题
|
| | | List<SMTQwenAgent> listAgent = getUsefulAgentList(tranReq.getAgentGroupSet(), _mapId2Agent, tranReq.getCurGroupType(), null);
|
| | | for(String keywrod : listKeyword)
|
| | | {
|
| | | tranReq.sendChunkedBlock("begin", "开始匹配关键字:" + keywrod);
|
| | | for(SMTQwenAgent agent : listAgent)
|
| | | |
| | | // 如果关键字存在,则直接使用
|
| | | if(listKeyword.size() == 0)
|
| | | {
|
| | | agent.queryUnknowQuestionList(keywrod, tranReq);
|
| | | tranReq.sendChunkedBlock("begin", "关键字切分失败, 直接用原始问题进行匹配");
|
| | | listKeyword.add(rawKeyword);
|
| | | }
|
| | |
|
| | | if(tranReq.getContentSampleQuestionCount() >= maxQuestion)
|
| | | break;
|
| | | }
|
| | | |
| | | // 如果无法从agent中找到足够多问题,则从例子中寻找
|
| | | if(tranReq.getContentSampleQuestionCount() < maxQuestion)
|
| | | {
|
| | | tranReq.sendChunkedBlock("begin", "适配器中匹配的相关问题不足,从例子中寻找匹配");
|
| | | Set<String> matchQuestion = new HashSet<>();
|
| | | Set<String> randQuestion = new HashSet<>();
|
| | | SMTDatabase db = SMTAIServerApp.getApp().allocDatabase();
|
| | | JaccardSimilarity jaccardSimilarity = new JaccardSimilarity();
|
| | | try
|
| | | // 首先尝试从agent中找到相关问题
|
| | | List<SMTQwenAgent> listAgent = getUsefulAgentList(tranReq.getAgentGroupSet(), _mapId2Agent, tranReq.getCurGroupType(), null);
|
| | | for(String keywrod : listKeyword)
|
| | | {
|
| | | String curGroupType = tranReq.getCurGroupType();
|
| | | Set<String> setAgentGroup = tranReq.getAgentGroupSet();
|
| | | DBRecords recs = db.querySQL("SELECT A.sample_question, A.sample_match, A.group_id, G.group_type FROM ai_scene_sample A LEFT JOIN ai_scene_group G ON A.group_id=G.group_id", null);
|
| | | for(DBRecord rec : recs.getRecords())
|
| | | tranReq.sendChunkedBlock("begin", "开始匹配关键字:" + keywrod);
|
| | | for(SMTQwenAgent agent : listAgent)
|
| | | {
|
| | | String groupId = rec.getString("group_id");
|
| | | |
| | | // 如果例子不在有权限分组,则忽略
|
| | | if(setAgentGroup != null && !setAgentGroup.contains(groupId))
|
| | | continue;
|
| | | |
| | | String groupType = rec.getString("group_type");
|
| | | if(curGroupType != null && !curGroupType.equals(groupType))
|
| | | continue;
|
| | | |
| | | // 将例子加入随机问题列表
|
| | | String question = rec.getString("sample_question");
|
| | | if(randQuestion.size() < maxQuestion)
|
| | | randQuestion.add(question);
|
| | | |
| | | // 如果例子中包含关键字,则直接加入
|
| | | for(String keywrod : listKeyword)
|
| | | agent.queryUnknowQuestionList(keywrod, tranReq);
|
| | | }
|
| | | |
| | | if(tranReq.getContentSampleQuestionCount() >= maxQuestion)
|
| | | break;
|
| | | }
|
| | | |
| | | // 如果无法从agent中找到足够多问题,则从例子中寻找
|
| | | if(tranReq.getContentSampleQuestionCount() < maxQuestion)
|
| | | {
|
| | | tranReq.sendChunkedBlock("begin", "适配器中匹配的相关问题不足,从例子中寻找匹配");
|
| | | Set<String> matchQuestion = new HashSet<>();
|
| | | Set<String> randQuestion = new HashSet<>();
|
| | | SMTDatabase db = SMTAIServerApp.getApp().allocDatabase();
|
| | | JaccardSimilarity jaccardSimilarity = new JaccardSimilarity();
|
| | | try
|
| | | {
|
| | | String curGroupType = tranReq.getCurGroupType();
|
| | | Set<String> setAgentGroup = tranReq.getAgentGroupSet();
|
| | | DBRecords recs = db.querySQL("SELECT A.sample_question, A.sample_match, A.group_id, G.group_type FROM ai_scene_sample A LEFT JOIN ai_scene_group G ON A.group_id=G.group_id", null);
|
| | | for(DBRecord rec : recs.getRecords())
|
| | | {
|
| | | // 如果关键字包含在问题中,则直接加入并退出
|
| | | if(question.indexOf(keywrod) >= 0)
|
| | | {
|
| | | tranReq.sendChunkedBlock("begin", "关键字[" + keywrod + "]包含在里子[" + question + "]中");
|
| | | matchQuestion.add(question);
|
| | | break;
|
| | | }
|
| | | String groupId = rec.getString("group_id");
|
| | |
|
| | | // 如果存在匹配字段,则按照匹配字段和关键字匹配相似度
|
| | | String sJsonMatch = rec.getString("sample_match");
|
| | | if(!SMTStatic.isNullOrEmpty(sJsonMatch))
|
| | | // 如果例子不在有权限分组,则忽略
|
| | | if(setAgentGroup != null && !setAgentGroup.contains(groupId))
|
| | | continue;
|
| | | |
| | | String groupType = rec.getString("group_type");
|
| | | if(curGroupType != null && !curGroupType.equals(groupType))
|
| | | continue;
|
| | | |
| | | // 将例子加入随机问题列表
|
| | | String question = rec.getString("sample_question");
|
| | | if(randQuestion.size() < maxQuestion)
|
| | | randQuestion.add(question);
|
| | | |
| | | // 如果例子中包含关键字,则直接加入
|
| | | for(String keywrod : listKeyword)
|
| | | {
|
| | | for(Json jsonMatch : Json.read(sJsonMatch).asJsonList())
|
| | | // 如果关键字包含在问题中,则直接加入并退出
|
| | | if(question.indexOf(keywrod) >= 0)
|
| | | {
|
| | | String sMatch = jsonMatch.asString();
|
| | | double match = jaccardSimilarity.apply(keywrod, sMatch);
|
| | | if(match > 0.3 || sMatch.indexOf(keywrod) >= 0 || keywrod.indexOf(sMatch) >= 0)
|
| | | tranReq.sendChunkedBlock("begin", "关键字[" + keywrod + "]包含在里子[" + question + "]中");
|
| | | matchQuestion.add(question);
|
| | | break;
|
| | | }
|
| | | |
| | | // 如果存在匹配字段,则按照匹配字段和关键字匹配相似度
|
| | | String sJsonMatch = rec.getString("sample_match");
|
| | | if(!SMTStatic.isNullOrEmpty(sJsonMatch))
|
| | | {
|
| | | for(Json jsonMatch : Json.read(sJsonMatch).asJsonList())
|
| | | {
|
| | | tranReq.sendChunkedBlock("begin", "关键字[" + keywrod + "]和例子[" + sMatch + "]的匹配度为:" + match);
|
| | | matchQuestion.add(question);
|
| | | break;
|
| | | String sMatch = jsonMatch.asString();
|
| | | double match = jaccardSimilarity.apply(keywrod, sMatch);
|
| | | if(match > 0.3 || sMatch.indexOf(keywrod) >= 0 || keywrod.indexOf(sMatch) >= 0)
|
| | | {
|
| | | tranReq.sendChunkedBlock("begin", "关键字[" + keywrod + "]和例子[" + sMatch + "]的匹配度为:" + match);
|
| | | matchQuestion.add(question);
|
| | | break;
|
| | | }
|
| | | }
|
| | | }
|
| | | |
| | | }
|
| | | |
| | | }
|
| | | }
|
| | | |
| | | // 将找到的数据加入匹配列表
|
| | | if(matchQuestion.size() < maxQuestion)
|
| | | {
|
| | | tranReq.sendChunkedBlock("begin", "匹配到的例子个数不足,加入随机匹配的例子");
|
| | | for(String randQ : randQuestion)
|
| | | |
| | | // 将找到的数据加入匹配列表
|
| | | if(matchQuestion.size() < maxQuestion)
|
| | | {
|
| | | if(matchQuestion.size() >= maxQuestion)
|
| | | break;
|
| | | |
| | | tranReq.sendChunkedBlock("begin", "加入随机匹配例子:" + randQ);
|
| | | matchQuestion.add(randQ);
|
| | | tranReq.sendChunkedBlock("begin", "匹配到的例子个数不足,加入随机匹配的例子");
|
| | | for(String randQ : randQuestion)
|
| | | {
|
| | | if(matchQuestion.size() >= maxQuestion)
|
| | | break;
|
| | | |
| | | tranReq.sendChunkedBlock("begin", "加入随机匹配例子:" + randQ);
|
| | | matchQuestion.add(randQ);
|
| | | }
|
| | | }
|
| | | |
| | | // 将匹配列表数据加入返回
|
| | | for(String matchQ : matchQuestion)
|
| | | {
|
| | | tranReq.addContentSampleQuestion(matchQ);
|
| | | }
|
| | | |
| | | // 只保留限定问题
|
| | | tranReq.sendChunkedBlock("begin", "限定匹配后的问题条目为" + maxQuestion + "条");
|
| | | tranReq.limitContentSampleQuestion(maxQuestion);
|
| | | }
|
| | | |
| | | // 将匹配列表数据加入返回
|
| | | for(String matchQ : matchQuestion)
|
| | | finally
|
| | | {
|
| | | tranReq.addContentSampleQuestion(matchQ);
|
| | | db.close();
|
| | | }
|
| | | |
| | | // 只保留限定问题
|
| | | tranReq.sendChunkedBlock("begin", "限定匹配后的问题条目为" + maxQuestion + "条");
|
| | | tranReq.limitContentSampleQuestion(maxQuestion);
|
| | | }
|
| | | finally
|
| | | {
|
| | | db.close();
|
| | | }
|
| | | }
|
| | |
|