0010 用视频质量分决定同组菜谱的先后
- 状态:已采纳
- 日期:2026-10-21
背景
- 推荐按「缺几样食材 → 是不是大杂烩 → 用上几样已选食材」排序,这几项都一样时按
recipe.csv的行号排。行号只是录入顺序,跟菜好不好做、视频好不好看无关。 - 同组的菜往往很多:选「番茄、鸡蛋」时,一样不缺的有 57 道,用户只看得到前几道。
- 视频质量差别很大:有的几百万播放、讲得细,有的几千播放、画面也不清楚。每周的视频巡检本来就要调 B 站接口,顺手就能拿到播放、点赞、收藏、投币和时长。
方案对比
| 问题 | 方案 | 取舍 |
|---|---|---|
| 分数用在哪 | 和食材匹配度加权混合 | 高分但缺食材的菜会排到前面,违背「按现有食材做菜」 |
| 只替换最后一级的行号 | 不影响匹配结果和分组,只决定同组先后,风险最小 | |
| 怎么算 | 只看播放量 | 老视频、热门 UP 主一直霸榜,播放量还会自我强化 |
| 互动率为主,播放量取对数为辅 | 点赞、收藏、投币占播放的比例更能说明「讲得好、有人照做」 | |
| 在哪算 | Web 和 iOS 运行时各自算 | 两边公式要逐行对齐,浮点误差可能让顺序不一致 |
pnpm convert 算好写成整数 score | 两端只比较整数,共享用例能保证顺序完全一致 | |
| 数据存哪 | 手填进 recipe.csv | 每周都变,手填不现实,还会污染 CSV 的 diff |
单独的 packages/data/video-stats.json | 每个视频一行,由脚本生成,diff 好读 |
决定
pnpm check:videos --stats在巡检的同时把每个视频的view、like、favorite、coin、duration写进packages/data/video-stats.json;失效的记{ "dead": true };这次没查到(限流、超时)的沿用上次的数据。- 分数(
packages/cook/src/utils/score.ts)是 0~100 的整数:- 互动率 =(点赞 + 收藏 + 投币)÷ 播放,15% 及以上算满,占 6 成;
- 播放量取
log10,1 千记 0、1 千万记满,占 4 成; - 超过 15 分钟的视频扣 10 分,跟着做不方便;
- 视频失效记 0 分;只有图文、或还没有数据的菜不写分数,排序时按 50 分算,不吃亏也不占便宜。
pnpm convert和pnpm fixtures读这份数据,把score写进recipe.json。TS 的recommendRecipes和 CookCore 的Recommender在用上的食材数相同时按分数从高到低排,分数也相同时才看行号。score是可选字段,旧版 App 解码时会忽略,不需要提高DATA_SCHEMA_VERSION。
影响
- 更新分数:本地(或能访问 B 站的机器上)运行
pnpm check:videos --stats && pnpm convert && pnpm fixtures,一起提交。GitHub Actions 的机房 IP 常被 B 站风控,先不在 workflow 里自动提交。 - 搜索(
searchRecipes)和随机推荐暂不使用分数。 - 下一步可以接入应用内信号:收藏数、「视频打不开 / 视频不对」的反馈直接扣分;点开率要先按结果位置纠偏(排在前面的天然点得多),等数据量够了再加。
- 权重是拍脑袋定的初值。有了
pnpm eval:search的评测数据后,按命中率和 MRR 调整,调整时更新这篇记录。