AI不确定性推理全解:从概率熵到大模型Agent落地实践

AI不确定性推理全解:从概率熵到大模型Agent落地实践 做 AI 应用开发的同学可能都有过这种体验大模型在对话里回答问题特别笃定语气自信甚至会把错误信息叙述得有理有据。可一旦把它放到医疗辅助、金融风控、企业知识库问答这类真实业务场景里这种“盲目的自信”就会变成隐患。最近 DeepMind 副总裁公开讨论了 AI 不确定性推理这个话题又把“模型如何知道自己不知道”推到了技术圈的讨论中心。这篇文章不打算只做观点解读而是把话题拆成一条可学习、可落地的技术脉络先从概念入手讲清楚什么是不确定性推理再补充概率与熵的基础知识然后给出语言模型和 AI Agent 项目里常见的实现思路最后用一个带决策层的问答系统案例演示如何把“不确定性”变成产品能力。适合以下读者阅读正在用大模型做业务系统却不知道如何判断模型输出可不可信的开发者。想入门 AI Agent、RAG 应用但对置信度、熵、校准等概念比较陌生的同学。需要把 AI 能力接入生产环境同时又担心幻觉、误判、失控的工程师。读完你会掌握不确定性推理要解决什么问题、有哪些可操作的实现手段、如何在项目里设计一套“不确定就转人工/触发检索”的兜底机制以及工程落地时需要注意的坑。1. 从 DeepMind 的讨论说起为什么不确定性突然成了焦点1.1 一个被忽略的问题模型不知道自己不知道传统软件系统的行为是确定的条件成立就走这个分支条件不成立就走另一个分支。开发者在写代码时可以精确预判系统在什么输入下会给出什么输出。大模型不一样。它本质上是基于海量文本训练的概率模型生成每个 token 时都在做概率采样。它给出的答案只是“在当前参数和上下文下概率上比较合理的延续”并不代表事实判断。更关键的是模型在训练过程中没有学过“如何表达自己的无知”它只知道根据分布生成文本。于是出现了一个典型的工程矛盾模型并不知道自己给出的答案是否正确但用户和业务系统默认它是正确的。一旦模型把幻觉内容以高置信度的方式输出系统的可靠性就会大打折扣。DeepMind 团队讨论不确定性推理本质上是在回应这个问题如果模型能对自身的判断给出一个可靠的不确定性估计应用层就可以用它做风险控制。1.2 不确定性推理不是让 AI“变笨”有人在第一次接触这个概念时会误以为不确定性推理就是让模型多回答“我不知道”。这是一种比较片面的理解。让模型说“我不知道”只是不确定性推理的一种外在表现。更核心的工作是让系统能够量化自己的认知边界并在不确信时改变行为。比如如果模型对答案的置信度低于阈值就触发知识库检索。如果多次推理结果互相矛盾就转给人工处理。如果分类概率分布比较平坦就输出多个候选结果供用户选择。如果 Agent 对当前工具调用结果没有把握就放弃执行高风险动作。换句话说不确定性推理解决的不是“模型会不会错”而是“系统在模型可能出错时如何提前感知并做出安全反应”。1.3 哪些场景最需要不确定性推理从工程角度看以下几类场景对不确定性推理的需求最迫切场景为什么需要医疗辅助诊断错误结论可能导致严重后果模型需要给出置信区间和转人工信号金融风控自动化决策需要知道预测的可靠程度以便分配合适的人工审核资源企业知识库问答文档覆盖不足时模型容易编造答案系统需要感知“知识盲区”自动驾驶与机器人传感器和模型的不确定性需要统一估计才能做安全决策AI Agent 自动化操作执行下单、发邮件、删数据等高危动作前必须判断置信度是否足够这些场景的共性是错误成本高且不能通过简单增加数据彻底消除错误。系统要做的是在错误发生之前对“不确定性”建立感知和应对机制。2. 先厘清概念偶然不确定性 vs 认知不确定性2.1 两种不确定性的定义在机器学习里不确定性一般被分为两类偶然不确定性Aleatoric Uncertainty指数据本身固有的随机性。比如抛硬币的结果、传感器噪声、用户行为的随机波动。这类不确定性不会因为收集更多数据而消失只能通过概率模型去刻画它。认知不确定性Epistemic Uncertainty指模型因为知识不足而产生的认知盲区。比如模型没见过某种数据分布、训练语料过时、上下文信息太少。这类不确定性可以通过增加数据、扩充知识、改进模型来降低。这两种区分的价值在于当系统判断出不确定性主要来自认知层面时可以通过检索知识、访问数据库、询问用户来补救如果不确定性主要来自数据本身的随机性那再多的知识补充也无法消除系统应该谨慎决策而不是盲目追问。2.2 用天气预报理解两类不确定性以天气预报为例假设我们拥有非常完整的气象数据和精细的模型仍然无法百分之百确定明天是否下雨因为大气系统本身存在随机扰动。这是偶然不确定性。如果模型只在热带地区的数据上训练过现在要预测寒带城市的天气那么模型对“降雪概率”的判断会非常不靠谱。这是认知不确定性。理解这个区别后在 AI 应用设计时就会有一个清晰的思路先判断模型的不确定来自哪里再决定用哪种策略去应对。2.3 和大模型落地有什么关系大模型场景下的不确定性来源很多可以按下面这个思路归类训练语料覆盖不足模型对某些小众领域、新知识、特定格式的输入了解不够回答容易失真。这属于认知不确定性。上下文信息缺失用户只给了一个模糊的问题没有提供足够条件模型只能在多个可能答案里猜。这既是认知不确定性也带有偶然性。生成过程的随机性采样温度较高时同一个问题可能得到不同的回答。这是生成机制带来的随机性本质上更接近偶然不确定性。当我们说“要为大模型系统增加不确定性推理”时其实是希望系统能把上面这些来源的信号综合起来输出一个可供上层决策使用的置信度。3. 数学基础概率、熵与模型校准3.1 从贝叶斯公式理解不确定性更新贝叶斯公式是不确定性推理最基础的工具P(A|B) P(B|A) * P(A) / P(B)它的含义是在看到新证据 B 之前我们对 A 有一个先验概率 P(A)看到 B 之后通过似然 P(B|A) 更新为后验概率 P(A|B)。这个思路在 AI 系统里非常实用。例如一个 Agent 接到用户问题后可以先根据历史数据给出一个初始答案分布再通过检索到的知识库片段更新答案分布。如果新证据和先验答案一致置信度上升如果矛盾置信度下降。很多生产系统在做“检索增强生成”时实际上就在做类似的更新先用检索结果降低模型对未知知识的认知不确定性再让生成模型基于更充分的上下文作答。3.2 用熵度量“有多不确定”有了概率分布之后需要用一个标量来量化不确定程度。最常用的指标是信息熵H(p) -Σ p(x) · log p(x)熵越大说明概率分布越平缓系统对答案越不确定熵越小说明概率集中在某个类别或某个答案上系统越确定。分类场景中最直接的例子概率分布是 [0.98, 0.01, 0.01]熵很小模型基本确认答案属于第一类。概率分布是 [0.34, 0.33, 0.33]熵很大模型完全无法区分三类这时直接输出最高概率的类别就很危险。下面这段代码演示了如何计算 softmax 概率、熵和最大概率。这是做不确定性判断时最基础的工具。# uncertainty_basics.py import numpy as np def softmax(logits: np.ndarray) - np.ndarray: # 减去最大值做数值稳定处理避免 exp 溢出 max_logit np.max(logits) exp_logits np.exp(logits - max_logit) return exp_logits / np.sum(exp_logits) def distribution_entropy(probs: np.ndarray) - float: # 计算概率分布的熵概率夹紧到极小值防止 log(0) probs np.clip(probs, 1e-12, 1.0) return -float(np.sum(probs * np.log(probs))) # 模拟模型输出的 logits logits np.array([2.0, 1.0, 0.1]) probs softmax(logits) print(softmax 概率:, np.round(probs, 4)) print(分布熵:, round(distribution_entropy(probs), 4)) print(最大类概率:, round(np.max(probs), 4))运行结果softmax 概率: [0.659 0.243 0.098] 分布熵: 0.8159 最大类概率: 0.659如果把 logits 改成 [0.0, 0.0, 0.0]三个类别的概率会非常接近熵也会显著变大。这时候就不建议直接把最高概率的类别作为最终答案。3.3 校准置信度 70% 的时候正确率是否接近 70%熵和最大概率可以衡量“模型自己觉得有多确定”但这里还有一个重要问题模型的自信程度和真实正确率是否匹配这就涉及到校准Calibration。校准良好的系统应该满足当模型预测置信度为 0.7 时这类样本的真实正确率也接近 70%。如果模型对所有样本都给出 0.99 的置信度但真实正确率只有 70%那就是典型的过度自信。常用的评估指标是期望校准误差ECE。计算思路是把置信度分成多个区间统计每个区间内模型平均置信度与真实准确率的差值再按样本数量加权平均。# calibration_demo.py import numpy as np def expected_calibration_error(confidences, correct, n_bins10): confidences: 模型对每个样本给出的置信度 correct: 每个样本是否预测正确用 0/1 表示 bins np.linspace(0.0, 1.0, n_bins 1) ece 0.0 total len(confidences) for i in range(n_bins): in_bin (confidences bins[i]) (confidences bins[i 1]) if np.sum(in_bin) 0: continue bin_conf np.mean(confidences[in_bin]) bin_acc np.mean(correct[in_bin]) # 该区间样本数 / 总样本数 * |置信度 - 准确率| ece np.sum(in_bin) * abs(bin_conf - bin_acc) / total return ece # 模拟数据模型整体偏乐观 confidences np.array([0.95, 0.92, 0.88, 0.75, 0.70, 0.60, 0.55, 0.45, 0.40, 0.30]) correct np.array([1, 1, 0, 1, 0, 1, 0, 1, 0, 0]) print(ECE:, round(expected_calibration_error(confidences, correct), 4))ECE 越低说明模型的置信度越可信。实际项目中我们可以用验证集持续监控这个指标当 ECE 明显偏高时就要考虑对模型做温度缩放或者在决策层引入更保守的策略。3.4 为什么工程上要同时关注“概率”和“校准”只看 logits 或概率是不够的。一个没有经过校准的模型哪怕 softmax 输出 0.95真实准确率也可能只有 60%。只看“熵”也不够因为熵描述的是模型内部的不确定性并不等于事实层面的可靠性。正确做法是把两个层面同时纳入系统概率层面用熵、最大概率、多次采样一致性作为实时不确定信号。校准层面用 ECE 等指标在离线阶段评估模型置信度是否可靠并据此设置合理阈值。4. 语言模型和 AI Agent 里的不确定性推理思路4.1 读取模型输出的概率信息在实际项目中获取不确定性信号的第一个入口是模型自身的概率输出。如果是分类任务可以直接读取每个类别的概率或者读取最后一个分类层的 logits再通过 softmax 得到分布。这是成本最低的方式。如果是生成任务情况会复杂一些。生成文本时会为每个 token 产生一个概率分布但我们最终关心的是整段答案的可信度。比较简单的办法是取所有 token 概率的平均值或几何平均值但这样只能反映“生成过程是否顺畅”不能完全反映“答案是否符合事实”。一个常见误区是把文本生成过程中的高概率当成答案正确。实际上模型可以非常流畅、非常自信地生成一段完全错误的内容。因此生产系统不能只依赖 token 概率。4.2 多次采样与语义熵对于开放生成任务更稳妥的思路是多次采样。让模型在较高 temperature 下对同一个问题生成 N 个回答然后度量这些回答之间的语义一致性。如果 N 个回答在语义上高度一致说明模型对答案相对确定如果回答之间分歧很大说明模型并没有形成稳定判断。这里需要注意不能直接比较文本是否完全相同而应该做语义相似度比较。可以用编辑距离、BLEU、向量余弦相似度等方法。下面用一个简化版本的示例来演示核心思路。# semantic_entropy_demo.py from difflib import SequenceMatcher import numpy as np responses [ 今天上海会下雨建议带伞。, 今天上海有降雨最好带伞。, 今天上海不会下雨不用带伞。 ] def similarity(a: str, b: str) - float: # 简化用字符序列相似度实际项目中可用 embedding 余弦相似度 return SequenceMatcher(None, a, b).ratio() def pairwise_similarity(responses): n len(responses) matrix np.zeros((n, n)) for i in range(n): for j in range(n): matrix[i][j] similarity(responses[i], responses[j]) return matrix sim_matrix pairwise_similarity(responses) print(回答两两相似度矩阵:) print(np.round(sim_matrix, 2)) print(平均相似度:, round(float(sim_matrix.mean()), 2))运行结果回答两两相似度矩阵: [[1. 0.68 0.24] [0.68 1. 0.2 ] [0.24 0.2 1. ]] 平均相似度: 0.53平均相似度只有 0.53提示模型对这个问题没有形成一致答案系统应该触发兜底策略。如果三次回答都非常相似平均相似度接近 1.0系统就可以相对放心地直接返回。实际生产中通常会使用 embedding 模型计算向量余弦相似度比字符相似度更稳健。这里用 SequenceMatcher 只是为了演示流程不依赖外部模型。4.3 让模型显式给出置信度另一种实现思路是修改 Prompt让模型在回答内容之外额外输出一个 0 到 1 的置信度。例如请回答下面的问题。回答结束后另起一行输出你对答案的置信度范围 0 到 1只输出数字。 问题上海明天会下雨吗这种方式的优点是简单直接缺点是模型口头报出的置信度往往校准得很差。在温度较高时让它输出 0.9它可能依然给出错误答案。所以Prompt 自报置信度更适合作为辅助信号不能作为唯一的决策依据。如果想更可靠可以把自报置信度和多次采样结果结合起来如果模型自报置信度低或者多次采样结果不一致只要有一个信号异常系统就进入降级处理。4.4 Agent 策略不确定就调用工具在 AI Agent 场景里不确定性推理不只是用来判断“要不要拒绝回答”还可以驱动 Agent 的行为。一个比较常用的策略是“不确定性驱动的工具调用”Agent 收到用户指令。先在大模型内部生成一个初步方案。如果方案对应的置信度偏低Agent 不直接执行而是先检索知识库、查询数据库、调用搜索接口。工具结果返回后根据新证据更新置信度再决定是否继续执行。举个例子用户让 Agent“把上周的订单汇总发到邮箱”。Agent 如果能明确找到上周订单数据置信度较高可以直接执行如果它对时间范围、订单状态、收件人邮箱存在多种理解就应该先向用户确认而不是贸然发邮件。这种机制本质上把不确定性推理变成了系统的“安全阀”宁可多问一次也不在模糊状态下执行高风险操作。5. 实战给 QA 系统加上“不确定性决策层”5.1 场景与目标假设有一个企业知识库问答系统用户会问关于订单、物流、售后等问题。系统内部使用一个大模型生成答案。目前的痛点是模型遇到知识库没覆盖的问题时会编造一个看似合理的回答。现在我们要增加一个“不确定性决策层”让系统在不确定时自动选择直接回答。多次采样后给出多数答案。转人工或触发知识库检索。目标不是让模型永不犯错而是让错误发生在可控范围内。5.2 决策流程设计决策流程可以设计成下面几步第一步模型对问题生成初始答案同时得到一组 logits。第二步根据 logits 计算熵。如果熵低于阈值说明模型对答案比较确定直接返回。第三步如果熵高于阈值模型进入多次采样模式。设置较高 temperature生成多个答案。第四步计算多次采样答案之间的语义一致性。如果一致性较高则选择出现频率最高的答案如果一致性很低则转人工或触发检索。这里把熵作为第一道门槛把多次采样一致性作为第二道门槛。两道门槛都通过才认为答案可靠。5.3 完整代码实现下面这段代码是完整可运行的最小示例。为了不依赖具体大模型 API我用随机函数模拟模型输出核心决策逻辑可以直接迁移到真实项目。# uncertain_qa_demo.py import numpy as np from collections import Counter def softmax(logits: np.ndarray) - np.ndarray: max_logit np.max(logits) exp_logits np.exp(logits - max_logit) return exp_logits / np.sum(exp_logits) def distribution_entropy(probs: np.ndarray) - float: probs np.clip(probs, 1e-12, 1.0) return -float(np.sum(probs * np.log(probs))) def simulate_model_answer(question: str, seed: int 0): 模拟模型返回答案和 logits。 真实项目中这里替换成 LLM API 调用即可。 rng np.random.default_rng(seed) answers [ 订单会在 24 小时内发货。, 订单预计明天发出。, 我无法确定订单状态请联系人工客服。 ] logits rng.normal(sizelen(answers)) probs softmax(logits) idx int(np.argmax(probs)) return answers[idx], probs def run_decision(question: str, entropy_threshold: float 1.0, max_samples: int 5): 带不确定性决策层的问答流程 # 第一轮直接生成答案计算熵 answer, probs simulate_model_answer(question, seed0) ent distribution_entropy(probs) if ent entropy_threshold: return { answer: answer, strategy: 直接回答, entropy: round(ent, 4), samples: None } # 低置信度时多次采样 sample_answers [] for i in range(max_samples): ans, _ simulate_model_answer(question, seedi) sample_answers.append(ans) counter Counter(sample_answers) most_common_ans, most_common_cnt counter.most_common(1)[0] # 如果多数答案占比超过 60%认为是稳定答案 if most_common_cnt / max_samples 0.6: final_answer most_common_ans strategy 多次采样后回答 else: final_answer 需要转人工或触发知识库检索 strategy 转人工/检索 return { answer: final_answer, strategy: strategy, entropy: round(ent, 4), samples: sample_answers } # 运行示例 result run_decision(我的订单什么时候发货) print(最终回答:, result[answer]) print(使用策略:, result[strategy]) print(第一轮熵值:, result[entropy]) if result[samples]: print(多次采样结果:) for s in result[samples]: print( -, s)5.4 运行结果与分析由于使用了随机数模拟每次运行结果会略有不同。但决策逻辑是稳定的如果第一轮熵比较低系统直接回答延迟最低。如果熵较高系统自动进入多次采样模式。多次采样后如果答案一致返回多数答案如果答案分散转人工或触发知识库检索。这个流程最大的好处是把“模型是否可信”的判断从用户侧转移到了系统侧。用户可能无法分辨模型答案的真假但系统可以通过概率和一致性信号提前识别高风险输出。5.5 如何迁移到真实 LLM 项目把这个示例迁移到真实项目时需要做几处关键替换第一simulate_model_answer函数替换成真实模型调用。对于 OpenAI 兼容接口可以传入 temperature 参数实现不同采样对于开源模型可以直接修改采样参数。第二logits 不一定总是能拿到。如果接口不提供 logits可以用多次采样的平均置信度来代替第一轮熵判断。第三文本相似度建议使用 embedding 模型计算余弦相似度而不是字符相似度。字符相似度对中文同义表达不敏感意思是相近但写法不同的句子可能被误判为不一致。第四阈值需要根据实际数据调参。可以用一批历史问题做验证统计不同阈值下的转人工率、误判率和延迟选择业务上可接受的平衡点。6. 常见误区与排查清单6.1 常见误区不确定性推理听起来简单实际落地时容易踩坑。这里整理几个常见误区。第一个误区是把“模型说不知道”等同于“系统处理了不确定性”。很多模型在 Prompt 引导下会说“我不确定”但这只是表面行为系统并没有量化不确定性。如果后续决策仍然依赖最高概率答案那“我不知道”只是一句空话。第二个误区是只看熵不看校准。熵低只能说明模型内部概率分布集中不代表概率值可靠。就像学生考试时信心满满但成绩未必好。需要同时关注离线校准指标。第三个误区是多次采样时 temperature 设置不合理。temperature 太低多次采样结果基本一致失去排查意义temperature 太高回答会变得混乱无法稳定判断。通常用 0.7 到 1.0 作为多次采样的起点比较合适具体要看模型和场景。第四个误区是忽视延迟。多次采样会把推理成本放大 N 倍。如果不做分级策略所有请求都走多次采样系统的服务能力会明显下降。更合理的做法是先用低成本信号判断只有低置信度样本才进入多次采样流程。6.2 常见问题排查表问题现象可能原因排查与解决思路模型对所有问题都给出高置信度模型校准差输出概率过度自信使用验证集计算 ECE尝试温度缩放调整决策阈值多次采样结果一致但答案依然是错的语义一致性不等于正确性模型可能稳定地犯错引入外部知识源校验结合检索结果做事实核对熵值很高但系统仍直接返回答案决策层没有把熵纳入判断逻辑检查决策代码确保熵超过阈值时进入降级流程转人工率高业务无法承受成本第一轮阈值设置过松统计历史数据用精确率和召回率曲线重新选择阈值多次采样后回答分散但频率最高的答案不是正确选项候选答案设计不合理或采样次数太少增加采样次数优化 Prompt引入更好的语义聚类方法7. 工程落地建议把不确定性变成产品能力7.1 把校准指标加入评估体系在模型评估阶段除了准确率、BLEU、ROUGE 等常规指标建议增加校准相关指标。比如计算测试集上的 ECE、绘制置信度-准确率曲线。如果团队在评估模型时只比较“谁的回答更准”很容易选出一个表面分数高但过度自信的模型。校准指标能帮团队识别出那些“犯错时不自知”的模型这类模型在真实业务中风险其实更高。7.2 阈值、日志与人工回流不确定性决策层的阈值不应该拍脑袋定建议按照下面的方式管理在测试集上模拟不同阈值下的转人工率、错误率、直答率。根据业务可接受的风险水平选择阈值。上线后记录每条请求的熵、采样一致性、决策策略、最终用户反馈。定期用线上日志评估阈值是否需要调整。同时要建立人工回流闭环。转人工的样本不能只停留在客服系统里应该定期分析哪些问题是模型频繁不确定的是不是知识库缺少对应内容据此反向优化知识库和 Prompt。7.3 成本与延迟控制多次采样会显著增加推理成本。一个可行的优化思路是级联决策先用低温度单次生成计算快速信号比如熵。只有低置信度样本才进入多次采样流程。只有多次采样仍然不一致的样本才转人工或触发更强力的检索。这种“瀑布式”策略能在保证安全性的同时把平均延迟和成本控制在可接受范围内。7.4 安全边界置信度不等于真实风险概率最后必须强调一个原则模型输出的置信度只是模型内部的统计信号业务上不能把它当成真实世界的概率来使用。在医疗、金融、法律等高风险场景模型置信度不能作为唯一决策依据。比如金融系统不能因为模型给出了 95% 的违约概率就直接拒绝贷款还需要把模型输出交给业务规则引擎结合其他因子综合判断。不确定性推理的价值在于辅助决策而不是替代业务风控。它让系统知道“什么时候应该放慢速度、寻求更多信息”这正是可靠 AI 应用的重要能力。8. 总结与下一步学习建议本文围绕 AI 不确定性推理这个主题建立了从概念到落地的一套知识框架。你可以把关键点浓缩成下面几句话不确定性分为偶然而知与认知两大类应对策略完全不同。熵用来量化模型对答案的确定程度校准用来衡量置信度是否可信。生成式场景下多次采样与语义一致性比单次 token 概率更可靠。工程落地时不确定性决策层就是系统的安全阀低置信度时检索、转人工、放弃执行。不确定阈值需要结合成本和风险在测试集上反复验证。如果接下来想深入研究可以按这条路继续走第一优先级在现有项目里增加“熵 多次采样一致性”两个信号记录线上日志观察模型在什么场景下最不确定。第二优先级用验证集计算 ECE尝试最简单的温度缩放校准方法。第三优先级阅读贝叶斯深度学习和概率模型相关材料理解 Dropout 不确定性、深度集成等学术方向的思路。第四优先级如果团队在做 AI Agent可以把不确定性驱动工具调用的策略落到一个具体流程上先跑通一个小范围实验。实际项目里不需要一开始就搭建一套复杂的不确定性推理引擎。从最简单的“熵阈值 转人工”开始把信号收集起来再逐步优化阈值和决策策略效果往往比直接套用复杂模型更快。希望你也能在自己的 AI 系统里给不确定性留一个位置。