fair-eval-protocol
Skill1 starsChanged 27 days agoMITView on GitHub
横向比较多个模型 / checkpoint / API 供应商 / prompt 版本之前,先把评测协议冻结下来,保证比的是同一件事:冻结输入(对实际发出去的字节做哈希清单)、统一分辨率和解码参数、只在所有臂都产出的样本交集上比、指标口径写死、拒答/内容审核/报错单独计数不偷偷丢、记录每臂实际请求参数、先烟测再起量、先读输出和轨迹再信汇总分、报告带每臂 N。适用于 LLM、VLM、Agent、文生图、图像编辑、ckpt 对比等任何「A 比 B 好」的结论。触发词:公平对比、评测协议、横评、模型对比、ckpt 对比、A/B 评测、fair comparison, eval protocol, model comparison, benchmark setup, apples-to-apples。不用于:只跑一个模型看效果、纯人工偏好盲测页面的搭建、单个指标的实现细节。
In this repository25 other files it gives its agents.
- AGENTS.mdAGENTS.md
- skills/pelican-bicycle-eval/AGENTS.mdAGENTS.md
- skills/tech-talk-deck/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- skills/pelican-bicycle-eval/CLAUDE.mdCLAUDE.md
- api-relay-verifySkill
- architecture-plan-authoringSkill
- batch-vlm-requestsSkill
- decision-stress-testingSkill
- deck-portraitSkill
- edit-drift-evalSkill
- lecture-video-cutSkill
- paper-arch-figureSkill
- paper-quick-readSkill
- pelican-bicycle-evalSkill
- problem-solving-lensesSkill
- question-clarifyingSkill
- quiz-drillSkill
- self-understanding-interviewSkill
- tech-talk-deckSkill
- unfamiliar-topic-learningSkill
- weekly-review-authoringSkill
- working-reportSkill
- xhs-43-deckSkill
- xiaohongshu-content-extractionSkill
The file
Files
fair-eval-protocol · 公平评测协议
一句话:先把「怎么比」定死、存档,再去跑「谁更好」。 跑完再改规则,结论就不可信了。
大多数「A 比 B 好 3 个点」的翻车,不是模型的问题,而是两边吃的输入不一样、参数不一样、失败样本被悄悄丢掉、或者分数在量环境故障而不是能力。本 skill 只写判断;长清单在 references/,两个脚本在 scripts/(只用 Python 标准库)。
什么时候用
- 要比较两个及以上的「臂」(arm):不同模型、同一模型不同 ckpt、同一模型不同供应商 / 接口路由、不同 prompt 或系统提示、不同解码参数。
- 结论会被别人拿去做决定(选型、上线、写报告、发帖)。
- 之前的对比结果「看着不对」,要排查是不是协议问题。
不用:只想看一个模型能不能做某件事;只需要搭盲测页面(协议冻结后再去用盲测工具)。
第一步:先问清楚在比什么
开工前用两三句话和用户对齐,答不上来就停:
- 问题:比的是「模型本身」还是「整条线上链路」(含预处理、后处理、供应商封装)?两者都合法,但不能混在一张排名里。图像编辑的具体例子见
references/example-image-edit.md。 - 臂:每个臂的精确标识——模型 ID、ckpt 路径或 step、供应商路由字符串(真正发出去的那个)、prompt 版本。别名、家族名不算。
- 样本集:从哪来、多少条、有没有和任何一臂的训练数据重叠。
- 指标:主指标一个,写清楚输入是哪两样东西、怎么算、越大越好还是越小越好。
- 预算:总调用次数 × 臂数 × 重复次数,付费调用先给估价。
第二步:冻结协议(跑之前写进 protocol.json)
字段清单和模板见 references/protocol-checklist.md。核心几条:
- 冻结输入字节。 预处理(缩放、裁剪、转码、模板渲染)只做一次,产物落盘,用
scripts/freeze_manifest.py freeze生成manifest.jsonl+manifest.digest。所有臂读同一份文件,不允许各臂各自预处理。 - 统一能统一的,记录统一不了的。 分辨率、prompt(逐字节相同)、system prompt、temperature / top_p / max_tokens / seed、推理档位、重复次数。某一臂的接口不支持某个参数时,不要硬凑,写进「未对齐项」,结论里带上。
- 指标口径写死。 包括:比较的是哪两个产物(比如「模型输入」vs「模型原生输出」,而不是缩略图或二次缩放后的图)、怎么归一化、怎么聚合(均值 / 中位数 / 胜率)、要不要 bootstrap 区间。
- 失败分类写死。 至少分
ok / refused / content_filter / error / timeout / invalid_output,每类单独计数。重试几次、几次后算失败,也提前定。 - 走官方直连。 第三方中转、转售网关可能降质、注入隐藏上下文、改写参数、关掉思考;要比模型就走官方接口,不得已用了中转就把它当成一个独立的臂,不能和直连结果混算。
第三步:烟测,然后读输出
- 每臂先跑 1~3 条,打开原始输出逐条看:图、文本、Agent 轨迹的前十几步。
- 核对「实际请求参数」和协议是否一致——从请求日志 / 响应元数据里读,不从配置文件推断。供应商偷偷改尺寸、截断、换默认值都只会在这里露馅。
- 看到下面任何一种,先修环境,不要起量:模型说「文件打不开」「工具不可用」「题目有歧义」;反复换工具兜圈子;输出尺寸和请求不符;大量空输出。
为什么必须读: 环境故障和真实难度在汇总指标上长得一模一样。一场 Agent 评测里考生跑满步数上限、几百万 token、交付物一个没动,看指标像「题太难」;读轨迹才发现第 11 步它就说了「这些 PDF 用现有工具读不了」——是环境没给对应工具。在读之前已经并行起的十几场全部作废。另外,「可读」要用被测模型手里实际的工具来验证,你自己脚本能打开不等于它能打开。
第四步:起量,只在交集上比
- 每臂结果写成
results.jsonl,每行带sample_id、status、input_sha256、params(实际发出去的)。 - 跑
scripts/intersect.py:得到所有臂都ok的交集common_ids.txt,以及每臂每类失败的计数和逐样本原因。 - 主指标只在交集上算。 失败率作为独立指标并列报告,不能让「拒答多的那一臂」因为难题被过滤掉而显得分高。
- 交集占比明显偏低(经验上 < 80%)时,交集本身已经偏向简单样本,结论里要写明,必要时补一版「失败按最差分计入全集」的口径做对照。
第五步:先对照肉眼,再信指标
- 新指标或代理指标上线前,挑几条极端 case 逐条对照肉眼 / 人工判断。指标和肉眼不一致就换指标,不要靠文案解释为什么分数和画面对不上。
- 例子:图像多轮编辑里某模型背景碎成马赛克,但平均像素差反而低于另一个只是轻微偏色的模型——均值把高频纹理的损失抹平了。换成「编辑区域以外的纹理(梯度)相关性」后,与肉眼判断全部一致。
- 汇总分出来后,每臂随机抽几条 + 分数最高 / 最低各几条,看原始输出。
第六步:报告
报告模板见 references/protocol-checklist.md 末尾。必须有:
- 一句大白话结论,然后才是表格。
- 每臂 N:manifest 总数、ok 数、各类失败数、交集 N(
intersect.py生成的report.md可直接贴)。 - 协议摘要:manifest digest、分辨率、解码参数、每臂实际路由 / 模型 ID、跑批日期。
- 未对齐项:哪些参数没能统一、可能往哪个方向影响结论。
- 指标的盲区:这个指标看不到什么。
不写自己不信的数字。某个数协议有问题,就修协议重跑或删掉,而不是写上去再附免责声明。
脚本
# 冻结输入(目录或样本表);默认拒绝覆盖已有清单
python3 scripts/freeze_manifest.py freeze --inputs <frozen_inputs_dir> --out <run>/manifest.jsonl
python3 scripts/freeze_manifest.py freeze --samples samples.jsonl --out <run>/manifest.jsonl
# 跑批前 / 交付前复核:输入文件和清单都没被动过
python3 scripts/freeze_manifest.py verify --manifest <run>/manifest.jsonl --base-dir <frozen_inputs_dir>
# 交集 + 每臂 N + 失败原因 + 参数一致性告警
python3 scripts/intersect.py --manifest <run>/manifest.jsonl \
--arm A=<run>/A/results.jsonl --arm B=<run>/B/results.jsonl --out-dir <run>/intersectintersect.py 会告警:同一臂出现多套请求参数、没记录参数、实际输入哈希与冻结清单不一致、结果里有清单外的 sample_id、交集占比过低。
参考
references/protocol-checklist.md:协议字段清单、protocol.json模板、报告模板。references/pitfalls.md:按领域(LLM / VLM / Agent / 文生图 / 图像编辑 / ckpt)列的常见不公平来源。references/example-image-edit.md:多家图像编辑 API 对比的完整例子(模型本身 vs 线上链路两种口径、共同原生尺寸、合法的指标操作数)。
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

