EvoRec 项目介绍:动态商品库推荐、离线实验与服务闭环

这篇文章记录 EvoRec 如何从冷启动研究问题发展为带有离线实验和本地可操作 Demo 的项目,并区分实验结果、系统能力与尚未验证的范围。

截至 2026-10-27:R01–R06 离线研究已形成完整记录;当前本地 Demo 提供两条分开的体验路径——批准的冻结 R06 模型,以及不依赖研究模型的合成商品内容基线。它不是生产推荐服务,也不表示完整研究 PRD 已完成。

本文的早期实验数字和失败记录仍按当时协议保留。最新版本还修复了发现页、反馈来源绑定及标签页状态恢复问题;这些页面和恢复检查不能替代完整模型负载复验。当前 R06 结果仍保留 A-frozen-s17:多兴趣方案没有显示稳定优势,冷商品进入候选池略有增加,但无历史冷目标仍未命中。Demo 里的 adaptive 是兼容入口并固定解析为 dense,不是动态学习路由。

一、项目背景与目标

EvoRec 面向动态商品库的冷启动问题,将离线推荐研究、服务端请求处理和本地交互演示放在同一个项目中。关键问题不只是模型排序分数,还包括新品何时进入候选集、反馈怎样改变后续请求,以及模型与商品版本如何保持可追溯。

为什么选择推荐系统

推荐系统是一个既有理论深度又有工程复杂度的领域。它涉及机器学习、信息检索、系统设计等多个方面,同时也有明确的业务价值和评估标准。选择“动态商品库推荐”这个场景,是因为它包含了推荐系统中最核心的挑战:

  • 冷启动问题:新商品没有历史交互数据,如何快速让它们参与推荐?
  • 实时性要求:商品库不断更新,系统需要快速响应新品入库。
  • 多路召回融合:需要平衡协同过滤、内容检索等多种策略。
  • 效果可验证:有清晰的离线评估指标和在线业务指标。

项目目标

项目覆盖以下能力:

  • 召回与排序:协同过滤、内容双塔、策略门控、冷样本加权和多兴趣候选的离线实现与比较。
  • 服务与持久化:FastAPI 请求编排、PostgreSQL 请求/结果记录、反馈与商品版本管理。
  • 商品生命周期:导入校验、异步构建、预览、显式发布、下架和回滚。
  • 对照评估:固定输入与策略、分组指标、不确定性分析及结果追溯。

研究轨迹现已覆盖 R01–R06:热门与协同基线、序列模型、内容双塔、门控与冷商品保留、冷样本加权排序,以及多兴趣召回和残差排序的受控比较。系统侧也已把推荐请求、PostgreSQL 持久化、反馈、商品构建/发布、结果查看与本地页面接通。二者是不同层面的成果:离线指标回答冻结协议下的研究问题,Demo 证明本地流程可操作,不代表线上业务效果。

二、核心问题与解决思路

问题场景

考虑一个典型的电商推荐场景:每天都有新商品上架,这些新商品没有任何历史交互数据。如果使用纯协同过滤方法,这些商品永远不会被推荐给用户,因为它们不在模型的"词表"中。但对商家来说,新品的曝光至关重要;对用户来说,新品可能正是他们感兴趣的。

这就是推荐系统中的"冷启动"问题。EvoRec 项目专注于解决这个问题,同时保持整体推荐质量。

技术挑战

  • 冷商品可达性:没有交互历史的商品如何进入候选集?
  • 多路召回融合:如何平衡协同过滤(基于用户行为)和内容检索(基于商品特征)?
  • 动态策略调整:针对不同用户(新用户 vs 活跃用户),应该采用什么样的召回策略?
  • 排序优化:如何在排序阶段提升冷商品的曝光,而不损害整体效果?

系统目标

EvoRec 的最终目标是构建一个完整的可演示系统,包括:

  • 推荐服务:支持实时推荐请求,处理用户反馈(收藏、屏蔽等)。
  • 商品管理:支持新品入库、编码、索引构建和发布。
  • 策略对比:可视化展示不同策略的效果差异。
  • 效果看板:实时监控推荐质量和冷商品曝光率。

成功标准不仅是功能完成,更重要的是实验可信、结果可追溯。每个设计决策都需要有数据支撑。

EvoRec 本地 Demo 发现页真实截图
本地 Demo 发现页,摄于 2026-10-27;使用合成目录与内容基线,未加载 R06 模型。(点击图片查看原图)
EvoRec 本地 Demo 商品详情真实截图
同一演示环境中的商品详情;缺失封面保留占位图。该截图展示界面行为,不代表 R06 离线实验效果。(点击图片查看原图)

截图来源与运行配置见固定版本截图记录。

三、技术选型与架构设计

技术栈选择

技术选择围绕离线实验效率、服务边界和本地可复现演示:

  • 算法框架:Python + PyTorch — 推荐算法领域的主流选择,有丰富的预训练模型和工具库。
  • 向量检索:Faiss — Facebook 开源的高性能相似度搜索库,支持多种索引类型。
  • 数据存储:PostgreSQL — 可靠的关系数据库,支持事务和复杂查询。
  • API 服务:FastAPI — 现代 Python Web 框架,自动生成文档,异步支持好。
  • 前端展示:原生 HTML/CSS/JavaScript — 当前本地 Demo 用无构建步骤页面展示推荐、反馈、商品管理与结果查看;React 等框架仍是后续选项。

架构设计原则

系统架构遵循以下原则:

  • 模块解耦:算法、数据、服务和展示模块独立开发和测试。
  • 契约优先:先定义接口和数据格式,再实现具体逻辑。
  • 版本管理:模型、编码器、索引作为一个 bundle 统一版本。
  • 可测试性:关键路径有自动化检查,使用测试替身隔离依赖。
离线研究:src/evorec/research → 候选生成 / 训练 / 评估
                              │ 固定模型与数据版本
                              ▼
浏览器 → FastAPI → Recommend.execute → PostgreSQL
                    │ 请求快照 / 资格过滤 / Top-K / 幂等结果
                    ├── 冻结 R06:CF + 内容召回 + 排序器
                    └── 新品 Demo:合成目录内容基线
后台 workers:商品目录构建 / 策略比较 / 批量评估

图中的冻结模型与合成内容基线是两条分别配置的路径;离线研究产物不会自动成为线上活动模型。

关于 C++ 的考虑

考虑到主要算法实验基于 Python,实现初期没有在性能关键路径额外引入 C++:

  • 先用 Python 验证:在明确瓶颈之前,不引入额外复杂度。
  • 保留优化空间:如果后续测量发现性能问题,可以用 pybind11 封装 C++ 扩展。
  • 利用现有工具:Faiss 本身就是 C++ 实现,通过 Python 绑定使用即可。

这一取舍减少了跨语言边界,同时保留了在测得实际瓶颈后再评估 C++ 扩展的空间。

四、工程框架搭建

设计原则

工程组织需要满足以下原则:

  • 契约先行:先定义接口和数据格式,模块之间通过契约通信。
  • 可测试性:核心逻辑独立于外部依赖,可以用测试替身验证。
  • 版本一致性:模型、编码器和索引作为一个 bundle 统一管理。
  • 清晰的状态转换:区分“服务启动”和“推荐就绪”,明确商品的生命周期。
src/evorec/domain/          领域对象、规则与协议
src/evorec/application/     推荐、反馈、商品与评估用例
src/evorec/infrastructure/ 数据库、模型与 worker 适配器
src/evorec/api/             FastAPI 路由与请求契约
src/evorec/research/        离线数据处理、训练与评估
web/                        原生 HTML/CSS/JavaScript 页面
db/                         PostgreSQL schema 与迁移
scripts/                    服务、目录、比较和评估任务入口

核心模块

  • domain/ — 领域对象和业务逻辑,不依赖具体实现。
  • infrastructure/ — PostgreSQL 与模型运行时等外部依赖适配器。
  • application/ — 应用层服务,协调领域对象和适配器。
  • api/ — FastAPI 路由和请求处理。
  • research/ — 离线实验脚本和评估代码。

当前实际进展

下列清单是 2026-09-15 初始框架阶段的记录,不是当前系统能力的完整说明。此后服务与本地 Demo 已继续落地:

  • 建立了 FastAPI 服务骨架,定义了推荐接口的输入输出契约。
  • 实现了 55 项自动检查,覆盖请求绑定、参数验证、超时处理等边界情况。
  • 使用测试替身隔离了模型和存储依赖,确保应用层逻辑可独立验证。
  • 定义了商品状态机,明确了从入库到上线的完整流程。
EvoRec API 接口响应示例
历史示意(2026-09-15 初始框架):推荐请求的早期数据契约,当前路由和响应以仓库 API 契约为准。
自动检查结果
历史记录(2026-09-15 初始框架):当时 55 项契约与边界检查通过,不代表当前测试总量或完整 Demo 验收。

历史验证边界:当时的 55 项检查只支持契约和应用层边界,不证明推荐效果、数据库事务或真实吞吐。后续数据库、推荐服务与页面交互另有独立验证记录,不能把这组旧检查数当作当前回归规模。

五、离线实验档案:R01–R05

以下实验按发生顺序保留其数据、指标和当时结论。它们是历史运行,不是当前服务性能或新商品质量的证据;R06 是后续冻结比较,负责更新当前策略取舍。

  • 数据从哪里来,包含哪些字段。
  • 如何清洗交互、统一商品 ID 和处理缺失数据。
  • 如何划分训练、验证和测试数据。
  • 怎样避免未来信息进入训练或评估。
  • “模型冷物品”和“刚刚发布的新品”有什么区别。
  • 首次跑通的基线、使用的设备、资源消耗与结果。

R01 已完成。 从官方 Video_Games 交互文件读取前 50,000 条,得到 20,375 个用户和 18,508 件商品;在 2,291 个测试正反馈上,热门推荐 NDCG@10 为 0.007388,ItemCF 为 0.004636。共有 79 项检查通过,9,852 条逐请求结果完成独立核对。前缀样本中 1,101 个测试目标在请求时尚未被观察到,保留在主指标分母中。

R02 已完成。 完整扫描 4,555,500 条交互,按固定用户哈希保留约二十分之一用户的全部记录,得到 226,172 条交互和 137,103 个用户。GPU 自注意力序列模型完成 4 次训练、39 个 epoch 和三个种子运行;测试 NDCG@10 为热门 0.004755、时间衰减协同融合 0.008380、序列模型均值 0.005628 ± 0.000222。序列模型超过历史热门,但没有超过更强的时间衰减基线。

R02 序列模型训练曲线
R02 序列模型训练曲线:39 轮、4 次训练。损失下降不保证验证指标持续改善。
R02 序列模型与统计基线对比
R02 序列模型与统计基线对比:三种子标准差不是置信区间;序列模型未超过强协同基线。

本轮还发现 6,874 个模型冷且可用目标全部未命中。没有商品表示入口时,继续增加 Transformer 训练轮数无法让新商品进入词表;下一步先补内容候选路径,并登记新的评价窗口。

R03 已完成。 引入内容双塔架构,使用商品标题、品牌和类别进行语义编码。完成 48 个 epoch 训练,构建协同过滤与内容检索的混合召回策略。内容融合改善整体排序性能,但冷商品命中率仍低于预期。

内容双塔结构与实现边界
内容双塔结构与实现边界:R03 训练,R04 冻结复用。在线业务接入仍是计划。
R03 内容双塔训练曲线
R03 内容双塔训练曲线:48 轮、4 次训练。按验证指标保留检查点;静态内容可用假设。
R03 整体排序与冷商品召回
R03 整体排序与冷商品召回:内容融合改善整体排序,但冷商品命中少于纯内容路径。

R04 历史实验。 冻结 R03 模型,预登记五种冷商品保留与门控策略,并在新用户验证集上按整体质量下限和同分规则选择配置。测试集上 seed 17 的 reserve-2 比 fixed 多命中 2 个冷目标,gated-2 没有提升;命中集合并非嵌套。因此,这组结果只说明指定策略在该次固定测试中的差异,不足以支持门控稳定提升效果的泛化结论。

冷商品保留与门控流程
冷商品保留与门控流程:五种策略在实验前固定。门控只读取历史信号;未跳过任一检索路径。
R04 验证集策略比较
R04 验证集策略比较:冻结 R03 模型,使用新用户验证选择策略;红线为整体 NDCG 下限。
R04 测试集消融实验
R04 测试集消融实验:固定 seed 17 的五种预登记策略;测试中的差异不用于回改选型。
R04 冷商品落选位置分析
R04 冷商品落选位置分析:比较同一批冷目标的命中位置;排序集合可能交叉,不是严格漏斗。
R04 门控活动与冷商品曝光
R04 门控活动与冷商品曝光:改变列表的请求比例和新增冷商品位置数量,与目标命中率分别评价。

R05 历史实验。 引入 ColdListMLP,对冷样本加权训练。原始同候选池对比中 ColdListMLP 仅运行 seed 17,普通 ListMLP 有三个种子;因此不能把该单种子差异概括为可重复的稳定提升。后续在独立样本上的三种子复验报告 NDCG@10 为 0.009315 ± 0.000387,冷目标命中数为 26 / 24 / 27;它验证了另一轮固定协议下的结果,并不消除不同样本或策略之间的不确定性。详见R05 三种子复验。后续 R06 的多兴趣方案配对区间跨零,当前选择仍是 A-frozen-s17。

R05 新排序模型训练曲线
R05 新排序模型训练曲线:4 次训练、35 轮。普通损失与冷样本加权损失的绝对值不直接比较;最佳轮次只看验证集。
R05 同候选池排序比较
R05 同候选池排序比较:ColdListMLP 只运行 seed 17;普通 ListMLP 有三个种子。R03 参考使用不同编码器与召回链路。

R06 固定协议结果

R06 已完成,但没有证据支持替换原路径。 测试用户与 R01–R05 的交集为零,共 12,524 个正反馈请求、9,373 名用户。比较的是相同候选数量预算下的均值内容召回和近期多兴趣召回。验证规则保留 A-frozen-s17,本轮没有换路径。

方法族(三个种子) 内容召回 排序器 整体 NDCG@10 冷 Recall@20
A-frozen 均值 冻结 R05 0.010074 ± 0.000129 0.003774
B-frozen 均值 + 多兴趣 同一组冻结模型 0.010040 ± 0.000117 0.003917
C-adapted 均值 + 多兴趣 重新训练 0.009820 ± 0.000216 0.003678
D-adapted 均值 同阶段重训练对照 0.010155 ± 0.000027 0.003583

冷目标进入候选池由 115 / 6,978 增至 122 / 6,978。无历史冷目标仍是 0 / 3,928。B 减 A 的整体 NDCG 差值为 −0.000033769,95% 边际区间 [−0.000260567, +0.000184014];C 减 D 为 −0.000335551,[−0.000686012, +0.000000421]。两个区间都跨过零。测试批次里均值内容路径用时 7.865 秒,多兴趣计算另用 12.469 秒。这是离线批次时间,不是线上延迟。共 6 次训练、74 轮。50 项预登记区间按用户聚类重采样 10,000 次后独立复算,条件于固定检查点,不含训练随机性,也没有做多重比较校正。三个种子的平均不是集成推荐。数字来自仓库 README 的当前结果表。

六、推荐方法与实现

离线研究包括流行度与时间衰减协同基线、序列模型、商品内容双塔、冷商品保留/门控、冷样本加权排序,以及 R06 多兴趣召回和候选内残差排序。实验数据按时间协议切分,模型拟合与请求时可用商品资格分开处理;同一轮固定候选范围和评估输入,并分别报告整体与冷商品指标。这里的内容是项目实际实现和实验,不是论文复现目录。

R06 在独立留出用户上比较 A-frozen、B-frozen、C-adapted、D-adapted 四组方法:冷目标入池从 115/6,978 增至 122/6,978,但无历史目标仍为 0/3,928;配对区间跨零,验证规则因此保留 A-frozen-s17。它说明增加候选路径还不足以解决冷启动,也没有证据替换当前保留模型。

七、实验协议与结果

每轮实验记录样本、时间切分、随机种子、候选池和指标定义。R06 使用 12,524 个正反馈事件和 9,373 名用户,与 R01–R05 用户无交集;模型质量同时查看 NDCG@10、冷 Recall@20 与配对不确定性。种子标准差不是置信区间,配对区间跨零也不能写成方法胜出。最新研究结论和区间见R06 报告。

自适应预算路由算法、生成式推荐及更完整的研究 PRD 仍未交付;固定别名 adaptive 不应被当成这些研究功能。

八、服务与商品闭环

推荐请求时序图
推荐请求时序图:一次推荐请求如何经过各个模块。
商品状态图
商品状态图:新品从校验、编码到索引构建与发布的状态流转。

推荐服务由 FastAPI 与 PostgreSQL 支撑。Recommend.execute 捕获会话历史、商品资格和模型绑定的请求快照,执行召回排序、资格过滤、去重与 Top-K,再保存并返回同一版本结果;相同幂等键重放原结果,输入冲突会拒绝。反馈携带请求来源与会话 epoch。商品管理采用导入校验、后台构建、预览和显式发布分步流程,避免把导入误当成线上资格。批准的冻结 R06 包与合成商品内容基线属于两条独立路径。

页面状态隔离迟到响应并在刷新时恢复服务端可确认的状态。浏览器标签页存储异常时提示恢复风险,并在当前页面内存中保留原操作编号供重试;若刷新或关闭页面,未写入的内存状态不保证恢复。详见Web 行为说明与恢复验证记录。

九、负载诊断与性能边界

项目已对 R06 服务做过 HTTP 期限、并发、队列和结果持久化路径的诊断。2026-10-14 的历史冻结包在完整商品目录、单 worker、原 2 秒期限下,两轮并发负载各 120/120 成功且无 504,客户端 p95 约 1.87 秒;这是特定机器、包和提交上的测量,不是长期服务级别。更早出现的间歇 504 根因未全部归因,2026-10-27 版本也没有重新验收完整 R06 负载。

当前没有 C++/pybind11 扩展,也没有足够证据报告它的性能收益。300 ms、20 QPS、长期稳定性和生产级 SLA 均未验收。回归检查、网页演示和离线算法指标回答不同问题,不能互相替代。

十、项目限制与交付

截至本文更新,可交付物包括 R01–R06 离线报告与复算材料,以及能够本地启动的推荐 Demo:冻结模型路径用于反馈与策略体验,合成内容路径用于新品导入、构建和发布;比较、评估任务和结果页提供研究结果浏览。还没有被证明的是稳定服务级别、持续负载能力或真实业务收益。后续工作应继续针对这些边界补充可复核的证据,并明确新研究功能与现有能力的差别。

十一、持续更新日志

以下保留早期 R01–R05 的数据、失败与当时结论,作为历史记录。后续证据修正了结论时,以最新日期摘要和对应实验报告为准,不把旧结论套用到当前模型或 Demo。

2026-10-27|Demo、R06 结论与恢复边界更新

  • 本次推进:把文章的阶段摘要从早期 M0/R05 更新到当前本地 Demo,澄清离线研究与可操作系统是两类证据,并保留早期实验数字作为历史记录。
  • 研究结论:R06 的 A-frozen / B-frozen / C-adapted / D-adapted 配对结果未支持替换 A-frozen-s17;候选池冷目标为 115/6,978 → 122/6,978,但无历史冷目标仍为 0/3,928。配对整体 NDCG 与冷 Recall 区间跨零。见固定版本 R06 报告。
  • 系统交付:本地 Demo 有冻结 R06 与合成新品内容基线两条路径;后者的内容推荐不是模型效果验证。adaptive 在冻结 R06 上是解析到 dense 的兼容别名,不代表动态学习路由。2026-10-27 版本 a4f8556 的 235 项前端脚本与 28 项 API/页面检查及对应 CI 有记录,见当前 README 与验收边界。
  • 恢复边界:隐藏/撤销入口在同一标签页刷新后可从服务端会话恢复;存储写入异常时本页内存仍保留原操作编号供重试,并提示不要刷新或离开。关闭标签页或刷新后未保存的内存状态不保证恢复。详情见页面交互说明与反馈恢复检查。
  • 未确认范围:10 月 27 日版本没有重新训练或重新验收完整 R06 负载。10 月 14 日历史冻结验收报告了两轮 120/120、0 次 504,但更早间歇 504 的完整根因尚未确定;不能据此宣称 504 已修复、20 QPS / 300 ms SLA 已达成或已具备生产稳定性。
  • 后续方向:按版本补齐完整 R06 负载与历史 504 的根因调查,持续区分已验证恢复行为与尚未覆盖的存储、负载和服务级别目标。

2026-10-07 / 10-08|R06 并发入场、目录减配撤回,以及数据库阶段计时

  • 本次问题:完整 R06 请求在负载下超时。需要分清是入场互斥、目录捕获,还是数据库连接和事务。
  • 实际改动:允许同一会话里不同推荐键并行捕获,写入仍互斥。目录行捕获做过减配,随后因负载验收没有通过而撤回,并补上首次请求诊断。数据库驱动把连接、查询、解码和事务拆开计时。目录减配与撤回在 PR #40(1704141、fb74404),并发入场在 PR #41(5679bdd),数据库阶段计时在 PR #42(27e6f4f)。
  • 验证过程:仓库验收记录区分隔离的并发 TCP、逐请求阶段,以及完整回归边界。本文只转述提交说明,没有复跑。
  • 结果与证据:目录性能实验的负面结果和撤回依据已归档。并发入场修复之后,负载超时仍未解决。数据库阶段数字以仓库当次归档为准,这里不另算提升比例。
  • 遇到的问题:减配如果只在微基准上变快、负载验收失败,就不能留在服务路径上。
  • 当前结论:R06 服务路径的耗时可以拆开看,但现有优化没有把负载超时消掉。撤回本身是这次记录要保留的结果。
  • 下一步:继续用阶段记录定位超时,而不是把未验收的减配写回默认路径。

2026-10-06|进程可靠性、批量评估工作台,以及 Demo 交付边界

  • 本次问题:演示需要说明进程中断之后哪些请求算完成,以及批量快照评估和普通推荐记录怎样分开。同时要冻住 R06 集成状态,避免把演示范围说成研究结论。
  • 实际改动:增加进程可靠性验收和批量快照评估工作台(/app/evaluations 与 evaluation_worker)。中断重放按终态身份核对,断连时的传输结果和服务端原请求账本分开记。验收地址要和实际 PID 的隔离边界一致。发布锁改成按实际 catalog_control 表隔离,独立演示 schema 不再和业务库抢同一把锁。加严重置后的新计算与重放核对;目录捕获减配的失败和保留边界写入文档。PR #35 至 #39。
  • 验证过程:分层验收覆盖可靠性负载、批量评估、授权重置和推荐超时恢复。旧锁升级要求先停掉同一目录的 API 和各类 worker,再统一启动新代码。
  • 结果与证据:README 写明这不是原 R06 全量时间协议复现,也不代表 300 ms / 20 QPS / 99% 已达标。完整包在原 2 秒期限的 TCP 与浏览器操作验收通过的说法,以仓库 docs/validation/demo-deadline-statistics-20261006.json 为准。
  • 遇到的问题:严格验收曾经失败。失败记录保留,没有改成通过。
  • 当前结论:可演示的是单实例、本地可信环境。多协调实例、所有 worker 锁和持续负载没有验收。
  • 下一步:作者自己连续计时复演并解释边界。这一步不能由助手代签。

2026-10-05|推荐页、新品内容基线、回滚重试,以及可选的 R06 接入

  • 本次问题:离线 R06 包还不能被一次 HTTP 请求用上;新品也不能冒充旧模型里的商品。页面上的快速点击和版本切换会把过期结果留下来。
  • 实际改动:接通冻结 R06 的可信快照、可选服务路由和恢复。推荐卡片按实际商品补齐元数据,并丢掉迟到响应。增加隔离的 R06 演示入口、独立新品内容基线,以及来源绑定的结果页。同一次推荐的并发点击合并,失败后保留重试键。版本切换和下架后失效旧构建预览。增加守卫回滚页面,以及可恢复的版本操作重试。推荐中断用执行租约收敛,客户端幂等键保留。PR #24 至 #34。
  • 验证过程:仓库按层记录 HTTP、TCP 和浏览器验收,并保留旧协议重放失败的诊断。新品入口只需要服务环境和本地 PostgreSQL,使用临时合成目录,明确不是 R06 实验效果。
  • 结果与证据:冻结 R06 默认关闭,必须显式启用、批准准备并发布。新品内容基线最多 5,000 件,不会训练 R06,也不会让任意新 ID 获得旧权重。固定示例商品不可用或表示漂移时,创建或重置会话返回 409,不另选种子。
  • 遇到的问题:完整包在原期限上曾经超时。历史失败留在验证记录里,没有改写成当时已经通过。
  • 当前结论:推荐、反馈、新品发布和结果页可以在本地演示。公网身份、多 worker 租约续期和线上收益仍然没有证据。
  • 下一步:把演示入口和 R06 研究入口在说明里分开,避免用内容基线代替 R06 质量。

2026-10-03 / 10-04|冻结 R06 排序器、召回、异步排序和目录准备

  • 本次问题:R06 要先变成可校验的冻结包,才能谈到服务接入。任意新商品不能直接进入旧模型。
  • 实际改动:导出冻结排序器和商品特征,限制 JSON 深度。补齐冻结的协同过滤与内容召回,以及可选的分块 CPU 召回。增加请求快照和冻结商品子集,组装受控冻结包并核对实际商品身份。原子准备冻结商品,未接通的发布与准备隔离。增加有界异步排序和取消清退。安全文本编码器可单独导出。对应合并为 PR #14 至 #23,其中 #15 是冻结商品特征与无目标标签的候选池。
  • 验证过程:提交说明记录双环境重放、干净源码重放、全量实库准备,以及分块召回的交错基准。本文不复算这些基准。
  • 结果与证据:服务接入本身记在 2026-10-05。这一阶段的产物是可校验的冻结包和请求快照,不是线上延迟结论。分块召回是可选路径,有对照基准,但不在这里填写提升比例。
  • 遇到的问题:全量实库准备有过失败并修正。失败修正留在对应验收提交里。
  • 当前结论:冻结包可以在资源上限内加载并回放黄金样本。只跑校验脚本不会切换活动版本。
  • 下一步:接入时继续要求显式开关和批准包,不把校验通过当成已经发布。

2026-09-22 至 10-02|从内存演示到 V0.1–V0.3

  • 本次问题:09-16 的文章还停在离线实验。需要一条能创建会话、记反馈、导入商品和比较策略的本地路径,同时不把研究模型提前接进默认推荐。
  • 实际改动:09-22 增加 MIT 许可证、M1 内存演示和本地 PostgreSQL 说明,并写入架构说明。09-23 把 HTTP 流程持久化到 PostgreSQL,反馈按 event_id 幂等,补齐推荐结果收敛,并从详情浏览回填曝光。09-24 做成 V0.1 推荐体验和 24 件虚构商品,加上本地持久发布与商品管理;研究文档移出仓库根目录,并记录 R02–R05 的干净复验。09-28 完成 V0.2 商品文件导入和发布,以及单实例恢复验收。10-02 完成 V0.3:策略对比写入数据库,由独立的 comparison_worker 跑后台任务。PR #3 至 #13。
  • 验证过程:服务测试把 PostgreSQL 集成测试视为必需项:设置 EVOREC_DATABASE_URL 后在该库创建并清理临时 schema,连不上就失败,不再静默跳过。V0.2 有单实例验收记录。
  • 结果与证据:没有数据库配置时服务仍可用进程内后端。GET /health/live 只表示进程存活;只配置旧演示种子时 GET /health/ready 返回 503,发布受控 bundle 且恢复对齐后可以返回 200。策略对比的完整结果与普通推荐记录隔离。默认内容基线的 dense 是 CPU 基线,adaptive 不是学习型路由。
  • 遇到的问题:页面必须从 http://127.0.0.1:8000/app 打开。file:// 打不开 API。只启动 API、不启动 worker 时,构建和对比任务会一直排队。
  • 当前结论:这一阶段交付的是单实例演示和离线报告索引,不是 R06 在线质量,也不是公网服务。
  • 下一步:把已批准的冻结包接进可选路由,并继续和内容基线分开说明。

2026-09-17|R06 多兴趣召回:覆盖略增,不支持替换原路径

  • 本次问题:R05 之后要在相同候选数量预算下,比较均值内容召回和近期多兴趣召回,并避免用新用户样本直接和旧轮指标相减。
  • 实际改动:实现多兴趣召回和匹配排序训练,预登记消融,发布审计后的结果与成本分析。测试用户与 R01–R05 的用户交集为零。保留验证规则 A-frozen-s17。提交 bf73ce7、31a4116,PR #2。
  • 验证过程:全部候选来源、特征和模型输出重新计算核对。50 项预登记区间按用户聚类重采样 10,000 次后独立复算。区间条件于固定检查点,不含训练随机性,也没有做多重比较校正。
  • 结果与证据:测试共 12,524 个正反馈请求、9,373 名用户。三个种子的整体 NDCG@10 为:A-frozen(均值内容,冻结 R05)0.010074 ± 0.000129,B-frozen(多兴趣,同一组冻结模型)0.010040 ± 0.000117,C-adapted(多兴趣,重新训练)0.009820 ± 0.000216,D-adapted(均值内容,同阶段重训练)0.010155 ± 0.000027。冷 Recall@20 均值依次为 0.003774、0.003917、0.003678、0.003583。冷目标进入候选池由 115 / 6,978 增至 122 / 6,978;无历史冷目标仍为 0 / 3,928。B−A 的整体 NDCG 差值为 −0.000033769,95% 边际区间 [−0.000260567, +0.000184014];C−D 为 −0.000335551,[−0.000686012, +0.000000421]。两者都跨过零。测试批次的均值内容路径用时 7.865 秒,多兴趣计算另用 12.469 秒。这不是线上延迟。共 6 次训练、74 轮。数字来自仓库 README 的当前结果表,不是本文重新计算。
  • 遇到的问题:三个种子的指标平均不是集成推荐。静态商品元数据没有历史版本。R06 测试现已查看,后续调参需要新协议。
  • 当前结论:本轮没有证据支持用多兴趣路径替换原路径。覆盖有小幅变化,排序收益未获支持。R05 的原始报告和三种子复验保留,但不同用户样本的指标不能直接当作跨轮提升。
  • 下一步:解释无历史冷目标为什么仍然不可达,以及候选增益为什么没有变成排名增益。工程接入不能改写这条研究结论。

2026-09-15|真实基线、用户采样与持续训练报告

  • 实际改动:完成 R01 热门 / ItemCF 实验、R02 完整用户采样、R03 三种子序列训练和自动曲线。
  • 结果与证据:226,172 条交互、39 个 epoch;序列模型三种子测试均值为 0.005628 ± 0.000222,低于时间衰减协同融合的 0.008380。
  • 当前结论:更复杂的网络没有自动战胜时间先验;6,874 个模型冷且可用目标全部未命中,冷商品可达性是下一轮首先要解决的问题。
  • 下一步:补充内容候选路径,冻结评价窗口后重新比较整体、冷物品和低频物品。

2026-09-16|内容双塔、门控策略与冷样本加权排序

  • 本次问题:R02 发现 6,874 个模型冷目标全部未命中。纯协同过滤方法无法处理训练期间未见过的商品,必须补充内容检索路径。即使有了内容路径,如何在不降低整体效果的前提下提升冷商品曝光,以及如何在排序阶段更好地平衡冷热样本,也需要专门设计。
  • 实际改动:
    • R03:实现内容双塔架构,使用商品标题、品牌和类别构建语义向量;完成 48 轮训练;设计协同+内容的混合召回策略。
    • R04:冻结 R03 模型,设计五种冷商品保留与门控策略;在验证集上选择最优策略,测试集上进行消融实验;分析冷商品在召回、粗排、精排各阶段的落选位置。
    • R05:引入 ColdListMLP 排序模型,对冷样本进行加权训练;完成 35 轮训练,在相同候选池下与普通 ListMLP 对比。
  • 验证过程:统计训练集商品词表覆盖率、测试集冷商品占比;检查 Amazon Review 数据集元数据字段完整性;使用 Sentence-BERT 编码商品内容并构建 Faiss 索引;在验证集上比较门控策略效果后锁定配置;训练冷样本加权模型并在测试集上评估。
  • 结果与证据:
    • R03 内容融合改善整体 NDCG,但冷商品命中率低于预期;测试集中约 75% 的目标商品在训练时未被观察到。
    • R04 门控策略在验证集上选出最优配置;测试集消融实验显示门控机制能够在保持整体性能的前提下提升冷商品曝光;落选位置分析表明大部分冷商品在召回和粗排阶段被过滤。
    • R05 冷样本加权排序模型在保持整体性能的同时提升冷商品排序效果;所有实验图表已整理到博客图片目录。
  • 遇到的问题:
    • 内容编码方案需要在效果和可控性之间权衡(最终选择 Sentence-BERT)。
    • 混合召回的融合权重、候选数量分配需要多次实验调优。
    • 门控策略设计需要显式考虑商品是否在词表、用户历史长度等条件。
    • 冷样本加权需要平衡整体性能和冷商品效果,权重过大会损害整体指标。
  • 当前结论:
    • 纯协同过滤方法在词表外商品上完全失效,必须引入内容路径作为独立召回通道。
    • 混合召回需要显式设计路由策略,单一方法无法解决所有场景。
    • 门控机制能够在不跳过检索路径的前提下动态调整召回策略,提升冷商品曝光。
    • 排序阶段的冷样本加权是补充手段,主要提升仍来自召回和粗排的覆盖范围。
  • 下一步:完善在线业务接入,将离线实验结果集成到可操作的推荐系统;补充前端展示与效果看板;记录真实用户交互数据用于后续迭代。2026-10-08 补记:后来的本地演示没有改写本条的 R05 结论;R06 没有支持替换原路径,页面也不是当时计划的 React 应用,见上方条目。