2026年2月2日,凤希AI伴侣的导航栏数据升级项目正式全量上线。坦白说,导航栏这种界面层的东西放在很多产品里就是改个样式,但这次不一样——我们把它从一个静态入口列表,改造成了一套依赖实时数据、由AI动态决策的推荐系统。我参与了这个项目的数据链路改造、算法策略设计和上线复盘,整个过程让我对“AI落地”有了比写模型代码更深刻的认知。这篇内容的初衷,是想把导航栏数据升级背后那些踩过的坑、取舍过的方案、纠结过的指标梳理清楚。如果你正在做类似的产品功能改造,或者团队里正准备把某个AI能力真正放到线上场景里,这篇东西应该能帮你少走不少弯路。
1. 这次升级到底动了什么:导航栏从“入口列表”变成“数据产品”
1.1 旧导航栏的问题:所有用户看到同一份菜单
在升级之前,凤希AI伴侣的底部导航栏是标准的三件套布局:首页、会话、我的。顶部还有一个功能入口区域,放了一些固定的二级入口,比如回忆相册、喜好档案、亲密关系管理等。结构上挺常规,但问题恰恰出在“常规”上。
所有用户看到的入口一模一样,不管你是第一天注册的新用户,还是已经用了两年的深度用户,导航栏都在用同一套逻辑跟你对话。新用户一进来,看到的是“回忆相册”“时光胶囊”这类需要一定使用时长才能产生价值的入口,他根本不知道点进去有什么意义;而老用户要高频使用的“连续对话”“关系梳理”功能,却因为入口层级太深,每次都要多点两三次才能到达。
我们后台的数据也验证了这个判断——部分二级入口的周点击率不到1.5%,但用户访问深度的统计却显示,很多用户会通过搜索框反复找某些功能。这说明不是用户不需要这些功能,而是入口设计在阻碍他们发现价值。导航栏这个产品中位置最显眼、曝光最高的区域,实际转化效率配上它的曝光量,完全不合格。
1.2 新导航栏的数据架构:行为流、画像、上下文信号
这次升级的核心思路,是把导航栏从“静态菜单”变成“动态推荐位”。每个位置的展示内容,不再由配置文件写死,而是由一个实时计算服务根据用户当前的状态动态生成。
整个数据架构分了三层:
- 行为数据层:负责收集用户的点击、浏览、对话、停留时长等事件,统一清洗后写入实时特征存储。
- 画像与状态层:维护用户的长期兴趣标签、功能使用频次、最近活跃时段、关系状态等特征。
- 决策服务层:综合以上特征,通过规则加轻量模型的方式,计算每个候选入口的实时排序,再通过接口下发给客户端。
底层技术上我们选了开源的数据管道方案,事件走消息队列,实时特征计算用流处理框架,特征存储用的内存数据库,线上服务通过接口读取特征并完成推理。这套组合在社区里很成熟,选型的时候我们没有刻意追求新框架,主要看团队维护成本和稳定性。
1.3 为什么选择导航栏作为AI落地的第一站
很多团队做AI落地,喜欢先找一个高大上的场景,比如智能对话、自动生成内容。但我们这次反着来,选了导航栏这个看起来最不起眼的地方。原因很简单:导航栏的决策链路短、效果可测量、试错成本低。
一个推荐式的导航栏,用户点不点击、点了之后有没有继续使用,数据当天就能看到反馈。而且就算排序策略出了问题,最多就是用户少点了一个入口,不会对产品造成破坏性影响。这种低试错成本的场景,特别适合用来验证AI落地的整个闭环:数据采集、特征计算、模型推理、在线评估、快速迭代。
事实证明这个选择是对的。经历了这一轮导航栏数据升级,我们把整个AI在线推荐的基础设施跑通了,后面再做首页信息流推荐、主动推送提醒,都直接复用了这一套数据管道和评估体系。可以说,导航栏是那根撬动整个产品数据化的杠杆。
2. 数据基础与埋点改造:没有干净的数据,AI就是空中楼阁
2.1 埋点方案选型与事件设计
改造前,凤希AI伴侣已经有基础埋点,但维度非常粗,只有页面浏览和应用启动这类系统级事件,完全不够支撑个性化推荐。所以我们第一步做的不是算法,而是重新设计了一套行为事件埋点体系。
事件设计这块,我们踩过不少坑,第一个教训是别只埋点击,要把“曝光”和“点击”分离开。只统计点击的话,你永远不知道用户是因为看到了但不感兴趣才没点,还是压根没看到那个入口。只有同时埋曝光和点击,才能算出真实点击率,也才能区分是推荐不准,还是视觉设计不够吸引人。
事件的数据结构我们定成了一套标准化格式。以导航项的点击事件为例,线上打点数据长这样:
{ "event": "nav_item_click", "user_id": "u_20260202001", "session_id": "s_7fa21c", "item_id": "memories_album", "position": 3, "scene": "home_bottom_nav", "from_rec": true, "timestamp": 1769990400000 }position字段特别重要,它记录了这个入口在导航栏第几位。排序模型上线后,我们靠这个字段分析用户点击率与位置的关系,发现第三位之后点击率断崖式下跌,这个数据直接影响了我们对推荐策略的预期管理——再强的算法也对抗不了位置效应,这在后面评估模型效果时是必须剥离的干扰项。
2.2 数据链路与实时性取舍
埋点设计好之后,接下来是数据链路。最开始的方案是追求极致的实时性,所有行为事件都走实时计算,用户上一个行为发生几百毫秒内就要反映到导航栏。但做了一轮压测之后,我们主动把这个目标降低了一个档次。
原因是:导航栏的使用场景并不要求秒级响应。用户打开App、看到导航栏、做出点击,这中间至少有几百毫秒的感知时间,哪怕推荐结果滞后一两分钟,用户体验上的差异也几乎无感。与其花大量成本去优化实时链路的稳定性,不如把精力放在特征准确性和推荐策略上。
所以我们最终采用了实时和准实时混合的架构:用户每次打开导航栏时,实时拉取当前会话的上下文信号,比如当前所处的聊天场景、最近一条消息的时间;而用户的长期兴趣标签、功能使用频次这类变化较慢的特征,则通过准实时管道每五分钟更新一次,缓存到特征存储中。这样既保证了导航栏能感知到用户当下的状态,又大幅降低了对实时计算集群的压力。
这个取舍在后期帮了大忙,线上服务的依赖变少了,故障率也随之下降。经验就是:实时性需要服务的业务目标来决定,不是越实时越好,实时意味着成本和风险同时上升。
2.3 数据质量治理的实操细节
埋点和链路都跑起来之后,真正开始折磨人的是数据质量。我给你列几个我们实际踩过的场景,你就知道数据这块有多折腾。
首先是会话ID的断裂问题。客户端在某个版本里会频繁重建会话,导致一个完整的用户操作被拆成了好几段,按会话维度统计行为序列时就出现了大量空档。我们花了两种方式兜底,一是客户端不再每次页面切换都重建会话,二是服务端增加了按用户ID加时间窗口拼接行为序列的逻辑。
其次是曝光日志的重复上报。导航栏在页面渲染时会触发曝光回调,但由于异步加载的时序问题,同一个导航项在一个页面周期内最多被上报了三次曝光。这直接导致曝光基数虚高,点击率被稀释得没法看。排查了三天,最后定位到是前端回调函数里少了一个防重复标记。
再就是用户特征里的脏数据。有一个阶段,用户画像里出现了一批异常的“高活跃用户”,表现为每天点击几百次同一入口。后来查到是有少量设备在多开环境下的行为互相写入,通过增加设备指纹校验拦截掉之后,这批脏数据才被清洗干净。
数据治理做得好不好,会直接决定AI模型在线上表现的稳定性。这个环节没有任何捷径可言,必须靠一套靠谱的监控看板加值班排查机制。我个人的体会是:算法可以慢慢优化,但数据准确性的问题一旦爆发,所有下游包括推荐、报表、运营策略都会一起失真,那个代价是最高的。
3. AI排序与个性化推荐:导航栏背后的算法设计
3.1 召回层:候选功能池怎么构建
导航栏空间有限,底部导航只有三个固定槽位,顶部的功能宫格可以放六到八个入口。槽位这么少,候选池就不需要做得特别大,但候选池的构建逻辑直接决定了推荐的上限。
我们的候选池分成两大部分:
固定保底项,任何用户进来都会看到的那几个入口,比如“首页”“会话”“我的”,这是产品的基本骨架,不能因为个性化推荐就随便动,否则用户会失去空间方位感。
动态候选池,这才是AI发挥作用的部分。动态候选来自三个渠道:一是用户最常使用的高频功能,比如某位用户最近每天晚上都会使用“睡前陪伴”模式,这个功能就要进入候选;二是基于当前场景的推荐,比如用户刚刚聊完一段回忆类话题,时关系链路上“回忆相册”的匹配度就会变高;三是运营配置的探索性入口,用来给新功能导流,或者把某些长尾功能重新推到前台。
候选池的召回策略,本质上是在回答一个问题:用户此刻可能想干什么。高频功能捕捉的是稳定偏好,场景匹配捕捉的是即时意图,运营入口捕捉的是产品引导需要。三条召回路径各有目标,最后在排序层汇总时才会有足够的多样性。
3.2 排序层:从规则到轻量模型的演进
排序层一开始我们用的纯规则,后来才切换成轻量模型。这个演进过程比较有代表性,我说得详细一点。
规则版本的逻辑是人工定义几个特征,再加权求和。比如一个入口的排序分,大致由三部分组成:
- 个人亲和度:用户最近30天对该功能的使用频次,加入时间衰减。
- 上下文匹配度:当前会话所处场景与该功能的关联强度,这个关联强度是运营和产品一起人工打分的。
- 新鲜度补偿:近期上线的新功能给一个临时加权,帮助冷启动。
规则版本大概长这样:
def rank_items(context, user_features, item_features): scores = {} for item in item_features: affinity = user_features.get(item, {}).get("affinity", 0) context_match = context.get(item, 0) * 1.2 recency_bonus = item_features.get(item, {}).get("recency_bonus", 0) scores[item] = 0.5 * affinity + 0.35 * context_match + 0.15 * recency_bonus return sorted(scores.items(), key=lambda x: x[1], reverse=True)规则版本的好处是简单、可解释、上线快,我们用了大概三周就上线了。但问题也很快暴露:人工权重很难覆盖复杂的用户行为模式。比如有的用户使用某个功能并不频繁,但在特定时间段使用的意愿非常强烈,规则里很难表达这种组合规律。
所以我们在规则版本稳定后,换成了轻量级的树模型,特征就是前面那几类数据拆出来的几十个特征,训练数据来自线上曝光点击日志,每天自动产出训练集,模型在线下验证AUC达到预期后,再通过模型服务平台灰度推送到线上。
切换到模型版后,一个直观的变化是:排序不再只看使用频次,还能捕捉到很多隐含信号。比如用户在深夜时段对“情绪记录”类功能的偏好,模型自动学到了这种时间交互特征,这在纯规则里几乎没法人工配出来。
3.3 冷启动与探索利用:新用户和长尾功能怎么办
个性化推荐的老问题一定是冷启动,导航栏推荐也不例外。
新用户没有行为历史,画像特征几乎全空,直接套模型只能输出平均结果,相当于随机排序。我们处理冷启动的方案是分层的:
- 第一阶段:新用户前三天看到的是运营和产品共同配置的“新手引导版导航栏”,入口顺序由功能的教育成本决定,最简单的功能在前。
- 第二阶段:有了少量行为数据后,进入“规则兜底版”,按当天点击行为做加权。
- 第三阶段:累计行为超过一定阈值后,进入正常的模型排序。
这套分层策略本质上是在承认:冷启动阶段没有数据,再强的模型也白搭,不如用一套稳定的引导逻辑先把用户留住了再说。
长尾功能的探索这块,我们单独设置了一个探索概率。具体做法是,排序时给每个功能一个基础探索权重,这个权重跟功能自身的曝光量挂钩,曝光越少的功能探索权重越高,再用一个全局系数控制探索的整体比例。这样既能保证大部分用户看到的是适合他们的功能,又能保证一小部分流量用于尝试长尾功能和验证新入口的价值。
探索比例我们一开始设了15%,上线几天后发现整体点击率被拉低了1个百分点,后来压到了8%。这个数值没有标准答案,取决于产品对新功能冷启动的迫切程度和核心指标的容忍度。建议你上线时从低往高调,先用小流量验证探索收益,不要一上来就设个大比例,不然业务方会很慌。
4. 上线评估与效果复盘:指标怎么定、坑怎么排
4.1 指标体系和实验设计
导航栏数据升级的评估,不能只看点击率这一个数。点击率上去了,但如果用户点进去之后发现不是想要的,反而伤害体验。所以我们设计了一组分层的指标体系。
过程指标:曝光率、点击率、点击后停留时长、点击后功能完成率。这组指标衡量直接的转化效率。
结果指标:功能使用渗透率、次月留存率、人均会话轮次。这组指标衡量导航栏升级对产品整体健康度的影响。
体验指标:用户反馈、主动关闭推荐、重置导航栏的比例。我们专门做了一个“恢复默认设置”的入口,这个行为一旦出现,基本可以判定用户对个性化推荐不满意,这个信号比任何调研都真实。
实验设计上,我们没有搞全量上线,而是按用户ID做了分层分流实验。实验组用新导航栏,对照组用旧导航栏,两组的用户画像分布保持均衡。为了排除导航栏顺序变化带来的干扰,我们统计点击率时做了位置因素校准,也就是分位置分层看点击率,避免实验组因为推荐把高价值功能排到了第一位,产生虚假的点击率提升。
这个过程里反复提醒自己的是:AI推荐类的实验,最容易出的问题就是“因为变了所以好了”,而不是“因为推荐合理所以好了”。位置效应、新奇效应、选择性偏差,每一项都可能在数据里伪装成胜利,所以评估体系在设计上就要尽可能把这些因素剥离开。
4.2 线上排查实录:一组常见问题排查表
上线过程中遇到的问题五花八门,我挑几个最有代表性的整理成了速查表,方便你遇到类似问题时对照排查。
| 问题现象 | 可能原因 | 排查方向与解决方案 |
|---|---|---|
| 导航栏推荐结果长时间不变 | 用户特征缓存未刷新或更新任务异常 | 检查准实时特征管道的调度日志,确认上游行为数据是否正常写入 |
| 部分用户强烈排斥个性化入口 | 个性化排序把用户不熟悉的功能排到了前面 | 增加用户主动反馈入口,同时调低探索比例,增加历史高频功能的权重 |
| 实验组点击率提升但使用深度下降 | 位置效应导致高频功能前置,用户点击了但不一定真正需要 | 引入点击后完成率指标,分层对比同一入口的转化差异 |
| 模型推理耗时波动大 | 特征存储热点导致超时 | 增加缓存分层,把高频特征放到本地缓存,减少对远程存储的依赖 |
| 新用户弹窗误触导航推荐 | 冷启动策略版本异常,新手导航被模型接管 | 在冷启动分层逻辑里增加账号年龄条件,未满三天的用户直接走固定导航 |
有一类问题特别容易忽视,就是模型和数据管道之间的“时间不同步”。比如模型用了当天某个时段的事件做特征,但数据管道因为重放机制,把同一个事件重复灌进了特征里,导致特征值异常放大。我们赶上过一次,当时排序结果明显偏向某个功能,查了大半天才发现是消息队列重复消费,而不是模型本身出了问题。这种问题很难靠模型侧修复,必须把数据管道的幂等性做扎实。
4.3 可解释性与用户信任的平衡
导航栏加了AI推荐之后,我们其实面临一个隐形压力:用户能不能理解导航栏的顺序变化。普通的个性化推荐系统,比如电商首页,用户对推荐结果是有预期的,但在工具属性更强的AI伴侣产品里,导航栏被用户默认为“固定的功能分布”,一旦变化幅度过大,用户会产生一种掌控感丧失的焦虑。
针对这个心理预期,我们做了两个设计。第一,控制“推荐扰动幅度”,单次更新最多调换两个动态槽位的位置,底部固定导航原则上不动,避免用户每次打开看到的整个界面都在跳。第二,在导航栏下方增加一行小字解释,类似“根据你的使用习惯为你调整了入口”,当入口变化发生时才会出现,让用户明白这个变化不是产品出了bug,而是有逻辑的主动调整。
这两件事投入不大,但对数据指标的影响很明显。上线初期我们做过一次对比,加了差异化说明文案的实验组,用户的主动反馈率和对个性化功能的满意度都有明显提升。这说明不管算法多聪明,不给用户一个理解它的入口,诚意就会打折扣。
5. 深度思考:AI落地的真正门槛不在模型,而在数据与场景
5.1 为什么很多AI功能上线即死
过去一年里,我看到很多团队在热门方向上一拥而上,但真正能在线上稳定跑起来的少之又少。做导航栏这个项目的过程中,我对这种现象有了更具体的理解。
很多AI功能上线即死,说起来原因无非是三个:第一,数据基础根本没打好,特征缺失、埋点混乱、样本集分布跟线上不一致,导致模型在离线评估时挺好看,一上线上就放飞自我。第二,场景选得不对,用了大量资源去解决一个用户压根不痛的问题,比如在用户刚进入产品时就推一堆复杂的AI能力,违背了用户这一秒的心理状态。第三,没有把AI当成一个系统来设计,只做了模型推理这一环,没有围绕它建立反馈闭环、监控预警、异常兜底。
就拿导航栏这种最朴素的场景来说,它看起来简单,但只有AI模型远远不够,得有数据采集、特征存储、候选召回、排序推理、在线评估、问题监控一整套配套系统。AI落地从来不是训练一个模型那么简单,它是把数据、场景、模型、工程、评估凝合成一个整体。任何一个环节断裂,项目都会变成“上线即死”的另一个案例。
5.2 数据、场景、模型优先级怎么排
如果一定要给优先级排个序,我在这轮升级里的体会是:场景需求优先,其次数据建设,最后才是模型复杂度。
场景需求优先的意思,是先从产品和用户行为中找到真正值得被AI优化的那个缺口。选择导航栏不是因为AI适合做导航,而是因为这个位置曝光高、转化差、用户有真实诉求,有需求才值得投入。
数据建设优先于模型,是因为没有数据支撑的模型等于无米之炊。我们前期花了接近一半的时间在埋点、清洗、特征工程和数据监控上,直到这套数据管道稳定跑了两周之后,才开始正式训练排序模型。那段时间团队内部也有点焦虑,觉得怎么还没开始写模型代码,但后来所有效果上的突破,都离不开前期投入的数据地基。
模型复杂度这个事最不需要焦虑。导航栏排序在早期用规则就已经比静态导航提升明显了,后面换树模型,是在规则基础上再进一步。先解决“从无到有”,再解决“从有到优”,这个次序不要搞反。一上来就上大模型、深度学习,往往是在没有稳定数据和反馈闭环的情况下自娱自乐。
5.3 后续演进方向
这次导航栏数据升级留下的基础设施,对凤希AI伴侣后续的产品演进作用很大。行为数据管道和特征平台已经能支撑更多场景的个性化能力,导航栏排序模型沉淀下来的特征工程经验,也完全可以复用到信息流推荐、主动提醒等方向。
我们列了几个可能的演进方向,供同样在做AI产品创新的团队参考。
第一,从导航栏推荐走向全局个性化体验。未来不只是入口列表动态化,首页的内容卡片、聊天里的引导提示,都可以基于同一套用户意图理解来驱动。
第二,从被动推荐走向主动服务。有了用户状态和场景识别的能力之后,产品可以考虑在合适的时机主动触发服务,而不是等用户点进来才响应。这个方向对数据实时性的要求会比导航栏高不少,但这套底座已经验证过了。
第三,让推荐系统具备更深层的关系感知。AI伴侣是强关系型产品,用户的使用场景往往跟情感状态、关系周期密切相关。导航栏只是入口层的浅层个性化,更深的价值在理解用户处于哪个阶段、当前最需要什么样的陪伴方式,把这些理解变成产品逻辑。
顺着这个思路往下走,导航栏数据升级就不只是一个界面改造项目,它是整个产品走向“更好的AI落地”的那个起点。技术选型上我们没有用到什么论文级别的方法,反而大量的时间花在了数据质量、评估口径、用户信任这些看似不起眼的事上。如果你正在准备类似的升级,我建议你也把注意力放在这些基础环节上,花同样的时间,得到的收益会比多调几个模型参数实在得多。最后分享一个小小的实操经验:每次改版上线前,一定要在测试环境里用真实的用户行为序列跑一遍全链路,别只造几条理想化的样本数据去验证。真实数据里那些异常值、缺失值、重复项,才是线上事故最常出现的源头。能在上线前用这些问题数据提前炸一炸系统,上线后就会从容很多。