BE引擎召回配置

阿里云召回引擎BE,是阿里巴巴集团推荐行业自研的召回引擎,提供全面召回的能力,具有高稳定、高性能的索引和查询机制、低运维成本、通过灵活过滤和配置策略加速迭代效率,支持秒级在线实时数据更新等特性。详细的介绍参考产品简介

PAI-Rec 引擎内建支持对于 BE 引擎的访问,本文介绍如何通过配置就可以从 BE 召回数据。

数据源

首先要配置下数据源,这样通过数据源就可以访问到BE 引擎。

{
  "BEConfs": {
    "be-test": {
      "Username": "",
      "Password": "",
      "Endpoint": "http://xxx.aime.aliyuncs.com",
      "ReleaseType": "product"
    }
  }
}

上面的配置可以从 BE 实例控制台获取到

image-20220311085350245

召回

BE 支持 X2I、向量、多路合并的多种类型的召回。这些召回的配置基本类似,下面一一说明。通常情况下,BE 会负责所有召回的输出,我们一般会使用多路合并的召回。但是多路合并的召回,具体每一路可以分为 X2I, 或者是向量召回。

多路合并召回

多数情况下,我们用此路召回。此路召回包含多个子链路召回,每个链路会配置优先级。

 {
      "Name": "BeRecall",
      "RecallType": "BeRecall",
      "BeConf": {
        "Count": 500,
        "BeName": "be-test",
        "BizName": "be_common",
        "BeRecallType": "multi_merge_recall",
        "BeRecallParams": [
          {
            "Count": 50,
            "RecallType": "x2i_recall",
            "RecallName": "retarget_u2i",
            "TriggerType": "user",
            "UserTriggers": [
              {
                "TriggerKey": "uid"
              }
            ],
            "ItemIdName": "item_id"
          },
          {
            "Count": 75,
            "RecallType": "x2i_recall",
            "RecallName": "etrec_i2i",
            "TriggerType": "u2i_realtime",
            "UserTriggerDaoConf": {
              "AdapterType": "hologres",
              "HologresName": "pairec-holo",
              "HologresTableName": "user_realtime_behavior_holo",
              "WhereClause": "",
              "Limit": 50,
              "TriggerCount": 20,
              "EventPlayTime": "",
              "EventWeight": "click:1;pre_go:2;add_collection:3;go:4",
              "WeightExpression": "exp(-0.2 * (currentTime-eventTime)/3600/24)",
              "NoUsePlayTimeField": true
            },
            "ItemIdName": "item_id",
             "PropertyFields": [
                "child_brand_id_new",
                "root_brand_id",
                "child_category_id",
                "vertical_id"
              ],
              "DiversityRules": [
                {
                  "Dimensions": [
                    "vertical_id"
                  ],
                  "Size": 10
                },
                {
                  "Dimensions": [
                    "child_category_id"
                  ],
                  "Size": 5
                },
                {
                  "Dimensions": [
                    "root_brand_id"
                  ],
                  "Size": 3
                },
                {
                  "Dimensions": [
                    "child_brand_id_new"
                  ],
                  "Size": 2
                }
              ]
            },
            "ItemIdName": "item_id",
            "TriggerIdName": "trigger_id",
            "UserTriggerRulesConf": {
              "DefaultValue": 3,
              "TriggerCounts": [
                7,
                7,
                6,
                5,
                5,
                3
              ]
            }
          },
          {
            "Count": 75,
            "RecallType": "x2i_recall",
            "RecallName": "offline_etrec_i2i",
            "TriggerType": "u2i",
            "UserCollaborativeDaoConf": {
              "AdapterType": "hologres",
              "HologresName": "pairec-holo",
              "User2ItemTable": "ali_rec_sln_u2i_trigger_list_holo"
            },
            "ItemIdName": "item_id",
            "TriggerIdName": "trigger_id",
            "UserTriggerRulesConf": {
              "DefaultValue": 3,
              "TriggerCounts": [
                7,
                7,
                6,
                5,
                5,
                3
              ]
            }
          },
          {
            "Count": 50,
            "RecallType": "x2i_recall",
            "RecallName": "vertical_hot",
            "TriggerType": "user",
            "UserTriggers": [
              {
                "TriggerKey": "os"
              },
              {
                "TriggerKey": "rel_sex"
              },
              {
                "TriggerKey": "is_ordered_user"
              }
            ],
            "ItemIdName": "item_id"
          },
          {
            "Count": 250,
            "RecallType": "x2i_recall",
            "RecallName": "mind_embedding",
            "TriggerType": "user",
            "UserTriggers": [
              {
                "TriggerKey": "uid"
              }
            ],
            "ItemIdName": "item_id"
          },
          {
            "Count": 100,
            "RecallType": "x2i_recall",
            "RecallName": "global_hot",
            "TriggerType": "fixvalue",
            "TriggerValue": "-1",
            "ItemIdName": "item_id"
          }
        ],
        "BeFilterNames": [
          "UserExposureFilter",
          "BizBlacklistFilter"
        ]
      }

BeRecallParams 包含多个子链路配置。每个子链路需要配置召回类型(RecallType) 和召回名称(RecallName)。

  • Count BeConf 下表示总的召回输出的 item 数量是 500 个

  • BeName BEConfs 里定义的数据源名称

  • BizName be 配置里的业务名称

  • BeRecallType 多路合并,固定值 multi_merge_recall

  • BeRecallParams 定义了每一路的配置,每一路的配置是 x2i 或者是向量。 在上面的例子中, xi2 需要指定 RecallType = x2i_recall

通常的表现形式为:

 {
      "Name": "BeRecall",
      "RecallType": "BeRecall",
      "BeConf": {
        "Count": 500,
        "BeName": "be-test",
        "BizName": "be_common",
        "BeRecallType": "multi_merge_recall",
        "BeRecallParams": [
          {
            "Count": 50,
            "RecallType": "x2i_recall",
            // 各路的具体定义
        ],
        "BeFilterNames": [ // 过滤规则定义
          "UserExposureFilter",
          "BizBlacklistFilter"
        ],
        "BeABParams":{ // be ab 参数的设置
        
        }
      }

X2I 召回的定义

我们具体介绍下 BeRecallParams 里每一路的配置的含义。

  • Count 定义了每一路召回的数量

  • RecallName 每一路的召回名称,需要和 be 里的配置保持一致

  • ItemIdName 返回的召回数据中,item id 的字段名称

在 X2I 的召回中,最主要是计算这个 X, 就是通常含义的 trigger。 我们支持多种不同的trigger , 下面详细说明。

固定值 Trigger
         {
            "Count": 100,
            "RecallType": "x2i_recall",
            "RecallName": "global_hot",
            "TriggerType": "fixvalue",
            "TriggerValue": "-1",
            "ItemIdName": "item_id"
          }
  • TriggerType = fixvalue , trigger 是个固定值,一般是全局的热门召回。 细节可以参考 这里

根据 user 属性组装 Trigger
        {
            "Count": 50,
            "RecallType": "x2i_recall",
            "RecallName": "vertical_hot",
            "TriggerType": "user",
            "UserTriggers": [
              {
                "TriggerKey": "os"
              },
              {
                "TriggerKey": "rel_sex"
              },
              {
                "TriggerKey": "is_ordered_user"
              }
            ],
            "ItemIdName": "item_id"
          },
          {
            "Count": 250,
            "RecallType": "x2i_recall",
            "RecallName": "mind_embedding",
            "TriggerType": "user",
            "UserTriggers": [
              {
                "TriggerKey": "uid"
              }
            ],
            "ItemIdName": "item_id"
          }
  • TriggerType = user , 我们可以根据 user 的属性,比如说 uid , 或者多个属性进行拼装成 trigger 进行召回。下面就是根据 uid 进行召回,可以理解成 U2I 召回

    "UserTriggers": [
      {
       "TriggerKey": "uid"
      }
    ]
    
  • 根据 user 属性我们可以进行分组召回,多个属性拼接成一个值。类似下面的设置, 下面是把三个属性进行拼装。具体原理可以参考分组热门召回

              "UserTriggers": [
                  {
                    "TriggerKey": "os"
                  },
                  {
                    "TriggerKey": "rel_sex"
                  },
                  {
                    "TriggerKey": "is_ordered_user"
                  }
                ],
    
U2I2I 召回
       {
            "Count": 75,
            "RecallType": "x2i_recall",
            "RecallName": "offline_etrec_i2i",
            "TriggerType": "u2i",
            "UserCollaborativeDaoConf": {
              "AdapterType": "hologres",
              "HologresName": "pairec-holo",
              "User2ItemTable": "ali_rec_sln_u2i_trigger_list_holo"
            },
            "ItemIdName": "item_id",
            "TriggerIdName": "trigger_id",
            "UserTriggerRulesConf": {
              "DefaultValue": 3,
              "TriggerCounts": [
                7,
                7,
                6,
                5,
                5,
                3
              ]
            }
          }
  • TriggerType = u2i, 我们需要找出 user 发生过行为的 item 列表, 然后根据 I2I 进行召回。传给 BE 时,需要把 U2I 的trigger 构造好。 这里需要提供一个外部表。这里类似协同过滤的配置

    "UserCollaborativeDaoConf": {
                  "AdapterType": "hologres",
                  "HologresName": "pairec-holo",
                  "User2ItemTable": "ali_rec_sln_u2i_trigger_list_holo"
    },
    

    表结构

    User2ItemTable 表

    表字段

    类型

    字段说明

    user_id

    string

    用户id, 保持唯一性

    item_ids

    string

    用户浏览的 item id 列表。 支持形式: Itemid1,itemid2,itemid3 或者 itemid1:score1,itemid2:score2

trigger 打散设置

在组装 trigger 后,传给 BE 后,有可能前面几个 trigger 就能召回足够的数据,导致后面的 trigger 不起作用,这里我们可以指定每个 trigger 的限定数据量。

TriggerIdName UserTriggerRulesConf 配套使用, 限定每个 trigger召回数量,给到 BE

  • TriggerCounts 是个列表,依次根据给最大值的 score 匹配。 如果 trigger 列表长,从 defaultvalue 取值。如果defaultvalue 不提供,TriggerCounts 列表最后的值,当成 defaultvalue

  • 适用于 TriggerType=u2i 或者 TriggerType= u2i_realtime

实时 U2I2I 召回
          {
            "Count": 75,
            "RecallType": "x2i_recall",
            "RecallName": "etrec_i2i",
            "TriggerType": "u2i_realtime",
            "UserTriggerDaoConf": {
              "AdapterType": "hologres",
              "HologresName": "pairec-holo",
              "HologresTableName": "user_realtime_behavior_holo",
              "WhereClause": "",
              "Limit": 50,
              "TriggerCount": 20,
              "EventPlayTime": "",
              "EventWeight": "click:1;pre_go:2;add_collection:3;go:4",
              "WeightExpression": "exp(-0.2 * (currentTime-eventTime)/3600/24)",
              "NoUsePlayTimeField": true
            },
             "PropertyFields": [
                "child_brand_id_new",
                "root_brand_id",
                "child_category_id",
                "vertical_id"
              ],
              "DiversityRules": [
                {
                  "Dimensions": [
                    "vertical_id"
                  ],
                  "Size": 10
                },
                {
                  "Dimensions": [
                    "child_category_id"
                  ],
                  "Size": 5
                },
                {
                  "Dimensions": [
                    "root_brand_id"
                  ],
                  "Size": 3
                },
                {
                  "Dimensions": [
                    "child_brand_id_new"
                  ],
                  "Size": 2
                }
              ]
            },
            "ItemIdName": "item_id",
            "TriggerIdName": "trigger_id",
            "UserTriggerRulesConf": {
              "DefaultValue": 3,
              "TriggerCounts": [
                7,
                7,
                6,
                5,
                5,
                3
              ]
            }
          }
  • TriggerType = u2i_realtime, 可以实时的进行 U2I2I 的召回,思路就是实时获取到 U2I 的列表,然后组装 trigger 进行召回。具体原理参考这里

额外的几个字段进行说明

  • Limit 是 获取 U2I 行为表的行数

  • TriggerCount 是最终计算出的 trigger 数量。如果没有显示指定此值, 会取 limit 的值

  • NoUsePlayTimeField 如果场景中没有 playtime的含义,设置为 true 即可

  • WeightMode 计算权重score 模式, max 或者 sum, 默认 sum

trigger 打散设置

和 u2i 设置一样的,限制 BE 中 每个 trigger 的召回数量, 需要设置 TriggerIdName 和 UserTriggerRulesConf。

通过 Limit 和 TriggerCount 可以选取最终 trigger 的数量。在这个选取过程中,我们希望做到 trigger 也能有一定的多样性。这时需要设置打散规则。

  • PropertyFields 打散规则需要根据不同的属性设置,这里指定哪些属性字段需要额外加载。

  • DiversityRules 根据维度字段(Dimensions 设置), 来设置 trigger 数量的上限,用 Size 表示。如果没有符合规则的 trigger ,我们会获取最大 score 的 trigger 进行填充

实时 dssm 向量召回
 {
            "Count": 600,
            "RecallType": "x2i_recall",
            "RecallName": "realtime_dssm_embedding",
            "TriggerType": "user_realtime_embedding",
            "UserRealtimeEmbeddingTrigger": {
              "EmbeddingNum": 1200,
              "RecallAlgo": "ali_recall_dssm_be_seq_rt",
              "UserFeatureConfs": [
                {
                  "FeatureDaoConf": {
                    "LoadFromCacheFeaturesName": "user_v1",
                    "FeatureStore": "user"
                  }
                },
                {
                  "FeatureDaoConf": {
                    "LoadFromCacheFeaturesName": "be_50_seq",
                    "FeatureStore": "user"
                  }
                },
                {
                  "FeatureDaoConf": {
                    "LoadFromCacheFeaturesName": "user_be_rt",
                    "FeatureStore": "user"
                  }
                }
              ]
            },
            "ItemIdName": "item_id"
          }

这里的执行流程是获取 user 特征, 然后调用 eas 模型 ali_recall_dssm_be_seq_rt,模型会实时算出 user embedding , 然后计算 item 的相似性,返回 item 列表。 然后把 item 列表传给 BE , 主要用于过滤数据。

  • TriggerType = user_realtime_embedding, 固定值

  • UserFeatureConfs 用户的特征加载逻辑,特征加载参考这里

  • RecallAlgo 模型的名称,在AlgoConfs 里能找到。需要注意, ResponseFuncName 要设置固定值 easyrecUserRealtimeEmbeddingResponseFunc

  {
      "Name": "ali_recall_dssm_be_seq_rt",
      "Type": "EAS",
      "EasConf": {
        "Processor": "EasyRec",
        "Timeout": 300,
        "ResponseFuncName": "easyrecUserRealtimeEmbeddingResponseFunc",
        "EndpointType": "DIRECT",
        "Url": "http://xxx.vpc.cn-hangzhou.pai-eas.aliyuncs.com/api/predict/ali_recall_dssm_be_seq_rt",
        "Auth": "xxx"
      }
    }
  • EmbeddingNum 告诉模型返回的 item 的数量

实时 mind 向量召回
      {
            "Count": 600,
            "RecallType": "x2i_recall",
            "RecallName": "realtime_mind_embedding",
            "TriggerType": "user_realtime_embedding_mind",
            "UserRealtimeEmbeddingTrigger": {
              "EmbeddingNum": 500,
              "RecallAlgo": "ali_recall_mind_be_seq",
              "DistinctParamName": "", 
              "DistinctParamValue": "", 
              "UserFeatureConfs": [
                {
                  "FeatureDaoConf": {
                    "LoadFromCacheFeaturesName": "user_v1",
                    "FeatureStore": "user"
                  }
                },
                {
                  "FeatureDaoConf": {
                    "LoadFromCacheFeaturesName": "be_50_seq",
                    "FeatureStore": "user"
                  }
                }
              ]
            },
            "ItemIdName": "item_id"
          }

和上面实时 dssm 的逻辑是一致的。

  • TriggerType = user_realtime_embedding_mind, 固定值

  • UserFeatureConfs 用户的特征加载逻辑,特征加载参考这里

  • RecallAlgo 模型的名称,在AlgoConfs 里能找到。需要注意, ResponseFuncName 要设置固定值 easyrecUserRealtimeEmbeddingMindResponseFunc

   {
      "Name": "ali_recall_mind_be_seq",
      "Type": "EAS",
      "EasConf": {
        "Processor": "EasyRec",
        "Timeout": 300,
        "ResponseFuncName": "easyrecUserRealtimeEmbeddingMindResponseFunc",
        "EndpointType": "DIRECT",
        "Url": "http://1301055674620248.vpc.cn-hangzhou.pai-eas.aliyuncs.com/api/predict/ali_recall_mind_be_seq",
        "Auth": "YTcwZGU1ZTI4NGJmN2Y5ZmViM2Q0MDM4ZDczOTJmNDhlZmUzYzdiOQ=="
      }
    }
  • EmbeddingNum 告诉模型返回的 item 的数量

  • DistinctParamName 打散参数名称

  • DistinctParamValue 打散参数配置, 会构造 BE 请求键值对 {DistinctParamName}={DistinctParamValue}

过滤规则

BE 引擎在召回的过程中,也可以根据一定的规则进行数据过滤,比如常见的曝光过滤。比如上面的例子中,我们设置

 "BeFilterNames": [
          "UserExposureFilter",
          "BizBlacklistFilter"
        ]

UserExposureFilter 就是曝光过滤的名称,BizBlacklistFilter 是自定义过滤规则的名称。

曝光过滤

通常的做法,在 BE 中就能进行数据过滤。在数据回流中,写入到 BE 中,在召回数据时,自然会过滤数据。但是通过数据回流是有一定的延迟性的,如果想及时的过滤掉下发的数据,我们需要借助外部的存储,把短时间内下发的数据存储起来,每次进行召回时,需要把过滤的数据获取到实时的传给 BE , BE 会进行实时的过滤。

"BeFilterConfs": [
    {
      "Name": "UserExposureFilter",
      "FilterType": "User2ItemExposureFilter",
      "MaxItems": 50,
      "TimeInterval": 600,
      "WriteLog": true,
      "DaoConf": {
        "AdapterType": "hologres",
        "HologresName": "pairec-holo",
        "HologresTableName": "exposure_history_prepub"
      }
    }
  ]

这里的曝光过滤和这里的类似,只不过需要定义在 BeFilterConfs 中。

  • Name 自定义的曝光过滤名称

  • FilterType 过滤类型,固定值 User2ItemExposureFilter

  • MaxItems 获取最近的条目批次数量,相当于 limit ${MaxItems}, MaxItems 这里不是指的具体的 item 数量, 而是批次的概念,也就是说一次推荐请求算作是一次,和一次请求里有多个具体的物料 item 无关

  • TimeInterval 按照时间戳取最近的过滤条目。 create_time >= ${current_time - TimeInterval }

  • WriteLog 是否写入曝光日志。

  • DaoConf 曝光表的定义

自定义过滤

有些时候,需要自定义过滤规则来通过 BE 实现,过滤规则通过 KV 结构传到 BE 侧。 PAI-REC 引擎支持自定义的过滤规则。需要实现以下接口

type IBeFilter interface {
	BuildQueryParams(user *module.User, context *context.RecommendContext) map[string]string
}

实现接口后,通过 AddStartHook 进行注册

pairec.AddStartHook(func() error {

		berecall.RegisterFilter("BizBlacklistFilter", &befilter.BizBlacklistFilter{})

		return nil
	})

BE AB 参数的支持

BE 也会支持一些自定义参数来支持召回逻辑的调整。在传给 BE 时,需要设置好相关的 KV 参数。 引擎也支持这类规则的设置。

"BeABParams":{ 
  "click_filter_secs": 3600,
  "click_filter_count": 500
}

配置中心AB 实验参数的支持

在引擎侧可以配置 BE 相关的配置,但是我们希望在 AB 实验上也能灵活的支持相关的召回实验,在引擎侧,我们也预定了一些实验参数来更方便的设置。

参数名称

参数类型

参数说明

样例

“recall.” + be 召回名称 + “.beABParams”

json object

BE AB 参数的设置,需要注意的是,这里beABParams 会全面覆盖引擎侧的配置

“recall.BeRecallV3.beABParams”:{“expose_filter_count”:5000}

“recall.” + be 召回名称 + “.includeRecalls”

json array

包含的子路召回的列表

“recall.BeRecallV3.includeRecalls”:[“etrec_i2i”]

“recall.” + be 召回名称 + “.excludeRecalls”

json array

排除子路召回的列表

“recall.BeRecallV3.excludeRecalls”:[“etrec_i2i”]

“recall.” + be 召回名称 + “.” + 子路召回的名称

json object

某一路子路的召回配置

“recall.BeRecallV3.etrec_i2i”:{
“Count”: 75,
“RecallType”: “x2i_recall”,
“RecallName”: “etrec_i2i”,
“TriggerType”: “u2i_realtime”,
“RecallTableName”: “ali_rec_sln_etrec_i2i_item_score_be_vertical”,
“UserTriggerDaoConf”: {
“AdapterType”: “hologres”,
“HologresName”: “pairec-holo”,
“HologresTableName”: “user_realtime_behavior_holo”,
“WhereClause”: “”,
“Limit”: 50,
“TriggerCount”: 10,
“EventPlayTime”: “”,
“EventWeight”: “click:1;pre_go:2;add_collection:3;go:4”,
“WeightExpression”: “exp(-0.2 * (currentTime-eventTime)/3600/24)”,
“WeightMode”: “max”,
“PropertyFields”:[“root_brand_id”, “root_category_id”, “child_brand_id”, “child_brand_id_new”, “child_category_id”, “vertical_id”],
“NoUsePlayTimeField”: true,
“DiversityRules”:[
{
“Dimensions”:[“vertical_id”],
”Size”:4
},
{
“Dimensions”:[“child_brand_id_new”],
”Size”:1
}
]
},
“ItemIdName”: “item_id”,
“UserTriggerRulesConf”:{
“DefaultValue”:5,
“TriggerCounts”:[20, 15, 10]
},
”TriggerIdName”:”trigger_id”
}

具体的实例来详细的说明下。

  • 假设 BeRecall 的配置中有 be ab 参数的设置

"BeABParams":{ 
  "click_filter_secs": 3600,
  "click_filter_count": 500
}

如果希望在实验中进行调整,可以这样设置

"recall.BeRecall.beABParams":{
  "click_filter_secs": 7200,
  "click_filter_count": 1000
}
  • BeRecall 包含很多路召回,但在某个实验中只想包含 retarget_u2i, etrec_u2i, offline_etrec_u2i, global_hot 这几路召回,可以这样设置

"recall.BeRecall.includeRecalls":[
"etrec_i2i",
"retarget_u2i",
"offline_etrec_u2i",
"global_hot"
]
  • 如果只想排除某些路召回,可以这样设置

"recall.BeRecall.excludeRecalls":[
"retarget_u2i",
"global_hot"
]
  • 假设 etrec_u2i 配置如下

 {
            "Count": 75,
            "RecallType": "x2i_recall",
            "RecallName": "etrec_i2i",
            "TriggerType": "u2i_realtime",
            "UserTriggerDaoConf": {
              "AdapterType": "hologres",
              "HologresName": "pairec-holo",
              "HologresTableName": "user_realtime_behavior_holo",
              "WhereClause": "",
              "Limit": 50,
              "TriggerCount": 20,
              "EventPlayTime": "",
              "EventWeight": "click:1;pre_go:2;add_collection:3;go:4",
              "WeightExpression": "exp(-0.2 * (currentTime-eventTime)/3600/24)",
              "NoUsePlayTimeField": true
            }
          }

但希望在实验中,对 etrec_i2i 这一路召回增加打散相关的配置。我们可以把调整后的配置都放到实验参数里。可以这样设置

 "recall.BeRecall.etrec_i2i": {
            "Count": 75,
            "RecallType": "x2i_recall",
            "RecallName": "etrec_i2i",
            "TriggerType": "u2i_realtime",
            "UserTriggerDaoConf": {
              "AdapterType": "hologres",
              "HologresName": "pairec-holo",
              "HologresTableName": "user_realtime_behavior_holo",
              "WhereClause": "",
              "Limit": 50,
              "TriggerCount": 20,
              "EventPlayTime": "",
              "EventWeight": "click:1;pre_go:2;add_collection:3;go:4",
              "WeightExpression": "exp(-0.2 * (currentTime-eventTime)/3600/24)",
              "NoUsePlayTimeField": true
            },
             "PropertyFields": [
                "child_brand_id_new",
                "root_brand_id",
                "child_category_id",
                "vertical_id"
              ],
              "DiversityRules": [
                {
                  "Dimensions": [
                    "vertical_id"
                  ],
                  "Size": 10
                },
                {
                  "Dimensions": [
                    "child_category_id"
                  ],
                  "Size": 5
                },
                {
                  "Dimensions": [
                    "root_brand_id"
                  ],
                  "Size": 3
                },
                {
                  "Dimensions": [
                    "child_brand_id_new"
                  ],
                  "Size": 2
                }
              ]
            },
            "ItemIdName": "item_id",
            "TriggerIdName": "trigger_id",
            "UserTriggerRulesConf": {
              "DefaultValue": 3,
              "TriggerCounts": [
                7,
                7,
                6,
                5,
                5,
                3
              ]
            }
          }