系列前四篇把评测系统从图纸做到亲手跑通:决策图选什么、施工图怎么搭、数据规格书建什么表、实操教程跑通最小版本。但那都是”自己搭给自己用”。真正的规模化问题是:公司有几十个业务场景要评测,平台组不可能替每个业务写题和判分标准,业务同学也不该各自维护执行引擎。答案是把评测做成自助平台,分界原则一句话:平台沉淀与场景无关的自动化,用户携带只有他们知道的场景知识。 这篇给出这条分界线的三个物化形态——一套后端接口、一组开源底座、一份前端功能清单。
一、分界原则:判据只有一条
一件事归平台还是归用户,判据是:换一个业务方,这件事要不要重做?要重做的是场景知识,归用户;照样成立的是自动化,归平台。
| 换业务方照样成立 → 归平台 | 换业务方就要重做 → 归用户 |
|---|---|
| 评测运行的调度、并发、重试 | 评测样本(题目与参考答案) |
| 数据集版本化与不可变快照机制 | 判分标准(rubric、oracle 选择) |
| 评分器的执行框架与校准流程 | 每个场景的通过阈值 |
| 多模型对比与统计口径(含置信区间) | 任务类目体系(什么算 code_gen、什么算客服) |
| 报表、趋势、错题下钻的呈现 | 「这个分数能不能接受」的业务判断 |
| CI 门禁、webhook、配额、权限 | 金集样本的审核决定 |
这把刀在系列里已经切过一次:施工图篇的元规律是”开源承包通用管道,自研沉淀私有知识”——那是公司与开源生态的分界。本篇把同一把刀往公司内部再切一层:平台组与业务组的分界。两次切割的判据同构:管道无场景,知识有主人。
由此导出平台的三个承诺和用户的三个责任:
- 平台承诺:你带题和标准来,我给你①可重复地跑(版本钉死)、②永久地存(血缘可溯)、③公平地比(统一口径)。
- 用户责任:①题是你的(样本从你的业务 trace 和领域知识里来)、②尺是你的(判分标准你定义、你审核)、③线是你的(多少分算过,你拍板)。
二、总体架构:薄平台,厚底座
flowchart TB
subgraph FE["前端(八个功能模块)"]
UI["场景工作台 / 运行台 / 报告页<br>裁判校准中心 ..."]
end
subgraph API["平台 API 层(自研薄层)"]
GW2["七组端点<br>场景·评分器·运行·模型<br>报告·集成·标签供给"]
end
subgraph EXEC["执行层"]
W["评测 Worker 池<br>Inspect AI headless"]
end
subgraph BASE["底座"]
LF["Langfuse<br>trace / scores"]
PG["PostgreSQL<br>平台元数据"]
OBJ["对象存储<br>样本内容 / .eval 日志"]
end
LLMGW["LLM 网关(LiteLLM)"]
CI["CI / IM"]
RT["路由侧<br>M2 注册表 / M4 策略"]
UI --> GW2
GW2 --> W
GW2 --> PG
W --> LLMGW
W --> LF
W --> OBJ
GW2 -->|"webhook / gate"| CI
GW2 -->|"能力标签 · 偏好对"| RT
读图要点:自研的只有 API 层和前端,且都是薄层——执行归 Inspect AI,观测归 Langfuse,模型访问归 LiteLLM 网关(评测流量与业务流量同一入口,成本进同一本账,这是实操教程第 4 步已经跑通的接法)。平台的自研价值不在这些管道里,在第一节那张分界表的右列如何被接住。
三、后端接口:七组端点
每个端点标注一个问题的答案:这个端点传递的是场景知识(用户→平台),还是自动化服务(平台→用户)?这是第一节判据在 API 设计上的投影。
3.1 场景与数据集组(用户提交场景知识)
| 端点 | 语义 |
|---|---|
POST /scenarios | 建场景:名称、task_class、描述、负责人 |
POST /scenarios/{id}/samples | 批量提交样本,落地即 candidate 状态(审核状态机) |
PATCH /samples/{id} | 审核动作:改写输入、补判分标准、candidate → reviewed |
POST /scenarios/{id}/dataset-versions | 把 reviewed 样本冻结为不可变数据集版本 |
GET /dataset-versions/{v}/diff?base={v0} | 两版数据集差异(加了哪些题、退了哪些题) |
样本 schema 直接采用数据规格书那份(input/oracle_type/oracle_spec/source_trace_id/status),这里不重复。
3.2 评分器组(目录归平台,语义归用户)
| 端点 | 语义 |
|---|---|
GET /scorers | 内置评分器目录(includes/match/json_fields/model_graded_qa…,即 Inspect 内置 + 平台扩展) |
POST /scorers | 注册自定义评分器:规则型(沙箱执行的脚本)或裁判型(rubric + judge 模型版本) |
POST /scorers/{id}/calibrations | 对裁判型评分器跑校准集,返回与人工标注的一致率——不达标的 judge 不许用于金集 |
LLM-as-judge 的完整定义:裁判型评分器不是”选个模型当裁判”,注册时是一个五元组对象——裁判模型(版本钉死)、rubric(版本化)、偏差对策开关、回避规则、校准绑定:
scorer_id: cs-rubric-judge@2.1.0
type: judge
judge_model: strong-api-x@2026-06 # 裁判模型版本钉死
rubric: rubric-cs@2.1.0 # rubric 是独立版本化对象,改一字出新版
pairwise_swap: true # 成对比较时交换位置跑两次,抗位置偏差
exclusions: ["strong-api-x*"] # 裁判不评自家产出
calibration: cal-cs@1.0.0 # 绑定校准集(一种 oracle_type=human 的数据集)
其中三条纪律——钉版本、换位置、避自家——是 MT-Bench 论文钉死的三种裁判偏差(位置、冗长、自我增强)的工程对策,施工图 M7 的原文照录。分界在此非常清楚:rubric 写什么是用户的场景知识,纪律怎么执行是平台的自动化——用户可以改评分标准,但不能关掉换位重跑,也不能让裁判给自家打分。judge 的调用同样走统一网关,裁判成本归到发起场景的账下。
3.3 运行组(纯自动化)
| 端点 | 语义 |
|---|---|
POST /runs | 提交评测:只接受四元组版本引用,见下方示例 |
GET /runs/{id} | 状态与进度 |
GET /runs/{id}/results | 样本级结果(请求级标签的 API 形态) |
POST /runs/{id}/cancel | 取消 |
POST /runs
{
"dataset_version": "cs-faq@1.3.0",
"scorer": "cs-rubric-judge@2.1.0",
"models": ["qwen3-32b-sft-0801", "strong-api-x"],
"prompt_pack": "cs-bot@4.0.2",
"idempotency_key": "run-cs-faq-20260809-a"
}
3.4 模型组(对用户只读)
GET /models:模型池与能力标签(含 n、置信区间、capability_eval_run 出处)。写入只有平台的标签流水线有权限——标签禁止手填,这条纪律从施工图篇 M2 一路贯彻到这里。
3.5 报告与对比组(纯自动化)
| 端点 | 语义 |
|---|---|
POST /comparisons | N 模型 × 同一数据集版本 × 同一评分器的对比矩阵 |
GET /scenarios/{id}/trend | 该场景各模型历史通过率曲线(nightly 积累) |
GET /runs/{id}/failures | 错题清单(判 I 的样本 + 模型输出 + 评分解释) |
3.6 集成组(平台伸向外部系统的手)
| 端点 | 语义 |
|---|---|
GET /runs/{id}/gate?threshold=0.75 | 返回 {"pass": false, "accuracy": 0.71}——CI 门禁只需 curl 这一下 |
POST /webhooks | run 完成 / 门禁失败 / 趋势异动时回调 CI 或 IM |
POST /tokens | 场景级 API token(业务方把评测挂进自己的流水线用) |
3.7 标签与路由供给组(评测结果的出口)
系列主线「评测产标签,标签产路由器」在平台上的物化——没有这组端点,平台只是打分工具;有了它,平台才成为路由系统的上游(蒸馏定律:路由器是评测器的蒸馏,这组端点就是蒸馏数据的出料口):
| 端点 | 语义 |
|---|---|
GET /models/{id}/capabilities | 模型 × task_class 能力标签:pass_rate、n、Wilson 区间、eval_run 出处、fresh/stale |
POST /capability-labels/refresh | run 完成后平台自动触发的聚合任务(亦可手动):按标签口径(n 门槛、失效三规则)重算并写回模型注册表——人不许手填 |
GET /exports/request-labels | 请求级标签批量导出 (sample_id, model, score, scorer_version, run_id)——L3 路由预测器训练数据的原料 |
POST /exports/preference-pairs | 给定模型对 + 数据集版本,按规格四的导出逻辑生成偏好对;平台强制 scorer_version 一致性约束,跨口径分数拒绝配对 |
webhook 事件 capability_label.changed | 标签变更推送——路由策略中心(施工图 M4)订阅它触发策略重估 |
分界判据在这组端点上依然成立:标签的口径与生产(聚合规则、n 门槛、失效规则、一致性约束)换业务方照样成立,归平台;标签的消费(用哪个标签路由、阈值定多少)是路由策略的事——平台到”导出 + 事件”为止,不替路由器做决定。
接口设计三纪律
- 一切引用版本号,不接受散装内容。
POST /runs不接受内联的样本或 rubric——先注册、再冻结、后引用。这是数据契约定律在 API 上的执行:没有版本引用,归因树就断。 - 写操作幂等(
idempotency_key):评测跑一次很贵,重试语义必须明确。 - 平台不解释分数。分数语义在 scorer 定义里,阈值判断在用户的门禁配置里——平台只负责算得对、存得住、比得公。平台一旦开始替用户解释”0.8 算好吗”,分界就塌了。
四、开源底座:三层装配,或直接采用半成品
4.1 推荐装配(自研薄层路线)
执行引擎 Inspect AI(headless,eval() Python API + read_eval_log,教程篇全部亲手验证);观测与分数存储 Langfuse;模型访问 LiteLLM 网关。自研只剩 API 薄层(FastAPI 量级)和前端。
4.2 「半成品平台」对比(也许你根本不用自研)
三个开源项目已经各自实现了”数据集 + 实验 + 打分 + UI”的大半(以下特性与许可均核实自各官方仓库/文档,2026-08-09):
| 项目 | 许可 | 已覆盖 | 特色 |
|---|---|---|---|
| Langfuse | MIT(ee/ 目录除外) | trace、datasets、scores、OpenAPI 全量 REST API、自部署 | 和 LiteLLM 现成集成,trace 底座最强 |
| Opik(Comet) | Apache-2.0(含 server + Web UI 全开源) | datasets、experiments、LLM 裁判指标库、playground、仪表盘、REST API | 许可最干净、评测功能最”平台化” |
| Phoenix(Arize) | ELv2(非 OSI 开源,注意分发限制) | OTel tracing、datasets & experiments、evals、OpenAPI、自部署 | OpenTelemetry 原生,与 OTel 语义约定同路 |
选型判断(观点):小团队(≤2 人做平台)别自研——直接采用 Opik 或 Langfuse 当”80% 的平台”,把人力花在第一节右列的运营上。自研薄层路线只在两种情况成立:①公司已有统一前端/权限体系,业务方需要”业务语言”而非”trace 语言”的界面;②需要把能力标签写回模型注册表、把门禁嵌进已有 CI 体系这类深度集成。无论选哪条,三样东西开源都不会替你做:场景工作台的业务语义、门禁阈值的治理流程、能力标签到路由的回写链(第三样已在 3.7 落成端点)——那正是分界表右列和施工图自研列的交集。
五、前端:八个功能模块
每个模块一行「用户在这里决定什么 / 平台在这里自动化什么」——前端就是分界线的可视化:
| 模块 | 用户决定(场景知识) | 平台自动化 |
|---|---|---|
| ① 场景工作台 | 建场景、写描述、定 task_class | 模板、校验、权限 |
| ② 样本审核队列 | 逐条通过/驳回/改写,补判分标准 | candidate→golden 状态机、与源 trace 对照展示、批量导入去重 |
| ③ 运行台 | 选数据集版本 × 评分器 × 模型集合 | 调度、并发、进度、失败重试 |
| ④ 报告页 | 看哪个模型可接受 | 对比矩阵、按类目下钻、错题本(判 I 样本 + 输出 + 评分解释)、样本级 transcript |
| ⑤ 趋势页 | 判断异动要不要追 | nightly 曲线、版本标注线(数据集/模型/评分器哪个变了) |
| ⑥ 门禁配置 | 定阈值、选触发时机 | gate API、CI token、webhook、失败通知 |
| ⑦ 模型池管理(管理员) | 上架/下架模型 | 能力标签展示(含 n 与置信区间)、配额与预算 |
| ⑧ 裁判校准中心 | 标注校准集(人工期望判分)、决定 rubric 怎么改 | 跑一致率、发/收「上岗证」(不达标的 judge 全平台拦截)、一致率趋势监控(judge 漂移预警) |
三个设计要点:
- 错题本是整个前端最有价值的页面。通过率是给管理层的,错题本是给用户改进用的——它就是请求级标签的 UI 化,也是用户下一轮吸新样本的直接来源(错题天然是难题)。
- 趋势页必须画”版本标注线”。分数曲线上每次数据集/评分器/模型版本变更都标一条竖线,否则用户面对异动的第一反应是”模型退化了”,而归因树告诉我们多数异动是前三类假异动。
- 校准中心是 judge 的”驾照考场”。没有它,归因树的「评分问题」分支永远查无实据;有了它,“裁判还靠谱吗”从争论变成查询。
六、成立判据:15 分钟自助旅程
平台是否成立,判据是这条时序图里平台组的人一次都不出现:
sequenceDiagram
participant U as 业务同学
participant FE as 前端
participant API as 平台 API
participant W as 评测 Worker
U->>FE: 建场景「客服 FAQ」
U->>FE: 粘贴 20 条样本(含参考答案)
FE->>API: POST samples(candidate)
U->>FE: 逐条审核 → 冻结 cs-faq@1.0.0
U->>FE: 选评分器模板 改写 rubric
FE->>API: POST scorers(裁判型)
U->>FE: 选 3 个模型 发起对比
FE->>API: POST /runs(四元组引用)
API->>W: 调度执行
W-->>API: 样本级结果回写
U->>FE: 看对比矩阵 下钻错题本
U->>FE: 设门禁 threshold=0.8 接入 CI
Note over U,W: 全程无平台组人工介入
一个例外值得点明:若选的是裁判型评分器,旅程中会被平台多拦一步——judge 必须先在校准中心拿到”上岗证”(模块⑧),未达标的裁判不能用于正式 run。这一步拦的不是用户,是分数的可信度。
七、落地顺序:API 先于 UI,读先于写
- 阶段 A(第 1–2 周):headless API。 用 FastAPI 包住教程篇的
eval()+read_eval_log,先出运行组和集成组的五个端点——curl 也是客户端,第一个业务方完全可以用 CLI 自助。前端晚于 API 不是妥协,是纪律:接口被真实使用打磨过再画界面。 - 阶段 B(第 3–4 周):读页面。 报告页 + 趋势页 + 错题本——读多写少,先做读,业务方最先感知到的价值是”看得清”。
- 阶段 C(第 2 个月):写页面与治理。 场景工作台、审核队列、门禁配置、校准中心、配额。这一步才需要权限体系。标签与路由供给组(3.7)也放这一阶段:它要靠积累的 run 数据才有内容,且它的消费方(路由器)本来就该晚于评测上线——施工顺序定律在平台内部同样成立。
八、带得走的总表:分界线的三个物化形态
| 事项 | 归属 | 物化在哪 |
|---|---|---|
| 样本与参考答案 | 用户 | POST samples + 审核队列(模块②) |
| 判分标准 | 用户 | POST /scorers + rubric 编辑器(模块①) |
| 通过阈值 | 用户 | gate?threshold= + 门禁配置(模块⑥) |
| 执行与调度 | 平台 | 运行组端点 + Inspect worker |
| 版本化与血缘 | 平台 | dataset-versions 端点 + 四元组强制引用 |
| 统计口径 | 平台 | comparisons 端点(含置信区间) |
| judge 质量治理 | 共担 | calibrations 端点 + 校准中心(模块⑧):用户标校准集,平台算一致率并拦截 |
| 裁判纪律(钉版本/换位/避自家) | 平台强制 | scorer 五元组 schema,用户改不了纪律开关 |
| 能力标签口径与生产 | 平台 | capability-labels/refresh + 标签流水线(n 门槛、失效规则) |
| 路由训练数据 | 平台(生产)→ 路由侧(消费) | exports/request-labels + exports/preference-pairs(3.7) |
| 能力标签 | 平台(生产)→ 用户(消费) | GET /models 只读 |
本篇元规律(平台分界定律):评测平台的产品边界 = 用「换一个业务方要不要重做」这一条判据切出来的线;后端接口、开源选型、前端模块,都是同一条线的三次投影。系列的分界刀法至此切了三层:开源 vs 自研(公司↔生态)→ 字段契约(模块↔模块)→ 平台 vs 用户(平台组↔业务组)——每往下一层,“谁拥有知识”就更具体一分。
诚实的提醒
- 七组端点、八个模块、三阶段顺序均为我的设计方案,行业无统一标准;端点粒度应随团队规模合并(两人团队可以把场景组和评分器组合成一个”场景包”资源)。裁判三纪律的依据是 MT-Bench 论文钉死的三种偏差(正文带链接),但”五元组 schema + 平台强制执行”这个产品化形态是我的设计。
- 三个开源项目的功能与许可信息核实自其官方仓库与文档(2026-08-09 当日):Langfuse MIT(
ee/除外)、Opik Apache-2.0、Phoenix ELv2。我未亲手部署过 Opik 与 Phoenix(Langfuse 的数据模型此前核实过文档、Inspect AI 在教程篇亲手跑通);许可细节以各项目 LICENSE 文件为准,选型前自行复核。 - 「15 分钟旅程」是设计目标不是实测数字。
成本最低的亲手验证实验(半天):不写前端,用 FastAPI 只包三个端点——POST /runs(内部调教程篇的 inspect_eval())、GET /runs/{id}(读 .eval 日志)、GET /runs/{id}/gate?threshold=(返回 pass/fail)。写完用 curl 走一遍第六节的旅程(场景和样本先用文件系统代替数据库)。这 30 行就是平台的种子:你会立刻体会”接口先于界面”为什么成立——以及第一个真实用户(你自己)会立刻要求哪个端点,那就是阶段 B 的优先级。
参考来源
工程实践 / 官方文档
arXiv 论文
- Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena(arXiv 2306.05685,NeurIPS 2023)(裁判三偏差的出处,逐节笔记)
- RouteLLM(arXiv 2406.18665,ICLR 2025)(偏好对训练路由器,3.7 出料口的下游)
本站相关旧文(本系列)
- 决策地图·评测路由篇 → 施工图篇 → 数据规格书篇 → 实操教程篇 → 本篇
- 门禁篇:不可逆边界定律 ・ Eval 是新的 PRD