在把大模型接入业务链路的过程中,我们很快撞上一个结构性问题:判别和生成被塞进了同一个组件。
判别只需要一个标签加一个概率,生成需要一段自然语言。两者的输出契约、失败模式、成本结构、SLA 要求完全不同,却共用一次调用。这篇文章讨论一种把两者拆开的做法——用只输出结构化判断的模型承担判别职责,并把这层单独设计。
内容偏架构与设计决策,涉及分层、接口契约、选型边界、可观测性和治理,不涉及模型训练细节。
一、分层:判别层不该和生成层共用一个组件
先看现在的常见链路:
- 输入先过规则引擎;
- 规则兜不住,转给生成式大模型,要求按 schema 输出;
- 外面套一层解析 + 校验 + 重试;
- 重试超限降级人工。
这条链路的问题不在性能,在职责。生成模型被要求"先写一段话,再从话里抠出标签",于是外围必须常驻一套解析与重试代码,而这套代码的存在意义仅仅是弥合接口不匹配。
判断型模型的输出值域是封闭的:选项由调用方给定,刻度由调用方给定,布尔问题只返回概率。输出即契约,中间没有解析阶段。
把它放进分层架构后,职责划分是清晰的:
- 判别层:输出路由结果、风险档位、审核队列归属;
- 生成层:输出解释、摘要、回复草稿、审计说明。
两者的价值主张不同。判别层优化的是决策成本和风险可控性,生成层优化的是表达质量。混在一起,会导致解析成功率这类系统指标和校准准确率这类业务指标互相干扰,告警规则也没法分开配。
二、接口契约:三类问题、封闭值域、单一批量调用
契约只有三种形状,先钉死,后面所有设计以此为准。
枚举选择
- 输入:问题文本 + 候选选项集合(上限约 255);
- 输出:选项集合中的一个元素。
价值在于值域封闭。下游不需要写"未知值兜底"分支,因为不可能返回集合外的值。
有序打分
- 输入:问题文本 + 有序刻度(通常 2~10 档)+ 档位语义锚点;
- 输出:某一档,或两档之间的位置。
注意它是序数而非连续量。不要拿它做均值、方差这类基数运算。
布尔概率
- 输入:一个可判定真假的陈述句;
- 输出:其为真的概率(浮点数)。
这里有第一个设计陷阱:接口没有独立的置信度字段,概率值本身就是那个数。 我看到不少二手资料把它描述成 Bool,照此写适配层会直接报错——返回的是浮点数。"是否是"和"有多确信"在这类接口里是同一个字段,需要布尔值时阈值由调用方自己定。
批量求值
三类问题可在同一请求内并行求值,彼此隔离,增加问题数量几乎不增加响应时间。
对应的架构含义是:判别层应设计成批式接口,而不是单问题接口。 一次调用把一段材料上的所有判断问完,是这类模型的基本用法;逐问题调用纯属浪费。
# 契约示意:一次材料求值,多问题并行
resp = judge(
evidence=material,
questions=[
{
"id": "route", "type": "choice",
"options": ["billing", "technical", "account", "unknown"],
"text": "该请求属于哪个类目?"},
{
"id": "risk", "type": "score", "range": [0, 9],
"anchors": {
"0": "无风险", "9": "高危"},
"text": "该请求的风险等级?"},
{
"id": "abuse", "type": "bool",
"text": "该请求包含滥用意图"},
],
)
# resp.questions[i] -> {answer, probability, model_id}
因为不存在解析失败,这一层的失败模式被简化为一种:返回了一个错误的值。 没有"格式坏了""字段缺失"这类工程异常。这是它最实际的架构收益。
顺带纠正一个说法:结构化输出本来就没有幻觉的产生空间,所以"零幻觉"谈不上优势。它真正省掉的是解析与重试这一整套工程,这与模型判断得准不准是两回事。把工程收益当作能力收益,是选型时常见的误判。
三、选型边界:三种判别实现的分工
把判断型模型、规则引擎/小分类器、生成式大模型放在一起看,边界大致是这样。
规则引擎与传统分类器
- 标签空间固定,改输出就得动模型;
- 换提问方式需要重新训练;
- 优势是确定性强、成本近乎为零。
生成式大模型
- 能力上限高,什么都能答;
- 每次判断都要付 token 成本,延迟高;
- 需要额外的约束层(schema 校验、重试)才可靠。
判断型模型
- 换题成本约等于改一组选项,不重训;
- 不生成 token,延迟与单价低一到两个数量级;
- 边界很硬:不写摘要、不生成代码、不总结文档。
可以落成一条选型判断:
- 需求是"从有限集合里选一个 / 定一个档 / 判一个真假" → 判断型模型;
- 需求是"生成一段人看的内容" → 生成层;
- 需求是"确定性强、分布稳定、规则可枚举" → 规则或小分类器,不必上模型。
需要强调的是第三点的反面:如果任务本身不是判断,判断型模型就不合适。 它的定价里没有"顺带干点别的"的余地。
四、校准:把概率和阈值分成两层设计
很多团队接进来之后只用了 answer,把 probability 丢掉。这是最可惜的地方。
校准的定义只有一句话:在一大堆预测里,模型说 90% 的那些,大约有 90% 是对的。它衡量的是模型对自己把握估计得准不准,与答得对不对是两件事。
由此得到两个设计约束:
- 概率是群体的统计性质,不是单条预测的保证。单独抽一条出来,它什么都不承诺。
- 阈值必须按动作定义,不能全局共用一个。 路由一个咨询请求和批准一笔转账,误判代价差几个数量级。
架构上,这意味着判别层内部应该再分两个概念:
- 概率层:模型输出,不可变;
- 阈值层:业务配置,可按动作调整,需要版本化。
阈值层的典型用法是把判别结果做成漏斗:
- 高置信区间 → 自动执行;
- 中置信区间 → 转人工复核;
- 低置信区间 → 升级给生成式大模型或人工兜底。
所以它不替代大模型,而是把本来要送进大模型的一部分决策提前截流,把最贵的那一层留给真正需要它的部分。
五、可观测性:判别层要盯的不是准确率
判别层上线后,原先盯的"解析成功率""超时率"这类指标已经失效。需要新建三类。
分档准确率曲线
按置信度分桶(如 0.5 以下、0.5~0.65、0.65~0.8、0.8~0.9、0.9 以上),每桶单独统计实际准确率。整体准确率会掩盖分档失真——公开测评里就有案例显示,某一档宣称 0.90 实际只兑现约六成,而整体数字看起来正常。
自动化率
门槛以上样本占比,直接对应"这套系统省下了多少决策成本"。
版本溯源
每次返回都带模型版本号,写进日志。因为校准漂移是静默的:模型一升级,各分档比例悄悄变化,接口不报错也不告警,只能在业务指标上慢慢察觉。
还有一个容易被忽略的指标,是噪声地板。公开测评里有一份自己给出了 0.024 的下限,意思是低于这个量级的差异没有统计意义。我建议在自己的数据集上也先估一个下限,否则团队会为 0.01 的波动开复盘会。
六、稳定性设计:三件必须写进规范的事
第一,模型版本钉死。
使用带版本号的模型 ID,禁止浮动别名。阈值与模型版本必须成对配置。
第二,选项顺序纳入版本管理。
同一模型、同一批题,仅调换选项顺序,准确率可能从 72% 掉到 21%。因此"选项顺序变更"应视同模型变更,触发重新校准。
第三,显式弃权出口。
它不会弃权。 强制二选一时它不会回答"不知道",只会挑一个相对最不坏的。所以候选集合里必须由调用方自己保留 unknown 或 needs_review 类目,不能指望模型主动说"拿不准"。
另外要提前规划一点:它不解释,不给出任何理由。 凡是需要审计、问责、合规留痕的场景,都必须叠加生成模型专门撰写说明。这也再次印证分层的必要性——判别层负责决策,生成层负责解释。
七、验收与治理
验收报告里只写一个准确率是没有意义的,要看一条曲线:
- 横轴是置信度门槛;
- 一条线是门槛以上可自动化的样本比例;
- 一条线是这批样本的准确率。
举个公开数据集的例子:整体命中率 0.598,看起来很平庸;但门槛提到 0.8 之后,可以自动处理 34% 的样本,这批里精度 0.92。整体平庸不妨碍切出一块可靠的自动化区间——这就是验收要回答的问题。
同时提醒样本量问题:我见过两份测评结论完全相反,一份 60 条、一份 2000 条,而 60 条那份里有 50 条落在 0.9~1.0 这一档。这种分布本身就不正常。样本量差三十倍的结果不能横向比较。
治理层面有两条:
- 阈值是业务授权,不是技术参数。 "这个判断做错一次要赔多少"该由承担后果的业务负责人来定。
- 留三样记录:门槛值、模型版本、测量所用数据集。缺任何一样,半年后就没人说得清为什么是这个数,也没人敢动它。
八、部署形态与成本
这类模型适合自托管。目前已有 Apache-2.0 的完整实现,四亿参数级别、单张 T4 上三十毫秒一次、数据不出网,能满足多数合规约束。
但有一个前提必须写在选型结论里:能力来自微调,不来自权重。 有两个互不相干的复现都验证了同一句话——直接用基座权重,准确率低到接近"永远输出最常见那一类"。拿到权重不等于拿到能力。
好在校准成本很低。单卡过一遍数据,几分钟、不到一块钱。这个成本远低于一次错误接入的代价,因此校准应当设计成例行任务,而不是上线前的单次动作。
最后一条部署原则:判别层应嵌在流水线中做判断,不应让它向外写内容。 输出值域封闭是它最大的架构价值,任何试图让它"顺便生成一段话"的设计都会把这个价值抵消掉。
小结
这类模型值得单独立一层,理由不是便宜,而是它把"决策"和"表达"这两件性质不同的事分开了。
分开之后,风险第一次变得可以度量:每个决策附带一个概率,阈值由调用方按动作定义,误判代价由业务方核算。但这个概率准不准,文档里不会写——只能在自己的数据上量,而且数据分布一换就得重新量。