A/B 服务集成¶
集成 A/B 实验功能¶
设置当前环境,环境的值为 daily, prepub, product。 有两种方式设置
a. 在 config.json 里设置 RunMode b. 设置环境变量 PAIREC_ENVIRONMENT, 环境变量的优先级更高
设置 abtest config, 在 config.json 里增加配置
"ABTestConf":{
"Host":"http://xxx",
"Token" : "xxxx" // 如果 ab server 是部署到 eas 上的, 需要配置
}
只要有此值,就是创建 ABTest client, 启动是如果报错, 直接 panic
3.pairec 本身已经预定了一些实验参数,设置实验参数,需要完全按照参数名称的规则来,否则匹配了实验,也找不到对应的参数
参数名称 |
参数类型 |
参数说明 |
样例 |
---|---|---|---|
类目+ “.RecallNames” |
json array |
召回的列表,需要包含所有的召回 |
“default.RecallNames”:[ “HomepageEtrecRecall”**, **”HomepageDssmRecall”] |
“recall.” + 具体的recall name |
json object |
根据 recall config , 创建新的 recall |
{“recall.MyRecall”:{“version”:”v2”}} |
filterNames |
json array |
过滤列表,包含所有的过滤流程 |
{“filterNames”:[“UniqueFilter”, “UserExposureFilter”]} |
rankconf |
recconf.RankConfig |
排序算法的配置 |
“rankconf”:{“RankAlgoList”:[“pai_homepage_fm”],”RankScore”:”${pai_homepage_fm}”} |
features.scene.name |
string |
Features load 对应的场景名称 |
“homepagetf” |
user_features.scene.name |
string |
User Features 预期对应的场景名称,预期功能参考这里 |
“Home_feed” |
类目+ “.SortNames” |
json array |
排序模块的列表,需要包含所有排序的模块名称 |
“default.SortNames”: [ |
“sort.” + 具体的sort name |
json object |
根据sort config 创建新的 sort |
{ |
generalRankConf |
recconf.GeneralRankConfig |
粗排的配置, 包括 user feature 的获取,算法配置 RankConf, 详细配置参考这里 |
{“generalRankConf”:{“FeatureLoadConfs”:[{“FeatureDaoConf”:{}}],”RankConf”:{},”ActionConfs”:[]}} |
coldStartGeneralRankConf |
recconf.ColdStartGeneralRankConfig |
冷启动粗排配置, 详细配置参考这里 |
{“coldStartGeneralRankConf”:{“FeatureLoadConfs”:[{“FeatureDaoConf”:{}}],”RankConf”:{},”ActionConfs”:[]}} |
coldStartRankConf |
recconf.ColdStartRankConfig |
冷启动召回,rank 阶段配置,指定 rank 算法 |
{“coldStartRankConf”:{“RecallName”:”ColdStartRecall”, “AlgoName”:”linucb”}} |
4.每次请求来,都需要匹配实验,构造好实验上下文。代码如下
func (c *HomeFeedController) makeRecommendContext() {
c.context = context.NewRecommendContext()
c.context.Size = c.param.Limit
c.context.Param = &c.param
c.context.RecommendId = c.RequestId
c.context.Config = recconf.Config
c.context.Debug = c.param.Debug
abcontext := model.ExperimentContext{
Uid: c.param.DistinctId,
RequestId: c.RequestId,
FilterParams: map[string]interface{}{},
}
if abtest.GetExperimentClient() != nil {
c.context.ExperimentResult = abtest.GetExperimentClient().MatchExperiment(c.param.SceneId, &abcontext)
log.Info(c.context.ExperimentResult.Info())
}
}
5.用户代码调整实验参数,只有 RecommendContext 对象,都能通过 context.ExperimentResult 获取到。
count := r.recallCount
if context.ExperimentResult != nil {
count = context.ExperimentResult.GetLayerParams("").GetInt("recall.base.count", count)
}
fmt.Println("test count", count)
GetLayerParams 获取某一层上的实验参数,可以通过 Get, GetInt, GetFloat, GetInt64 获取参数,第一个参数是参数名称,第二个参数是默认值,如果没有找到的情况下,返回默认值
6.有时我们需要对某一个具体的召回做实验,通过不同的参数来调整 recall 的配置。之前的做法
对某一个具体的参数值当做实验参数,如果有多个实验参数的话,需要配置多个
在 config 中新增一个 recall 配置,在实验参数中引用全新的 recall name
目前支持新的方式,在实验中可以配置一组实验参数,pairec 在运行中,根据已有的recall 名称,clone 出新实例,新实例接受这组实验参数。 为了实现这一目的,需要遵循以下规则
实验参数名称为 “recall.”(固定前缀) + 已有的 recall name。
参数配置必须是 json map 的形式
已有的 recall 必须实现 CloneWithConfig 方法,接受参数列表,返回具体的 recall 实例。 例如
type MyRecall struct {
version string
}
func NewMyRecall() *MyRecall {
r := MyRecall{version: "v1"}
return &r
}
func (m *MyRecall) CloneWithConfig(params map[string]interface{}) *MyRecall {
r := MyRecall{}
if _, ok := params["version"]; ok {
r.version = params["version"].(string)
}
return &r
}
原理实现: 召回运行时,首先检查召回相关的实验参数,如果有,根据已有的召回实例反射调用 CloneWithConfig 方法,传入实验参数从而生成新的召回实例。新的召回实例会注册到系统中,如果下次调用,直接返回已有的实例,而无需重新创建。
集成 A/B 参数功能¶
使用方式
// 获取到具体的场景名称
scene := context.GetParameter("scene").(string)
// 根据场景获取参数列表,然后用具体的 Get* function 获取具体的参数值
count := abtest.GetParams(scene).GetInt("count", 100)
fmt.Println("recall count:", count)