jiayongqiang 2 дней назад
Родитель
Сommit
71b387b56e

BIN
agent/dist/agent-0.1.6-py3-none-any.whl


BIN
agent/dist/agent-0.1.6.tar.gz


BIN
agent/dist/agent-0.1.8.2-py3-none-any.whl


BIN
agent/dist/agent-0.1.8.2.tar.gz


BIN
agent/logs/aitagging-app.2026-05-13_15-07-47_974217.log.zip


BIN
agent/logs/aitagging-app.2026-05-14_10-30-41_494585.log.zip


+ 10 - 3
agent/src/agent/api_outter.py

@@ -63,7 +63,7 @@ async def execute_reg(log_id:str,tag_category_id:str,phrase: str)-> list:
                     from aitag_tag_info tti left join aitag_tag_category  ttc 
                     on tti.category_id = ttc.id 
                     where ttc.is_delete=0 and tti.is_delete=0 and ttc.state =  0 and tti.state = 0 and tti.tag_level = ttc.visibility_level
-                    and '{phrase}' ~ tti.reg
+                    and '{phrase}' ~ tti.reg and tti.reg is not null and length(tti.reg) > 0
                     """    
     if tag_category_id:
         sql += f""" and ttc.id = '{tag_category_id}'"""
@@ -124,11 +124,17 @@ def start_tagging(id:str, instucde: Optional[str] = None):
         )
     return is_marine
 
+def generate_html(phrase, matched_rule, tag_name):
+    highlighted_phrase = re.sub(matched_rule, r'<strong>\g<0></strong>', phrase)
+    html_output = f"映射文本【{highlighted_phrase}】与映射规则【{matched_rule}】匹配,映射为标签【{tag_name}】"
+    return html_output
+
 # 定义预设规则匹配函数
 def defined_rule_match(phrase: str):
+    phrase = re.sub(r'职业.*?(?=投向)', '', phrase)
     result = []
     try:
-        sql = """select tag_type,tag_nm,defined_rule from aitag_predefined_rules where %s ~ defined_rule """
+        sql = """select DISTINCT on (tag_type,tag_nm) tag_type,tag_nm, defined_rule from aitag_predefined_rules where %s ~ defined_rule and defined_rule is not null and tag_nm is not null order by tag_type,tag_nm,defined_rule desc"""
         rules = dao.query(sql, (phrase,))
         print(rules)
         if rules and len(rules) > 0:
@@ -138,7 +144,7 @@ def defined_rule_match(phrase: str):
                 if tag_info and len(tag_info) > 0:
                     result.append({
                         "id": tag_info[0][0],
-                        "desc": f"映射文本【{phrase}】与映射规则【{matched[2]}】匹配,映射为标签【{tag_info[0][2]}】",
+                        "desc": generate_html(phrase, matched[2], tag_info[0][2]),
                         "passr": True,
                         "tag_code": tag_info[0][4],
                         "tag_name": tag_info[0][2],
@@ -181,6 +187,7 @@ async def run_ai_pipeline(log_id: str, tag_category_id: str, phrase: str, instuc
             if result:
                 try:
                     tags = dao.query_dict(""" select id,tag_nm as tag_name,tag_code, tag_path,category_id,tag_prompt from aitag_tag_info where id in %s """, (tuple(result),))
+                    logger.info(f"筛选结果: {tags}")
                     result = await reflect_check(phrase,is_marine, tags)
                 except Exception as e:
                     logger.error(f"LLM reflection check failed: {e}")

+ 1 - 1
agent/src/agent/core/es.py

@@ -143,7 +143,7 @@ def hybrid_search(query_vector):
     r =  response["hits"]["hits"]
     return [item["_id"] for item in r]
 
-def bm25_vector_search(query:str,query_vector,rrf_score_threshold=0.016):
+def bm25_vector_search(query:str,query_vector,rrf_score_threshold=0.0157):
     resp_bm25 = es.search(
         index=INDEX_NAME,
         size=10,

+ 18 - 8
agent/tests/test_bm25.py

@@ -1,10 +1,20 @@
-from agent.api_outter import vector_similarity_search
+from agent.api_outter import vector_similarity_search,execute_reg
 import agent.core.dao as dao
+async def test_bm25():
+    phrase = "职业:民宿服务; 投向:民宿服务; 用途:经营民宿"
+    result =  await execute_reg(None,None,phrase)
+    print('to here 1')
+    print(result)
+    # step2: 向量检索
+    if not result or len(result) == 0:
+        result = vector_similarity_search(phrase)
+        print('to here 2')
+        print(result)
+    # step3: LLM 打标
+    if result:
+        tags = dao.query_dict(""" select id,tag_nm as tag_name,tag_code, tag_path,category_id,tag_prompt from aitag_tag_info where id in %s """, (tuple(result),))
+        print('to here 3')
+        print(tags)
 
-phrase = "职业:民宿服务; 投向:民宿服务; 用途:经营民宿"
-r = vector_similarity_search(phrase)
-print(r)
-
-tags = dao.query_dict(""" select id,tag_nm as tag_name,tag_code, tag_path,category_id,tag_prompt from aitag_tag_info where id in %s """, (tuple(r),))
-print(tags)
-
+import asyncio
+asyncio.run(test_bm25())

+ 1 - 1
agent/tests/test_query.py

@@ -1,4 +1,4 @@
 import requests
 
-result = requests.get("http://10.192.72.13:9876/api/aitag/v1/query?business_attr=test_attr3")
+result = requests.get("http://10.192.72.13:9876/api/aitag/v1/query?business_attr=test_attr8")
 print(result.text)

+ 8 - 1
agent/tests/test_reg.py

@@ -21,4 +21,11 @@ for t in test_cases:
 
 a = False
 b = False
-print(a == b)
+print(a == b)
+
+
+text = "职业:水产养殖人员 投向:内陆养殖 用途:其他海洋服务,老年人"
+# 匹配从“职业”开始,直到“投向”之前的所有内容,并将其替换为空字符串
+result = re.sub(r'职业:.*?(?=投向)', '', text)
+
+print(result)

+ 2 - 2
agent/tests/test_tagging.py

@@ -8,8 +8,8 @@ res = requests.post("http://localhost:9876/api/aitag/v1/tagging", json={
     # "timestamp": 1234567890,
     # "sign": "test_sign",
     "esb_seq_no":"abc",
-    "business_attr": "test_attr7",
-    "phrase": "测试:职业:水产养殖人员 投向:内陆养殖 用途:其他海洋服务",
+    "business_attr": "test_attr10",
+    "phrase": "测试:职业:自由;投向:建筑;用途:旅游设施投资",
     "instucde": "901020300",
     "contract_no":"contract_no",
     "instucde_nm":"instucde_nm",

+ 3 - 3
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/config/FastApiConfig.java

@@ -17,15 +17,15 @@ public class FastApiConfig {
     /**
      * 请求超时时间(毫秒)
      */
-    private int timeout = 10000;
+    private int timeout = 60000;
 
     /**
      * 连接超时时间(毫秒)
      */
-    private int connectTimeout = 5000;
+    private int connectTimeout = 60000;
 
     /**
      * 读取超时时间(毫秒)
      */
-    private int readTimeout = 10000;
+    private int readTimeout = 60000;
 }

+ 3 - 1
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/FastApiServiceImpl.java

@@ -148,7 +148,9 @@ public class FastApiServiceImpl implements FastApiService {
                 }
 
                 AiTaggingQueryResponseVo v =  JSON.parseObject(responseBody, AiTaggingQueryResponseVo.class);
-                v.getData().setResult(Arrays.stream(v.getData().getResult()).filter(r->r.getPassr()).toArray(AiTaggingQueryResponseVo.AiTagResultVo[]::new));
+                if(v!=null && v.getData()!=null && v.getData().getResult()!=null ){
+                    v.getData().setResult(Arrays.stream(v.getData().getResult()).filter(r->r.getPassr()).toArray(AiTaggingQueryResponseVo.AiTagResultVo[]::new));
+                }
                 return v;
             }
         } catch (Exception e) {

+ 12 - 4
web/src/views/aiTagging/externalPage/components/IntelligentRecommend.vue

@@ -3,7 +3,7 @@
     <!-- 智能推荐标题 -->
     <div class="section-header">
       <h3 class="section-title">智能推荐</h3>
-      <a href="javascript:void(0)" class="switch-to-manual" @click="handleSwitchToManual">
+      <a href="javascript:void(0)" v-if="taggingState==1" class="switch-to-manual" @click="handleSwitchToManual">
         以下都不合适?切换人工打标
       </a>
     </div>
@@ -22,15 +22,19 @@
         :class="{ 'selected': tag.selected }"
       >
         <!-- 标签路径 -->
-        <div class="tag-path" @click.stop="handleTagSelect(index)">
+        <div class="tag-path" v-if="taggingState==1" @click.stop="handleTagSelect(index)">
           <span>{{ tag.tag_path }}</span>
           <i v-if="tag.selected" class="el-icon-check selected-icon"></i>
         </div>
+         <div class="tag-path" v-if="taggingState!=1" >
+          <span>{{ tag.tag_path }}</span>
+          
+        </div>
         
         <!-- 打标依据 -->
         <div class="tag-basis" @click.stop="handleTagSelect(index)">
           <div class="basis-label">打标依据:</div>
-          <div class="basis-content">{{ tag.desc }}</div>
+          <div class="basis-content" v-html="tag.desc"></div>
         </div>
         
         <!-- 不准确反馈 -->
@@ -61,7 +65,11 @@ export default {
     currentSystem: {
       type: String,
       default: ''
-    }
+    },
+    taggingState: {
+      type: Number,
+      default: 0
+       },
   },
   computed: {
     // 检查是否有推荐结果

+ 5 - 4
web/src/views/aiTagging/externalPage/externalEdit.vue

@@ -24,7 +24,7 @@
           :key="index"
           :type="getTagType(index)"
           class="selected-tag"
-          closable
+          :closable="taggingState==1"
           @close="handleTagRemove(index)"
           :title="tag.tag_name"
         >
@@ -60,6 +60,7 @@
           v-if="currentMode === 'intelligent'"
           :recommendations="tagRecommendations"
           :current-system="currentSystem"
+          :tagging-state="taggingState"
           @tagSelect="handleTagSelect"
           @switchToManual="switchToManual"
           @retryIntelligentTagging="retryIntelligentTagging"
@@ -421,9 +422,9 @@ export default {
             this.tagSystems = systems.map(system => system.categoryNm || '').filter(name => name);
             
             // 默认选中第一个标签体系
-            if (this.tagSystems.length > 0) {
-              this.currentSystem = this.tagSystems[0];
-            }
+            // if (this.tagSystems.length > 0) {
+            //   this.currentSystem = this.tagSystems[0];
+            // }
           } else {
             this.$message.error(response.message || '获取标签体系列表失败');
           }

+ 5 - 9
web/src/views/aiTagging/taggingTest/taggingApply.vue

@@ -90,7 +90,7 @@
           <div class="tag-result-body">
             <div class="result-item">
               <span class="result-label">打标依据:</span>
-              <div class="result-text">{{ result.reason || '暂无依据' }}</div>
+              <div class="result-text" v-html="result.reason || '暂无依据'"></div>
             </div>
           </div>
         </el-card>
@@ -266,7 +266,8 @@ export default {
         method: 'POST',
         data: queryParams,
         callback: (code, error, response) => {
-          if (response.code == '0') {
+
+          if (response.code == '0' && response.data.code!='500') {
             // 处理查询结果
             // 实际数据在 response.data.data 中
             const responseData = response.data && response.data.data ? response.data.data : null;
@@ -287,7 +288,7 @@ export default {
               this.pollingTimer = setTimeout(() => {
                 this.pollTaggingResult(businessAttr, loadingInstance);
               }, 3000);
-            } else if (state === 1 || state === 2 || state === 3) {
+            } else  {
               // 打标完成、已确认或已推送,停止轮询
               loadingInstance.close();
               this.clearPolling();
@@ -340,12 +341,7 @@ export default {
                 results: this.taggingResults,
                 time: this.taggingTime
               });
-            } else {
-              // 未知状态,继续轮询
-              this.pollingTimer = setTimeout(() => {
-                this.pollTaggingResult(businessAttr, loadingInstance);
-              }, 3000);
-            }
+            } 
           } else {
             // 接口调用失败,停止轮询
             loadingInstance.close();