抖音 Feed 流排序机制揭秘——内容分发的“心脏系统”

479 阅读2分钟

抖音的核心增长来自于其 Feed流的极致推荐体验,你刷的每一条短视频背后,都是一个复杂的排序系统在做“个性化判断”。本篇将从业务层拆解排序流程,再结合 Node.js 演示一个简化版 Feed 流排序系统。


🧭 一、Feed 流的推荐流程是什么?

Feed 流排序通常分为以下五个阶段:

  1. 召回(Recall) :根据兴趣/社交/热度快速筛出 10w+
  2. 初筛(Pre-filter) :剔除低质内容、黑名单、频繁内容
  3. 粗排(Rough Rank) :根据多个模型快速打分
  4. 精排(Fine Rank) :深度模型精确打分
  5. 重排/策略干预(Re-Rank) :保证新内容、多样性等

🔍 二、字节跳动如何设计 Feed 排序?

  • 内容打分 = ctr × 质量 × 新鲜度 × 策略权重

  • 策略干预(混排/强插)

    • 强插广告、热点内容、新创作者
  • Feed 多样性控制

    • 限制连刷相同风格内容(避免审美疲劳)

⚙️ 三、Node.js 实现一个简化版 Feed 排序原型

1. 内容源模拟(假设我们有100条短视频)

const contentPool = Array.from({ length: 100 }, (_, i) => ({
  id: i,
  ctr: Math.random(),              // 点击率预估
  quality: Math.random(),          // 视频质量得分
  freshness: Math.random(),        // 新鲜度打分
  isHot: Math.random() > 0.9,      // 热门标记
}));

2. 排序打分函数设计

function calculateScore(item) {
  let score = item.ctr * 0.4 + item.quality * 0.4 + item.freshness * 0.2;
  if (item.isHot) score += 0.1; // 热点内容加权
  return score;
}

3. 完整推荐流程模拟

function getFeed(userId, count = 10) {
  const filtered = contentPool.filter(item => item.quality > 0.2); // 过滤低质
  const scored = filtered.map(item => ({
    ...item,
    score: calculateScore(item),
  }));
  const sorted = scored.sort((a, b) => b.score - a.score); // 排序
  return sorted.slice(0, count);
}

console.log("推荐内容:", getFeed(123));

4. 输出示例:

推荐内容:
[
  { id: 28, ctr: 0.92, quality: 0.91, freshness: 0.68, score: 0.843 },
  { id: 15, ctr: 0.85, quality: 0.83, freshness: 0.71, score: 0.802 },
  ...
]

🧠 四、工程中的复杂度来自哪里?

模块难点
精排模型Deep CTR/DSSM/DIN 等深度模型
多样性类别隔离、兴趣切换判定
实时性用户行为、内容入库实时更新
策略系统AB 实验、运营内容优先级干预

✍️ 五、总结与思考

  • 抖音排序系统是“模型 + 策略 + 实时性”的综合体现
  • 高点击率≠高排序得分,排序目标是长留存 +满意度最大化
  • 简化版本帮助我们理解:Feed 本质上是多因子排序

🎁 拓展阅读