这道题其实问的是,当检索已经做得很准了,生成模型为什么还会翻车,以及怎么解决。本质上是在考你对 [[RAG]] 流水线里检索和生成之间那个灰色地带的理解深度。
先说定位。很多人以为检索准了,生成就应该好,但实际情况经常是检索出来的片段本身没问题,模型就是不照着说。这里要分清楚几类情况:一种是检索片段太长或者互相矛盾,模型被搞糊涂了,这叫上下文组织问题;另一种是模型直接忽略检索内容,自己在那自由发挥,这是注意力对齐问题;还有一种是检索里全是专业术语,模型根本不认识,这是领域适配问题。你得先判断是哪种,才能对症下药。
具体说一下优化手段。最轻量的是提示工程,零成本。我会在 [[System Prompt]] 里加硬约束,比如“基于以下材料回答,禁止推测”,同时要求它给出引用标记,这样模型就知道必须忠实于上下文。还可以给几个 [[Few-shot]] 例子,展示“检索片段到忠实回答”的映射。另外,把温度调低,限制它的创造性。如果这些还不行,那就动上下文组织。比如片段太长,我会做递归摘要或者关键句提取,只喂最相关的部分。多片段冲突的话,先做 [[重排]],把最相关的排前面,或者检测到冲突时让模型分段生成。这里有个坑:位置偏见,模型容易记住开头和结尾,中间内容容易丢,所以我会把关键信息放在首尾,或者重要信息重复一遍。
如果轻量手段不够,就得考虑微调了,成本高一些。我会用 [[SFT]] 构造“检索上下文到忠实回答”的数据对,重点训练 拒答能力,上下文不足时明确说不知道,而不是瞎编。还有引用生成,让模型学会在回答里标注来源。更进一步,可以用 [[RLHF]] 或 [[DPO]],在奖励模型里加入“事实一致性”维度,惩罚 [[Hallucination]]。如果检索内容涉及大量领域术语,还需要做领域预训练,否则模型听不懂。
再说系统级的方案。比如生成后校验,用一个 NLI 模型或者 LLM 自己检查回答是否被上下文蕴含,不通过就拒答或重新生成。还有多模型路由,简单问题用小模型快速响应,复杂或高风险问题触发大模型加严格校验。
举个例子,在客服退款场景中,用户问“我买了东西没收到,怎么退钱”,检索模块命中了两条政策:一条说“未收到货可申请退款”,另一条说“需先联系卖家确认”。模型如果忽略其中一条,直接给“可以退款”,用户照做但卖家不同意,就会出问题。这时候,我会用提示工程要求模型必须综合所有相关片段,如果冲突则要求用户先确认。同时用生成后校验,确保回答被上下文蕴含。
这里有个落地风险:检索片段的格式不统一是常见隐形杀手。比如 PDF 解析残留乱码、表格转文本丢失结构,这些都会让模型误解。所以上线前我会特别检查数据预处理的质量。
其实还有一个延伸点,就是当检索和生成都调优到极致后,瓶颈可能出现在模型本身的知识边界上。比如检索内容是正确的,但模型内部预训练知识跟它矛盾,模型会倾向于相信自己的记忆。这时候就需要做 [[Self-RAG]] 或者 [[Chain-of-Verification]],让模型自己反思,先基于检索生成,再验证一致性。
所以整体来看,我的做法是先用轻量手段快速验证,不行再上微调,同时配合系统级兜底。我更倾向于把提示工程和上下文组织作为第一道防线,因为它们成本低、见效快,而微调是最后才考虑的重武器。