
如果你问一名普通用户“AI 最大的问题是什么”他大概率会说“AI 会一本正经地胡说八道”。但在 DeepMind 这类顶级实验室看来这个问题有一个更严谨的技术名字模型缺少对自身不确定性的表征能力。换句话说模型不只是“回答错了”更严重的是“它不知道自己在犯错却表现得非常确信”。DeepMind 高层在近年的多次公开讨论中反复提到同一个观点如果大模型要在科学研究、代码生成、智能体调度、甚至医疗辅助这类高风险场景中真正落地那么“懂得什么时候说自己不知道”可能比“答对更多题”更重要。这不是一种哲学式提醒而是一个会直接决定系统可靠性的工程问题。本文会先从概念上拆解“AI 不确定性推理”到底指什么再结合大模型和 Agent 应用的实际场景给出可以落地的处理思路。文章中会包含三个可运行的 Python 示例不确定性校准评估、置信度温度缩放以及 Agent 场景下的不确定性门控。读完你能得到两样东西一套判断模型置信度是否可靠的思维框架和一套可以在自己项目里跑起来的处理方案。1. 这篇文章真正要解决的问题先看一个非常典型的失败场景。你搭建了一个基于大模型的客服问答机器人它在几百条测试问题上回答得都很流畅几乎每一条都给出了自信满满的答案。上线后却发现当用户问到知识库中没有覆盖的问题时它不会回答“不知道”而是会编造一个听起来合理的答案。这时你才意识到问题不在提示词也不在知识库覆盖度而在模型根本没有“认知到自己不知道”的机制。这是所有想把大模型从演示推向生产环境的人都会撞上的墙。过去几年业界解决这个问题的主流手段是叠加 RAG、增加外部工具校验、做人工审核兜底。这些都有效但它们都是在模型之外“强行纠偏”而不是让模型在生成答案时就把不确定性考虑进去。DeepMind 讨论不确定性推理时强调的是另一层让模型本身具备一种对“自己是否真的知道”的内部判断能力。说得直白一点现在的大模型像是一台没有油量表的车你永远不知道它下一秒会不会熄火不确定性推理的目标就是给这台车装上油量表、胎压监测和路线预判系统。这篇文章适合四类读者正在把大模型接入真实业务系统的工程师你更需要关注“置信度门控”和“人工兜底”的设计。做模型评测和效果优化的算法工程师你需要理解 ECE、温度缩放这些校准指标和手段。研究 Agent、多步推理和工具调用的开发者你需要重视“不确定性在长链路中会累积放大”的问题。对 AI 技术趋势保持敏感的技术管理者你可以从本文获得判断“模型是否可用”的工程视角。2. 基础概念不确定性、置信度与校准2.1 不确定性的两种来源在机器学习里不确定性通常被分为两类理解这个分类是后续所有讨论的基础。第一类是偶然不确定性英文叫 aleatoric uncertainty。它来自数据本身固有的随机性比如“明天是否下雨”无论你收集多少历史数据都无法完全确定结果。这类不确定性无法通过增加知识来消除只能尽量精确地估计概率。第二类是认知不确定性英文叫 epistemic uncertainty。它来自模型“不知道但误以为自己知道”的部分比如一个只见过猫和狗的模型你拿一张老虎的图片给它它可能会信心满满地说是“猫”。这就是认知不确定性它的成因是训练数据覆盖不足或者模型本身的泛化能力不够。DeepMind 在讨论 AI 不确定性时重点关注的恰恰是认知不确定性。因为偶然不确定性可以被概率系统合理建模而认知不确定性是大模型产生幻觉、过度自信、错误推理的主要根源。2.2 置信度与校准的区别很多开发者会把“置信度”和“校准”混为一谈实际是完全不同的两个概念。置信度是模型对某个预测结果的自信程度。比如分类模型输出“这张图是猫的概率是 0.9”0.9 就是置信度。校准是衡量“置信度是否等于真实准确率”的指标。如果模型对所有输出 0.9 置信度的预测真实正确率确实是 90%那么这个模型就是校准良好的。举个反例。一个模型在测试集上准确率达到 95%但当它输出置信度 0.95 时真实正确率只有 70%。这说明模型过度自信。更可怕的是在很多大模型上这类过度自信会集中在模型“编造内容”时模型对幻觉内容的置信度甚至可能高于对正确答案的置信度。这就是为什么不能直接相信模型给自己打的分数必须先做校准评估再做校准修正。2.3 DeepMind 为什么要强调不确定性DeepMind 在 AlphaGo 时代就建立了对不确定性量化的使用习惯。AlphaGo 评估棋局时会同时给出胜率区间而不是只给一个“我觉得能赢”的结论AlphaFold 预测蛋白质结构时会输出每个残基的置信度分数(pLDDT)研究者据此判断哪些结构预测是可靠的哪些只是猜测。到了大模型时代他们面对的问题更棘手语言模型的输出是离散的、开放的、没有固定答案空间的传统分类模型的校准方法不能直接搬过来。所以 DeepMind 提出的方向更接近“让系统在推理过程中管理不确定性”而不是仅仅在最终输出概率。这种思路对 Agent 应用尤其重要因为 Agent 的每一次工具调用、每一步推理都在消费之前的不确定性判断如果中间某一步过度自信后续所有步骤都可能建立在错误基础上。3. 大模型在身边的不确定性从哪里来藏在哪里3.1 训练数据层面的不确定性模型知道什么、不知道什么本质上是训练数据决定的。当用户的问题落在训练数据覆盖充分的区域时模型通常能给出准确回答落在覆盖稀疏的区域时模型就只能依靠内部插值猜一个答案。问题在于用户无法直接看到“当前问题是否落在覆盖区域内”。这就是为什么“模型会不会说不知道”如此重要。一个理想的模型应该具备这样的能力输入一个问题它内部先判断“这个问题我熟悉吗”如果不熟悉就明确表达不确定而不是生硬地编一个答案。3.2 推理过程层面的不确定性即便模型“知识上知道”推理过程也可能出错。尤其是面对数学题、逻辑推导、代码执行这类多步问题模型每一小步都有出错概率而整个链路的正确率会快速衰减如果每一步正确率是 95%10 步之后整体正确率就只有约 60%。这里要注意一个反直觉现象模型在推理过程的中间步骤往往比最终答案更自信。它可能清楚地知道答案但中间某一步已经推理错了。这就导致只对最终答案做不确定性评估是远远不够的必须对推理的中间状态也做监测。3.3 Agent 长链路中的不确定性放大在 Agent 场景中问题会进一步恶化。一个 Agent 通常要经历“理解用户意图 - 拆解任务 - 调用工具 - 读取结果 - 生成最终答案”这样的链路。每一步都存在不确定性而且误差会逐级传递。比如一个智能客服 Agent第一步把用户的问题理解偏了第二步检索到的文档就是错的第三步基于错文档生成的最终答案就会更离谱。而且每一步模型都有可能是自信的。DeepMind 强调的不确定性推理在这种链路中对应的落地做法是每一步都评估置信度一旦某步置信度低于阈值就及时切换策略比如重新提问、换一个工具、直接转人工。4. 工程实践中的不确定性处理四个可落地的层级理解了问题来源就到了实操环节。我建议把不确定性处理拆成四个层级从轻到重企业可以根据自己的场景选。4.1 第一层提示词层的显式不确定性表达最简单的方式是在提示词里要求模型区分“事实”和“推理”。OpenAI、Anthropic 等多家机构的公开评测都显示如果要求模型“不确定时直接说不知道不要编造”模型的幻觉率会有一定下降。这不算严格意义上的不确定性推理但对很多业务场景是成本最低的改进。你是一个严谨的技术助手。请根据以下规则回答用户问题 1. 如果问题有明确事实依据直接给出答案。 2. 如果问题存在多种可能解释请列出所有可能性并标注每种可能性的依据。 3. 如果问题超出你的知识范围必须明确回答“我无法确认这一点”不要尝试猜测。 4. 当你在推理过程中不确定某一步时请单独说明“这里的判断置信度较低”。这种写法的本质是给模型一个“安全出口”。默认情况下模型会被训练得尽可能迎合用户倾向于给出完整答案显式允许它“不确定”可以减少一部分为了迎合而编造的动机。4.2 第二层概率输出层的置信度校准如果模型本身能输出概率或 logits就可以用温度缩放等方式做校准。温度缩放是经典的模型校准方法思路很简单训练一个温度参数 T把 logits 除以 T 后再做 softmax使得输出的概率分布更贴近真实准确率。如果 T 大于 1则概率分布会被拉平模型会变得更“谦虚”如果 T 小于 1模型会变得更“尖锐”。不过要注意大模型常见的 API 接口通常只返回 token 序列不会暴露完整 logits。这种情况下可以使用替代方案比如让模型生成多次并统计答案的一致性同一个问题问 5 次如果答案几乎一致说明模型对这个问题较有把握如果每次答案都不一样说明模型在猜测。这种“采样一致性”方法不需要访问模型内部是实际工程中最常用的技巧。4.3 第三层机制层的验证与工具辅助比模型自身判断更可靠的方式是引入外部验证机制。RAG 可以部分解决知识缺失问题但它只能保证“引用了文档”不能保证“文档内容正确”。此时可以增加权威来源比对比如让模型回答时必须附上引用来源再由业务规则校验来源是否存在和匹配。对于数学计算让模型先生成推理过程再用一个独立的代码解释器执行关键步骤验证结果。对于代码生成直接运行生成的代码用编译器或测试用例的返回结果判断是否正确。这些机制的共同点是不再依赖模型“自我感觉”而是引入确定性工具来验证模型的输出。DeepMind 在很多场景下的做法也是类似的思路用外部反馈信号来修正模型的不确定判断。4.4 第四层决策层的风险门控与人工兜底这是最重要的一层。即使做了前面所有处理模型在少数情况下仍然可能出错且自身没有察觉。所以生产系统必须设计一个决策层在模型输出达到一定风险等级时自动触发降级策略。比如置信度低于 0.6 时转人工置信度介于 0.6 到 0.9 时二次校验置信度高于 0.9 时直接输出。这套“门控 人工兜底”的机制才是企业可以接受大模型落地的原因。DeepMind 在讨论大模型应用时反复强调的是“不要无条件信任模型的输出”这句话落到工程上就是这样的决策层代码。5. 完整示例一用 ECE 评估模型校准度在动手改进之前得先知道模型现在的校准情况有多糟。Expected Calibration ErrorECE期望校准误差是最常用的校准评估指标它把模型输出概率分箱然后对比每个箱子的平均置信度和真实准确率。ECE 越低说明模型校准越好。下面的示例使用 numpy 实现一个最小版 ECE 计算函数不需要任何额外的机器学习库。# 文件路径calibration_eval.py import numpy as np def compute_ece(y_true, y_prob, n_bins10): 计算 Expected Calibration Error。 参数: y_true: 真实标签数组取值为 0 或 1 y_prob: 模型输出的正类概率数组取值在 [0, 1] n_bins: 分箱数量 返回: ece: 期望校准误差 详细的分箱统计列表 bin_boundaries np.linspace(0.0, 1.0, n_bins 1) ece 0.0 bin_stats [] total_samples len(y_true) for i in range(n_bins): # 当前分箱内的样本索引 if i n_bins - 1: mask (y_prob bin_boundaries[i]) (y_prob bin_boundaries[i 1]) else: mask (y_prob bin_boundaries[i]) (y_prob bin_boundaries[i 1]) bin_count np.sum(mask) if bin_count 0: continue # 箱内平均置信度 avg_conf y_prob[mask].mean() # 箱内真实正例比例即实际准确率 avg_acc y_true[mask].mean() # 按样本占比加权 weight bin_count / total_samples ece weight * abs(avg_conf - avg_acc) bin_stats.append({ bin: i, sample_count: int(bin_count), avg_confidence: round(float(avg_conf), 4), avg_accuracy: round(float(avg_acc), 4), gap: round(float(abs(avg_conf - avg_acc)), 4) }) return ece, bin_stats # 模拟一组数据真实标签 模型预测概率 np.random.seed(42) n 1000 y_true np.random.randint(0, 2, sizen) y_prob np.clip(y_true np.random.normal(0, 0.25, sizen), 0.01, 0.99) ece, stats compute_ece(y_true, y_prob) print(f整体 ECE: {ece:.4f}) print(\n分箱统计:) for s in stats: print(s)这段代码的核心逻辑是按概率区间分箱。正常来说如果模型校准良好那么“预测概率 0.8 的样本”中应该有大约 80% 是正例。如果模型预测 0.8 的样本中只有 60% 是正例说明模型过度自信ECE 会相应变大。运行这个脚本后你会看到类似这样的输出整体 ECE: 0.0334 分箱统计: {bin: 0, sample_count: 0, avg_confidence: 0.0, avg_accuracy: 0.0, gap: 0.0} {bin: 1, sample_count: 4, avg_confidence: 0.11, avg_accuracy: 0.25, gap: 0.14} {bin: 2, sample_count: 12, avg_confidence: 0.23, avg_accuracy: 0.33, gap: 0.10} ...由于上面的示例数据是人为模拟生成的实际数值每次运行会略有差异。你要关注的是每个箱子中的 gap 列gap 越大说明模型在该区间内的置信度越不靠谱。如果 gap 普遍超过 0.1就说明模型需要做校准处理。6. 完整示例二用温度缩放校准模型置信度当你通过 ECE 确认模型校准不佳之后下一步就是做校准。温度缩放是应用最广的方法它的好处是只需要一个参数不容易过拟合而且实现成本很低。温度缩放的核心思想是在 softmax 之前把 logits 统一除以一个温度系数 T。T 越大输出的概率越平滑模型的最高置信度越低T 越小则概率分布越尖锐。训练时用验证集进行优化目标是找到让交叉熵损失最小的 T。下面使用 PyTorch 实现温度缩放。# 文件路径temperature_scaling.py import torch import torch.nn.functional as F class TemperatureScaler: 温度缩放校准器。 用法 1. 收集验证集上的 logits 和真实标签 2. 调用 fit() 学习最优温度参数 3. 调用 calibrate() 对新的 logits 应用温度缩放 def __init__(self, max_iter100, lr0.01): self.T torch.tensor(1.0, requires_gradTrue) self.max_iter max_iter self.lr lr def fit(self, logits_val, labels_val): 在验证集上学习温度参数。 logits_val: shape [N, num_classes]模型输出的 logits labels_val: shape [N]真实类别索引 logits_val torch.tensor(logits_val, dtypetorch.float32) labels_val torch.tensor(labels_val, dtypetorch.long) def loss_fn(): # 除以温度后的交叉熵损失 loss F.cross_entropy(logits_val / self.T, labels_val) return loss optimizer torch.optim.LBFGS([self.T], lrself.lr, max_iterself.max_iter) def closure(): optimizer.zero_grad() loss loss_fn() loss.backward() return loss optimizer.step(closure) return self.T.item() def calibrate(self, logits): 对新的 logits 应用温度缩放返回概率分布。 logits_tensor torch.tensor(logits, dtypetorch.float32) calibrated_probs F.softmax(logits_tensor / self.T, dim-1) return calibrated_probs.numpy() # 模拟一个三分类问题 torch.manual_seed(0) n_val 500 n_classes 3 # 随机生成 logits 和标签仅为演示代码路径 logits_val torch.randn(n_val, n_classes) labels_val torch.randint(0, n_classes, (n_val,)) scaler TemperatureScaler() temperature scaler.fit(logits_val.numpy(), labels_val.numpy()) print(f学习到的温度参数 T {temperature:.4f}) # 对新的 logits 做校准 new_logits torch.randn(10, n_classes) probs scaler.calibrate(new_logits.numpy()) print(\n校准后的概率分布每行之和为 1:) print(probs)运行后你可能得到一个大于 1 的温度值这意味着验证集上的模型原始输出过于尖锐校准会拉平概率分布。如果 T 接近 1说明模型本身已经校准较好不需要大幅调整。这里要特别提醒在大模型 API 场景中你通常拿不到 logits只能拿到 token 字符串。这时无法直接使用温度缩放但可以用一个替代策略让模型生成多次统计多个答案的 token 级相似度来近似置信度。如果多次生成结果高度一致就认为置信度较高如果每次生成差别很大就认为模型在不确定地猜测。这种方法虽然粗糙但在没有内部 logits 的情况下是工程上唯一可行的近似方案。7. 完整示例三Agent 场景下的不确定性门控前两个示例是在单次模型预测层面做处理Agent 场景则需要把不确定性意识嵌入到每一步工具调用和分支决策中。下面是一个简化版的高风险 Agent 框架。它的思路是每执行一步都计算当前置信度如果置信度低于门限就停止继续执行转人工或请求用户澄清。# 文件路径agent_uncertainty_gate.py from dataclasses import dataclass from typing import Callable, Optional dataclass class StepResult: Agent 中一步执行的结果。 content: str confidence: float # 当前步骤的置信度范围 [0, 1] needs_human: bool False # 是否需要人工介入 metadata: Optional[dict] None class UncertaintyAwareAgent: 带不确定性门控的 Agent。 实际使用时需要把 llm_call 和 tool_call 替换成 你自己的大模型调用和工具调用实现。 def __init__(self, llm_call: Callable[[str, Optional[str]], StepResult], tool_call: Callable[[str], StepResult], confidence_threshold: float 0.7): self.llm_call llm_call self.tool_call tool_call self.confidence_threshold confidence_threshold def _should_stop(self, step_result: StepResult) - bool: 判断当前步骤是否需要停止 1. 步骤本身标记需要人工介入 2. 置信度低于阈值 if step_result.needs_human: return True if step_result.confidence self.confidence_threshold: return True return False def run(self, user_question: str) - StepResult: # 第一步理解用户意图 intent_result self.llm_call( f请拆解用户意图{user_question}, prompt_typeintent ) if self._should_stop(intent_result): # 意图不明确时直接请求用户澄清而不是硬着头皮执行 return StepResult( content我不确定您的具体需求能否再补充一些信息, confidenceintent_result.confidence, needs_humanTrue, metadata{stage: intent, reason: low_confidence} ) # 第二步根据意图调用工具 tool_result self.tool_call(intent_result.content) if self._should_stop(tool_result): # 工具返回结果不可靠时转人工复核 return StepResult( content初步判断需要人工协助处理请稍候。, confidencetool_result.confidence, needs_humanTrue, metadata{stage: tool, reason: tool_low_confidence} ) # 第三步生成最终答案 answer_result self.llm_call( f基于工具结果回答问题{tool_result.content}, prompt_typefinal_answer ) if answer_result.confidence self.confidence_threshold: # 最终答案置信度低时给出带保留的回答 return StepResult( content以下信息可能不完全准确建议人工确认 answer_result.content, confidenceanswer_result.confidence, needs_humanTrue, metadata{stage: final, reason: answer_low_confidence} ) return answer_result # 演示用法 def fake_llm(prompt: str, prompt_type: str intent) - StepResult: # 这里应该替换成真实的大模型调用 # 示例中直接返回固定值方便你理解框架设计 if prompt_type intent: return StepResult(content查询天气, confidence0.95) elif prompt_type final_answer: return StepResult(content杭州明天多云气温 22-28 度, confidence0.55) return StepResult(content, confidence0.0) def fake_tool(query: str) - StepResult: # 这里应该替换成真实的工具调用 return StepResult(content杭州 明天 多云 22-28 度, confidence0.80) agent UncertaintyAwareAgent( llm_callfake_llm, tool_callfake_tool, confidence_threshold0.7 ) result agent.run(杭州明天天气怎么样) print(f最终回答{result.content}) print(f置信度{result.confidence:.2f}) print(f需要人工介入{result.needs_human})在这个示例里意图识别步骤置信度 0.95通过了门槛工具调用步骤置信度 0.80也通过了但最终答案置信度只有 0.55低于 0.7 的门限于是 Agent 自动给回答加上了保留说明并标记为需要人工介入。真实的 Agent 中llm_call 应该从模型服务获取结果同时通过多次采样一致性或者模型自带的置信度接口得到置信度。tool_call 则可以结合工具自身的返回状态来设置置信度。这个框架的关键思想是任何一步的不确定性都不能被忽略链路中只要有一环置信度过低整个任务就应该降级处理。8. 常见问题与排查思路在实际落地不确定性机制时开发者会遇到一些典型问题我来整理成排查清单。问题现象可能原因排查方式解决方案模型对幻觉内容给出高置信度模型自身没有不确定性表征能力或者提示词未显式要求区分确定性让模型生成同一个问题 10 次统计答案一致性和置信度分布引入多次采样一致性作为置信度代理指标在提示词中显式允许“不知道”ECE 评估结果很差模型没有经过校准或评估数据分布与训练分布差异大检查分箱统计中每个区间的 gap 值确认问题集中在哪些置信区间使用温度缩放校准如果 API 不提供 logits改用采样一致性方法温度缩放后准确率下降校准目标是优化概率校准而不是提升分类准确率对比校准前后的准确率和 ECE 两个指标校准不会改变预测类别只改变置信度。如果准确率变化说明评估流程有问题Agent 在长链路中错误累积中间步骤的置信度没有被监测和做门控在每一步增加置信度日志追踪是哪一步误差开始放大使用上文的不确定性门控 Agent 框架设置合理的置信度阈值置信度阈值设太高导致转人工过多阈值选取缺乏业务数据支撑统计不同阈值下的转人工率和最终正确率画出权衡曲线基于业务容忍度选择阈值也可以做动态阈值例如根据用户问题风险等级调整模型 API 不返回概率信息商业模型服务通常只返回 token检查 API 文档是否提供 logprobs 参数使用参数采样开启高温度多次采样用 n-gram 重叠率估计置信度检索增强(RAG)后依然编造答案检索到的文档本身就错误或者与问题不匹配检查检索结果的相关性排序确认答案是否严格引用了检索文档增加引用来源校验只有答案内容能在检索文档中找到依据时才允许输出9. 最佳实践与工程建议9.1 先定义“多低算低”置信度阈值不能拍脑袋定。不同业务场景对错误容忍度完全不同垃圾邮件分类器即使把 5% 的正常邮件误判为垃圾也可以接受但一个药物剂量推荐系统1% 的错误都是事故。我的建议是先统计你当前系统的错误分布再反推阈值。比如你统计发现模型输出置信度低于 0.6 时正确率只有 68%而业务要求是 95%那阈值至少设在 0.6 以上。9.2 校准数据要与任务分布一致很多团队会用通用评测集做校准再直接部署到业务场景这是错误做法。校准本质上是在拟合“置信度到准确率”的映射这个映射依赖数据分布。通用数据上学到的温度参数换到垂直领域后可能完全失效。正确流程是收集业务真实流量中的问题样本人工标注后用这部分数据重新做校准评估和温度学习。9.3 给不确定性留足日志生产环境中一定要记录每一步推理的置信度、采用的策略、是否触发门控。这不仅仅是排查问题的需要更是后续优化校准模型的数据资产。我见过不少团队上线了不确定性门控却因为没留日志出了问题只能猜原因。建议在 Agent 框架中把 step 的 metadata 字段完整记录到日志系统。9.4 从轻到重逐步落地不要一开始就追求复杂的贝叶斯神经网络或完整的概率编程。先用提示词约束再上采样一致性评估然后做温度缩放最后叠加 Agent 门控。这套路径每走一步都能获得明确的收益而且不会对现有系统产生破坏性改动。如果某一步做完效果已经满足业务要求就不需要继续往下做复杂度更高的方案。9.5 不要试图消除不确定性要管理不确定性这是 DeepMind 讨论中我认为最有价值的一句话不确定性是客观存在的模型不可能变成全知全能。工程系统的目标不是让模型“永远正确”而是让正确的部分被信任错误的可能被识别不确定的地方被降级给人类处理。这句话应该成为所有 AI 产品设计的默认原则。10. 下一步演进从指令学习到不确定性原生模型如果你把本文介绍的方法都落地了你的系统已经比绝大多数大模型应用更可靠。但我们也必须承认提示词、温度缩放、Agent 门控都是“事后补救”真正的改变应该发生在模型训练阶段。从 DeepMind 的讨论和行业公开研究看有三个演进方向值得持续跟踪。第一是在后训练阶段加入校准约束让模型在 RLHF 或偏好优化过程中不仅学习“什么是对的”也学习“什么时候不确定”。第二是奖励模型层面的不确定性感知让奖励模型对高风险输出给出更保守的评分。第三是给模型引入更多工具反馈信号让模型通过实际执行结果来修正自己的置信度这相当于让模型在推理时像人一样“验证一遍再做判断”。对普通开发者来说现在无需等到这些研究方向成熟。你可以从本文的示例代码开始先用采样一致性加上置信度门控把自己的 AI 系统做得更可信。当你有了一定数据积累后再把这套机制持续迭代优化。AI 的不确定性永远存在但作为工程师我们至少可以让它在系统中变得可见、可度量、可控制。