重排配置

更新时间:
复制 MD 格式

重排(Sort)阶段在精排之后进行,在这里可以进行排序以及打散、添加窗口规则等逻辑。

如何配置

重排的配置对应配置总览中的 SortConfs,SortConfs 是一个 []object 结构,可以配置多个重排策略,目前 PAI-Rec 内置的有 BoostScoreSort、BoostScoreByWeight、ItemRankScore、DiversityRuleSort、DPPSort 和 MultiRecallMixSort。

重排公共配置一览

每种重排配置,都会用到公共配置中的一部分,在此统一解释,在单独的重排配置中则不再赘述。

配置示例:

{
    "SortConfs": [
        {
            "Name": "",
            "SortType": ""
        }
    ]
}

字段名

类型

是否必填

描述

Name

string

是

自定义重排名称,可以在 SortNames 中引用

SortType

string

是

排序类型,枚举值

  • ItemRankScore

  • BoostScoreSort

  • DiversityRuleSort

  • DPPSort

  • MultiRecallMixSort

  • TrafficControlSort

提降权重排(BoostScoreSort)

当调用精排模型后,每个 item 会有个模型返回的 score,有时候根据业务运营需求,需要对 score 进行操作,即提降权操作。

提降权操作在设置上分为两部分

  • 设置条件规则,通过 item 或者 user 的某些属性,比如类目,性别等属性来判断是否符合规则条件

  • 设置提降权表达式,目前只支持对 score 设置表达式,比如 score * 1.2, score * 0.5 等等

配置示例

{
    "SortConfs": [
        {
            "Name": "BoostScoreSort",
            "SortType": "BoostScoreSort",
            "Debug": false,
            "BoostScoreConditions": [
                {
                    "Conditions": [
                        {
                            "Name": "sex",
                            "Domain": "item",
                            "Type": "string",
                            "Value": "gender",
                            "Operator": "equal"
                        }
                    ],
                    "Expression": "score * 2"
                }
            ]
        }
    ]
}

上面配置中所表达的意思为:对特征(sex)的值等于male的item,score乘以2。

字段名

类型

是否必填

描述

Name

string

是

自定义 sort 名称

SortType

string

是

重排类型,固定值: BoostScoreSort

Debug

bool

否

测试标记,这里为 true 情况下, 提降权之前的原始 score 会以 org_score 记录到 item 的 properties 中,然后请求中打开 debug 标记,可以看到 item属性值。这只为了方便调试,线上不应该打开

BoostScoreConditions

json array

是

提降权的条件配置,可以配置多个,可以根据不同的条件,进行提降权

  • Conditions

[]FilterParamConfig

是

提降权的条件规则

  • Expression

string

是

提降权 score 的表达式, score 表示当前的物品得分。表达式里可以引用 item 的属性,比如 item_weight 是 item 的属性,表达式可以这样设置: score * item_weight 。

FilterParamConfig 配置如下:

字段名

类型

是否必填

描述

Name

string

是

item 或者 user 的特征名

Domain

string

是

枚举值,item/user。指的是 Name 选项属于 item 特征还是 user 特征,Name 必须在 item 或 user 的 properties 里找到。

Operator

string

是

枚举值:equal/not_equal/in/not_in/greater/greaterThan/less/lessThan/contains/not_contains

Type

string

是

特征的类型

Value

object

是

特征的值

具体的条件设置,可以参考数量调整过滤(AdjustCountFilter)。

权重提降权重排(BoostScoreByWeight)

在对item进行提降权的时候,不同的item可能会有不同的权重,这个权重是item表中的一个字段,需要通过权重字段对score进行提降权。

score的计算公式:weight * item.score

配置示例

{
    "SortConfs": [
        {
            "Name": "BoostScoreByWeight",
            "SortType": "BoostScoreByWeight",
            "TimeInterval": 172800,
            "BoostScoreByWeightDao": {
                "AdapterType": "hologres",
                "HologresName": "pai_rec",
                "HologresTableName": "test",
                "ItemFieldName": "item_id",
                "WeightFieldName": "weight"
            }
        }
    ]
}

BoostScoreByWeightDao

字段名

类型

是否必填

描述

AdapterType

string

是

数据源的类型,当前只支持 hologres

HologresName

string

是

在数据源配置(HologresConfs)中配置好的 holo 的自定义名称,如数据源配置中的 holo_info

HologresTableName

string

是

holo 中 item 权重表的表名

ItemFieldName

string

是

item 权重表的主键

WeightFieldName

string

是

item 权重表中的权重字段

Item分数重排(ItemRankScore)

ItemRankScore 可以通过 item 的 score 对 item 进行倒序排序,这个是引擎内置的,可以直接在 SortNames 中使用。

多样性重排(DiversityRuleSort)

在推荐结果进行输出时,我们除了考虑要抓住用户的兴趣点,还要考虑推荐条目多样性的需求,即不同品类,不同属性的物品可以混合输出。

这里我们配置的规则参考如下:

推荐多样性打散规则

术语定义:

  1. 打散维度:用来打散的item属性,比如类目、作者、Tag等

  2. 打散策略:

    • 最小间隔k,即最多允许某一打散维度连续出现k次。

    • 最多次数m,即在大小为n的窗口内同一打散维度的item不允许出现超过m次。

打散逻辑:

  • 打散规则只在同一次请求的返回结果里做,不需要考虑跨请求的多样性。

  • 可以配置多个打散维度。

  • 可以针对每个打散维度配置多个打散策略,并且每个打散策略可以配置不同的参数(k,m,n)。

配置示例

{
    "SortConfs": [
        {
            "Name": "DiversityRuleSort",
            "SortType": "DiversityRuleSort",
            "DiversitySize": 100,
            "DiversityRules": [
                {
                    "Dimensions": ["spfl"],
                    "WindowSize": 10,
                    "FrequencySize": 1
                }
            ],
            "ExcludeRecalls": [
                "ColdStartVideoVectorRecall",
                "LinUcbRecall_default2"
            ],
            "Conditions": [
                {
                    "Name": "spflPick",
                    "Domain": "user",
                    "Type": "string",
                    "Value": "",
                    "Operator": "equal"
                }
            ]
        }
    ]
}

此重排需要配合 ExcludeRecalls 参数使用。

DiversityRules

字段名

类型

是否必填

描述

Name

string

是

自定义 sort 名称

SortType

string

是

重排类型,固定值:DiversityRuleSort

DiversitySize

int

否

打散的物品数量,默认值为请求的 size 大小

Conditions

[]FilterParamConfig

否

打散规则条件,用户属性符合一定条件下才能走打散规则。具体条件设置,可以参考条件匹配 Operator 示例。这里的条件是根据 user 的属性来设置的,需要设置 Domain = user

ExcludeRecalls

[]string

否

需要排除多样性排序的召回 id 列表

DiversityRules

json array

是

打散规则,可以设置多条规则

  • Dimensions

[]string

是

根据物品 item 的哪些属性进行打散

  • IntervalSize

int

是

控制相同维度的物品出现的次数,上面描述的 k 值

  • WindowSize

int

否

窗口大小, 上面描述的 n 值

  • FrequencySize

int

否

窗口内重复的次数, 上面描述的 m 值

  • Weight

int

否

多样性规则所占的权重

ExclusionRules

json array

否

排除规则,把符合条件的某些物品在相应的位置上排除

  • Positions

[]int

是

物品的输出位置,从1开始。如果接口里请求size=10,位置就是1,2,3...10

  • Conditions

[]FilterParamConfig

是

规则条件。具体条件设置,可以参考条件匹配 Operator 示例。主要针对物品的属性设置。

ExploreItemSize

int

否

默认情况下,如果候选集第一个物品不符合打散规则时,会继续搜索,直至全部搜索完成。此参数控制搜索的候选集数量,如果超过此值,不再搜索

排除规则和搜索深度的示例参考如下

对于tag=t1符合条件的item不应出现在1,2,3,4的输出位置上,1,2,3,4出现的物品还是要符合打散规则,但不能是tag=t1。

{
    "Name": "DiversityRuleSort",
    "SortType": "DiversityRuleSort",
    "DiversityRules": [
        {
            "Dimensions": [
                "tag"
            ],
            "WindowSize": 5,
            "FrequencySize": 1
        }
    ],
    "ExclusionRules": [
        {
            "Positions": [
                1,2,3,4
            ],
            "Conditions": [
                {
                    "Name": "tag",
                    "Domain": "item",
                    "Type": "string",
                    "Value": "t1",
                    "Operator": "equal"
                }
            ]
        }
    ],
    "ExploreItemSize" : 200
}

在搜索物品满足多样性规则时,在默认情况下,只有当物品满足所有规则时,才会输出。如果任何一条多样性规则不满足时,就会搜索下一个物品,直至找到满足规则的物品。如果候选集中所有的物品都不满足所有规则,那么就会选取最开始的搜索物品进行输出。

目前还提供一种策略,就是给多样性规则上增加权重,如果候选集中所有的物品都不满足所有规则时,会选择物品满足规则权重之和最大的那个进行输出(如果有多个物品满足的话,选择位置最靠前的物品)。

带有权重的配置参考如下:

{
    "Name": "DiversityRuleSort",
    "SortType": "DiversityRuleSort",
    "DiversityRules": [
        {
            "Dimensions": [
                "tag"
            ],
            "WindowSize": 5,
            "FrequencySize": 1,
            "Weight": 1
        },
        {
            "Dimensions": [
                "category"
            ],
            "WindowSize": 3,
            "FrequencySize": 1,
             "Weight": 3
        }
    ],
    "ExclusionRules": [
        {
            "Positions": [
                1
            ],
            "Conditions": [
                {
                    "Name": "tag",
                    "Domain": "item",
                    "Type": "string",
                    "Value": "t1",
                    "Operator": "equal"
                }
            ]
        }
    ]
}

多值维度打散(MultiValueDimensionConf)

默认情况下,打散维度(Dimensions)中的每个 item 属性都按单值处理,即取属性的字符串值做精确匹配来判断两个 item 是否属于同一维度。但有些场景下,item 的某个属性本身是多值的(例如一个商品同时属于多个类目、带有多个标签,如 tag = "sports,news,tech")。此时可以通过 MultiValueDimensionConf 将该维度声明为多值维度,引擎会先按分隔符将属性值切分为多个值,再进行打散判断。

打散判断逻辑:对于多值维度,只要两个 item 在该维度上存在任意一个相同的值,就认为它们在该维度上"相同"(会受打散规则约束);普通(单值)维度仍然是取值完全相等才算相同。当一条打散规则配置了多个 Dimensions 时,需要所有维度都判定为"相同",两个 item 才会被视为同一维度。

配置示例

{
  "SortConfs": [
    {
      "Name": "DiversityRuleSort",
      "SortType": "DiversityRuleSort",
      "DiversityRules": [
        {
          "Dimensions": ["tag"],
          "WindowSize": 5,
          "FrequencySize": 1
        }
      ],
      "MultiValueDimensionConf": [
        {
          "DimensionName": "tag",
          "Delimiter": ","
        }
      ]
    }
  ]
}

上面配置表示:item 的 tag 属性是一个用英文逗号分隔的多值字段(如 "sports,news,tech"),引擎会按逗号切分后进行打散。在大小为 5 的窗口内,只要两个 item 的 tag 中存在任意一个相同的标签,就认为它们重复,最多允许出现 1 次。

字段名

类型

是否必填

描述

DimensionName

string

是

多值维度的名称,需与 DiversityRules.Dimensions 中的某个维度名一致,且该名称必须是 item 的属性名

Delimiter

string

是

多值属性的分隔符,引擎会按该分隔符将属性值切分为多个值,例如英文逗号 ","

说明

  • MultiValueDimensionConf 是对 DiversityRules 中已有维度的补充声明,只有在 Dimensions 中出现过的维度名,在此处配置才会生效。

  • 只需为多值属性配置,未在此列出的维度仍按单值精确匹配处理。

  • 可以同时声明多个多值维度。

多样性重排V2(DiversityRuleSortV2)

DiversityRuleSortV2 是 DiversityRuleSort(V1)的增强版本,在完整继承 V1 所有打散能力的基础上,新增了跨页打散(Cross-Page Diversity)功能,解决了翻页场景下相邻页之间打散规则失效的问题。

与 DiversityRuleSort(V1)的关系

DiversityRuleSortV2 完整继承 V1 的全部能力:

  • 多维度打散规则(Dimensions)

  • 最小间隔策略(IntervalSize)与窗口频率策略(WindowSize / FrequencySize)

  • 规则权重兜底(Weight)

  • 位置排斥规则(ExclusionRules)

  • 召回排除(ExcludeRecalls)

  • 条件触发(Conditions)

  • 搜索深度控制(ExploreItemSize)

  • 多值维度打散(MultiValueDimensionConf)

  • AB 实验参数克隆(CloneWithConfig)

当不配置 CrossPageDiversity 时,V2 的行为与 V1 完全一致。

跨页打散(V2 独有功能)

背景问题

V1 的打散规则只在同一次请求的返回结果内生效。在翻页(下拉加载)场景中,每次请求独立打散,导致前一页尾部与后一页头部可能出现相同类目/属性连续出现的情况,用户体验不佳。

例如:第 1 页最后 3 条都是"数码"类目,第 2 页开头又出现"数码"类目,用户感知上打散失效。

工作原理
  1. 客户端传参:客户端在翻页请求中,将上一页尾部的物品 ID 列表通过请求参数(默认 last_page_item_ids)传递给引擎。

  2. 维度值加载:引擎根据配置的 DiversityDaoConf 数据源,查询这些物品的打散维度值(如类目、作者等)。

  3. 历史预热:将上一页尾部的维度值作为"历史前缀"注入打散规则的匹配窗口。

  4. 约束生效:当前页的打散匹配会将历史前缀纳入计算,确保当前页头部物品与上一页尾部之间也满足打散规则。

注意:历史前缀只影响打散规则的 Match 判定,不会进入最终结果列表,不占用 DiversitySize 名额。
种子策略优化

V1 在打散时,会将候选集的第一个物品无条件放入结果(不经过任何 Match 检查)。V2 在跨页预热成功(warmed=true)时,跳过无条件种子逻辑,所有物品(包括第一个)都必须经过打散规则匹配,确保页首物品也受跨页窗口约束。未预热时,行为与 V1 完全一致。

自动降级
  • 数据源(DAO)构造失败 → 自动关闭跨页打散,退化为 V1 行为

  • 请求中未携带 last_page_item_ids 参数 → 跳过预热,退化为 V1 行为

  • 维度值查询失败 → 跳过预热,退化为 V1 行为

  • 打散维度未被 DistinctFields 覆盖 → 启动时打印 Warning 日志,该维度的跨页预热无效

配置示例

基础配置(等同于 V1)
{
  "SortConfs": [
    {
      "Name": "DiversityRuleSortV2",
      "SortType": "DiversityRuleSortV2",
      "DiversitySize": 100,
      "DiversityRules": [
        {
          "Dimensions": ["category"],
          "WindowSize": 10,
          "FrequencySize": 1
        }
      ],
      "ExcludeRecalls": ["ColdStartRecall"],
      "Conditions": [
        {
          "Name": "user_level",
          "Domain": "user",
          "Type": "string",
          "Value": "vip",
          "Operator": "equal"
        }
      ]
    }
  ]
}
开启跨页打散(V2 独有)
{
  "SortConfs": [
    {
      "Name": "DiversityRuleSortV2",
      "SortType": "DiversityRuleSortV2",
      "DiversitySize": 100,
      "DiversityRules": [
        {
          "Dimensions": ["category"],
          "WindowSize": 6,
          "FrequencySize": 1
        },
        {
          "Dimensions": ["author"],
          "IntervalSize": 2
        }
      ],
      "CrossPageDiversity": {
        "Enable": true,
        "LastItemIdsParam": "last_page_item_ids",
        "DiversityDaoConf": {
          "AdapterType": "featurestore",
          "FeatureStoreName": "my_fs",
          "FeatureStoreViewName": "item_feature_view",
          "DistinctFields": ["category", "author"],
          "CacheTimeInMinutes": 60,
          "CacheSize": 100000
        }
      }
    }
  ]
}

配置字段说明

公共字段(与 V1 一致)

字段名

类型

是否必填

描述

Name

string

是

自定义 sort 名称

SortType

string

是

重排类型,固定值:DiversityRuleSortV2

DiversitySize

int

否

打散的物品数量,默认值为请求的 size 大小

Conditions

[]FilterParamConfig

否

打散规则触发条件,用户属性符合条件时才执行打散。Domain 需设置为 user

ExcludeRecalls

[]string

否

需要排除多样性排序的召回名称列表,被排除的召回物品会追加到结果末尾

ExploreItemSize

int

否

搜索深度控制。默认搜索全部候选集,设置此值后,搜索超过此数量的候选物品后停止搜索

DiversityRules(与 V1 一致)

字段名

类型

是否必填

描述

Dimensions

[]string

是

根据物品 item 的哪些属性进行打散,如 category、author、tag 等

IntervalSize

int

否

最小间隔 k,即最多允许同一打散维度连续出现 k 次

WindowSize

int

否

窗口大小 n

FrequencySize

int

否

窗口内允许的最大重复次数 m,即在大小为 n 的窗口内同一维度不允许出现超过 m 次

Weight

int

否

规则权重。设置后,当所有候选物品都不满足全部规则时,选择满足规则权重之和最大的物品输出

ExclusionRules(与 V1 一致)

字段名

类型

是否必填

描述

Positions

[]int

是

排斥位置列表,从 1 开始。符合条件的物品不会出现在这些位置上

Conditions

[]FilterParamConfig

是

排斥条件,主要针对物品属性设置,Domain 设置为 item

MultiValueDimensionConf(与 V1 一致)

字段名

类型

是否必填

描述

DimensionName

string

是

多值维度的名称,需与 DiversityRules 中的 Dimensions 对应

Delimiter

string

是

多值分隔符,用于将物品属性值拆分为多个值进行打散判断

CrossPageDiversity(V2 独有)

字段名

类型

是否必填

描述

Enable

bool

是

是否开启跨页打散,默认 false

LastItemIdsParam

string

否

请求参数名,用于获取上一页尾部物品 ID 列表。默认值:last_page_item_ids

DiversityDaoConf

object

是

跨页维度值的数据源配置

DiversityDaoConf

字段名

类型

是否必填

描述

AdapterType

string

是

数据源类型,枚举值:hologres / featurestore

HologresName

string

条件必填

AdapterType 为 hologres 时必填,对应数据源配置中的 Hologres 自定义名称

HologresTableName

string

条件必填

AdapterType 为 hologres 时必填,Hologres 中物品属性表名

ItemKeyField

string

条件必填

AdapterType 为 hologres 时必填,物品属性表的主键字段名

FeatureStoreName

string

条件必填

AdapterType 为 featurestore 时必填,FeatureStore 数据源名称

FeatureStoreViewName

string

条件必填

AdapterType 为 featurestore 时必填,FeatureStore 特征视图名称

DistinctFields

[]string

是

需要查询的打散维度字段列表,必须覆盖 DiversityRules 中所有 Dimensions,否则未覆盖的维度跨页预热无效

CacheTimeInMinutes

int

否

维度值在内存中的缓存时间(分钟)

CacheSize

int

否

缓存容量,默认 10000000

客户端接入说明

开启跨页打散后,客户端需要在翻页请求中携带上一页尾部的物品 ID 列表:

  • 参数名:由 LastItemIdsParam 配置,默认 last_page_item_ids

  • 传参方式:通过推荐接口的 features 字段传递

  • 支持格式:

    • JSON 数组字符串:"[\"id1\",\"id2\",\"id3\"]"

    • 逗号分隔字符串:"id1,id2,id3"

    • 数组类型:["id1", "id2", "id3"]

说明
建议:传递上一页尾部 5~10 个物品 ID 即可。引擎内部会根据打散规则的窗口大小自动截取所需的最大数量,多余的 ID 会被忽略。

打散逻辑说明

打散的核心逻辑与 V1 保持一致:

  1. 从候选集中按顺序搜索物品,检查是否满足所有打散规则和排斥规则

  2. 找到满足全部规则的物品后输出,继续搜索下一个

  3. 如果候选集中所有物品都不满足全部规则:

    • 有权重(Weight):选择满足规则权重之和最大的物品输出(多个相同权重取位置最靠前的)

    • 无权重:选择搜索范围内的第一个物品输出

  4. 打散完成后,未参与打散的剩余物品追加到结果末尾

  5. 被 ExcludeRecalls 排除的召回物品追加到最终结果末尾

跨页打散的额外行为:在步骤 1 之前,引擎会加载上一页尾部物品的维度值,将其作为历史前缀注入打散窗口。Match 判定时,窗口扫描范围 = 历史前缀 + 当前页已选物品,从而保证跨页边界的打散效果。

流量调控重排(TrafficControlSort)

流量调控就是通过算法、策略、系统的设计和优化,构建出用来平衡平台利益和长期价值的流量分发系统。

流量调控的优势:

  • 扶持效果好:“流量调控”是基于PaiRec推荐系统架构而开发的流量干预功能,在不扰乱推荐系统整体推荐逻辑的基础上对所选物品池进行精准流量干预。

  • 效果可量化:与传统的“加权”方式相比,“流量调控”功能以物品池的曝光次数、曝光次数占比等可量化的指标为调控的目标,更容易实现定量扶持;

  • 易于管理:“流量调控”以任务为功能单元实现业务诉求,针对不同种类的流量干预需求可以建立不同的“流量调控”任务,这种方式便于灵活管理,您可以随时新建或结束一个任务。

  • 操作简单:您只需要新建并配置任务目标等信息,系统将根据您的配置自动干预流量的分发,不需要您持续观察和监测;

流量调控算法调参指南:调参指南,流量调控详细设置指南:流量调控使用流程

配置示例:

{
    "Name": "TrafficControlSort",
    "SortType": "TrafficControlSort",
    "PIDConf": {
        "DefaultKp": 5,
        "DefaultKi": 1,
        "DefaultKd": 1
    }
}

PID主要计算逻辑:

说明

output = Kp × error + Ki × integralSum + Kd × derivative

dt = 当前测量时间 - 上次测量时间,单位为秒

integralSum += 积分系数 × error × dt

derivative = (当前 error - 上次 error) / dt

PIDConf

说明

Kp、Ki、Kd 三个参数会参与PID公式的计算,并影响结果alpha值的大小,如果只有一个调控任务,只需关注三个参数之间的倍数即可。如果有多个调控任务,多个调控任务的alpha值最终会求和,类似于多个调控任务之间掰手腕来决定谁的调控力度更大,此时 Kp、Ki、Kd 的值最好在同一个量级,如果想让某个任务的调控力度更大,可以适当增大某个任务三个参数的值,可以通过ab实验的方式来具体修改某个任务或者某个目标的参数值。

字段名

类型

是否必填

描述

DefaultKp

Int

否

比例增益。乘以当前误差,误差越大调控越强,是响应主力,默认值1000。

DefaultKi

Int

否

积分增益。乘以累积误差,用来消除稳态偏差(长期没达标就持续加码),默认值10.

DefaultKd

Int

否

微分增益。乘以误差变化率,抑制超调、加快收敛,默认值10。

AllocateExperimentWise

Bool

否

是否按实验分别达标。true=每个实验维护独立 PID 状态;false=整条链路维护一个PID状态。

IntegralMin

Float64

否

默认值:-100。积分下限,限制 integralSum 的最小值,主要用于限制负向积分,防止反向调控长期累积。只有配置值 < 0 时才会覆盖默认值。

IntegralMax

Float64

否

默认值:100.积分上限,限制 integralSum 的最大值,用于防止目标长期未达成时积分持续增长,产生积分饱和,只有配置值 > 0 时才会覆盖默认值。

IntegralThreshold

Float64

否

积分分离阈值。默认值:0,不启用积分分离。当 |error| > IntegralThreshold时,积分项暂停,暂停后:

  • 本轮不继续累计积分;

  • PID 输出不包含已有的 Ki × integralSum;

  • 已有积分不会因此自动清零;

  • 误差重新进入阈值后,已有积分会重新参与输出。

ErrThreshold

Float64

否

变速积分阈值,用于计算当前积分增量系数。当配置为 0,表示不启用变速积分。当配置大于 0,相当于在计算积分总和时,再乘以一个系数。

ErrDiscount

Float64

否

历史积分衰减系数。0 < ErrDiscount <= 1。

  • 1.0 不衰减,完整保留历史积分。

  • 0.9 每轮保留 90% 历史积分。

  • 0.7 每轮保留 70%,衰减较快。

  • 0.3 每轮仅保留 30%,积分很容易被压低。

  • >1 放大历史积分,可能快速饱和,不建议。

  • <=0 不执行未达标积分衰减

MinExpTraffic

Float64

否

按实验调控时的小流量保护阈值。只有同时满足以下条件才生效:

  1. 任务是比例型;

  2. AllocateExperimentWise=true;

  3. 当前实验对应 target 流量低于阈值,或者没有实验流量记录。

满足条件后,控制器不使用该实验的流量数据,而是回退到全局流量数据。

FreezeMinutes

Int

否

每天凌晨的 PID 输出冻结时间,单位为分钟。

当前代码按 Asia/Shanghai 时区计算。

在冻结时间内,不重新计算 PID 输出值,而是返回上次的结果。因为日累计流量在刚跨天时样本量很小,占比和累计目标不稳定。直接使用新一天的早期数据可能导致输出突然变化,因此可以短时间复用上一次输出。

DPPSort

DPP多样性打散算法参考资料:《基于行列式点过程的推荐多样性提升算法的直观理解》。

前提条件:使用DPP算法的前提是已经有了item里的embedding向量,而且这个embedding向量能够表示 item 本身的内容,embedding的相似度能够表示item内容层面的相似度,而不是其他层面(如行为)的相似度。举例如下:

  • 建议:item图片embedding/文本描述信息的embedding/类目、属性等静态item内容组合得到embedding

  • 不建议:基于用户行为数据训练模型得到的embedding

本质上,想要打散的维度一定要能够在embedding里反映出来。比如,我们希望推荐列表在商品价格这个维度有一些多样性,那么在训练模型得到embedding向量时就一定要有价格特征,否则就无法达到我们预期的效果。

配置示例:

{
    "SortConfs": [
        {
            "Name": "DPPSort",
            "SortType": "DPPSort",
            "DPPConf": {
                "Name": "DPPSort",
                "DaoConf": {
                    "AdapterType": "hologres",
                    "HologresName": "geeko_rec"
                },
                "TableName": "item_embedding_metric_learning",
                "TableSuffixParam": "embedding_date",
                "TablePKey": "product_id",
                "EmbeddingColumn": "embedding",
                "Alpha": 4.5,
                "NormalizeEmb": "false",
                "WindowSize": 10
            }
        }
    ]
}

DPPConf

字段名

类型

是否必填

描述

Name

string

是

自定义 sort 名称

DaoConf

DaoConfig

是

配置Hologres相关信息

TableName

string

否

holo中 item的embedding向量表表名;当没有配置EmbeddingHookNames时必填

TableSuffixParam

string

否

不为空时,表示需要去PAI-Rec 引擎服务管理-参数管理 模块获取当前场景下名为该配置项的值,并用获取到的值作为TableName的后缀;用来daily切换向量表名,保持embedding是最新的版本;此时Hologres的表一般需要设置为分区表

TablePKey

string

否

embedding向量表的主键

EmbeddingColumn

string

否

embedding向量表的向量字段名

EmbeddingSeparator

string

否

embedding向量的分隔符,默认为英文逗号

Alpha

float

是

DPP算法用来平衡相关性和多样性的参数;值越大越偏向于相关性

CacheTimeInMinutes

int

否

embedding向量缓存在内存的时间,默认值:360

EmbeddingHookNames

[]string

否

生成item embedding的函数名, 需要提前注册好

NormalizeEmb

string

否

是否需要对embedding向量做L2 normalize;如果生成embedding时已经做了L2 normalize则不需要再做,否则需要配置为true

WindowSize

int

否

多样性算法的翻滚窗口大小;只保证窗口内的item列表的多样性;默认值为10

EmbMissedThreshold

float

否

当缺失embedding的item占比高于该值时报错,默认值为0.5

FilterRetrieveIds

[]string

否

指定不需要调用DPP模块的item列表,如冷启动item

EnsurePositiveSim

string

否

是否需要保证基于embedding计算的item相似度是正值,默认值:true

CandidateCount

int

否

打散候选集的大小,默认为所有进入重排阶段的item数量,可以设定为一个更小的数量,限制候选集为原来Top N个item

AbortRunCount

int

否

若进入重排阶段的item数量小于这个值,则当前请求不做打散,默认值:0

MinScorePercent

float

否

只有在item的最大值归一化后的排序分大于该值时,当前item才有资格被打散模块透出,默认值:0

SSDSort

SSD多样性打散算法参考资料:《提升推荐结果的多样性:MMR/DPP/SSD原理剖析》。

前提条件:使用SSD算法的前提是已经有了item里的embedding向量,而且这个embedding向量能够表示 item 本身的内容,embedding的相似度能够表示item内容层面的相似度,而不是其他层面(如行为)的相似度。举例如下:

建议:item图片embedding/文本描述信息的embedding/类目、属性等静态item内容组合得到embedding

不建议:基于用户行为数据训练模型得到的embedding

本质上,想要打散的维度一定要能够在embedding里反映出来。比如,我们希望推荐列表在商品价格这个维度有一些多样性,那么在训练模型得到embedding向量时就一定要有价格特征,否则就无法达到我们预期的效果。

配置示例:

{
    "SortConfs": [
        {
            "Name": "SSDSort",
            "SortType": "SSDSort",
            "SSDConf": {
                "Name": "SSDSort",
                "DaoConf": {
                    "AdapterType": "hologres",
                    "HologresName": "geeko_rec"
                },
                "TableName": "item_embedding_metric_learning",
                "TablePKey": "item_id",
                "EmbeddingColumn": "embedding",
                "Gamma": 0.25,
                "UseSSDStar": true,
                "NormalizeEmb": "false",
                "MinScorePercent": 0.1,
                "CandidateCount": 200,
                "WindowSize": 5
            }
        }
    ]
}

SSDConf

字段名

类型

是否必填

描述

Name

string

是

自定义sort名称

DaoConf

DaoConfig

是

配置hologres相关信息

TableName

string

否

holo中 item的embedding向量表表名;当没有配置EmbeddingHookNames时必填

TableSuffixParam

string

否

不为空时,表示需要去PAI-Rec 引擎服务管理-参数管理 模块获取当前场景下名为该配置项的值,并用获取到的值作为TableName的后缀;用来daily切换向量表名,保持embedding是最新的版本;此时Hologres的表一般需要设置为分区表

TablePKey

string

否

embedding向量表的主键

EmbeddingColumn

string

否

embedding向量表的向量字段名

EmbeddingSeparator

string

否

embedding向量的分隔符,默认为英文逗号

Gamma

float

是

SSD算法用来平衡相关性和多样性的参数;值越大越偏向于多样性

UseSSDStar

bool

否

是否开启SSD论文中提到的优化算法,默认值:false,建议开启

CacheTimeInMinutes

int

否

embedding向量缓存在内存的时间,默认值:360

EmbeddingHookNames

[]string

否

生成item embedding的函数名, 需要提前注册好

NormalizeEmb

string

否

是否需要对embedding向量做L2 normalize;如果生成embedding时已经做了L2 normalize则不需要再做,否则需要配置为true

WindowSize

int

否

多样性算法的滑动窗口大小;只保证窗口内的item列表的多样性;默认值为5

EmbMissedThreshold

float

否

当缺失embedding的item占比高于该值时报错,默认值为0.5

FilterRetrieveIds

[]string

否

指定不需要调用SSD模块的item列表,如冷启动item

EnsurePositiveSim

string

否

是否需要保证基于embedding计算的item相似度是正值,默认值:true

CandidateCount

int

否

打散候选集的大小,默认为所有进入重排阶段的item数量,可以设定为一个更小的数量,限制候选集为原来Top N个item

AbortRunCount

int

否

若进入重排阶段的item数量小于这个值,则当前请求不做打散,默认值:0

MinScorePercent

float

否

只有在item的最大值归一化后的排序分大于该值时,当前item才有资格被打散模块透出,默认值:0

多路召回重排(MultiRecallMixSort)

一般情况下,我们会有很多路召回,有时根据业务运营需求,需要根据召回的类型进行混合输出,比如

  • 对冷启动召回有曝光数量的要求

  • 多某一路召回有位置的要求

  • 也可以将Item的某个特征作为条件,控制输出位置或数量。

某路召回按照比例输出,如下配置:ColdStartRecall 数量将会占总数量的 10%。

{
    "SortConfs": [
        {
            "Name": "MixSort",
            "SortType": "MultiRecallMixSort",
            "RemainItem": false,
            "MixSortRules": [
                {
                    "MixStrategy": "random_position",
                    "NumberRate": 0.1,
                    "RecallNames": [
                        "ColdStartRecall"
                    ]
                }
            ]
        }
    ]
}

某路召回按照固定位置输出,配置如下:会先选择 GlobalHotRecall 中 score 最高的几个item填充在固定位置,剩余的 item,按照 score 排序,填充在剩余位置。

{
    "SortConfs": [
        {
            "Name": "MixSort",
            "SortType": "MultiRecallMixSort",
            "RemainItem": false,
            "MixSortRules": [
                {
                    "MixStrategy": "fix_position",
                    "Positions": [1,3,5],
                    "RecallNames": [
                        "GlobalHotRecall"
                    ]
                }
            ]
        }
    ]
}

使用条件过滤筛选出 item,然后按比例控制数量。

{
    "SortConfs": [
        {
            "Name": "MixSortByItemFeature",
            "SortType": "MultiRecallMixSort",
            "RemainItem": false,
            "MixSortRules": [
                {
                    "MixStrategy": "random_position",
                    "NumberRate": 0.1,
                    "Conditions": [
                        {
                            "Name": "gender",
                            "Domain": "item",
                            "Type": "string",
                            "Value": "man",
                            "Operator": "equal"
                        }
                    ]
                }
            ]
        }
    ]
}

使用条件过滤筛选出 item,然后按固定位置填充。

{
    "SortConfs": [
        {
            "Name": "MixSortByItemFeature",
            "SortType": "MultiRecallMixSort",
            "RemainItem": false,
            "MixSortRules": [
                {
                    "MixStrategy": "fix_position",
                    "Positions": [3,5,7],
                    "Conditions": [
                        {
                            "Name": "gender",
                            "Domain": "item",
                            "Type": "string",
                            "Value": "man",
                            "Operator": "equal"
                        }
                    ]
                }
            ]
        }
    ]
}
说明

上述配置是把 gender=man,且score最高的几个item优先插入到3,5,7的位置,剩余的item,按照score大小,再填充至其他位置。如果gender=man的item数量比较多,那么在3,5,7之外的位置,也会出现 gender=man的情况。

字段名

类型

是否必填

描述

Name

string

是

自定义 sort 名称

SortType

string

是

重排类型,固定值: MultiRecallMixSort

RemainItem

bool

否

是否保留所有的item , 比如有 500 个 item 需要处理,但我们一次请求假设有 30 个, 当为 false 情况下, item 数量只会保留混排的结果, 当为 true 情况下, 剩余的 item 也保留下来,不过在 30 item 结果的后面。 这样后续还可以再对接 sort 进行进一步控制处理

MixSortRules

json array

是

打散规则,可以设置多个

  • MixStrategy

string

是

混排策略,枚举值:random_position/fix_position

  • random_position:标识位置随机

  • fix_position:标识固定位置,需要指定 Positions

  • Positions

[]int

否

fix_position 的情况下,需要指定 Positions。 Positions 的位置从 1 开始

  • PositionField

string

否

fix_position 的情况下,通过 item 的属性字段获取 Postion。Positions 和 PositionField 冲突,只能设置其中一项

  • Number

int

否

数量的绝对值。

  • NumberRate

float

否

混排物品数量占比,只有MixStrategy=random_position 时设置,有效值为 0 ~ 1, 具体数量通过 请求的Size * NumberRate 算出

  • RecallNames

[]string

否

召回的名称,可以设置多个,设置多个的情况下,共享配置,但是具体哪个召回,不固定,顺序由进入到此 Sort 的位置决定

  • Conditions

[]FilterParamConfig

否

符合匹配条件的物品进行混排。具体条件设置,可以参考条件匹配 Operator 示例。

条件路由重排(ConditionSort)

ConditionSort 支持根据用户属性条件路由到不同的重排策略。当不同用户群体需要使用不同的重排逻辑时,可以通过配置条件规则将请求路由到对应的排序策略,未匹配任何条件时则使用默认排序策略。

条件路由规则按配置顺序依次匹配,命中第一个满足条件的排序策略后即执行该策略,不再继续匹配后续条件。

配置示例参考如下:

{
  "SortConfs": [
    {
      "Name": "ConditionSort",
      "SortType": "ConditionSort",
      "ConditionSortConfs": {
        "SortConfs": [
          {
            "Conditions": [
              {
                "Name": "user_level",
                "Domain": "user",
                "Type": "string",
                "Value": "vip",
                "Operator": "equal"
              }
            ],
            "SortName": "VipDiversitySort"
          },
          {
            "Conditions": [
              {
                "Name": "is_new_user",
                "Domain": "user",
                "Type": "int",
                "Value": 1,
                "Operator": "equal"
              }
            ],
            "SortName": "NewUserBoostSort"
          }
        ],
        "DefaultSortName": "DefaultDiversitySort"
      }
    }
  ]
}

上面配置中所表达的意思为:当用户属性 user_level 等于 vip 时,使用 VipDiversitySort 排序策略;当用户属性 is_new_user 等于 1 时,使用 NewUserBoostSort 排序策略;如果以上条件均不匹配,则使用 DefaultDiversitySort 作为默认排序策略。

字段名

类型

是否必填

描述

Name

string

是

自定义 sort 名称

SortType

string

是

重排类型,固定值:ConditionSort

ConditionSortConfs

object

是

条件路由配置

ConditionSortConfs.SortConfs

json array

是

条件-排序映射列表,按配置顺序依次匹配,命中第一个满足条件的排序策略后停止匹配

ConditionSortConfs.SortConfs[].Conditions

[]FilterParamConfig

否

路由条件规则,为空时该条目不会被匹配,将跳过并继续检查后续条目(最终可能走 DefaultSortName 兜底)

ConditionSortConfs.SortConfs[].SortName

string

是

条件匹配时要执行的排序策略名称,对应其他 SortConfs 中配置的 Name

ConditionSortConfs.DefaultSortName

string

否

默认排序策略名称,当所有条件均不匹配时使用。不配置时,若所有条件均不匹配则不执行任何排序操作

FilterParamConfig 配置如下:

字段名

类型

是否必填

描述

Name

string

是

item 或者 user 的特征名

Domain

string

是

枚举值,item/user。指的是 Name 选项属于 item 特征还是 user 特征,Name 必须在 item 或 user 的 properties 里找到。ConditionSort 中一般设置为 user,根据用户属性进行路由

Operator

string

是

枚举值:equal/not_equal/in/not_in/greater/greaterThan/less/lessThan/contains/not_contains/is_null/is_not_null/bool/expression

Type

string

是

特征的类型

Value

object

是

特征的值

重要
  1. SortName 引用:ConditionSortConfs.SortConfs[].SortName 和 DefaultSortName 引用的排序策略必须是已在 SortConfs 中配置的其他重排策略名称(如 DiversityRuleSort、BoostScoreSort 等)

  2. 匹配顺序:条件按配置顺序依次匹配,第一个命中的策略会被执行,后续条件不再匹配

  3. 默认策略:建议配置 DefaultSortName,确保所有请求都能被路由到合适的排序策略

如何使用

重排配置和召回配置类似,配置好后,提供一个分场景使用的SortNames,SortNames是一个 Map[string]object结构,其中key是场景,每个场景对应一组重排策略

{
    "SortNames": {
        "${scene_name}": [
            "ItemRankScore"
        ]
    }
}
  • ${scene_name} 为场景名,如果多个场景想使用同一份配置,则使用"default"。

  • ItemRankScore:此参数为在SortConfs中定义的重排的自定义名称。