Parcourir la source

完成所有功能的封装

Sherlock il y a 10 mois
Parent
commit
41ede95f26
5 fichiers modifiés avec 171 ajouts et 91 suppressions
  1. 22 14
      agent/agent.py
  2. 22 6
      agent/config.py
  3. 10 3
      agent/glm.py
  4. 0 68
      api_service.py
  5. 117 0
      utils/api_service.py

+ 22 - 14
agent/agent.py

@@ -33,7 +33,7 @@ class Agent:
         self.glm.set_modelname("glm-4-plus")
         prompt = Prompt.LICENSE_LIST_FILTER + f"""
         请根据上述逻辑,分析以下商品是否为授权生产的,并输出结果:
-        商品标题: {title}
+        商品名称: {title}
         已生产的产品清单:
         {license_list_str}
             
@@ -41,22 +41,14 @@ class Agent:
         - 如果找到匹配项则输出:
         ```json
         {{
-            "in_list": true
+            "in_list": true,
+            "march_product": 匹配到的产品
         }}
         ```
-            
-        - 如果没找到匹配项,但是判断为相似产品输出:
-        ```json
-        {{
-            "in_list": false,
-            "is_similarity": true
-        }}
-        ```
-        - 如果既不是授权生产的商品,也不是相似产品则输出:
+        - 如果未找到匹配项则输出:
         ```json
         {{
-            "in_list": false,
-            "is_similarity": false
+            "in_list": false
         }}
         ```
         """
@@ -72,7 +64,23 @@ class Agent:
         response = response.content
         
         return response
+    
+    def product_image_similarity_judgement(self, image_url1, image_url2):
+        """判断两个图像中的产品是否一致"""
+        self.glm.set_modelname("glm-4v-plus-0111")
+        prompt = Prompt.PRODUCT_JUDGEMENT
+        response = self.glm.image_response(prompt, image_url1, image_url2)
+        response = response.content
+        
+        return response
 
 if __name__ == "__main__":
     agent = Agent()
-    agent.brand_key_word_judgement("【防泼水】荷叶风衣连帽加绒外套防风外套保暖户外运动服女外套", "李宁")
+    image_url1 = 'http://h2.appsimg.com/a.appsimg.com/upload/merchandise/pdcvis/613214/2024/0902/118/27466cf6-fb28-4580-9009-95a3763e06bf.jpg'
+    image_url2 = 'http://h2.appsimg.com/a.appsimg.com/upload/merchandise/pdcvis/613214/2024/1120/169/8ca15632-9cb9-40e7-8915-e6773e17a05e.jpg'
+    agent.product_image_similarity_judgement(image_url1, image_url2)
+    
+    # ["http://h2.appsimg.com/a.appsimg.com/upload/merchandise/pdcvis/613214/2024/1120/88/9b9027dd-95b7-4024-b71e-fb7cbfde16a1.jpg",
+    #  "http://h2.appsimg.com/a.appsimg.com/upload/merchandise/pdcvis/613214/2024/0902/118/27466cf6-fb28-4580-9009-95a3763e06bf.jpg",
+    #  "http://h2.appsimg.com/a.appsimg.com/upload/merchandise/pdcvis/613214/2024/1120/169/8ca15632-9cb9-40e7-8915-e6773e17a05e.jpg",
+    #  "http://h2.appsimg.com/a.appsimg.com/upload/merchandise/pdcvis/613214/2024/1120/91/d42ae626-8606-4e29-8a75-a247ab6be790.jpg"]

+ 22 - 6
agent/config.py

@@ -37,14 +37,13 @@ class Prompt:
     LICENSE_LIST_FILTER = f"""
         你是一个产品过滤助手,你的任务是根据输入的商品名称和提供的商品清单,判断输入的商品名称是否为清单中的产品。
         判断思路:
-        遍历商品清单中的每一个产品。
-        检查输入的商品名称是否与商品清单中某个产品的产品名称在语义上匹配,而不仅仅是完全相同的字符串匹配
+        遍历商品清单中的每一个产品名称
+        检查输入的商品名称是否与商品清单中某个产品是相同的类型和系列
 
         匹配规则包括:
-        1. 关键词匹配:输入的商品名称和产品名称中包含相同的关键词(如“运动卫衣”、“套头衫”等)。
-        2. 语义相似性:输入的商品名称和产品名称描述的是同一类产品,即使表达方式不同(如“男子运动卫衣”和“男士休闲运动上衣”)。
-        3. 如果判定为不在产品生产清单中,那么就判断一下是否与清单中的某个商品是相似商品。
-        
+        1. 首先先根据商品名称判断商品的类型(如帽子、上衣、裤子、鞋子、背包等)和系列。
+        2. 之后再从给定的授权商品列表中查看是否有与该商品类型和系列一致的产品。
+        3. 请注意甄别同系列,不同类型的产品,不能将其作为匹配项。如商品名称为李宁反伍BADFIVE棒球帽男士女士运动帽,但是清单中有李宁反伍BADFIVE新秀2男子篮球文化鞋ABCT055-1,虽都属于李宁反伍BADFIVE系列,但是一个时运动帽,一个时篮球文化鞋,类型不同。
     """
     
     # 判断图像中是否包含LOGO,并判断是否为指定产品的logo
@@ -69,6 +68,23 @@ class Prompt:
         }}
     """
     
+    # 判断两个图像中的产品是否是一样的
+    PRODUCT_JUDGEMENT = f"""
+        你是一个产品图像分析助手,需要严格判断用户提供的两张图像中的产品是否完全相同,请按照以下步骤进行分析:
+        1. 定位产品位置,请只分析两张图像产品图像的部分,如果图像中没有产品直接判断为不一致。
+        2. 核心特征对比:首先确认两者是否属于同一类产品。其次从形状/结构、颜色/图案(注意光照导致的色差)、品牌标识(LOGO、商标细节等)等细致特征。如果颜色不一致,其他特征一致也判断为一致产品。
+        最终结果返回为以下给出的json格式
+        输出结果示例:
+        如果判断为产品一致则返回
+        {{
+            'is_similarity_product': true
+        }}
+        判断不一致则返回
+        {{
+            'is_similarity_product': false
+        }}
+    """
+    
     
     
 if __name__ == "__main__":

+ 10 - 3
agent/glm.py

@@ -30,7 +30,7 @@ class Glm:
         )
         return resonse.choices[0].message
     
-    def image_response(self, query):
+    def image_response(self, query, image_url1, image_url2):
         """单图像问答"""
         response = self.client.chat.completions.create(
             model="glm-4v-plus-0111",
@@ -44,11 +44,18 @@ class Glm:
                         },
                         {
                             "type": "image_url",
-                            "image_url": {"url": "http://h2.appsimg.com/a.appsimg.com/upload/merchandise/pdcvis/613214/2024/1120/88/9b9027dd-95b7-4024-b71e-fb7cbfde16a1.jpg"}
+                            "image_url": {"url": image_url1}
+                        },
+                        {
+                            "type": "image_url",
+                            "image_url": {"url": image_url2}
                         }
                     ]
                 }
-            ]
+            ],
+            response_format = {
+                "type": "json_object"
+            }
         )
         
         return response.choices[0].message

+ 0 - 68
api_service.py

@@ -1,68 +0,0 @@
-from agent.agent import Agent
-
-class ApiService:
-    @staticmethod
-    def keyword_judgement(url_data, basic_data):
-        """关键词引流判断"""
-        if url_data['tilte'] == None or url_data['brand_name'] == None or basic_data['brand_name'] == None:
-            return '信息不全,无法判定'
-        
-        # 标题判定
-        if basic_data['brand_name'] in url_data['title'] and url_data['brand_name'] != basic_data['brand_name']:
-            # 当产品名称中包含与判定商标一致的品牌名称,且详情页中的品牌名称与判定的品牌名称不一致时判定为关键词引流
-            return True
-        elif basic_data['brand_name'] in url_data['title'] and url_data['brand_name'] == basic_data['brand_name']:
-            return False
-        else:
-            # 图像判定
-            pass
-        
-        # 图像判定
-        return "无法判定"
-    
-    @staticmethod
-    def similarity_logo_judgement(url_data, basic_data):
-        """近似商标侵权判定"""
-        for similarity_logo in basic_data['similarity_logos']:
-            if similarity_logo in url_data['title']:
-                return True
-            elif similarity_logo in url_data['brand_name']:
-                return True
-            
-        # 判断基础数据中的名称是否包含在标题或者详情品牌名称中
-        if basic_data['brand_name'] in url_data['title'] or basic_data['brandname'] in url_data['brand_name']:
-            return False
-        else:
-            return '无法判定'
-        
-    @staticmethod
-    def logo_1to1_judgement(url_data, basic_data):
-        """商标一比一侵权"""
-        # 首先计算基础价格百分比
-        base_price = basic_data['base_price'] * basic_data['base_percent']
-
-        if url_data['title'].strip() == basic_data['product_name'].strip():
-            # 当商品名称与提供的产品名称完全一致时,进行判定
-            if url_data < base_price:
-                return True
-            else:
-                return False
-        else:
-            # 进行图像判定
-            pass
-        
-    @staticmethod
-    def low_price_judgement(url_data, basic_data):
-        """低价判断"""
-        if url_data['title'] == basic_data['product_name']:
-            if url_data['price'] < basic_data['base_price']:
-                return True
-            else:
-                return False
-        else:
-            # 进行图像判定
-            pass
-        
-    
-    
-    

+ 117 - 0
utils/api_service.py

@@ -0,0 +1,117 @@
+from agent.agent import Agent
+from db import MongoDao
+import json
+
+license_dao = MongoDao("ProductStandard")
+
+class ApiService:
+    agent = Agent()
+    @staticmethod
+    def keyword_judgement(url_data, basic_data):
+        """关键词引流判断"""
+        if url_data['title'] == None or url_data['brand_name'] == None or basic_data['brand_name'] == None:
+            return '信息不全,无法判定'
+        
+        # 标题判定
+        if basic_data['brand_name'] in url_data['title'] and url_data['brand_name'] != basic_data['brand_name']:
+            # 当产品名称中包含与判定商标一致的品牌名称,且详情页中的品牌名称与判定的品牌名称不一致时判定为关键词引流
+            return True
+
+        elif url_data['brand_name'] == basic_data['brand_name'] or basic_data['brand_name'] not in url_data['title']:
+            return False
+        else:
+            # 图像判定
+            pass
+        
+        # 图像判定
+        return "无法判定"
+    
+    @staticmethod
+    def similarity_logo_judgement(url_data, basic_data):
+        """近似商标侵权判定"""
+        for similarity_logo in basic_data['similarity_logos']:
+            if similarity_logo in url_data['title'] or similarity_logo in url_data['brand_name']:
+                return True
+            
+        # 判断基础数据中的名称是否包含在标题或者详情品牌名称中
+        if basic_data['brand_name'] in url_data['title'] or basic_data['brand_name'] in url_data['brand_name']:
+            return False
+        else:
+            return '无法判定'
+        
+    @staticmethod
+    def logo_1to1_judgement(url_data, basic_data):
+        """商标一比一侵权"""
+        # 首先计算基础价格百分比
+        base_price = basic_data['base_price'] * basic_data['price_percent']
+
+        if url_data['title'].strip() == basic_data['product_name'].strip():
+            # 当商品名称与提供的产品名称完全一致时,进行判定
+            if url_data['price'] < base_price:
+                return True
+            else:
+                return False
+        else:
+            for image_url1 in url_data['product_images']:
+                for image_url2 in basic_data['product_images']:
+                    similarity_product_judgement = json.loads(ApiService.agent.product_image_similarity_judgement(image_url1, image_url2))
+                    if similarity_product_judgement['is_similarity_product']:
+                        if url_data['price'] < base_price:
+                            return True
+                        else:
+                            return False
+            
+            return False
+        
+    @staticmethod
+    def low_price_judgement(url_data, basic_data):
+        """低价判断"""
+        if url_data['title'] == basic_data['product_name']:
+            if url_data['price'] < basic_data['base_price']:
+                return True
+            else:
+                return False
+        else:
+            # 进行图像判定
+            pass
+       
+    @staticmethod
+    def get_license_list(brand_name):
+        """获取品牌方授权生成的商品列表"""
+        license_list = []
+        records = license_dao.get_records_by_query({"BrandName": brand_name})
+        for record in records:
+            license_list.append(record['ProductTitle'].strip())
+        return license_list
+     
+    @staticmethod
+    def license_judgement(url_data, basic_data):
+        """未生产产品判断"""
+        license_list = ApiService.get_license_list(basic_data['brand_name'])
+        result = ApiService.agent.license_product_judgement(url_data['title'], license_list)
+        return result
+    
+if __name__ == '__main__':
+    url_data = {
+        'title': '休闲短裤女士运动潮流系列夏季女装裤子梭织运动裤',
+        'brand_name': '李宁',
+        'product_images': [
+            'http://h2.appsimg.com/a.appsimg.com/upload/merchandise/pdcvis/613214/2024/0902/118/27466cf6-fb28-4580-9009-95a3763e06bf.jpg',
+            'http://h2.appsimg.com/a.appsimg.com/upload/merchandise/pdcvis/613214/2024/1120/169/8ca15632-9cb9-40e7-8915-e6773e17a05e.jpg'  
+        ],
+        'price': 200
+    }
+    basic_data = {
+        'product_name': '休闲短裤女士运动潮流系列夏季女装裤子梭织运动裤',
+        'brand_name': '李宁',
+        'similarity_logos': ['李宇', '李柠'],
+        'product_images': [
+            'http://h2.appsimg.com/a.appsimg.com/upload/merchandise/pdcvis/613214/2024/1120/169/8ca15632-9cb9-40e7-8915-e6773e17a05e.jpg',
+            'http://h2.appsimg.com/a.appsimg.com/upload/merchandise/pdcvis/613214/2024/1120/169/8ca15632-9cb9-40e7-8915-e6773e17a05e.jpg' 
+        ],
+        'base_price': 200,
+        'price_percent': 0.9
+        
+    }
+    result = ApiService.logo_1to1_judgement(url_data, basic_data)
+    print(result)