1
秦芳睿
2025-04-22 e70a362606b78a822e93d5117a9013e8f9086faf
JAVA/SMTAIServer/src/main/java/com/smtaiserver/smtaiserver/javaai/qwen/SMTQwenAgentManager.java
@@ -97,134 +97,138 @@
   
   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();
         }
      }