信息茧房指的是用户在推荐系统长期反馈循环中,被越来越多同质化内容包围,视野逐渐收窄的现象。电商场景里表现为一直推同类商品,内容社区里表现为只看到同一话题的文章。这背后既有模型层面的原因——CTR模型天然会放大用户历史行为中的主流偏好,也有产品层面的原因——点击率导向的排序目标让长尾内容几乎没有曝光机会。要打破这个恶性循环,核心思路有两条:一是在最终排序结果里主动注入多样性,二是在流量分发阶段保留一定的探索预算,让系统有机会发现用户的潜在兴趣。

为什么推荐系统会陷入信息茧房
理解成因才能对症下药。推荐系统的训练数据来自用户的历史行为,而用户行为又被上一轮推荐结果所影响,这形成了一个典型的反馈回路。模型学到的分布,其实是系统自己制造出来的分布。当一个用户点了几条宠物视频,模型迅速提高宠物类内容的预估分,下一轮列表里宠物视频占比更高,用户点击宠物视频的概率也更大,如此循环,其他品类的内容被持续挤出曝光队列。
第二个原因是排序目标的单一化。绝大多数线上系统以点击率或者预估消费时长作为唯一排序依据,这类指标无法反映内容同质性带来的体验损耗。用户可能今天点了十条视频,但第二天就因为内容重复而流失。从长期留存的视角看,短期CTR指标的过度优化反而是有害的。
第三个原因在于召回通道的坍缩。多路召回中,个性化召回(比如协同过滤、双塔向量召回)的占比不断提升,热门兜底和随机探索通道被逐步压缩,召回结果本身就失去了多样性,后面排序层再怎么处理,候选池的多样性天花板已经定死了。
多样性注入:在重排阶段打散结果
多样性注入最直接的落地点是重排层,也就是在精排输出有序列表之后,对整个列表做一次二次编排。业界最经典的算法是MMR(Maximal Marginal Relevance),它的核心思想是每一步选择内容时,不只看相关性得分,还要惩罚与已选内容过于相似的候选。
def mmr(candidates, relevance_scores, sim_matrix, lambda_=0.7, k=10):
# candidates: 候选内容id列表
# relevance_scores: 精排相关性得分
# sim_matrix: 内容间相似度矩阵,可基于类目、标签或embedding计算
selected = []
remaining = list(range(len(candidates)))
while len(selected) < k and remaining:
best_idx, best_score = None, -float('inf')
for i in remaining:
max_sim = max([sim_matrix[i][j] for j in selected], default=0)
mmr_score = lambda_ * relevance_scores[i] - (1 - lambda_) * max_sim
if mmr_score > best_score:
best_score, best_idx = mmr_score, i
selected.append(best_idx)
remaining.remove(best_idx)
return [candidates[i] for i in selected]
参数lambda_控制准确性与多样性的权衡,取值越大多样性惩罚越弱。实际调参时建议从0.7起步,通过线上A/B实验观察CTR和用户次日留存的联合变化,找到一个留存提升而CTR跌幅可接受的位置。需要注意的是相似度矩阵的构建质量直接决定MMR效果,只用品类或标签计算相似度粒度太粗,用内容embedding的余弦相似度效果通常更好,但要控制好embedding的维度和计算开销。
MMR是贪心算法,复杂度可控但全局最优性没有保证。如果想追求更高质量,可以考虑DPP(Determinantal Point Process,行列式点过程)。DPP把一个候选集合的多样性用核矩阵行列式来度量,通过最大化行列式来选取一个既相关又多样的子集。DPP在YouTube和华为等公司的实践中都有落地报告,效果普遍优于简单打散规则,代价是计算行列式需要一定的工程优化,比如用贪心的快速近似算法把复杂度从立方级降下来。
除了算法层面,工程上还有一类简单有效的规则打散手段,比如滑窗约束——同一个二级类目在任意连续6个位置内最多出现2次;同作者约束——同一作者内容在首屏最多出现1条。这类规则实现成本低、可解释性强,很多团队的做法是规则打散做兜底,MMR或DPP做增益,两层叠加。
探索策略:给潜在兴趣留出流量空间
多样性注入解决的是已知候选池里的编排问题,但如果召回阶段根本拿不到新类型的内容,重排也无能为力。探索策略要解决的是流量分配问题:主动拿出一部分曝光,去试探用户没表现过、但可能感兴趣的内容。
最基础的方案是epsilon-Greedy,以小概率随机展示非最优内容,其余流量给贪心最优。实现极其简单,但随机探索浪费流量,用户体验不可控。工业界更常用的是UCB和汤普森采样这类基于不确定性的方法。它们的共同假设是:模型对一个内容的预估置信度低,说明这个内容值得探索。UCB在预估分上叠加一个随曝光次数减少而衰减的bonus项,汤普森采样则从每个内容的Beta分布中采样一个分数参与排序,天然平衡了利用与探索。
import numpy as np
class ThompsonSampling:
def __init__(self, n_items):
# 每个内容维护点击次数alpha和未点击次数beta
self.alpha = np.ones(n_items)
self.beta = np.ones(n_items)
def select(self, k=10):
# 从每个内容的Beta后验分布中采样
samples = np.random.beta(self.alpha, self.beta)
return np.argsort(samples)[-k:]
def update(self, item_id, clicked):
if clicked:
self.alpha[item_id] += 1
else:
self.beta[item_id] += 1
汤普森采样的优点是探索是概率性的、自适应的,表现差的内容探索几次后自然被挤出,不需要手工调探索比例。在内容冷启动场景,对新内容赋予较宽的先验分布(alpha和beta都取较小值或加时间衰减),可以让优质新内容快速起量。需要注意探索必须配合止损机制,比如单内容探索曝光超过一定量级仍无转化就强制退场,避免长期占用探索预算。
在更宏观的层面,还可以做用户兴趣的向量化扩展。具体做法是在用户兴趣画像embedding的基础上,叠加相邻兴趣簇的向量,形成扩展后的召回向量。比如一个重度科技内容用户,扩展时混入少量商业、科学簇的向量进行召回,让候选池本身带上探索属性。这类方案在短视频和信息流产品中验证效果不错,关键参数是扩展兴趣的流量占比,一般控制在10%到20%之间。
线上落地:评估指标与实验设计
多样性优化最大的落地难点是评估。只看CTR一定会跌,因为探索流量和打散都在牺牲短期准确性。建议构建一套多样性评估指标:列表层面的类目熵、 pairwise相似度均值、独立创作者数量,以及用户层面的session内类目覆盖数。同时观察长期指标,比如7日留存、人均使用时长和主动搜索率——后者的提升往往说明用户对推荐内容的不满在下降。
实验设计上建议分阶段推进:第一阶段只上规则打散,验证产品对多样性的容忍度;第二阶段引入MMR或DPP重排,观察CTR跌幅与留存涨幅的交换比;第三阶段开小比例探索流量(比如5%起)跑汤普森采样。每个阶段都用A/B实验做充分验证,避免多变量同时改动导致无法归因。信息茧房的治理不是一次性的算法升级,而是准确性导向与多样性导向之间的持续动态平衡,需要建立常态化的监控与调参机制,让系统在用户兴趣收窄时能够自动感知并干预。
信息茧房推荐系统多样性Exploration探索策略修改时间:2026-09-15 13:14:40