<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>上下文工程 on 方糖猫Blog</title>
    <link>https://ftmao.com/blog/tags/%E4%B8%8A%E4%B8%8B%E6%96%87%E5%B7%A5%E7%A8%8B/</link>
    <description>AI 视频、AI Agent 与工程实践笔记</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Thu, 30 Jul 2026 10:00:00 +0800</lastBuildDate><atom:link href="https://ftmao.com/blog/tags/%E4%B8%8A%E4%B8%8B%E6%96%87%E5%B7%A5%E7%A8%8B/index.xml" rel="self" type="application/rss+xml" /><item>
      <title>GenRec 笔记：Netflix 怎么把推荐排序器做成 LLM 原生</title>
      <link>https://ftmao.com/blog/posts/netflix-genrec-llm-native-recommendation/</link>
      <pubDate>Thu, 30 Jul 2026 10:00:00 +0800</pubDate>
      <guid>https://ftmao.com/blog/posts/netflix-genrec-llm-native-recommendation/</guid>
      <description>&lt;h1 id=&#34;genrec-笔记netflix-怎么把推荐排序器做成-llm-原生&#34;&gt;GenRec 笔记：Netflix 怎么把推荐排序器做成 LLM 原生&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;原文：&lt;a href=&#34;https://netflixtechblog.com/genrec-towards-llm-native-recommendation-at-netflix-f20be6f643e3&#34;&gt;GenRec: Towards LLM-Native Recommendation at Netflix&lt;/a&gt;
目标读者：做推荐、搜索、排序的后端工程师，以及关心「LLM 怎么落地进成熟业务系统」的 AI 工程师。
阅读目标：搞清楚 GenRec 的两阶段训练框架、目录感知打分头、prefill-only 推理这三个核心机制，以及它用远少于生产系统的标注数据追平甚至反超的原因。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一问题推荐栈的复杂度税&#34;&gt;一、问题：推荐栈的复杂度税&lt;/h2&gt;
&lt;p&gt;Netflix 现有生产排序器是多年演化的结果：数千个手工特征、专门的序列建模结构、特征交互结构、多任务目标，支撑电影、剧集、游戏、直播、播客等多种内容类型和多个产品界面。它能跑，但** onboarding 一个新场景（新内容类型、新界面）的成本极高**——特征工程、架构改动、基础设施、实验，一样都少不了。这是典型的复杂度税。&lt;/p&gt;
&lt;p&gt;与此同时，LLM 圈已经在推荐方向有不少探索（原文点名 PLUM、GLIDE、OneRec-Think）。思路很诱人：把用户历史和物品元数据直接表示成文本，靠 LLM 的世界知识和语言理解在共享语义空间里抓关系，甚至用自然语言 prompt 去「引导」推荐。但&lt;strong&gt;现成 LLM 直接上岗是不合格的推荐器&lt;/strong&gt;：偏向全局热门、幻觉出目录外的物品、无视业务约束、个性化弱。GenRec 要回答的问题就是：把 LLM 正经后训练成排序器，能不能打过一套调了多年的生产系统？&lt;/p&gt;
&lt;p&gt;任务设定本身很标准：全目录排序（有候选集时是 top-K）。给定用户、交互历史、当前上下文（设备、界面、地区、时间），输出一个个性化排序，优化目标是&lt;strong&gt;长期会员效用&lt;/strong&gt;（满意度和留存的代理），不是短期点击。&lt;/p&gt;
&lt;h2 id=&#34;二两阶段先适配再排序&#34;&gt;二、两阶段：先适配，再排序&lt;/h2&gt;
&lt;p&gt;GenRec 的训练分两阶段，分工明确：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Phase 1 —— Netflix 适配的基座 LLM&lt;/strong&gt;：从开源 LLM 出发，在 Netflix 专有语料上继续训练，让它学会内容理解、会员行为与偏好模式，同时保住通用语言能力。更新频率低，作为多个应用共享的「Netflix-aware」基座。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Phase 2 —— GenRec 本体&lt;/strong&gt;：在 Phase-1 基座上用排序数据和排序目标做后训练，专注排序质量与可控性，用奖励加权损失融入多种奖励信号；更新频率高，跟踪新内容和口味漂移；并且从设计上就在推理成本约束下优化。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    OSS[&amp;#34;开源 LLM&amp;#34;] --&amp;gt;|&amp;#34;Netflix 专有语料继续训练&amp;lt;br/&amp;gt;低频更新&amp;#34;| P1[&amp;#34;Phase 1&amp;lt;br/&amp;gt;Netflix 适配基座 LLM&amp;lt;br/&amp;gt;多应用共享&amp;#34;]
    LOG[&amp;#34;会员交互日志&amp;lt;br/&amp;gt;播放 时长 评分 弃看 等&amp;#34;] --&amp;gt;|&amp;#34;文本化为对话&amp;lt;br/&amp;gt;user 消息 上下文与历史&amp;lt;br/&amp;gt;assistant 消息 真实行为&amp;#34;| DATA[&amp;#34;Phase 2 训练数据&amp;#34;]
    P1 --&amp;gt; DATA
    DATA --&amp;gt;|&amp;#34;排序目标 + 语言建模目标&amp;lt;br/&amp;gt;+ 奖励加权损失&amp;#34;| P2[&amp;#34;Phase 2&amp;lt;br/&amp;gt;GenRec 排序模型&amp;lt;br/&amp;gt;高频更新 成本约束&amp;#34;]
    RM[&amp;#34;独立奖励模型&amp;lt;br/&amp;gt;长期满意度代理&amp;lt;br/&amp;gt;行为再平衡&amp;#34;] -.-&amp;gt;|&amp;#34;给每条样本一个标量权重&amp;#34;| P2
    style P1 fill:#fff3cd
    style P2 fill:#e8f5e9&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;这个两阶段划分是全文我觉得最值得抄的部分：&lt;strong&gt;基座慢迭代、排序快迭代&lt;/strong&gt;。基座沉淀通用能力，排序层追内容新鲜度——后面消融实验会证明，Phase-1 越陈旧，Phase-2 的相对收益越大。&lt;/p&gt;
&lt;h2 id=&#34;三训练数据即对话上下文即特征&#34;&gt;三、训练数据即对话，上下文即特征&lt;/h2&gt;
&lt;p&gt;Netflix 会员每天产生千亿级交互事件。GenRec 把日志转成单轮或多轮「对话」：user 消息是文本化的上下文、画像、历史、物品元数据和任务（比如「预测用户接下来会播放或点赞什么」），assistant 消息是会员的真实行为（播了什么、播了多久、给了什么反馈）。Phase-2 训练时，模型学的是 assistant 消息对 user 消息的条件依赖。&lt;/p&gt;
&lt;p&gt;注意一个容易误读的点：&lt;strong&gt;对话格式只为训练服务&lt;/strong&gt;。推理时不做自回归生成——把文本化的上下文喂进去，直接用打分头给候选物品算分。对话形式存在的原因是配合语言建模目标、保住模型对文本的理解能力。&lt;/p&gt;
&lt;p&gt;文本化的瓶颈是 token 预算。把用户历史里每个事件都摊开写，成本在 Netflix 规模下不可接受。于是上下文窗口成了新的「特征预算」，GenRec 的做法是给上下文做工程：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;完整保留&lt;/strong&gt;：高信号事件（长播放、点赞），细节给足；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;直接丢弃&lt;/strong&gt;：低信号事件（极短播放、快速划过）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;摘要压缩&lt;/strong&gt;：重复性行为（连续刷剧这类 binge 行为）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;选择性展开&lt;/strong&gt;：重要或冷启动物品（比如新上线内容）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;固定预算内优先近期的、高信号的历史，老的压缩或丢掉。prompt 结构上还要最大化共享前缀，吃满 prefix caching。&lt;strong&gt;「prompt 就是新的特征向量」&lt;/strong&gt;——这句话是全文的眼。&lt;/p&gt;
&lt;h2 id=&#34;四三个目标排序语言奖励&#34;&gt;四、三个目标：排序、语言、奖励&lt;/h2&gt;
&lt;p&gt;GenRec 的损失是三件事的组合：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;目录感知排序目标&lt;/strong&gt;：用高价值行为（足够长的播放、强显式反馈）做正例，带阈值和去噪逻辑；在目录或候选集上做交叉熵，让正例得分更高。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;语言建模目标&lt;/strong&gt;：保留 LM 损失，防止模型在文本化输入上丢掉语言理解能力，也给「推荐理由解释」这类生成场景留门。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;奖励加权对齐&lt;/strong&gt;：只在原始行为序列上训练，模型会学出坏习惯——过度偏向刷剧、只推单一内容类型。解法是独立奖励模型给每条训练样本算一个标量权重：长期满意度代理（这次短期行为对回访、目录探索、持续活跃有多大贡献）加行为再平衡（跨内容类型、跨上线阶段调节）。高价值样本加权，低价值样本降权。原文特别说明：这比完整 RL 简单省钱，实践中对齐效果够用；GRPO 这类 RL 方法有额外收益但成本高，留给未来工作。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;五架构与-serving打分头--prefill-only&#34;&gt;五、架构与 serving：打分头 + prefill-only&lt;/h2&gt;
&lt;p&gt;架构贴着基座走：decoder-only Transformer，加一个&lt;strong&gt;目录感知打分头&lt;/strong&gt;，只对 Netflix 在库物品打分。推理管线三步：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    V[&amp;#34;Verbalizer&amp;lt;br/&amp;gt;历史 上下文 物品元数据&amp;lt;br/&amp;gt;序列化成单条文本&amp;#34;] --&amp;gt; LLM[&amp;#34;LLM 前向一次&amp;lt;br/&amp;gt;取池化隐状态 h&amp;lt;br/&amp;gt;概括当前偏好与上下文&amp;#34;]
    LLM --&amp;gt; HEAD[&amp;#34;打分头&amp;lt;br/&amp;gt;h 与物品嵌入做点积或小 MLP&amp;lt;br/&amp;gt;softmax 得到分布&amp;#34;]
    CAT[&amp;#34;目录物品嵌入&amp;lt;br/&amp;gt;与主干联合训练&amp;#34;] --&amp;gt; HEAD
    HEAD --&amp;gt; RANK[&amp;#34;排序输出&amp;lt;br/&amp;gt;天然不会幻觉出目录外物品&amp;#34;]
    style HEAD fill:#fff3cd
    style RANK fill:#e8f5e9&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;打分头这步设计得很实在：物品嵌入、打分头、主干&lt;strong&gt;联合训练&lt;/strong&gt;；目录极大时用 sampled softmax 或候选集。由于分数只算在目录物品上，「幻觉出目录外内容」这个 LLM 推荐的老毛病在结构上就被掐死了——不需要后处理过滤。&lt;/p&gt;
&lt;p&gt;Serving 在 Netflix 内部 LLM 栈上跑 vLLM。成本由三个因素驱动：模型大小、上下文长度、推理模式。对应三个手段：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;小模型/蒸馏模型&lt;/strong&gt;：用更小或蒸馏过的基座，配更大更针对性的数据，用更低的成本换大部分质量；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;激进压缩上下文&lt;/strong&gt;：就是第三节那套上下文工程；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;prefill-only 推理&lt;/strong&gt;：不对候选集做自回归解码（那在成本上是自杀），prompt 只消费一次，单次前向给整个候选集打完分。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第三条是整套方案能上线的关键。一个排序器如果按 LLM 聊天那种方式逐 token 生成推荐结果，账永远算不过来；把 LLM 当成「一次性编码器 + 打分头」，账就算过来了。&lt;/p&gt;
&lt;h2 id=&#34;六实验结果少数据反而赢&#34;&gt;六、实验结果：少数据，反而赢&lt;/h2&gt;
&lt;p&gt;对照组是调了多年的生产排序器（数千个特征、定制架构）。结果分几层：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;离线&lt;/strong&gt;：用大约 40 分之一的 Phase-2 标注样本，MRR 反而高约 1.6%。继续加数据、加输入信号，指标继续涨。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;线上 A/B&lt;/strong&gt;：批量计算的推荐界面，约 10% 流量跑约 4 周，短期和长期指标均统计显著为正。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据与模型 scaling&lt;/strong&gt;：1B 和 10B 主干都随 Phase-2 数据量上涨，大模型绝对值更高、曲线形状相似；固定训练预算下，更大主干稳定更好——推荐也吃 scaling law。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Phase-1 vs 开源&lt;/strong&gt;：用 Netflix 适配基座比直接用现成开源 LLM，离线指标高约 10%-20%。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Phase-2 vs Phase-1&lt;/strong&gt;：在 Phase-1 刚训完的时间点，Phase-2 后训练带来 35%-50% 提升；Phase-1 越陈旧（新内容、口味漂移），Phase-2 相对收益越大，2 周后约 80%。这直接论证了两阶段划分的正确性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据效率&lt;/strong&gt;：从强 Phase-1 出发，GenRec 用 10-40 倍更少的 Phase-2 标注样本追平或超过生产排序器——这点值钱在 Phase-2 更新频率高，标注效率直接决定迭代速度。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;上下文压缩&lt;/strong&gt;：清洗事件、找 MRR 对事件数的「肘点」、调措辞详略，三步下来 token 预算可以压到原来的三分之一左右，离线指标几乎不掉；serving 成本约与上下文长度成正比，所以成本也同比降。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;七更大的判断从特征工程到上下文工程&#34;&gt;七、更大的判断：从特征工程到上下文工程&lt;/h2&gt;
&lt;p&gt;原文最后一节不是在总结 GenRec，是在押注一个范式转移，四条：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;特征工程 → 上下文工程&lt;/strong&gt;：建模范畴从「设计特征」变成「决定哪些信号进上下文、回溯多久、怎么在 token 预算内压缩」。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定制架构 → 共享基座&lt;/strong&gt;：双塔、DLRM、定制 attention 各立山头的时代，让位给「一个基座 + 数据与文本化策略 + 后训练目标 + 推理优化」的差异化。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scaling law 成为设计指南&lt;/strong&gt;：传统 RecSys 因为稀疏 ID、重工程、任务定制架构容易撞墙；LLM 化的推荐继承了清晰的数据和模型 scaling 行为，投入产出变得可规划。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RecSys 基建 → LLM 基建&lt;/strong&gt;：GPU、vLLM/Triton、batching、caching——推荐 serving 越来越像通用 LLM serving。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;工程实践联想&#34;&gt;工程实践联想&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;「prefill-only」是给 LLM 落地祛魅的一刀。&lt;/strong&gt; 很多团队评估「LLM 进生产」时默认按生成式推理算账，结论当然是不划算。GenRec 的示范是：先问这个任务是不是真的需要逐 token 生成。排序、分类、匹配这类任务，LLM 的正确用法是当编码器，一次前向出全部结果——成本模型完全不同。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;目录感知打分头是「防幻觉」的标准答案。&lt;/strong&gt; 不要在生成端防幻觉再靠后处理拦截，把输出空间在结构上约束到合法集合（打分头、受限解码、枚举候选），比训一个「不幻觉的模型」可靠得多。这个模式放之四海皆准：凡是输出必须在闭集内的场景，都该这么干。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;奖励加权是 RL 的穷人版，但可能够你用很久。&lt;/strong&gt; 完整 RLHF/GRPO 的成本和组织复杂度劝退大多数团队；「独立奖励模型给样本算权重、乘进损失」用监督训练的工程成本拿到对齐收益的大部分。先把这条路走通，再谈要不要上 RL。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;上下文工程是可以量化的工程，不是 prompt 玄学。&lt;/strong&gt; GenRec 把它做成了有肘点曲线、有详略实验、有三分之一预算硬指标的东西。做 RAG 的人应该直接抄这个流程：清洗事件 → 画「指标 vs 上下文量」曲线找肘点 → 在保留集合上调措辞密度。上下文不是越多越好，是有预算的。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;「prompt 是新的特征向量」意味着你的特征基建要换。&lt;/strong&gt; 特征平台管的是 Schema、版本、回填；上下文工程管的是文本化模板、压缩策略、共享前缀。如果你的推荐/排序团队还在纯特征工程范式里，GenRec 给出的信号是：下一个五年的技能树在后者。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;本篇小结&#34;&gt;本篇小结&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GenRec 是什么&lt;/strong&gt;：Netflix 的 LLM 排序器。文本化用户历史与上下文，在 Netflix 适配基座上做排序后训练，挂目录感知打分头，奖励加权对齐长期价值，prefill-only 推理控成本。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;核心机制&lt;/strong&gt;：两阶段（慢基座 + 快排序）、对话格式训练但非生成式推理、打分头把输出约束在目录内、奖励加权替代完整 RL。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关键数字&lt;/strong&gt;：40 倍更少标注样本下 MRR +1.6%；Phase-1 基座 +10%-20%；Phase-2 +35%-50%（基座陈旧 2 周后 +80%）；上下文压到三分之一指标几乎不掉；10% 流量 4 周 A/B 短期长期均显著为正。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最大的启示&lt;/strong&gt;：推荐的工程重心从特征工程转向上下文工程，「prompt 就是新的特征向量」；LLM 进排序系统的正确姿势是编码器 + 打分头，不是聊天生成。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保留意见&lt;/strong&gt;：原文没给具体基座模型、参数量细节和线上指标绝对值，成本数字也只有相对比较；「match or exceed 生产系统」的结论目前只在批量计算界面上验证过，实时低延迟场景没提。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;参考资料&#34;&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;原文：Ying Li, Arjun Rao, Shradha Sehgal, &lt;a href=&#34;https://netflixtechblog.com/genrec-towards-llm-native-recommendation-at-netflix-f20be6f643e3&#34;&gt;GenRec: Towards LLM-Native Recommendation at Netflix&lt;/a&gt;, Netflix TechBlog, 2026-07-30。&lt;/li&gt;
&lt;li&gt;原文点名的相关 LLM 推荐工作：PLUM、GLIDE、OneRec-Think。&lt;/li&gt;
&lt;li&gt;推理框架：&lt;a href=&#34;https://github.com/vllm-project/vllm&#34;&gt;vLLM&lt;/a&gt;（GenRec serving 所依赖）。&lt;/li&gt;
&lt;li&gt;原文提及的 RL 方法：&lt;a href=&#34;https://arxiv.org/abs/2402.03300&#34;&gt;GRPO&lt;/a&gt;（Group Relative Policy Optimization，DeepSeekMath 论文提出）。&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>
