在前面的文章中,我们实现了召回和排序,接下来将进入推荐逻辑处理阶段,通常称为推荐中心,推荐中心负责接收应用系统的推荐请求,读取召回和排序的结果并进行调整,最后返回给应用系统。推荐中心的调用流程如下所示:
推荐接口设计
通常推荐接口包括 Feed 流推荐和相似文章推荐
- Feed 流推荐:根据用户偏好,获取推荐文章列表(这里的时间戳用于区分是刷新推荐列表还是查看历史推荐列表) 参数:用户 ID,频道 ID,推荐文章数量,请求推荐的时间戳 结果:曝光参数,每篇文章的行为埋点参数,上一条推荐的时间戳
- 相似文章推荐:当用户浏览某文章时,获取该文章的相似文章列表 参数:文章 ID,推荐文章数量 结果:文章 ID 列表
行为埋点参数:
{ "param": '{"action": "exposure", "userId": 1, "articleId": [1,2,3,4], "algorithmCombine": "c1"}', "recommends": [ {"article_id": 1, "param": {"click": "{"action": "click", "userId": "1", "articleId": 1, "algorithmCombine": 'c1'}", "collect": "...", "share": "...","read":"..."}}, {"article_id": 2, "param": {"click": "...", "collect": "...", "share": "...", "read":"..."}}, {"article_id": 3, "param": {"click": "...", "collect": "...", "share": "...", "read":"..."}}, {"article_id": 4, "param": {"click": "...", "collect": "...", "share": "...", "read":"..."}} ] "timestamp": 1546391572}
这里接口采用 gRPC 框架,在 user_reco.proto 文件中定义 Protobuf 序列化协议,其中定义了 Feed 流推荐接口:rpc user_recommend(User) returns (Track) {} 和相似文章接口:rpc article_recommend(Article) returns(Similar) {}
syntax = "proto3";message User { string user_id = 1; int32 channel_id = 2; int32 article_num = 3; int64 time_stamp = 4;}// int32 ---> int64 article_idmessage Article { int64 article_id = 1; int32 article_num = 2;}message param2 { string click = 1; string collect = 2; string share = 3; string read = 4;}message param1 { int64 article_id = 1; param2 params = 2;}message Track { string exposure = 1; repeated param1 recommends = 2; int64 time_stamp = 3;}message Similar { repeated int64 article_id = 1;}service UserRecommend { rpc user_recommend(User) returns (Track) {} rpc article_recommend(Article) returns(Similar) {}}
接着,通过如下命令生成服务端文件 user_reco_pb2.py 和客户端文件 user_reco_pb2_grpc.py
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. user_reco.proto
定义参数解析类,用于解析推荐请求的参数,包括用户 ID、频道 ID、文章数量、请求时间戳以及算法名称
class Temp(object): user_id = -10 channel_id = -10 article_num = -10 time_stamp = -10 algo = ""
定义封装埋点参数方法,其中参数 res 为推荐结果,参数 temp 为用户请求参数,将推荐结果封装为在 user_reco.proto 文件中定义的 Track 结构,其中携带了文章对埋点参数,包括了事件名称、算法名称以及时间等等,方便后面解析用户对文章对行为信息
def add_track(res, temp): """ 封装埋点参数 :param res: 推荐文章id列表 :param temp: rpc参数 :return: 埋点参数 文章列表参数 单文章参数 """ # 添加埋点参数 track = {} # 准备曝光参数 # 全部字符串形式提供,在hive端不会解析问题 _exposure = {"action": "exposure", "userId": temp.user_id, "articleId": json.dumps(res), "algorithmComb