尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

为什么LLM的置信度分数不可信?工程化评估输出可靠性的替代方案

为什么LLM的置信度分数不可信?工程化评估输出可靠性的替代方案 当你向一个大型语言模型LLM提问并得到答案时你是否曾想过追问一句“你对这个答案有多大的信心” 或者你是否在构建基于LLM的应用时试图从模型的输出中提取一个“置信度分数”用来决定是否采纳这个答案或者触发人工审核如果你有过这样的想法或实践那么这篇文章就是为你写的。一个正在被广泛讨论但许多开发者尚未完全认清其风险的核心观点是不要向LLM索要置信度分数更不要盲目相信它给出的任何关于自身确定性的量化指标。这听起来可能有些反直觉。在传统软件和机器学习模型中置信度或概率分数是评估模型输出可靠性的基石。然而将这套逻辑直接套用在LLM上是一个危险且容易导致系统故障的误区。LLM本质上是一个基于海量文本训练的概率模型它的核心任务是“生成最可能的下一个词”而不是“评估自身知识的真实性或确定性”。当它被要求给出一个信心分数时它只是在“扮演”一个能评估信心的角色生成一段符合该角色预期的文本。这个分数本身很可能只是又一个“幻觉”的产物。本文将深入剖析为什么LLM的“自信”不可信拆解其背后的技术原理并通过实际场景和代码示例为你提供一套在工程实践中安全、有效评估LLM输出可靠性的替代方案。无论你是正在集成ChatGPT API的应用开发者还是研究RAG检索增强生成或智能体Agent架构的研究者理解这一点都将帮助你构建更稳健、更可信的AI系统。1. 为什么“置信度分数”在LLM中是一个伪命题要理解这个问题我们需要回到LLM的基本工作原理。LLM是一个自回归的语言模型它的训练目标是预测给定上文后下一个词的概率分布。当它生成“巴黎是法国的首都”这句话时它并不是在调用一个名为“世界地理知识”的数据库并返回一个匹配结果而是在计算“巴黎”、“是”、“法国”、“的”、“首都”这些词依次出现的概率有多高。这个概率基于它在训练数据中看到的模式——因为“巴黎是法国的首都”这个序列在它的训练语料中出现了无数次。那么当它被问及“巴黎是法国的首都吗”并回答“是的”之后如果你追问“你有多确定请给出一个0到1的分数”会发生什么LLM并没有一个独立的“确定性评估模块”。它只是在继续执行它的核心任务根据对话历史和当前问题生成合理的后续文本。它“知道”在人类对话中当被问及信心时通常会给出一个数字。因此它会从它的概率分布中采样出一个看起来合理的数字比如“0.95”。这个“0.95”是生成出来的就像它生成“是的”这个词一样。它并不代表模型对“巴黎是法国首都”这个事实有95%的把握只代表“在类似语境下人类说‘0.95’这个词的概率较高”。更危险的是LLM在“幻觉”即生成与事实不符的内容时同样可以表现得非常“自信”。因为它生成错误答案和生成高信心分数遵循的是同一套文本生成逻辑。一个完全虚构的事实同样可能被模型以“0.99”的“信心”输出。让我们用一个简单的代码示例来直观感受这一点。我们使用OpenAI的API或任何类似接口来模拟这个过程。import openai import os # 请替换为你的实际API Key或在环境变量中设置 # os.environ[OPENAI_API_KEY] your-api-key client openai.OpenAI(api_keyos.environ.get(OPENAI_API_KEY)) def ask_with_confidence(question): 向模型提问并要求其给出信心分数 prompt f请回答以下问题并在答案后以[信心分数]的格式附加一个0到1之间的数字表示你对答案的确信程度。 问题{question} 答案 response client.chat.completions.create( modelgpt-3.5-turbo, messages[{role: user, content: prompt}], temperature0.1, # 降低随机性让输出更确定 ) return response.choices[0].message.content # 测试1简单事实问题 question1 珠穆朗玛峰的高度是多少米 answer1 ask_with_confidence(question1) print(f问题{question1}) print(f回答{answer1}) print(- * 50) # 测试2可能诱发幻觉的复杂或模糊问题 question2 请详细描述一下名为量子波动速读法的科学原理及其发明者。 answer2 ask_with_confidence(question2) print(f问题{question2}) print(f回答{answer2})运行这段代码你可能会得到类似这样的输出问题珠穆朗玛峰的高度是多少米 回答珠穆朗玛峰的高度是8848米。[信心分数0.98] -------------------------------------------------- 问题请详细描述一下名为量子波动速读法的科学原理及其发明者。 回答量子波动速读法是一种被宣传但缺乏科学依据的速读方法声称通过感知书本的量子波动来快速理解内容其发明者信息不明多与一些商业培训机构的宣传相关。[信心分数0.85]对于第一个问题答案正确信心分数高。对于第二个问题模型正确地指出了该方法缺乏科学依据但依然给出了一个不低的“0.85”的信心分数。关键在于这个分数是模型“生成”的而不是“计算”出来的。如果我们问一个它完全不知道但会胡编乱造的事情呢它很可能在编造答案的同时附上一个同样高的信心分数。因此直接依赖LLM自我报告的信心分数来决策相当于用幻觉来验证幻觉其可靠性为零。2. LLM输出不确定性的真实来源是什么既然不能问LLM自己那我们该如何理解它的不确定性它的不确定性主要来自以下几个层面这些才是我们应该关注和衡量的知识边界与训练数据偏差LLM的知识完全来自其训练数据。对于训练数据中高频、一致出现的事实如“水的化学式是H₂O”模型输出稳定且正确。对于低频、矛盾或训练数据中不存在的信息模型容易产生幻觉或不确定的输出。提示词Prompt的敏感性与歧义LLM对提示词的微小变化极其敏感。同一个问题换一种问法可能得到不同甚至相反的答案。问题本身的模糊性也会直接导致答案的不确定性。生成过程的随机性即使使用相同的模型和提示词temperature温度和top_p核采样等参数也会影响输出。较高的温度会增加随机性导致同一问题多次询问得到不同答案。上下文长度与注意力机制局限在处理长文本时模型可能会“遗忘”或混淆上下文中的关键信息导致基于错误上下文生成答案。这些不确定性是固有的、系统性的。一个负责任的LLM应用架构必须设计外部机制来应对这些不确定性而不是寄希望于模型的内省。3. 工程实践如何不依赖“置信度”而评估LLM输出我们不能问LLM“你有多确定”但我们可以从外部设计一系列检查和平衡机制来评估其输出的可靠性。以下是几种经过验证的工程化方法。3.1 方法一自我一致性Self-Consistency与多次采样这是最直接且有效的方法之一。核心思想是让模型多次回答同一个问题通过调整随机种子或采样参数然后统计答案的一致性。高一致性通常意味着问题清晰且答案在模型的知识范围内是确定的。低一致性意味着问题模糊、有歧义或者触及了模型的知识盲区答案不可靠。import openai from collections import Counter import os client openai.OpenAI(api_keyos.environ.get(OPENAI_API_KEY)) def ask_multiple_times(question, n5, temperature0.7): 多次询问同一个问题收集答案 answers [] for i in range(n): response client.chat.completions.create( modelgpt-3.5-turbo, messages[{role: user, content: question}], temperaturetemperature, # 保持一定的随机性 ) answer response.choices[0].message.content.strip() answers.append(answer) return answers def analyze_consistency(answers): 分析答案的一致性 counter Counter(answers) most_common_answer, most_common_count counter.most_common(1)[0] total len(answers) consistency_ratio most_common_count / total print(f总共采样 {total} 次。) print(f出现最频繁的答案{most_common_answer} (出现了{most_common_count}次)) print(f一致性比例{consistency_ratio:.2%}) print(所有答案分布, dict(counter)) # 我们可以设定一个阈值比如一致性大于80%则认为答案相对可靠 reliability_threshold 0.8 is_reliable consistency_ratio reliability_threshold return is_reliable, most_common_answer # 测试一个事实性问题 print(测试1事实性问题 - 光在真空中的速度是多少) answers1 ask_multiple_times(光在真空中的速度是多少请只回答数字和单位。, n5) reliable1, final_answer1 analyze_consistency(answers1) print(f结论答案{final_answer1} 是否可靠 {reliable1}\n) # 测试一个模糊/有争议的问题 print(测试2模糊问题 - 最好的编程语言是什么) answers2 ask_multiple_times(最好的编程语言是什么请只回答语言名称。, n5) reliable2, final_answer2 analyze_consistency(answers2) print(f结论答案{final_answer2} 是否可靠 {reliable2})运行结果可能如下测试1事实性问题 - 光在真空中的速度是多少 总共采样 5 次。 出现最频繁的答案299792458 m/s (出现了4次) 一致性比例80.00% 所有答案分布{299792458 m/s: 4 约3.00×10^8 m/s: 1} 结论答案299792458 m/s 是否可靠 True 测试2模糊问题 - 最好的编程语言是什么 总共采样 5 次。 出现最频繁的答案Python (出现了2次) 一致性比例40.00% 所有答案分布{Python: 2 JavaScript: 1 Java: 1 C: 1} 结论答案Python 是否可靠 False通过这种方法我们无需模型自评而是通过其输出行为的统计特征从外部推断出了答案的可靠性。对于模糊问题低一致性比例本身就是一个强烈的风险信号。3.2 方法二基于检索的验证RAG架构的核心在RAG检索增强生成系统中评估可靠性的黄金标准是检查LLM生成的答案是否与提供给它的检索上下文Retrieved Context一致。步骤通常如下用户提问。从知识库如向量数据库中检索出与问题最相关的文档片段Context。将“问题上下文”一起交给LLM要求它基于给定的上下文生成答案。事后可以设计一个“验证步骤”检查生成的答案中的关键事实、实体或数据是否能在提供的上下文中找到明确支持。如果答案中出现了上下文未提及的新信息则可能是幻觉。# 假设我们有一个简单的“验证器”函数用于检查答案中的实体是否出现在上下文中 # 这是一个高度简化的示例真实场景可能需要更复杂的NLP匹配或使用另一个LLM进行验证。 def simple_fact_checker(answer, context): 一个简单的事实检查器。 在实际应用中这里可能会使用命名实体识别NER提取答案中的实体和主张 然后与上下文进行语义匹配或字符串匹配。 # 简化为如果答案中的主要部分非停用词不在上下文中则标记为潜在风险 import re from nltk.corpus import stopwords import nltk # 需要先下载stopwords: nltk.download(stopwords) stop_words set(stopwords.words(english)) words_in_answer set(re.findall(r\b\w\b, answer.lower())) meaningful_words words_in_answer - stop_words words_in_context set(re.findall(r\b\w\b, context.lower())) # 检查有多少关键答案词汇出现在上下文中 supporting_words meaningful_words words_in_context support_ratio len(supporting_words) / len(meaningful_words) if meaningful_words else 1.0 print(f答案中的关键词汇{meaningful_words}) print(f上下文中存在的关键词汇{words_in_context}) print(f重合的关键词汇{supporting_words}) print(f上下文支持度{support_ratio:.2%}) # 设定一个支持度阈值 threshold 0.5 # 50%的关键词需要被支持 return support_ratio threshold, support_ratio # 模拟一个RAG场景 question 特斯拉Cybertruck的续航里程是多少 retrieved_context 根据特斯拉官网2023年公布的数据Cybertruck全轮驱动版的续航里程估计为547公里340英里。 llm_answer 特斯拉Cybertruck的续航里程最高可达547公里并且支持快速充电。 is_supported, ratio simple_fact_checker(llm_answer, retrieved_context) print(f问题{question}) print(f检索到的上下文{retrieved_context}) print(fLLM生成的答案{llm_answer}) print(f答案是否被上下文支持 {is_supported} (支持度{ratio:.2%}))这个例子展示了RAG系统中内置验证的基本思路。更成熟的系统会使用专门的“一致性评估模型”或“事实核查模块”来完成这个任务。3.3 方法三元提示Meta-Prompting与思维链Chain-of-Thought验证我们可以通过设计更复杂的提示词引导LLM展示其推理过程然后我们对这个推理过程进行评估而不是只看最终答案。思维链CoT要求模型“一步一步思考”。通过检查其推理步骤的逻辑是否连贯、是否基于合理的事实可以间接评估最终答案的可靠性。如果推理链条断裂或包含明显错误则答案不可信。自我反思Self-Reflection在模型给出答案后要求它从另一个角度如“扮演一个挑剔的评审”来找出自己答案中可能存在的问题。虽然这依然是在让LLM评估自己但通过角色转换和任务分解有时能暴露出之前未发现的矛盾。def ask_with_cot(question): 使用思维链提示词提问 cot_prompt f请回答以下问题。请务必按照以下步骤进行 1. 首先逐步分析这个问题拆解其中的关键信息和要求。 2. 然后根据你的知识进行推理。 3. 最后得出最终答案。 问题{question} 请开始你的逐步思考 response client.chat.completions.create( modelgpt-3.5-turbo, messages[{role: user, content: cot_prompt}], temperature0.1, ) return response.choices[0].message.content # 测试一个需要计算或推理的问题 question 如果一个篮子里有3个苹果和4个橘子我拿走了2个水果那么篮子里最有可能还剩几个苹果和几个橘子 answer_with_cot ask_with_cot(question) print(answer_with_cot)输出会包含模型的推理过程。作为开发者你可以或设计一个规则引擎/轻量级模型来解析这个过程检查其合理性。例如推理中是否考虑了“拿走的水果可能是任意组合”这一关键点。4. 在Agent与RAG架构中集成可靠性评估在更复杂的LLM应用架构中如智能体Agent或RAG管道可靠性评估应作为一个独立的、可配置的组件有时称为“评估器”或“守卫”模块存在。一个典型的RAG Agent工作流可能如下用户输入 - [查询理解/路由] - [检索器] - 获取上下文 - [生成器(LLM)] - 生成初步答案 - [可靠性评估器] - 评估通过 - 是 - 返回答案给用户 | 否 | - [处理策略] - (例如请求澄清、返回保守答案、触发人工审核)可靠性评估器可以实现我们上面讨论的任一或多种方法一致性检查器让生成器用不同参数多次生成比较结果。事实核查器将答案与检索到的源文档进行比对。格式/规则验证器检查答案是否符合预定义的格式如JSON、日期或业务规则。# 一个概念性的Agent配置包含评估组件 agent_pipeline: steps: - name: query_understanding component: llm_router params: model: gpt-3.5-turbo prompt: 分析用户意图... - name: knowledge_retrieval component: vector_store_search params: top_k: 5 - name: answer_generation component: llm_generator params: model: gpt-4 temperature: 0.1 - name: reliability_assessment # 可靠性评估组件 component: ensemble_validator # 组合验证器 params: methods: - name: self_consistency runs: 3 threshold: 0.66 - name: fact_vs_context threshold: 0.7 fallback_action: human_review # 评估不通过时的降级策略5. 常见问题与排查思路在实际开发中你可能会遇到以下典型问题问题现象可能原因排查方式解决方案模型对明显错误答案给出高“自信”分数混淆了“文本生成概率”与“事实确定性”。模型在流畅地编造。使用“自我一致性”方法多次采样。检查答案是否在多次运行中稳定。放弃使用模型自评的信心分数改用外部一致性检验。RAG系统中答案与源文档矛盾模型忽略了提供的上下文或上下文本身质量差、不相关。实现一个“答案-上下文”对齐检查模块。查看检索到的文档相关性分数。优化检索器确保上下文质量。在提示词中强化“仅基于给定上下文回答”的指令。使用引用溯源Citation强制模型指明出处。评估器本身不一致或性能差评估方法如一致性检查的阈值设置不合理或评估逻辑有bug。构建一个包含“已知正确答案”和“已知幻觉答案”的测试集对评估器进行测试。校准评估阈值。考虑使用更复杂的评估模型如训练一个专门的“事实性分类器”。采用多种评估方法组合集成评估。系统对于模糊问题处理生硬评估器将所有低一致性答案都简单拒绝用户体验差。分析被拒绝问题的类型区分“知识性模糊”和“主观性/开放性”问题。设计更精细的降级策略。对于主观问题可以提示用户“这是一个开放性问题通常的看法有...”而不是直接拒绝。6. 最佳实践与工程建议彻底摒弃“置信度分数”依赖从架构设计之初就明确LLM自我报告的任何确定性指标都不可作为业务逻辑的判断依据。设计外部评估闭环将可靠性评估作为LLM应用的一个必选组件。根据应用场景的容错率选择合适的方法一致性检查、事实核查、规则验证等。实施分级处理策略不要简单地“通过”或“拒绝”答案。设计一个处理管道高可靠性直接返回给用户。中可靠性可以返回但附加说明如“根据现有信息答案可能是...”或提供引用来源。低可靠性触发降级策略如请求用户澄清、转向更保守的答案模板、或移交人工处理。持续监控与评估在生产环境中持续收集用户反馈、标注答案的正确性并用这些数据来优化你的检索器、生成提示词和评估器阈值。提示词工程通过精心设计的提示词可以在一定程度上约束模型减少幻觉。例如强调基于上下文“请严格根据以下提供的信息回答问题如果信息不足请明确说‘根据给定信息无法回答’。”要求展示推理“请一步步思考并最终给出答案。”限制回答范围“请用‘是’、‘否’或‘不确定’来回答。”理解成本与延迟的权衡自我一致性多次调用和复杂的验证流程会增加API调用成本和响应延迟。需要在可靠性、成本和用户体验之间取得平衡。理解“不要向LLM索要置信度分数”这一原则是构建可靠AI应用的关键一步。这迫使我们将评估的责任从黑箱模型内部转移到我们可控的、透明的工程系统之中。通过采用自我一致性检验、基于检索的验证、思维链分析等外部方法我们可以为LLM的输出构建起有效的“安全护栏”。最终一个健壮的LLM应用不是一个盲目信任模型的系统而是一个深知模型局限性并为此设计了多层次防御和验证机制的系统。这不仅是技术上的最佳实践也是在当前AI发展阶段对用户和业务负责的体现。
返回列表