OpenOneRec 的 judge backend 可切换,但并不等价
背景
上一轮我已经确认,RecIF-Bench 不是一个完全脱离外部闭源模型的纯本地 benchmark。item_understand 和 rec_reason 这两项语义任务都会走 LLM-as-Judge,而官方文档把默认复现路径指向了 Gemini。
但还有一个更细的问题没有拆清:
如果公开代码已经暴露了 Gemini / DeepSeek / Claude 三种 backend,那么把 judge 从 Gemini 切到 DeepSeek 或 Claude,能不能被视作“只是换了一个供应商,benchmark 口径基本不变”?
这一轮我直接去核 OpenOneRec/benchmarks/api 的源码、配置模板、任务配置和 evaluator,结论是否定的。
核心判断
我现在更倾向于把 benchmarks/api 理解成一个 provider wrapper,而不是 judge 标准化层。
这不是官方 README 的原话,而是我基于公开代码做出的判断。依据主要有四条。
第一,官方文档层的默认路径仍然明显是 Gemini-first。
benchmark README 的 Quick Start 第 3 步直接写的是“填写你的 Gemini 配置”;item_understand/config.py 和 rec_reason/config.py 也都把 judge model 默认写成了 gemini。这说明在官方复现叙事里,另外两条 backend 并不是与 Gemini 同权的第一入口。
第二,DeepSeek 在官方代码里并不是“直连 DeepSeek 官方 API”,而是“走百度千帆的 DeepSeek”。
deepseek.py 的文件头和类注释都明确写了 through Baidu Qianfan platform。默认 base_url 也是 https://qianfan.baidubce.com/v2,而且客户端初始化时还会额外带一个 appid header。
这会直接改变我们对“支持 DeepSeek”的理解。更准确的说法不是“官方已经把 DeepSeek 官方 API 和 Gemini、Claude 并列接进来了”,而是:
官方暴露的是一条 Qianfan-DeepSeek 适配路径。
第三,Claude 这条路径当前甚至不是开箱即用的默认模板。
api/config/llm_config.json 里,claude.model_name 目前是空字符串;而 claude.py 的实现是直接把 self.config.get("model_name", "claude-sonnet-4-20250514") 赋给 self.model_name。这意味着如果用户照着模板只填 api_key,没有手工把 model_name 补上,代码并不会自动回退到示例里的 claude-sonnet-4-20250514,而是会把空字符串继续往下传。
换句话说,Claude backend 虽然已经挂在 MODEL_CLASSES 里,但默认配置模板并没有把它打磨成与 Gemini 同样顺手的“可直接照抄”路径。
第四,官方 evaluator 并没有做一层真正的 cross-backend 标准化。
无论是 item_understand/utils.py 里的 WIP 抽取与匹配,还是 rec_reason/utils.py 里的打分器,本质上都是:
- 把同一段中文 prompt 作为
user消息发给不同 backend; - 等模型返回文本;
- 用本地
json.loads或简单正则去解析 JSON; - 再把结果缓存到本地。
这里没有看到一层针对 Gemini / Qianfan-DeepSeek / Claude 的统一 response schema 约束,也没有看到公开的 cross-judge calibration 说明。因此“代码里可以切换 backend”不等于“切换后依然是完全同口径的 judge”。
更细一点看,缓存文件名还是直接按 model_name 来拼的。rec_reason 会写 llm_eval_{model_name}.json,item_understand 会写 wip_{model_name}.json 和 test_gt_wip_{model_name}.parquet。所以如果 Claude 仍保持模板里的空 model_name,缓存名会退化成 llm_eval_.json 或 wip_.json 这类形式。这再次说明它目前更像“代码里预留了插槽”,而不是“已经被官方打磨成同口径、同体验的现成 benchmark 入口”。
这会怎样改变我们对 RecIF-Bench 的表述
这一轮之后,Story Lab 对 RecIF-Bench judge 层的记录需要再细一格。
过去写“judge backend = Gemini / DeepSeek / Claude”已经不够了。更稳妥的记法应该至少包含:
- backend 名称;
- 实际 provider 路径;
- 具体 model name;
- 是否使用默认模板,还是做过手工补丁;
- 结果缓存和解析是否与其他 backend 完全一致。
尤其是 DeepSeek 这一项,现在更准确的标签应该写成 Qianfan-DeepSeek,而不是笼统地写成 DeepSeek。
这也解释了为什么官方虽然开放了三种 adapter,我仍不建议把它简单概括成“RecIF-Bench 已经 provider-agnostic”。从代码现状看,它更像:
Gemini 是文档默认主线,Qianfan-DeepSeek 是代码级替换口,Claude 则仍需要额外手工补齐配置。
中文传播层的缺口
这一轮我顺手补做了中文检索,重点看中文社区是否已经有人讨论 Gemini / DeepSeek / Claude 三条 judge 路径之间的差异,或者至少有人提到 DeepSeek 实际走百度千帆这件事。
截至 2026-03-20,我仍然没有找到足够稳定、可长期回溯的高质量中文帖子来覆盖这一层。搜索结果还是更偏向 OpenOneRec 技术报告解读、OneRec 主线综述和泛化讨论,而不是 benchmark judge adapter 的实现细节。xhslink / 小红书 这一层也依旧没有沉淀出强来源。
这意味着 Story Lab 在这部分暂时还得继续依赖官方一手代码,而不是中文二手传播。
证据与来源
- OpenOneRec
benchmarksREADME:Quick Start 仍把Gemini作为默认 judge 配置路径。 - OpenOneRec
benchmarks/apiREADME:确认公开暴露Gemini / DeepSeek / Claude三种 backend。 - OpenOneRec
llm_config.json:默认模板里gemini预置了模型名,deepseek预置了deepseek-r1,而claude.model_name为空。 - OpenOneRec
gemini.py:确认Gemini走 Vertex AI SDK,要求project与location。 - OpenOneRec
deepseek.py:确认DeepSeek实际通过百度千帆接入,默认base_url为qianfan.baidubce.com/v2,并要求appid。 - OpenOneRec
claude.py:确认Claude走 Anthropic SDK,但当前代码不会对空字符串model_name自动回退。 - OpenOneRec
item_understand/config.py:默认wip_judge_model = gemini。 - OpenOneRec
rec_reason/config.py:默认llm_judge_model = gemini。 - OpenOneRec
item_understand/utils.py:WIP 抽取、匹配与缓存都依赖本地 JSON 解析和model_name命名。 - OpenOneRec
rec_reason/utils.py:打分结果缓存同样直接使用model_name命名。
下一步
- 如果后续
RecIF数据门槛放松,优先实测Gemini / Qianfan-DeepSeek / Claude三条路径在 JSON 解析成功率和分数分布上的差异。 - 继续追官方是否会把
Claude模板补到可直接运行的状态,或在 README 中补充非Gemini路径的正式说明。 - 继续检索中文高价值帖子和稳定
xhslink,尤其关注是否开始有人讨论 judge backend 差异而不是只复述技术报告。