大模型不确定性推理:让AI知道何时该说“不知道”
2026/8/31 3:04:46 网站建设 项目流程

最近和 AI 应用开发者交流时,被问得最多的一个问题不是“模型能不能答对”,而是“模型什么时候不该自信回答”。这个问题背后,正是 AI 不确定性推理。围绕大模型、Agent 和 AI 幻觉的讨论里,DeepMind 团队多次强调过一个方向:一个可靠的系统不只需要更强的生成能力,还要知道自身结论的边界在哪里。这篇技术文章会围绕不确定性推理展开,讲清楚它是什么、为什么重要,以及怎样基于 token 概率、多次采样和校准评估,把这些思路落地到实际工程中。

1. 为什么“知道不知道”比“答得多”更重要

1.1 从确定性输出到不确定性推理

传统软件系统的行为是可预期的:同一个输入,在相同条件下会得到相同结果。大模型改变了这一点。同一个问题,换一个温度参数,或者换一次采样,得到的内容可能完全不同。更关键的是,模型不会在每一次回答旁边写清楚“我这次回答有 80% 的把握”或“我其实没学过这个知识点”。

不确定性推理要解决的就是这个问题。它不是在问“模型输出的是什么”,而是在问“模型对这次输出有多确定”。这种确定程度需要有可计算、可验证、可接入业务逻辑的量化方式。

如果不做这一步,大模型应用就只能处于“看起来能回答问题”的状态。用户问一个超出知识边界的冷门问题,模型可能用非常流畅的话术编造一个看似合理的答案。此时系统无法区分“回答正确且自信”和“回答错误但自信”。对搜索摘要、智能客服、Agent 自动执行任务这类场景,这种区分能力直接决定系统能不能上线。

1.2 偶然不确定性与认知不确定性

机器学习里把不确定性分成两类,理解这个区分是落地的第一步。

偶然不确定性,也叫 aleatoric uncertainty,来自数据本身的内在随机性。例如天气预测中,同一个气象条件可能对应不同的实际天气;医疗诊断中,同一个影像特征可能对应不同疾病。这种不确定性即使收集更多数据也无法完全消除,只能建模成概率分布。

认知不确定性,也叫 epistemic uncertainty,来自模型知识的缺失。模型没见过的题型、训练数据里覆盖不足的领域、推理链路中缺失的关键事实,都会造成认知不确定性。这类不确定性理论上可以通过补充数据、改进训练、增加检索来降低。

把两类不确定性分开,工程意义很明显:偶然不确定性高时,系统应该输出概率或区间,而不是硬给一个点估计;认知不确定性高时,系统应该触发检索、人工确认或者拒绝回答。如果混在一起,就很难决定下一步动作。

不确定性类型来源能否通过更多数据降低典型应对策略
偶然不确定性数据本身随机性、标签噪声、任务歧义通常不能完全消除输出概率分布、置信区间,或让用户补充信息
认知不确定性训练数据覆盖不足、知识边界、推理缺失可以检索增强、补充训练数据、拒绝回答、转人工

1.3 大模型里的不确定性来源

大模型的不确定性不是单一来源。在实际系统中,至少可以观察到以下几类:

第一,采样不确定性。模型解码时从概率分布中采样,temperature越高,输出变化越大。这类不确定性可以通过多次采样观察。

第二,参数不确定性。训练完成后,模型权重是固定的,但我们并不清楚权重对某个输入的响应是否稳健。同一个问题换一种问法,模型表现可能有很大波动。

第三,知识边界不确定性。模型不知道自己哪些知识是完整的。训练数据截止时间之后的新闻、内部文档、数据库里的实时状态,都会超出模型的知识边界。

第四,任务歧义不确定性。用户的问题本身可能包含多种理解方式。比如“帮我写一封邮件”,没说收件人、语气、重点内容,模型只能猜测。此时模型表现得再自信,也是在猜。

第五,上下文幻觉。长上下文场景里,模型可能把无关信息当作依据,或者受 prompt 中误导性内容影响。这种不确定性往往表现为“输出流畅但事实错误”。

理解这些来源之后,才能选择合适的不确定性量化方法。不同方法衡量的对象不一样,后续接入业务的含义也不一样。

2. 量化不确定性:从 token 概率到校准区间

2.1 softmax 概率和 token logprob 是最直接的信号

大模型在生成每个 token 时,都会先计算词表上的概率分布,最终输出 token 通常来自这个分布。很多 API 会返回每个 token 的logprob,也就是对数概率。把这组值拿来做聚合,就得到最简单的不确定性信号。

需要说明的是,token 概率并不等于模型对整句话正确性的置信度。它只表示“在给定上下文和已生成内容时,下一个 token 被选中的概率”。但由于它计算成本低、获取方便,仍然是生产系统里最常用的基础信号。

下面是使用兼容 OpenAI 接口的模型服务获取 token logprob 的示例:

from openai import OpenAI client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY") resp = client.chat.completions.create( model="qwen2.5-7b-instruct", messages=[{"role": "user", "content": "鲁迅是哪里人?"}], temperature=0.2, logprobs=True, top_logprobs=5, ) content_logprobs = resp.choices[0].logprobs.content total = 0.0 count = 0 for item in content_logprobs: if item.logprob is not None: total += item.logprob count += 1 avg_logprob = total / max(count, 1) approx_confidence = math.exp(avg_logprob) print("平均 token 对数概率:", avg_logprob) print("近似置信度:", approx_confidence)

这里有几个关键点:

  • 请求时必须显式传logprobs=True,否则logprobs字段为空。
  • 不要直接对整句 logprob 求平均后当作“正确答案概率”,它只能作为一个相对信号。
  • top_logprobs可以看到候选 token 的概率差距。如果最高概率 token 和第二个 token 概率接近,说明模型在关键位置上是摇摆的。

2.2 多次采样与一致性投票

多次采样是另一种低成本方法。用相同的 prompt、相同的输入,设置temperature稍高,让模型生成多次,然后比较多个输出的语义一致性。

如果五次生成结果高度一致,说明模型在这个输入上比较稳定。如果五次结果各不相同,即使每一次输出都很流利,也需要提高警惕。

下面是一个简化示例:

import openai client = openai.OpenAI(api_key="your-key") def sample_multiple(prompt, n=5, temperature=0.7): resp = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": prompt}], n=n, temperature=temperature, ) texts = [choice.message.content.strip() for choice in resp.choices] return texts texts = sample_multiple("Python 里的 GIL 是什么?", n=5) # 这里需要归一化文本后计算两两语义相似度,简化示例只打印结果 for i, text in enumerate(texts): print(f"第 {i+1} 次:{text[:50]}")

实际生产里不要直接用字符串相等判断一致性,建议做两步处理:

  • 先把输出转成结构化字段,例如 JSON 里的关键字段。
  • 再做语义相似度比较,可以用 embedding 余弦相似度,也可以用规则判断核心字段是否一致。

一致性高不代表正确,只代表模型在该输入上的采样方差小。它要和正确率联合起来看,否则会出现“稳定地错”的情况。

2.3 模型集成、Monte Carlo Dropout 与贝叶斯近似

如果项目允许更高的计算成本,可以使用更接近贝叶斯推断的方法。

模型集成是经典做法。训练或部署多个结构相同但权重不同的模型,让它们分别预测,再用方差衡量不确定性。多个模型预测差异大,说明该输入处在模型不稳定区域。缺点是成本成倍增加,大模型场景下一般不会对完整模型做集成,更多是使用 LoRA 变体或者多套 checkpoint。

Monte Carlo Dropout 的思路是推理时保留 dropout,多次前向得到不同预测,用预测方差估计不确定性。它不需要训练多个模型,但需要模型支持推理阶段开启 dropout。对大模型推理服务来说,这种改造并不常见。

贝叶斯近似在大模型领域还在研究阶段。由于模型参数规模太大,直接计算参数后验分布不现实。当前工程上更可行的是借助已有研究成果的启发式方法,比如基于 hidden state 的置信度估计、基于 embedding 空间的密度估计、以及轻量级“不确定性评估头”。

这类方法适合对推理延迟不敏感、且希望获得比 token 概率更稳定信号的场景。落地前要先用评测集验证收益,不要因为论文效果好就直接替换现有方案。

2.4 从置信分到校准:ECE 与 Brier Score

模型给一个分数说“置信度 90%”,并不代表这个分数和真实正确率一致。只有当“置信度 90% 的样本,实际正确率也在 90% 左右”时,这个分数才是校准的。这个性质叫做 calibration。

评估校准最常用的指标是 ECE,期望校准误差。把预测按置信度分桶,比如 0 到 0.1、0.1 到 0.2,直到 0.9 到 1.0。对每个桶计算平均置信度和实际准确率的差距,再加权平均。

Brier Score 衡量的是概率预测和真实标签之间的整体偏差,公式为:

def brier_score(prob, label): # prob 是模型预测为正类的概率,label 是 0 或 1 return (prob - label) ** 2

ECE 和 Brier Score 都应该在独立评测集上计算。不能拿训练时见过的数据,也不能拿线上日志直接算,因为线上日志存在选择偏差,用户问的问题大多集中在模型相对擅长的区间。

如果发现 ECE 偏高,说明模型输出“很有把握”的时候,实际上经常犯错。此时就不能直接用原始置信度做业务决策,需要先做校准或者调整阈值。

3. 工程落地:把不确定性推理接进 Agent 和 RAG

3.1 Agent 决策:不确定性高时停止执行

Agent 应用和不带工具调用的聊天机器人最大的区别在于,Agent 会执行动作。一次错误的动作可能触发发送邮件、修改配置、调用支付接口、写入数据库等副作用。这时,模型输出置信度已经从“参考信息”变成了“风险控制信号”。

一个比较稳的设计是三层决策:

  • 第一层,生成阶段。根据 token logprob 和多次采样一致性计算基础置信度。
  • 第二层,动作阶段。判断模型选择工具的参数是否完整、是否超出合理范围。
  • 第三层,执行前兜底。对高影响动作设置人工确认或二次规则校验。

不确定性推理主要负责第一层和第二层。当置信度低于阈值时,Agent 不应该硬继续执行,而应该输出“需要澄清”或“无法确定,已停止操作”。

def decide_tool_action(tool_name, parameters, confidence): if confidence < 0.75: return { "action": "ask_user", "reason": "low_confidence", "message": "当前信息不足以安全执行该操作,请补充更多上下文。", } if tool_name == "send_email" and not parameters.get("recipient"): return { "action": "block", "reason": "missing_required_param", } return {"action": "execute", "params": parameters}

这里的关键不是阈值本身,而是“动作影响越大,阈值应该越高”。给 Agent 发送内部测试消息可以允许较低阈值,发起对外支付则必须接近最高阈值。

3.2 RAG 场景:检索结果不可靠时不要硬编

RAG,也就是检索增强生成,是目前降低知识幻觉的常见方案。但 RAG 的效果依赖一个前提:检索结果真的包含正确答案。实际工程里经常出现两种情况:

  • 检索结果与问题无关,模型却强行从中找关系。
  • 检索结果包含部分相关信息,但缺少关键细节,模型用自己训练时的记忆补全。

这两种情况都适合用不确定性推理做过滤。最简单的做法是把检索命中分数、生成置信度、上下文相关性分数三者组合成一个综合信号。当相关性低时,直接要求重检索而不是生成答案。

下面是一段伪代码逻辑:

def build_rag_answer(question, retrieved_docs, llm_generate): retrieval_score = max(doc.score for doc in retrieved_docs) if retrieval_score < 0.4: return { "answer": None, "status": "need_more_info", "message": "知识库中没有找到可靠资料。", } answer, token_confidence = llm_generate(question, retrieved_docs) if token_confidence < 0.5: return { "answer": None, "status": "low_confidence", "message": "生成结果置信度过低,建议联系人工客服。", } return {"answer": answer, "status": "ok"}

RAG 场景里最大的坑是“检索到了相似内容,但相似不等于正确”。比如用户问某公司最新财报数字,检索到的可能是上一季度的报告。单看文本相似度,得分不低。这时需要结合时间戳、文档版本、数字一致性等元信息做规则校验,不能只依赖模型自信程度。

3.3 产品交互:低置信度时主动澄清

面向用户的对话产品里,不确定性推理可以改变交互策略。模型不确定时,与其给一个流畅但可能错误的回答,不如主动向用户澄清。

澄清策略可以分等级:

  • 高置信度:直接回答。
  • 中等置信度:回答,但不加“肯定”语气,并提供“如果信息不对,请告诉我”的反馈入口。
  • 低置信度:不直接回答,列出用户的几个歧义点,请用户确认。
  • 极低置信度:明确说明超出能力范围,建议使用搜索或转人工。

这种策略能显著减少“幻觉型回答”带来的信任损失。用户能接受模型说“不知道”,但不能接受模型用一本正经的语气编造内容。

3.4 最小实现:给 LLM 输出加一个置信度评估层

综合前面几种方法,可以做一个最小可用的置信度评估层。思路是同时采三个信号:

  • token logprob 平均分
  • 多次采样的归一化一致性
  • 模型自评估分数

将三个信号做加权平均,得到最终置信度。

def evaluate_confidence(response, sampled_texts, self_report_score): token_conf = estimate_from_logprob(response) consistency = estimate_from_sampling(sampled_texts) self_conf = normalize(self_report_score, 0.0, 1.0) final_score = ( 0.4 * token_conf + 0.4 * consistency + 0.2 * self_conf ) return final_score

自评估分数是指让模型对自己的回答打分,例如在 prompt 中要求:

请评估你刚才的回答是否可靠,输出 0 到 1 之间的可靠度分数。只输出分数,不输出解释。

这个信号不能单独用,因为模型可能高估自己,但它能补充 token 概率和采样一致性没有覆盖的部分,例如“意识到了自己缺少某段知识”。三个信号组合之后,比单独使用任何一个都稳。

观察下来,这里要先明确一个原则:置信度评估层应该独立于对话主链路。主链路负责生成,评估层负责判断要不要用生成结果。如果把评估逻辑塞进 prompt 里让模型自己判断,容易出现既当运动员又当裁判的问题。

4. 生产环境接入路径与阈值设计

4.1 先确定决策层,再确定评估层

接入不确定性推理时,第一件事不是写代码,而是明确业务上要做什么决策。常见决策包括:

  • 是否直接展示回答
  • 是否允许 Agent 执行工具调用
  • 是否需要重新检索
  • 是否需要转人工
  • 是否需要用户澄清
  • 是否记录日志用于后续分析

决策不同,评估层的输入输出也不同。比如“是否展示回答”只需要一个粗略的风险分;“是否执行支付动作”则要求非常保守的规则加人工确认。

推荐顺序是:

  1. 列出所有可能动作。
  2. 给每个动作标风险等级。
  3. 确定每个风险等级需要什么信号。
  4. 再设计对应的评估函数和阈值。

不要反过来,先写了置信度函数再想怎么用,那样很容易出现“算了一个分但没人知道该拿它怎么办”的情况。

4.2 阈值、兜底和多级信号组合

阈值不应该拍脑袋定。简单做法是在评测集上画校准曲线,然后根据业务容忍度选阈值。

  • 如果误报成本高,也就是“把低置信度当高置信度”的后果严重,阈值要偏高。
  • 如果漏报成本高,也就是“把本可以正常执行的请求拦住”的代价大,阈值要偏低。

还需要准备多级信号。单一 token 概率容易被长回答拉低,也容易被短回答拉高。单一采样一致性采样成本高,延迟敏感场景用不了。实践中常用组合:

信号计算成本延迟影响特点
token logprob几乎无对短回答不稳定,回答越长越容易偏低
多次采样一致性明显增加能暴露采样方差,但成本为 N 倍
自评估分数增加一次额外生成可能高估,只能辅助
检索相关性分取决于检索链路RAG 场景下最有价值
规则校验适合财务、日期、邮箱等强约束字段

生产环境里,建议至少组合两个信号,并且为每个信号单独设置日志字段。这样后续排查问题时,能看清到底是哪一个信号触发了拦截。

4.3 日志、监控与回归评测

上线后要观察的不只是业务指标,还要包括置信度分布和校准度。

需要记录的字段至少包括:

  • 输入文本哈希或脱敏 ID
  • 输出文本
  • token logprob 均值
  • 多次采样一致性
  • 自评估分数
  • 最终置信度
  • 决策动作
  • 是否被用户纠错或投诉
  • 模型版本和温度参数

有了这些日志,就可以做离线回归:每周抽取新样本,重新计算 ECE 和 Brier Score,观察模型升级后校准度是否变化。模型版本从 A 升到 B,准确率可能提高,但置信度分布也可能整体偏移,导致线上阈值失效。这种情况只能用回归评测发现,不能等用户投诉。

5. 常见误区和排查链路

5.1 误区:softmax 概率高就是正确的

很多开发者第一次接不确定性推理时,会直接取 response 里第一个 token 的概率当成置信度。问题在于,模型生成是一个逐步过程,句子越长,整句概率越低,但每个 token 的局部概率可能都很高。

正确做法是把 token logprob 当作相对信号,不要当作绝对正确率。它更适合用来做排序和分组,比如把所有请求按 logprob 从低到高排列,优先人工审核最低的 10%。

5.2 误区:降低温度会让模型更可靠

降低temperature会让输出更稳定,但“稳定”和“正确”不是一回事。温度下降后,模型倾向于选择概率最高的 token,这个概率最高的路径可能是训练数据里常见说法,而不是事实正确的路径。

另外,低温度下多次采样的结果几乎一致,一致性分数会虚高。此时再用“采样一致性”作为不确定性信号就会失真。如果线上使用低温度,建议改用 logprob 和检索信号,不要依赖高温度采样实验得出的阈值。

5.3 误区:模型说“我不确定”就是在做不确定性推理

有些 prompt 设计会让模型回答“我不确定”,比如要求模型不知道时直接承认。这比硬编答案好,但它不是不确定性推理。

真正的不确定性推理要求分数可计算、可比较、可回测。模型说“我不确定”只是一个文本输出,无法变成阈值判断,也无法和线上校准数据做关联。所以应该保留这个交互体验,但在内部仍然计算 logprob、一致性和其他结构化信号。

5.4 从现象倒推原因的排查顺序

不确定性信号和预期不符时,按下面的顺序排查:

问题现象可能原因检查方式处理建议
置信度普遍偏高模型输出长度短、采样温度低、logprob 被极端值拉高按输出长度分桶统计置信度加入长度归一化或改用一致性信号
多次采样一致性高但错误率也高低温度、模型同源偏差、问题本身超出知识边界对比不同温度下的一致性分布引入检索信号和自评估,不只看一致性
阈值在测试集合适,线上失效线上输入分布与测试集不一致,或模型版本更新定期做分布漂移分析和回归评测重建校准集,重新标定阈值
模型自评估分数和人工评分相差大自评估 prompt 不稳、模型存在过度自信单独统计自评估分与实际准确率只作为辅助信号,不单独使用
Agent 拦截过多导致业务投诉阈值过高、信号权重不合适、用户输入本身模糊看拦截日志中拦截原因分布按动作风险分级设计不同阈值

排查时先确认输入没有变化,再确认模型版本和采样参数,最后再看评估函数实现。很多奇怪现象不是评估函数写错了,而是模型升级后输出分布变了,旧的阈值不再适用。

6. 最佳实践、可复用清单与下一步方向

6.1 建立自己的校准评测集

不要直接拿公开 benchmark 上的分数当作生产置信度。每个业务场景的输入差异很大,必须构造自己的评测集。

评测集至少包含:

  • 肯定能答对的基础问题
  • 知识边界之外的冷门问题
  • 上下文有矛盾信息的问题
  • 需要多步推理的问题
  • 用户表达本身有歧义的问题

每类问题标注期望行为:直接回答、澄清、拒绝回答、转人工。用这个集合验证置信度排序能力和校准度,不只是看准确率。

6.2 决策层兜底比单点评估更重要

不确定性推理能降低风险,但不能保证零错误。生产系统必须有决策层兜底:

  • 高风险操作配置人工确认。
  • 写操作前做参数白名单规则校验。
  • 用户可对结果反馈纠错。
  • 定期抽检低置信度区间的回答质量。

把不确定性分当作“风险提示”,而不是“事实判断依据”。这样即使某一项信号出现偏差,业务也不会被严重带偏。

6.3 面向 Agent 和 RAG 的扩展

下一步可以往两个方向扩展。

Agent 方向,把不确定性推理和工具调用链路结合。在模型选择工具时,不仅看意图匹配置信度,还要看参数完整性、上下文约束一致性和执行结果反馈。如果工具返回异常结果,后续回答也应该重新评估不确定性,而不是沿用最初的高置信度。

RAG 方向,把检索相关性和生成置信度做成联合评估。当检索召回合理但生成低置信度时,可能是上下文太长导致注意力分散;当检索得分低但生成高置信度时,要警惕模型在用训练记忆补全,而不是基于检索内容回答。

6.4 落地检查清单

检查项说明
是否已经列出业务决策类型没有决策类型,评估函数就不知道为谁服务
是否至少使用了两个信号单信号容易被多种噪声干扰
是否在独立评测集上做过校准不能只看准确率,要看 ECE 和 Brier Score
是否按动作风险设置不同阈值高影响动作和低影响动作不能用一个阈值
是否有日志记录每个信号否则出现问题后很难复盘
是否定期重新标定阈值模型升级或输入漂移后阈值可能失效
是否有兜底规则高风险操作必须有人工确认或规则拦截
是否区分了学习环境和生产环境学习环境可以只做 demo,生产环境要加日志和监控

不确定性推理不是一个一次性功能,而是一套持续维护的工程能力。它的价值不在于让模型“承认不知道”,而在于让整个系统能根据可计算的信号决定什么时候继续、什么时候停下、什么时候把问题交给用户或人工处理。上面这些方法都不复杂,难的是把每个信号建模清楚、把阈值校准到业务可接受范围,并在模型迭代过程中持续回归。从最小闭环开始,先接入 logprob 加日志,再逐步加入采样一致性、检索信号和规则兜底,是比较稳妥的演进路线。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询