本节摘要:需求矩阵的加权排序只回答"谁好",没回答"好在你的预算与延迟门槛内值不值"。本节把成本、延迟、质量作为三个平权维度摆上桌,先钉死口径——质量用带区间的盲测分(6.1 输出);成本用每千次任务成本(每千 token 单价 × 你的平均任务 token 数——拿单价当任务成本是选型第一口径陷阱);延迟用 P95/P99 而非平均值(平均 800ms 的服务可以让两成请求等 3 秒)。然后讲三种真实取舍模式:成本敏感的批量任务用钱换量、交互式产品延迟门槛先行、高价值决策质量优先并把另两维当约束。核心工具是 Pareto 前沿:一个候选若在三维上都被另一个候选"不差且至少一维严格更好",就是被支配解,出局没有任何借口;前沿本身是取舍集合不是答案,最后一刀由业务门槛切。附脚本:输入三维数据,输出前沿与出局名单。建设者侧的对应物是《Evals 实战》4.4 的线上成本延迟监控——选择者定门槛,建设者守门槛。
阅读完本节,你应当能够:
| 维度 | 正确口径 | 常见陷阱 |
|---|---|---|
| 质量 | 盲测 0/1/2 均分(带 bootstrap 区间,6.1) | 用榜单裸分(没过第 4 章三道折价) |
| 成本 | 每千次任务成本 = 每千 token 单价 × 平均任务 token 数 | 拿每千 token 单价直接比(任务长度不同,单价便宜的总账未必便宜) |
| 延迟 | P95/P99,交互场景加首 token 延迟 | 拿平均值(尾巴被平均数藏住,而用户只在尾巴上骂人) |
口径不钉死,三角就是三团雾:一个"单价便宜 30%"的模型如果平均任务 token 数是别人的三倍,总账反而更贵(示意情形,务必按自己的任务实测 token 数)。
| 业务形态 | 优先维 | 另两维的角色 | 典型动作 |
|---|---|---|---|
| 批量处理(离线分类、清洗) | 成本 | 质量设及格线,延迟几乎不管 | 及格线内选最便宜,必要时降档模型 |
| 交互产品(客服、助手) | 延迟 | 质量设底线,成本设预算上限 | P95 门槛先切,门槛内拼质量 |
| 高价值决策(合同审查、代码生成) | 质量 | 成本延迟都当约束 | 前沿右端取质量最高者,贵就贵 |
💡 三种模式的共同点:没有一个模式是"三维都最优"——那正是被支配解的对立面存在的原因。承认取舍,才读得懂前沿。
定义:候选 A 被 B 支配,当且仅当 B 在三维上都不比 A 差,且至少一维严格更好。被支配意味着"存在一个处处不逊色、至少一处更好的选项"——留着它没有论证义务,删掉它也不需要道歉。前沿(互不支配的集合)则是取舍集合:质量换成本、成本换延迟的谱系,最后由业务门槛(预算 ≤X、P95 ≤Y)在谱系上切一刀。
# pareto.py(纯标准库,可直接运行) """成本延迟质量三角:找 Pareto 非劣解——三维一起看,被支配者出局。""" CANDS = { # 示意数据:质量=盲测百分制;成本=元/千次任务;延迟=P95 毫秒 "fam-x-7b": {"quality": 90, "cost": 12, "latency": 2400}, "fam-y-8b": {"quality": 72, "cost": 6, "latency": 1100}, "cloud-a": {"quality": 92, "cost": 40, "latency": 2800}, "local-3b": {"quality": 58, "cost": 2, "latency": 700}, "fam-x-mini": {"quality": 80, "cost": 5, "latency": 900}, } def dominated(a, b): """a 被 b 支配:b 三维都不差且至少一维严格更好(质量越大越好,成本/延迟越小越好)。""" ge = (b["quality"] >= a["quality"] and b["cost"] <= a["cost"] and b["latency"] <= a["latency"]) strict = (b["quality"] > a["quality"] or b["cost"] < a["cost"] or b["latency"] < a["latency"]) return ge and strict if __name__ == "__main__": front = [n for n, m in CANDS.items() if not any(dominated(m, o) for o in CANDS.values() if o is not m)] print("成本延迟质量三角(质量 越大越好 / 成本·延迟 越小越好):") for n, m in sorted(CANDS.items(), key=lambda x: -x[1]["quality"]): tag = "Pareto 前沿" if n in front else "被支配 -> 出局" print(f" {n:11s} 质量 {m['quality']} 成本 {m['cost']:>2d} 元/千任务 P95 {m['latency']:>4d} ms {tag}") print("读法:前沿是取舍集合不是答案——再用业务门槛切一刀(如 P95<=1500ms 且预算<=15 元)")
一次运行的真实输出(实测,示意数据):
成本延迟质量三角(质量 越大越好 / 成本·延迟 越小越好): cloud-a 质量 92 成本 40 元/千任务 P95 2800 ms Pareto 前沿 fam-x-7b 质量 90 成本 12 元/千任务 P95 2400 ms Pareto 前沿 fam-x-mini 质量 80 成本 5 元/千任务 P95 900 ms Pareto 前沿 fam-y-8b 质量 72 成本 6 元/千任务 P95 1100 ms 被支配 -> 出局 local-3b 质量 58 成本 2 元/千任务 P95 700 ms Pareto 前沿 读法:前沿是取舍集合不是答案——再用业务门槛切一刀(如 P95<=1500ms 且预算<=15 元)
示例里最有教学价值的是 fam-y-8b 的出局方式:它单看并不差(72 分、6 元、1.1 秒),但 fam-x-mini 在三维上全面不逊色且严格更好(80 分、5 元、0.9 秒)——这就是被支配,出局不需要任何附加论证。而前沿上的四个候选谁也说不服谁:cloud-a 质量最高但最贵最慢,local-3b 便宜快但质量垫底——前沿内的选择是业务判断,不是数学结论,这正是它之后要交给门槛与评审会的原因。
⚠️ 前沿对数据误差敏感:质量分若没带区间(2.2),92 对 90 的"严格更好"可能只是抽样噪声——质量维度用区间中点比较,重叠时分差不作支配依据。
计费输入 + 输出 token 数从 API 响应里取,写法以官方文档为准),不要用文档标称价直接乘;三条纪律的共同逻辑:三角上每个数都该带日期与来源——这直接是 7.3 报告对证据的要求。建设者侧的对应物:《Evals 实战》4.4 讲线上成本与延迟的持续监控口径,选型定门槛之后由那边守住。
矩阵给了排序,三角给了取舍,现在只差把两者与全部证据装进一页纸——7.3 的选型报告,本书的最终交付物。