LLM 生产系统第 3 级:用组合置信度让智能体学会说「我不确定」

Stack Overflow Blog 2026-10-08T11:35:37.590134

当大模型系统从「能跑起来」走向「自己拿主意」,所有判断最终都会落到同一个数字上:置信度。本文拆解生产环境里的三级机制——怎么把几个彼此独立的信号拼成一个可靠的置信度分数、怎么验证这个分数真的准、以及怎么让高风险决策走独立复核,把拿不准的部分干净地交还给人类。

从「能跑起来」到「敢自己动手」

前两级成熟度解决的是让系统跑起来,并且能看见它在跑。到了第 3 级,问题变了:系统凭什么自己动手?

答案只有一个——置信度。而且不能是随便一个数字,必须是经过校准的置信度:

这三件事其实是同一套机制的三个侧面:

三者都做对,你才拥有一个「知道自己不知道」的系统,也才敢把更多事情交给它。对做 AI 编程工具和氛围编程(vibe coding,指用自然语言描述需求、由模型直接产出代码的工作方式)的人来说,这套机制尤其关键:代码生成看起来总是很自信,而「看起来很自信」恰恰是最不能当作依据的东西。

组合置信度:永远不要只信一个来源

如果你直接问大多数 LLM 系统「你有多确定?」,基本得不到有用的东西。要么它压根不给数字,要么给的只是模型自己报的分数——而模型自报的置信度校准极差,错得离谱的时候依然无比自信。

所以置信度必须工程化地造出来。生产环境用的分数,由多个相互独立的信号组合而成,绝不直接采用模型自己的说法:

@dataclass
class Signals:
    model_self: float            # 模型自评分数——有用,但权重调低(它过度自信)
    verification: float          # 确定性检查的通过比例(0..1)
    judge_agreed: bool | None    # 该决策被裁判复核过则为 True/False;未抽样则为 None(大多数决策都没被抽样)
    historical: float            # 该切片过去的准确率(例如 0.99 对比 0.80)

WEIGHTS = {"model_self": 0.25, "verification": 0.35, "judge": 0.25, "historical": 0.15}

def compose(s: Signals) -> float:
    # 只有约 8% 的决策会被裁判。当 judge_agreed 为 None 时,去掉裁判项,
    # 把剩下的权重重归一化——没被裁判的决策既不该被扣分(False),也不该被伪造加分(True)。
    parts = {"model_self": s.model_self, "verification": s.verification, "historical": s.historical}
    if s.judge_agreed is not None:
        parts["judge"] = 1.0 if s.judge_agreed else 0.0
    return sum(WEIGHTS[k] * v for k, v in parts.items()) / sum(WEIGHTS[k] for k in parts)

具体权重怎么分配并不重要,重要的是原则:单一的置信度来源就是单点故障。

模型自评那一项被刻意压到最低权重。原因很直白:一个自信犯错的模型,会被失败的验证或否定它的评审拉下来,所以光靠「自信地犯错」是过不了关的。另外三个信号都是你能独立核实的——确定性验证要么通过要么没通过,评审要么认同要么不认同,历史准确率是针对这一类样本实测出来的事实。模型对自己的评价,是唯一你无法独立核实的输入,这正是它话语权最小的原因。

校准:让 0.9 真的等于 90%

一个分数只有经过校准才有用。所谓校准,就是「0.9」要真的意味着「大约 90% 的情况是对的」。

怎么查?把决策按预测置信度分组,再测量每一组的真实准确率,就得到一张可靠性图(reliability diagram)。实测数据往往揭示同一个问题:模型自报高置信度的那一档,实际准确率明显低于它宣称的数字——偏差通常就集中在高分区。

对开发者来说,这意味着「模型说自己很确定」和「这件事真的有九成把握」是两回事,而后者才是能被自动执行、能被写进流水线的前提。

关键要点

分组校准表:模型说「95% 有把握」,实际只对了 71%

模型的「自信」到底值不值得信?检验方法很直接:把预测结果按置信度分档,再逐档核对真实正确率。

预测区间 平均预测值 实际准确率 结论
0.90 – 1.00 0.95 0.71 ⚠ 过度自信——需重新校准 / 提高阈值
0.80 – 0.90 0.85 0.84 ✓ 校准良好
0.70 – 0.80 0.75 0.77 ✓
< 0.70 0.55 0.52 ✓(不确定得恰到好处)

所谓「校准」(calibration),就是模型报出的把握度要能和真实正确率对得上。系统说「95% 有把握」,结果只有 71% 是对的——这不是小数点级别的偏差,而是整整一个档位的错配。自动执行的阈值只要设得松一点,系统就会带着 95% 的自信,去做一件实际正确率只有 71% 的事。

问题不在整体,只出在最高那一档

值得注意的是,中间几档的表现相当稳:0.80–0.90 档报 85%、实际 84%;0.70–0.80 档报 75%、实际 77%;低置信档也「不确定得恰到好处」。

换句话说,模型并不是完全不会估分,毛病集中体现在最高置信区间被系统性地高估了。修复方向因此很清楚:不需要推翻整套置信度机制,只要收紧高置信区间的阈值,或者单独对这一段重新校准即可。

对 AI 编程意味着什么

在 AI 编程、氛围编程(vibe coding,指让智能体自己动手写代码)这类场景里,这一点尤其关键。智能体自动改代码、跑测试、决定是否提交合并请求(PR),依据的正是这个分数。95% 的自信配上 71% 的正确率,意味着「基本没问题」这个结论的背后,仍有接近三成的出错概率。

配套代码同时承担两件事:生成这张分组校准表,并计算是否需要告警、差距有多大。

关键要点

查看原文