本节摘要:选型最常见的开局是"我们想要个更强的模型"——这句话无法执行也无法验收。本节交付需求矩阵:第一列把业务诉求拆成两类行——硬约束(数据合规、中文能力、部署形态、预算上限:不满足即出局,是门槛永远不进权重,因为"合规上差一点"没有意义)与加权维度(盲测质量分、API 稳定性、文档与生态、价格弹性、供应商风险:权重和为 10,德尔菲两轮定稿防止拍脑袋);每个候选在每格打 05 分,且每格必须能指出证据来源。第二列交付四层筛选漏斗:全市场 →(第 12 章的信息源工具)→ 初筛 58 个 →(硬约束)→ 存活 24 个 →(加权排序 + 第 6 章盲测复核)→ 胜者 1~2 个。脚本把"过滤 + 排序"固化成代码,团队共用同一把尺。最后三种常见病:需求膨胀(什么都想要)、权重拍脑袋、照抄大厂清单——各自有解法。矩阵填完,选型就从口味之争变成了表格之争。
阅读完本节,你应当能够:
"想要个更强的模型"缺三样东西:验收标准(多强算强)、取舍规则(强与便宜冲突听谁的)、追责路径(谁拍板的、凭什么)。需求矩阵补齐它们:
| 行类型 | 含义 | 例子 | 判定方式 |
|---|---|---|---|
| 硬约束 | 不满足即出局 | 数据不出境、中文能力达标、必须私有化 | 二值(是/否) |
| 加权维度 | 满足程度有高低 | 盲测质量分、稳定性、生态、价格弹性 | 0~5 分 × 权重 |
⚠️ 硬约束不进权重是最常被违反的纪律。"合规 20% 权重"意味着合规可以用质量换——这句话在评审会上说出来自己都会心虚。门槛就是门槛:先过滤,再排序。
模板(权重和固定为 10,维度可增删,硬约束按业务列):
| 类型 | 项 | 权重/口径 | 候选证据来源 |
|---|---|---|---|
| 硬约束 | 数据合规 | 私有化/指定区域部署 | 供应商合同、资质 |
| 硬约束 | 中文能力 | 中文基准 ≥ 及格线或盲测复核 | 4.2 距离近的中文榜单 + 盲测 |
| 加权 | 盲测质量分 | 3 | 第 6 章 0/1/2 均分(带区间) |
| 加权 | API 稳定性 | 2 | 历史可用率、限流口径(官方+自测) |
| 加权 | 文档与生态 | 2 | 工具链兼容、社区活跃(社区) |
| 加权 | 价格弹性 | 2 | 7.2 的每千次任务成本 |
| 加权 | 供应商风险 | 1 | 经营状况、锁定风险、5.1 治理三件事 |
权重纪律两条:德尔菲两轮——各干系人独立写权重,第一轮亮出分歧最大的维度讨论十分钟,第二轮收敛定稿;权重和恒为 10——加新维度必须从旧维度挪权重,防止"什么都重要"。
| 层 | 动作 | 工具(前章) | 规模变化 |
|---|---|---|---|
| 1 | 信息源初筛 | 1.2 形态归类 + 附录 B 速查 | 全市场 → 常看源 3~5 个 |
| 2 | 候选发现 | 4.3 核对表定信息源档位,4.2 距离矩阵定权重 | → 候选 5~8 个 |
| 3 | 硬约束过滤 | 本节矩阵的门槛区 | → 存活 2~4 个 |
| 4 | 盲测复核 + 加权排序 | 第 6 章盲测/竞技场 + 本节脚本 | → 胜者 1~2 个 |
筛选脚本(门槛过滤 + 加权排序一次做完):
# requirement_matrix.py(纯标准库,可直接运行) """需求矩阵:硬约束做门槛过滤,加权维度给候选排序,输出筛选漏斗。""" HARD = { # 硬约束:任一不满足即出局(是门槛,不是权重) "数据合规": {"fam-x-7b": True, "fam-y-8b": True, "cloud-a": False, "local-3b": True}, "中文能力": {"fam-x-7b": True, "fam-y-8b": True, "cloud-a": True, "local-3b": False}, } WEIGHTS = { # 加权维度:权重和为 10(德尔菲两轮定稿,纪律见正文) "盲测质量分": 3, "API稳定性": 2, "文档与生态": 2, "价格弹性": 2, "供应商风险": 1, } SCORES = { # 示意:各维 0~5 分;每格的证据来源写进选型报告(7.3) "fam-x-7b": {"盲测质量分": 5, "API稳定性": 4, "文档与生态": 4, "价格弹性": 3, "供应商风险": 4}, "fam-y-8b": {"盲测质量分": 3, "API稳定性": 4, "文档与生态": 3, "价格弹性": 4, "供应商风险": 4}, "cloud-a": {"盲测质量分": 5, "API稳定性": 5, "文档与生态": 5, "价格弹性": 2, "供应商风险": 2}, "local-3b": {"盲测质量分": 2, "API稳定性": 3, "文档与生态": 2, "价格弹性": 5, "供应商风险": 5}, } if __name__ == "__main__": passed = [c for c in SCORES if all(HARD[h][c] for h in HARD)] dropped = [c for c in SCORES if c not in passed] reason = {c: [h for h in HARD if not HARD[h][c]] for c in dropped} print(f"漏斗第 3 层(硬约束过滤):{len(SCORES)} 个候选 -> {len(passed)} 个存活") for c, why in reason.items(): print(f" 出局 {c}:不满足 {'、'.join(why)}") total_w = sum(WEIGHTS.values()) ranked = sorted(passed, key=lambda c: -sum(SCORES[c][d] * w for d, w in WEIGHTS.items())) print(f"漏斗第 4 层(加权排序,权重和 {total_w}):") for r, c in enumerate(ranked, 1): s = sum(SCORES[c][d] * w for d, w in WEIGHTS.items()) / (5 * total_w) * 100 print(f" 第{r}名 {c}:加权 {s:.0f}/100") print("读法:前 2 名进入盲测复核(第 6 章),末位作报告里的备选项(7.3)")
一次运行的真实输出(实测,示意输入):
漏斗第 3 层(硬约束过滤):4 个候选 -> 2 个存活 出局 cloud-a:不满足 数据合规 出局 local-3b:不满足 中文能力 漏斗第 4 层(加权排序,权重和 10): 第1名 fam-x-7b:加权 82/100 第2名 fam-y-8b:加权 70/100 读法:前 2 名进入盲测复核(第 6 章),末位作报告里的备选项(7.3)
注意示例的教学含义:cloud-a 盲测分与 fam-x-7b 同为 5,但硬约束一刀出局——加权排序再高的候选,门槛不过就没有然后。这正是"门槛不是权重"的代码化。
| 病 | 症状 | 解法 |
|---|---|---|
| 需求膨胀 | 矩阵 15 行权重全 2 | 权重和恒为 10;每行写"证据从哪来",写不出就删 |
| 权重拍脑袋 | 老板一人定权重 | 德尔菲两轮;分歧最大的维度恰恰最值得开会 |
| 照抄大厂清单 | 拿别家选型清单直接用 | 过一遍 4.2 距离矩阵——别人的场景权重不是你的 |
💡 矩阵的隐藏价值不在算分,在逼问证据:填"盲测质量分 5 分"时你必须指向第 6 章的输出文件——填不出来的格子,就是漏掉的自测。
排序有了,但"第 1 名加权 82 分"还不是一个能签字的决定——质量分旁边必须站着成本与延迟。7.2 把三角摆上桌。