LLM 生产系统第 3 级:用组合置信度让智能体学会说「我不确定」
当大模型系统从「能跑起来」走向「自己拿主意」,所有判断最终都会落到同一个数字上:置信度。本文拆解生产环境里的三级机制——怎么把几个彼此独立的信号拼成一个可靠的置信度分数、怎么验证这个分数真的准、以及怎么让高风险决策走独立复核,把拿不准的部分干净地交还给人类。
从「能跑起来」到「敢自己动手」
前两级成熟度解决的是让系统跑起来,并且能看见它在跑。到了第 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)。实测数据往往揭示同一个问题:模型自报高置信度的那一档,实际准确率明显低于它宣称的数字——偏差通常就集中在高分区。
对开发者来说,这意味着「模型说自己很确定」和「这件事真的有九成把握」是两回事,而后者才是能被自动执行、能被写进流水线的前提。
关键要点
- 第 3 级成熟度的核心问题不是「能不能跑」,而是「凭什么自己动手」,答案是可校准的置信度。
- 置信度分数必须由多个可独立核实的信号组合而成;模型自评权重最低,因为它无法被外部验证。
- 裁判抽样只覆盖少数决策,未抽样的决策应去掉该项并重新归一化权重,而不是默认加分或扣分。
- 置信度分数要经过校准检验:预测为 0.9 的那批决策,真实准确率应当接近 90%,高分区往往正是偏差最明显的地方。
- 高风险决策走独立复核,低置信度决策转人工;一条真正有效的自动流水线,前提是系统知道自己什么时候不知道。
分组校准表:模型说「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% 的正确率,意味着「基本没问题」这个结论的背后,仍有接近三成的出错概率。
配套代码同时承担两件事:生成这张分组校准表,并计算是否需要告警、差距有多大。
关键要点
- 模型自报的置信度不等于真实正确率:0.90–1.00 档平均报 0.95,实际只有 0.71。
- 中间档校准良好,问题集中在最高置信区间,系统对高分过于自信。
- 修复不必重做整套机制:收紧高置信阈值,或对高分段单独重新校准。
- 在 AI 编程/氛围编程中,智能体依据该分数自动改代码、跑测试、提交合并请求;高置信误判会直接放大自动化风险。
- 配套检查应同时输出分组校准表和告警/差距计算。