跳到正文

RAG PROJECT INTERVIEW · Q18 / 25

资料里没有答案时,RAG 怎么避免强行生成?

从“最相近不等于相关”出发,讲清阈值、无答案测试集、Query 回退和拒答策略怎样共同控制幻觉。

作者与复核:吴师兄内容依据:公开 RAG 教程、GitHub 教学代码与工程推导查看关联教程 →查看吴师兄公开作品 →

25 道题目Q18
本页内容13 节

30 秒先说结论

检索结果必须先通过相关性和证据充分性判断,不能因为 Top-K 非空就交给模型生成。阈值要用“应该回答”和“应该拒答”两类真实问题共同校准;低于门槛时可以尝试原 Query 回退、受控扩展检索或明确拒答,但不能为了提高回答率无限降低阈值。

先看一个常见场景。

知识库里只有国内差旅报销制度,用户却问:“海外出差时,当地交通票据丢失应该怎么补办?”

资料里没有海外票据补办规则,但向量库通常仍会返回几段“最相近”的内容,比如国内票据遗失说明、差旅报销材料清单,或者交通费用标准。

这些内容都和问题有关,却没有真正回答问题。

如果系统把它们直接交给大模型,大模型很可能把几段相近内容整理成一套完整流程。文字顺,步骤也像那么回事,但关键规定并不在资料里。

这就是 RAG 面试中很容易被低估的一道题:

资料里没有答案时,RAG 怎么判断证据不够,并避免强行生成?

很多人的第一反应是:“设置一个相似度阈值,低于阈值就拒答。”

这句话只答到了最外层。面试官很快会继续问:

  1. 向量库几乎总能返回结果,相关和足够怎样区分?
  2. 阈值应该怎么定,换模型后还能不能继续用?
  3. 有答案却被拒绝,和没答案却强答,哪个更严重?
  4. 检索分数过关后,生成阶段为什么仍可能编造?

为什么“搜到了”仍然可能没有答案?

向量检索做的是相对排序。

给它一个问题,它会在当前索引里找出语义上最接近的若干片段。即使整座知识库都没有正确答案,仍然可以排出第一名、第二名和第三名。

第一名只代表“在现有候选中最像”,不代表“足以支持结论”。

关键词检索也有类似问题。问题里出现“票据”“交通”“补办”,资料里恰好有这些词,搜索结果就可能看起来很相关。但如果原文只讲国内流程,它仍然无法回答海外场景。

因此至少要区分三种状态。

第一种,证据明确存在。问题要求的对象、条件和结论都能在原文中找到。

第二种,证据部分存在。资料覆盖了主题,却缺少时间、地区、版本、对象或例外条件。

第三种,只有相似内容。候选与问题属于同一大类,但无法推出答案。

相关、部分充分和可以作答的证据边界

检索分数回答“像不像”,证据判断还要回答“能不能由这些原文推出结论”。

第二种最危险。

完全无关的内容往往容易被挡住,部分相关的内容却很容易让模型补齐缺失细节。模型会沿着已有文本继续组织,最终给出一段语气确定、事实却没有依据的回答。

所以,无答案控制真正判断的不是“有没有文档”,而是“当前文档是否足以回答当前问题”。

一次安全作答要经过哪几道门?

可以把链路拆成四道门。

第一道门是搜索范围。

请求属于哪个用户、允许查哪个知识库、哪些文档和版本,以及哪些内容当前仍然有效,都要在检索前确定。这些条件应该直接约束搜索范围,而不是搜完全库后再由前端隐藏。范围错了,后面的高分没有意义。

下面用一个纯教学场景说明权限边界。假设用户只能查看公开制度,检索却把内部草稿带了回来。即使草稿能回答问题,系统也不能使用它。无答案控制首先是一条权限和版本边界,而不只是相似度边界。

第二道门是候选相关性。

相似度门槛可以先筛掉明显不相关的片段,但分数的含义与 Embedding 模型、距离定义、向量库和语料分布都有关。例如,余弦相似度和 L2 距离的方向与数值含义并不相同,即使都被转成“相似度”,也不能共用同一个门槛。

因此,门槛要用当前知识库中可回答和不可回答的问题一起校准。看一个分数所在的区间只能完成粗筛,不能代替后面的证据充分性判断。

第三道门是证据充分性。

候选相关,并不代表问题所需条件已经齐全。系统要检查核心实体、限定条件和必要证据是否出现。流程题可能需要完整步骤,比较题可能需要两边信息,多跳问题可能需要两段原文共同成立。

第四道门是生成后核验。

检索阶段通过后,模型仍可能加入证据外的数字、时间、范围或强断言。输出中的事实句需要再次和本轮证据对应。找不到支持的句子,应该删除、改写为不确定表达,或者让整次回答进入降级流程。

无答案控制的四道门

范围过滤、相关性筛选、充分性判断和生成后核验,分别拦截不同来源的错误。

这四道门不能互相替代。

Prompt 里写一句“资料不足就说不知道”,不能修复错误的搜索范围。相似度很高,也不能证明一组片段覆盖了答案所需的全部条件。生成后增加引用编号,同样不能让一条没有依据的结论自动变真。

阈值应该怎么定?

阈值不是从网上抄一个小数,也不是看几个演示问题拍出来的。

先准备两组问题。

第一组是可回答问题。每个问题都要标出参考答案,以及能直接支持答案的原文位置。

第二组是不可回答问题。它们不是随便写的无关问题,而应覆盖真实风险,比如知识库没有这个主题、主题相关但缺少关键条件、询问旧资料之外的新版本、需要的两份证据只存在一份。

然后用同一套检索配置跑完两组问题,记录最高分、前几条候选、重排分数、关键词覆盖和最终动作。

调门槛时要同时观察两类错误。

一类是误拒绝。资料里明明有答案,系统却说没有依据。

另一类是错误放行。资料里没有答案,系统仍然让模型生成。

二者不会同时自动变好。从阈值取舍上看,门槛提高时,错误放行可能减少,误拒绝却可能增加;门槛降低时,回答率可能上升,无依据回答也可能一起上升。最终变化必须用同一批正反样本验证。

用可回答与不可回答问题共同校准门槛

门槛选择不是追求某一边全对,而是看两类错误在具体业务中的代价,并保留逐题证据。

评测时不要只留下一个平均分。最好按问题类型分组查看。

原词明确的问题、口语改写的问题、领域术语、版本条件和多段证据问题,它们的分数分布可能不同。一个统一门槛挡住了大部分无关问题,仍可能在“相关但不充分”的问题上失效。

模型、Chunk 切分、距离度量或知识库更新后,也要重新跑回归。分数是当前流水线的产物,不是一条永远有效的业务规则。

四类“看似相关却不能答”的陷阱

第一种,主题相关,限定条件缺失

还是前面的问题。用户问海外票据补办,候选只讲国内票据遗失。

这时不能因为“票据”“遗失”“交通”都对上就回答。应该把“海外”视作答案成立的必要条件。如果证据没有覆盖这个条件,系统最多只能说明找到了国内相关规定,不能外推海外流程。

第二种,新旧版本冲突

用户问当前流程,知识库里只有旧版制度。

旧版原文可能与问题高度相关,甚至每个关键词都能命中。但相关性不能替代时效性。搜索前应优先检查文档状态和版本,无法确认当前有效版本时,回答要明确边界。

第三种,Query 重写改变了原意

用户问:“这个现在不能申请了吗?”重写模型却把它改成“这个如何申请”。

改写后的问题更容易搜到申请流程,但把否定关系弄丢了。例如,改写后没有合格结果时,可以再用原问题检索。同时要保存两次检索的候选,用连续对话与换题样本检查回退究竟救回了什么,又引入了什么噪声。

更稳妥的做法还要保存原 Query、改写 Query 和两边候选,检查实体、否定词和时间条件是否保持。回退只能救一部分错误,不能证明改写一定可信。

第四种,证据被切散了

用户问一个带例外条件的问题,前一个 Chunk 写适用范围,后一个 Chunk 才写“以下情况除外”。检索只带回前半段,模型就可能给出相反结论。

这不是简单的低分问题,而是证据不完整。系统可以根据前后 Chunk ID 扩展上下文,也可以在评测集中把完整证据标成多个必要片段。只命中其中一段时,不应算作可以回答。

这四类失败分别指向范围、版本、Query 和 Chunk。把它们全归为“阈值太低”,只会让排查越来越乱。

为什么一个综合分仍然不够?

有些系统会把向量分数、关键词覆盖、Rerank 分数和模型判断合成一个“可回答分”。这样做方便执行统一决策,但综合分本身不能代替证据分析。

第一,几个分数未必是同一把尺子。向量相似度、BM25 分数和 Rerank 输出的范围不同,直接相加会让某一路长期主导结果。

第二,同一个分数可能对应不同缺口。一个问题得分偏低,可能是用户换了说法,也可能是正确文档不在允许范围,或者证据被切散。处理动作不能只由分数高低决定。

第三,必要条件很难被一个平均分表达。问题问“新版流程在海外是否适用”,候选同时出现“新版”和“海外”,却分别来自两段互不相关的资料。词面覆盖很好,证据链仍然不成立。

因此,系统可以用综合分做第一层筛选,但决策记录还要保留本次问题需要哪些信息、候选实际覆盖哪些信息、缺少什么条件,以及最终为什么选择回答、澄清或拒绝。

一种便于审计的返回结构可以包含四部分:decision 表示回答或拒绝,evidence 保存本轮采用的原文,missing_conditions 记录没有找到的条件,reason 说明触发了哪条规则。

用户未必需要看到所有内部字段,但研发人员必须能回放。否则系统今天拒绝一个问题,团队只知道“分数没过”,无法判断应该补资料、改切分还是调检索。

对于部分可回答的问题,还可以把回答拆成已证实与未证实两部分。

例如资料能确认国内票据遗失流程,却没有海外规定。可以把“只回答国内部分,并明确标出海外部分缺少证据”当作一种待业务验证的降级设计;它不能默认适用于所有产品,也不能把国内规则外推到海外。

这要求充分性判断落到答案要点,而不是只给整道题一个真假标签。

充分性规则还要和问题类型对应。定义题可能只需要一段直接原文,流程题需要关键步骤,比较题需要双方证据,带例外的问题则必须同时找到通用规则和限制条件。系统不知道问题需要什么,就无法判断当前证据缺了什么。

因此,可以先把 Query 解析成待验证要点,再逐项绑定证据。解析模型只负责提出检查清单,不负责补答案。某个要点没有原文支持时,它应留在缺失列表里,而不是由模型常识填上。

这种设计也方便向用户解释:“已找到申请材料,但未找到办理时限”,比一个模糊的低置信度分数更容易理解和修正。

怎样把“证据充分”落实到事实句?

充分性判断如果只停在整道问题上,仍然容易漏掉局部编造。一个回答往往同时包含对象、条件、动作、时间和例外,其中四项有依据,不代表第五项也可以由模型补全。

可以先把问题转成待核对的事实槽位。例如“海外票据丢失后多久内补办”至少包含适用地区、票据状态、处理动作和办理时限。检索结果回来后,逐项记录哪段原文支持哪个槽位。某个槽位没有证据,就不能因为其他三项分数很高而判定整题可以完整作答。

这一步不要求模型公开内部推理过程。服务端只需要得到结构化的检查结果:本轮准备陈述哪些事实、每个事实绑定哪些证据、还缺哪些条件、证据之间是否冲突。之后再由策略层决定完整回答、有限回答、澄清还是拒答。

冲突证据要单独处理。新旧制度、不同地区或不同用户类型的规则可能同时被召回,且各自都与问题相关。如果系统只把它们的分数相加,很可能拼出一份从未存在过的流程。此时应先比较版本、适用范围和来源状态;无法确定哪条有效时,把冲突暴露给用户或转人工,而不是让生成模型自行“综合”。

生成后还要做一次反向检查。把答案拆成可验证陈述,确认每条陈述引用的原文确实包含相同实体、条件与结论。模型写出证据没有提供的具体时限、金额或强制措辞时,即使整段回答主题正确,也应删除该句或退回重新生成。

为了便于复盘,每次决策应保存所需事实槽位、采用证据、缺失项、冲突项、最终动作和规则版本。这样发生误拒绝时,可以区分是需求拆错、证据没找齐还是策略过严;发生错误放行时,也能定位是哪条缺失条件被错误忽略。它比只保存一个置信度数字更能指导修复。

证据不够时,系统可以做什么?

不是所有低置信度请求都必须立刻结束,可以按风险选择动作。

第一种动作是受控重试。

系统可以调整文本匹配要求、改写问题,或者适度扩大候选。每次重试都要有次数上限,并记录使用了什么策略。不能不断放宽门槛,直到勉强找到一段能说的话。

第二种动作是澄清。

问题缺少产品、地区、时间或对象时,询问用户补充条件往往比猜测更好。“您问的是哪个版本?”比依据错误版本回答一整段更可靠。

第三种动作是有限降级。

系统可以返回已经找到的相关资料,同时清楚说明它只能覆盖哪部分。例如:“现有资料只包含国内票据遗失处理,未找到海外场景规定。”这既没有假装完全不知道,也没有把局部证据扩成完整结论。

第四种动作是拒答。

当资料范围不允许、关键证据缺失,或者事实核验失败时,直接说明当前知识库没有足够依据。拒答文案应描述缺少什么,而不是只抛一句“无法回答”。

证据不足时的四种动作

重试、澄清、有限降级和拒答对应不同缺口,动作越往后,系统越明确地停止生成事实。

怎么证明这套机制真的有效?

验证至少要覆盖检索、决策和生成三个层面。

检索层记录正确证据是否进入前 K 条、候选是否来自允许范围,以及必要的多段证据是否找齐。

决策层建立一个混淆表:可回答问题被正确放行多少,不可回答问题被正确拒绝多少,同时单独列出误拒绝和错误放行。业务更害怕哪一类错误,要提前说明,不能只报一个整体准确率。

生成层逐句检查事实是否有证据支持。尤其关注数字、日期、条款编号、适用范围和“必须”“一定”这类强断言。

回归集还要保存每次 bad case 的原问题、文档版本、候选原文、各阶段分数、系统动作和最终输出。下次换 Embedding、调整 Chunk 或更新知识库时,重新跑同一批问题。

如果只测“答案看起来对不对”,很难知道是检索真的找到了证据,还是模型凭常识碰巧说对了。

无答案追问怎么接:先说错误代价

回答这组问题前,先说明业务更怕误拒绝还是错误放行。门槛、澄清和拒答策略,都应围绕这两类代价展开。

只用最高相似度能判断无答案吗?

不能。最高分只说明它比其他候选更接近,不说明它覆盖问题所需的全部条件。还要检查实体、时间、范围、必要证据和来源状态。

为什么不把门槛调高一点,宁可多拒绝?

门槛过高会把口语改写、长尾术语和多段证据问题一起挡住。应该用两类样本观察误拒绝与错误放行,再根据风险选择门槛和澄清策略。

Prompt 要求“资料不足就拒答”够不够?

不够。模型不知道搜索范围是否正确,也可能把相关但不充分的片段当成完整证据。Prompt 是最后约束之一,不是前面三道门的替代品。

HyDE 能不能解决知识库没有答案?

不能。HyDE 生成的是用于检索的假设文本,不是真实证据。它可以帮助寻找表达不同的资料,却不能把假设内容当成知识库事实。

误拒绝后应该直接降低阈值吗?

先定位原因。可能是 Query 改写错了、正确文档不在搜索范围、Chunk 切坏了、模型不理解术语,或者候选数量太少。直接降低门槛可能让另一批无答案问题被放行。

用四道门讲清回答边界

完整口述按“范围、相关、充分、核验”四道门展开,再把重试、澄清、有限降级和拒答放到对应缺口后面:

RAG 的无答案控制不能只判断检索有没有返回结果。当索引非空并要求返回 Top-K 时,向量库通常仍会给出相对更接近的内容,但这些内容未必足以回答。我的设计会分四层:先按用户、知识库、文档状态和版本限定搜索范围,再用相关性门槛筛掉明显无关候选,然后判断候选是否覆盖问题所需的实体、条件和多段证据,最后对生成结果中的事实句做证据核验。

阈值不会直接照搬某个示例值。我会准备资料里有答案和没有答案的两类问题,记录候选、分数和正确证据,分别统计有答案却被拒绝的误拒绝,以及没答案却被放行的错误回答。更换 Embedding、切分策略或知识库版本后,都要重新回归。

证据不足时也不是只有一种处理。系统可以在有限次数内改写或扩大候选,条件不清时询问用户,只有部分资料时说明能回答的边界,关键证据缺失时直接拒答。核心原则是相关不等于充分,假设文本不等于证据,不能为了提高回答率不断放宽门槛。

收尾时不要停在某个相似度阈值。应明确哪类证据缺口会触发什么动作,怎样分别观察误拒绝与错误放行,以及系统在不确定时能否给出清楚、可回归的退路。

INTERVIEW FOLLOW-UPS

面试官会怎样继续追问?

这些追问会继续检查方案取舍、验证方法和项目事实。
  1. Q01

    相似度阈值为什么没有通用数值?

  2. Q02

    有一段相关证据但不足以回答完整问题时怎么办?

  3. Q03

    扩大 Top-K 与降低阈值有什么不同风险?

  4. Q04

    怎样评估该回答时回答、该拒绝时拒绝?

PROJECT CHECK

换成你的项目,这几件事能否说清楚?

  • 构建有答案与无答案两组问题
  • 保存阈值附近的边界样本
  • 区分重试、降级和拒答动作
  • 检查回答每个事实是否有证据
用自己的项目经历练一次