十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

大模型不确定性推理:让AI知道何时该说“不知道”

大模型不确定性推理:让AI知道何时该说“不知道” 最近和 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_urlhttp://localhost:8000/v1, api_keyEMPTY) resp client.chat.completions.create( modelqwen2.5-7b-instruct, messages[{role: user, content: 鲁迅是哪里人}], temperature0.2, logprobsTrue, top_logprobs5, ) 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)这里有几个关键点请求时必须显式传logprobsTrue否则logprobs字段为空。不要直接对整句 logprob 求平均后当作“正确答案概率”它只能作为一个相对信号。top_logprobs可以看到候选 token 的概率差距。如果最高概率 token 和第二个 token 概率接近说明模型在关键位置上是摇摆的。2.2 多次采样与一致性投票多次采样是另一种低成本方法。用相同的 prompt、相同的输入设置temperature稍高让模型生成多次然后比较多个输出的语义一致性。如果五次生成结果高度一致说明模型在这个输入上比较稳定。如果五次结果各不相同即使每一次输出都很流利也需要提高警惕。下面是一个简化示例import openai client openai.OpenAI(api_keyyour-key) def sample_multiple(prompt, n5, temperature0.7): resp client.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: prompt}], nn, temperaturetemperature, ) texts [choice.message.content.strip() for choice in resp.choices] return texts texts sample_multiple(Python 里的 GIL 是什么, n5) # 这里需要归一化文本后计算两两语义相似度简化示例只打印结果 for i, text in enumerate(texts): print(f第 {i1} 次{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) ** 2ECE 和 Brier Score 都应该在独立评测集上计算。不能拿训练时见过的数据也不能拿线上日志直接算因为线上日志存在选择偏差用户问的问题大多集中在模型相对擅长的区间。如果发现 ECE 偏高说明模型输出“很有把握”的时候实际上经常犯错。此时就不能直接用原始置信度做业务决策需要先做校准或者调整阈值。3. 工程落地把不确定性推理接进 Agent 和 RAG3.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 执行工具调用是否需要重新检索是否需要转人工是否需要用户澄清是否记录日志用于后续分析决策不同评估层的输入输出也不同。比如“是否展示回答”只需要一个粗略的风险分“是否执行支付动作”则要求非常保守的规则加人工确认。推荐顺序是列出所有可能动作。给每个动作标风险等级。确定每个风险等级需要什么信号。再设计对应的评估函数和阈值。不要反过来先写了置信度函数再想怎么用那样很容易出现“算了一个分但没人知道该拿它怎么办”的情况。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 加日志再逐步加入采样一致性、检索信号和规则兜底是比较稳妥的演进路线。
返回列表